diff --git a/rest-api/openapi/custom.yaml b/rest-api/openapi/custom.yaml index edb34e1..0f6bfac 100644 --- a/rest-api/openapi/custom.yaml +++ b/rest-api/openapi/custom.yaml @@ -181,6 +181,30 @@ paths: description: Project saved successfully '404': description: Project not found + /projects/{project_name}/diagram-editors: + get: + tags: + - Diagrams + summary: Get a list of all open diagram editors for a project by name + operationId: getDiagramEditorsByProjectName + parameters: + - name: project_name + in: path + required: true + description: Unique name of the project + schema: + type: string + responses: + '200': + description: A list of open diagram editors + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/DiagramEditor' + '404': + description: Project not found /projects/{project_name}/diagrams: get: tags: diff --git a/rest-api/src/com/db/capella/Main.java b/rest-api/src/com/db/capella/Main.java index fd9d7c9..c8073e0 100644 --- a/rest-api/src/com/db/capella/Main.java +++ b/rest-api/src/com/db/capella/Main.java @@ -14,7 +14,7 @@ import org.osgi.framework.FrameworkUtil; public class Main implements IStartup { - public static final String BASE_URI = "http://localhost:5007/api/v1"; + public static final String BASE_URI = "http://0.0.0.0:5007/api/v1"; public static void log(int severity, String message, Throwable exception) { Bundle bundle = FrameworkUtil.getBundle(Main.class); diff --git a/rest-api/src/com/db/capella/api/impl/ProjectsApiServiceImpl.java b/rest-api/src/com/db/capella/api/impl/ProjectsApiServiceImpl.java index bf251a5..c6c20ee 100644 --- a/rest-api/src/com/db/capella/api/impl/ProjectsApiServiceImpl.java +++ b/rest-api/src/com/db/capella/api/impl/ProjectsApiServiceImpl.java @@ -1,22 +1,37 @@ package com.db.capella.api.impl; +import java.io.File; +import java.util.Collection; + +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.swt.widgets.Display; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.emf.common.util.URI; +import org.eclipse.sirius.business.api.dialect.DialectManager; +import org.eclipse.sirius.business.api.session.Session; +import org.eclipse.sirius.business.api.session.SessionManager; +import org.eclipse.sirius.diagram.ui.part.SiriusDiagramEditor; +import org.eclipse.sirius.ui.business.api.session.SessionEditorInput; +import org.eclipse.sirius.viewpoint.DRepresentationDescriptor; +import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.part.FileEditorInput; import com.db.capella.api.ApiException; import com.db.capella.api.ApiResponseMessage; import com.db.capella.api.NotFoundException; import com.db.capella.api.ProjectsApiService; import com.db.capella.integration.WorkspaceProjectInt; +import com.db.capella.model.Diagram; import com.db.capella.model.ImportProjectRequest; import jakarta.ws.rs.core.Response; @@ -24,6 +39,33 @@ @jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJerseyServerCodegen", comments = "Generator version: 7.7.0") public class ProjectsApiServiceImpl extends ProjectsApiService { + private static URI getEMFURIForAirdFile(IPath directoryPath) { + File directory = directoryPath.toFile(); + if (directory.isDirectory()) { + File[] files = directory.listFiles((dir, name) -> name.endsWith(".aird")); + if (files != null && files.length > 0) { + // Assuming there's only one .aird file in the directory + File airdFile = files[0]; + return URI.createFileURI(airdFile.getAbsolutePath()); + } + } + return null; + } + + private Session getSession(IProject project) throws ApiException { + URI airdFileName = getEMFURIForAirdFile(project.getLocation()); + if (airdFileName == null) { + throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "An .aird file is required to get the SystemEngineering"); + } + final Session session = SessionManager.INSTANCE.getSession(airdFileName, new NullProgressMonitor()); + if (session == null) { + throw new ApiException(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Cannot get session for project"); + } + return session; + } + private IProject getWorkspaceProjectByName(String name) throws ApiException { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProject workspaceProject = workspace.getRoot().getProject(name); @@ -34,12 +76,22 @@ private IProject getWorkspaceProjectByName(String name) throws ApiException { } @Override - public Response closeProjectByName(String projectName, - SecurityContext securityContext) - throws NotFoundException { - // do some magic! + public Response closeProjectByName(String projectName, SecurityContext securityContext) throws NotFoundException { + IProject workspaceProject; + try { + workspaceProject = getWorkspaceProjectByName(projectName); + } catch (ApiException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + try { + workspaceProject.close(null); + } catch (Exception e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } return Response.ok() - .entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")) + .entity(new ApiResponseMessage(ApiResponseMessage.OK, "Project '" + projectName + "' is closed.")) .build(); } @@ -48,20 +100,65 @@ public Response deleteProjectByName(String projectName, Boolean deleteContents, SecurityContext securityContext) throws NotFoundException { - // do some magic! - return Response.ok() - .entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")) - .build(); + IProject workspaceProject = null; + try { + workspaceProject = getWorkspaceProjectByName(projectName); + } catch (ApiException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + try { + workspaceProject.delete(deleteContents, true, null); + } catch (Exception e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "Project deleted")).build(); } @Override - public Response getDiagramsByProjectName(String projectName, - SecurityContext securityContext) + public Response getDiagramsByProjectName(String projectName, SecurityContext securityContext) throws NotFoundException { - // do some magic! - return Response.ok() - .entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")) - .build(); + IProject workspaceProject = null; + try { + workspaceProject = getWorkspaceProjectByName(projectName); + } catch (ApiException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + Session session = null; + try { + session = getSession(workspaceProject); + } catch (ApiException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + Collection representationDescriptors = DialectManager.INSTANCE + .getAllRepresentationDescriptors(session); + java.util.List diagramList = new java.util.ArrayList(); + if (true) { + for (DRepresentationDescriptor representationDescriptor : representationDescriptors) { + Diagram diagram = new Diagram(); + diagram.setId(representationDescriptor.getUid()); + diagram.setName(representationDescriptor.getName()); + // DRepresentation representation = + // representationDescriptor.getRepresentation(); + // DDiagram dDiagram = (DDiagram) representation; + // for (DRepresentationElement representationElement : + // representation.getRepresentationElements()) { + // if (representationElement.getTarget() instanceof ModelElement) { + // ModelElement modelElement = (ModelElement) representationElement.getTarget(); + // System.out.println(modelElement.getLabel()); + // System.out.println(modelElement.getFullLabel()); + // } + // } + // diagram.setId(representation.getUid()); + // diagram.setDescription(representationDescriptor.getDescription()); + // diagram.setName(representation.getName()); + diagramList.add(diagram); + } + } + return Response.ok().entity(diagramList).build(); } @Override @@ -75,15 +172,44 @@ public Response getProjectByName(String projectName, } @Override - public Response importProject(ImportProjectRequest importProjectRequest, - SecurityContext securityContext) + public Response importProject(ImportProjectRequest body, SecurityContext securityContext) throws NotFoundException { - // do some magic! - return Response.ok() - .entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")) - .build(); - } - + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + String projectFolderPath = body.getLocation(); + File projectFolder = new File(projectFolderPath); + if (!projectFolder.exists()) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, "Project folder not found")).build(); + } + File dotProjectFile = new File(projectFolder, ".project"); + if (!dotProjectFile.exists()) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, + "Project folder does not contain .project file")) + .build(); + } + IPath projectLocation = new Path(dotProjectFile.getAbsolutePath()); + try { + IProjectDescription projectDescription = workspace + .loadProjectDescription(projectLocation); + IProject project = workspace.getRoot().getProject(projectDescription.getName()); + if (project.exists()) { + return Response.status(Response.Status.CONFLICT) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, "Project already exists")).build(); + } + project.create(projectDescription, null); + project.open(null); + WorkspaceProjectInt projectInt = new WorkspaceProjectInt( + (org.eclipse.core.internal.resources.Project) project); + // todo: URL in response header is `http://localhost:5007/projects/(...)` which + // is wrong + return Response.created(new java.net.URI("/projects/" + projectInt.getName())) + .build(); + } catch (Exception e) { + e.printStackTrace(); + } + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, "Failed to import project")).build(); @Override public Response listProjects(SecurityContext securityContext) throws NotFoundException { @@ -99,12 +225,22 @@ public Response listProjects(SecurityContext securityContext) } @Override - public Response openProjectByName(String projectName, - SecurityContext securityContext) - throws NotFoundException { - // do some magic! + public Response openProjectByName(String projectName, SecurityContext securityContext) throws NotFoundException { + IProject workspaceProject; + try { + workspaceProject = getWorkspaceProjectByName(projectName); + } catch (ApiException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } + try { + workspaceProject.open(null); + } catch (Exception e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(new ApiResponseMessage(ApiResponseMessage.ERROR, e.getMessage())).build(); + } return Response.ok() - .entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")) + .entity(new ApiResponseMessage(ApiResponseMessage.OK, "Project '" + projectName + "' is opened.")) .build(); }