diff --git a/README.md b/README.md index 32a39489..63959302 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,13 @@ Users must select the elements that shall be exported to gUFO either selecting f ![A screenshot showing the "transformation to gUFO" window](./docs/feature-gufo.png) +### Automatic Diagram Generation + +Diagram generation allows users to include into their projects automatically generated diagrams that advantage from OntoUML features to create meaningful views of their ontologies. + +![A gif demonstrating the diagram generation feature.](./docs/feature-diagram-generation.gif) + + #### Continuous Updates The cloud-based features offered in the plugin are periodically updated. Updates in these features usually do not require updates in the Visual Paradigm plugin. diff --git a/docs/feature-diagram-generation.gif b/docs/feature-diagram-generation.gif new file mode 100644 index 00000000..b5bbe3d4 Binary files /dev/null and b/docs/feature-diagram-generation.gif differ diff --git a/pom.xml b/pom.xml index d6ddf9e5..a4d16255 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ it.unibz.inf.ontouml ontouml-vp-plugin - 0.4.0 + 0.5.0 OntoUML 2 Plugin for Visual Paradigm @@ -18,7 +18,8 @@ - "${project.basedir}${file.separator}scripts${file.separator}run-vp.bat" + "${project.basedir}${file.separator}scripts${file.separator}run-vp.bat" + @@ -43,11 +44,41 @@ + + org.junit.jupiter + junit-jupiter-api + 5.7.0 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.7.0 + test + + + com.google.truth + truth + 1.1.2 + test + + + com.google.truth.extensions + truth-java8-extension + 1.1.2 + test + + + com.fasterxml.jackson.core + jackson-databind + 2.12.1 + com.google.code.gson gson 2.8.5 + com.visualparadigm.app com.visualparadigm.app.lib.openapi @@ -173,6 +204,14 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + ${java.home}/bin/javadoc + + org.apache.maven.plugins maven-compiler-plugin @@ -271,6 +310,11 @@ + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + diff --git a/src/main/java/it/unibz/inf/ontouml/vp/OntoUMLPlugin.java b/src/main/java/it/unibz/inf/ontouml/vp/OntoUMLPlugin.java index 1eb9eb50..e8472a7b 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/OntoUMLPlugin.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/OntoUMLPlugin.java @@ -16,7 +16,7 @@ */ public class OntoUMLPlugin implements VPPlugin { - public static final String PLUGIN_VERSION_RELEASE = "0.4.0"; + public static final String PLUGIN_VERSION_RELEASE = "0.5.0"; public static final String PLUGIN_ID = "it.unibz.inf.ontouml.vp"; public static final String PLUGIN_NAME = "OntoUML Plugin"; public static final String PLUGIN_REPO = "https://github.com/OntoUML/ontouml-vp-plugin/"; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyPropertiesController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyPropertiesController.java index 452f2a89..d8e46288 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyPropertiesController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyPropertiesController.java @@ -4,11 +4,7 @@ import com.vp.plugin.action.VPAction; import com.vp.plugin.action.VPContext; import com.vp.plugin.action.VPContextActionController; -import com.vp.plugin.model.IAssociation; -import com.vp.plugin.model.IAssociationEnd; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.ITaggedValue; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.uml.Association; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyStereotypeController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyStereotypeController.java index b6ee4cc9..ffb5da0a 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyStereotypeController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ApplyStereotypeController.java @@ -11,11 +11,7 @@ import it.unibz.inf.ontouml.vp.model.uml.Association; import it.unibz.inf.ontouml.vp.model.uml.Class; import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import it.unibz.inf.ontouml.vp.utils.ActionIdManager; -import it.unibz.inf.ontouml.vp.utils.OntoUMLConstraintsManager; -import it.unibz.inf.ontouml.vp.utils.Stereotype; -import it.unibz.inf.ontouml.vp.utils.StereotypesManager; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; +import it.unibz.inf.ontouml.vp.utils.*; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/DiagramVerificationController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/DiagramVerificationController.java deleted file mode 100644 index 025b4fb2..00000000 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/DiagramVerificationController.java +++ /dev/null @@ -1,128 +0,0 @@ -package it.unibz.inf.ontouml.vp.controllers; - -import com.vp.plugin.ApplicationManager; -import com.vp.plugin.action.VPAction; -import com.vp.plugin.action.VPActionController; -import com.vp.plugin.diagram.IClassDiagramUIModel; -import com.vp.plugin.diagram.IDiagramUIModel; -import com.vp.plugin.view.IDialog; -import com.vp.plugin.view.IDialogHandler; -import it.unibz.inf.ontouml.vp.model.ServerRequest; -import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import it.unibz.inf.ontouml.vp.views.ProgressPanel; -import java.awt.Component; - -/** Implementation of toolbar button action responsible for performing diagram verification. */ -public class DiagramVerificationController implements VPActionController { - - private ProgressPanel progressPanel; - private ProgressDialog loading; - private IDialog mainDialog; - DiagramVerificationRequest request; - Thread thread; - - /** - * Performs OntoUML diagram verification. - * - * @param action - */ - @Override - public void performAction(VPAction action) { - - if (!hasOpenedClassDiagram()) { - ViewManagerUtils.simpleDialog( - "Diagram Verification", "Please open a diagram before running this command."); - return; - } - - request = new DiagramVerificationRequest(); - - loading = new ProgressDialog(); - ApplicationManager.instance().getViewManager().showDialog(loading); - - Thread thread = new Thread(request); - thread.start(); - } - - /** - * Called when the menu containing the button is accessed allowing for action manipulation, such - * as enable/disable or selecting the button. - * - *

OBS: DOES NOT apply to this class. - */ - @Override - public void update(VPAction action) {} - - private static boolean hasOpenedClassDiagram() { - final IDiagramUIModel[] diagramArray = - ApplicationManager.instance().getProjectManager().getProject().toDiagramArray(); - - if (diagramArray == null) return false; - - for (IDiagramUIModel diagram : diagramArray) - if (diagram instanceof IClassDiagramUIModel && diagram.isOpened()) return true; - - return false; - } - - protected class ProgressDialog implements IDialogHandler { - - @Override - public Component getComponent() { - progressPanel = new ProgressPanel(request); - return progressPanel; - } - - @Override - public void prepare(IDialog dialog) { - mainDialog = dialog; - mainDialog.setTitle("Verification Service"); - mainDialog.setModal(false); - mainDialog.setResizable(false); - dialog.setSize(progressPanel.getWidth(), progressPanel.getHeight() + 20); - progressPanel.setContainerDialog(mainDialog); - } - - @Override - public void shown() {} - - @Override - public boolean canClosed() { - mainDialog.close(); - return true; - } - } - - protected class DiagramVerificationRequest extends ServerRequest { - - @Override - public void run() { - while (keepRunning()) { - try { - final String response = - OntoUMLServerAccessController.requestModelVerification( - ModelElement.generateModel(true), loading); - - if (keepRunning()) { - if (response != null) { - mainDialog.close(); - request.doStop(); - ViewManagerUtils.logDiagramVerificationResponse(response); - } else { - loading.canClosed(); - request.doStop(); - } - } else { - loading.canClosed(); - request.doStop(); - ViewManagerUtils.cleanAndShowMessage("Request cancelled by the user."); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } -} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GUFOExportController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GUFOExportController.java deleted file mode 100644 index 7406e08f..00000000 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GUFOExportController.java +++ /dev/null @@ -1,231 +0,0 @@ -package it.unibz.inf.ontouml.vp.controllers; - -import com.vp.plugin.ApplicationManager; -import com.vp.plugin.action.VPAction; -import com.vp.plugin.action.VPActionController; -import com.vp.plugin.view.IDialog; -import com.vp.plugin.view.IDialogHandler; -import it.unibz.inf.ontouml.vp.OntoUMLPlugin; -import it.unibz.inf.ontouml.vp.model.Configurations; -import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; -import it.unibz.inf.ontouml.vp.model.ServerRequest; -import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import it.unibz.inf.ontouml.vp.views.GUFOExportView; -import it.unibz.inf.ontouml.vp.views.ProgressPanel; -import java.awt.Component; -import java.awt.FileDialog; -import java.awt.Frame; -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.stream.Collectors; - -/** - * Implementation of toolbar button Export to gUFO. - * - * @author Victor Viola - * @author Claudenir Fonseca - */ -public class GUFOExportController implements VPActionController { - - private ProgressPanel progressPanel; - private ProgressDialog loading; - private IDialog mainDialog; - - private ExportDialog menu; - private GUFOExportView _exportMenuView; - private IDialog _dialog; - MenuExport requestMenu; - - @Override - public void performAction(VPAction action) { - - requestMenu = new MenuExport(); - menu = new ExportDialog(); - - if (OntoUMLPlugin.getExportToGUFOWindowOpen() == true) return; - else OntoUMLPlugin.setExportToGUFOWindowOpen(true); - - ApplicationManager.instance().getViewManager().showDialog(menu); - } - - /** - * Called when the menu containing the button is accessed allowing for action manipulation, such - * as enable/disable or selecting the button. - * - *

OBS: DOES NOT apply to this class. - */ - @Override - public void update(VPAction action) {} - - private void saveFile(BufferedReader buffer, String exportFormat) throws IOException { - final Configurations configs = Configurations.getInstance(); - final ProjectConfigurations projectConfigurations = configs.getProjectConfigurations(); - final FileDialog fd = - new FileDialog( - (Frame) ApplicationManager.instance().getViewManager().getRootFrame(), - "Choose destination", - FileDialog.SAVE); - - String suggestedFolderPath = projectConfigurations.getExportGUFOFolderPath(); - String suggestedFileName = projectConfigurations.getExportGUFOFilename(); - String exportFormatExtension = exportFormat != "Turtle" ? ".nt" : ".ttl"; - - if (suggestedFileName.isEmpty()) { - String projectName = ApplicationManager.instance().getProjectManager().getProject().getName(); - suggestedFileName = projectName + exportFormatExtension; - } - - fd.setDirectory(suggestedFolderPath); - fd.setFile(suggestedFileName); - fd.setVisible(true); - - if (fd.getDirectory() != null && fd.getFile() != null) { - final String fileDirectory = fd.getDirectory(); - final String fileName = - !fd.getFile().endsWith(exportFormatExtension) - ? fd.getFile() + exportFormatExtension - : fd.getFile(); - final String output = buffer.lines().collect(Collectors.joining("\n")); - - Files.write(Paths.get(fileDirectory, fileName), output.getBytes()); - projectConfigurations.setExportGUFOFolderPath(fileDirectory); - projectConfigurations.setExportGUFOFilename(fileName); - configs.save(); - } - } - - public class ProgressDialog implements IDialogHandler { - - @Override - public Component getComponent() { - progressPanel = new ProgressPanel(requestMenu); - return progressPanel; - } - - @Override - public void prepare(IDialog dialog) { - mainDialog = dialog; - mainDialog.setTitle("Export to GUFO"); - mainDialog.setModal(false); - mainDialog.setResizable(false); - dialog.setSize(progressPanel.getWidth(), progressPanel.getHeight() + 20); - progressPanel.setContainerDialog(mainDialog); - } - - @Override - public void shown() {} - - @Override - public boolean canClosed() { - mainDialog.close(); - return true; - } - } - - protected class ExportDialog implements IDialogHandler { - - /** - * Called once before the dialog is shown. Developer should return the content of the dialog - * (similar to the content pane). - */ - @Override - public Component getComponent() { - _exportMenuView = - new GUFOExportView(Configurations.getInstance().getProjectConfigurations(), requestMenu); - return _exportMenuView; - } - - /** - * Called after the getComponent(). A dialog is created on Visual Paradigm internally (it still - * not shown out). Developer can set the outlook of the dialog on prepare(). - */ - @Override - public void prepare(IDialog dialog) { - _dialog = dialog; - _dialog.setTitle(OntoUMLPlugin.PLUGIN_NAME + " Configurations"); - _dialog.setModal(false); - _dialog.setResizable(false); - _dialog.setSize(_exportMenuView.getWidth(), _exportMenuView.getHeight() + 20); - _exportMenuView.setContainerDialog(_dialog); - } - - /** Called when the dialog is shown. */ - @Override - public void shown() {} - - /** Called when the dialog is closed by the user clicking on the close button of the frame. */ - @Override - public boolean canClosed() { - requestMenu.doStop(); - OntoUMLPlugin.setExportToGUFOWindowOpen(false); - ViewManagerUtils.cleanAndShowMessage("Request cancelled by the user."); - return true; - } - } - - public class MenuExport extends ServerRequest { - - final Configurations configs = Configurations.getInstance(); - final ProjectConfigurations projectConfigurations = configs.getProjectConfigurations(); - - @Override - public void run() { - while (keepRunning()) { - try { - - if (keepRunning()) { - if (!_exportMenuView.getIsOpen()) { - - if (_exportMenuView.getIsToExport()) { - - loading = new ProgressDialog(); - ApplicationManager.instance().getViewManager().showDialog(loading); - - final BufferedReader gufo = - OntoUMLServerAccessController.transformToGUFO( - ModelElement.generateModel(_exportMenuView.getSavedElements(), true), - projectConfigurations.getExportGUFOIRI(), - projectConfigurations.getExportGUFOFormat(), - projectConfigurations.getExportGUFOURIFormat(), - projectConfigurations.getExportGUFOInverseBox(), - projectConfigurations.getExportGUFOObjectBox(), - projectConfigurations.getExportGUFOAnalysisBox(), - projectConfigurations.getExportGUFOPackagesBox(), - projectConfigurations.getExportGUFOElementMapping(), - projectConfigurations.getExportGUFOPackageMapping(), - loading); - - if (gufo != null) { - saveFile(gufo, projectConfigurations.getExportGUFOFormat()); - ViewManagerUtils.cleanAndShowMessage("Model exported successfully."); - requestMenu.doStop(); - } else { - menu.canClosed(); - requestMenu.doStop(); - ViewManagerUtils.cleanAndShowMessage( - "Unable to transform to GUFO. Please check your model."); - } - } else { - menu.canClosed(); - requestMenu.doStop(); - ViewManagerUtils.cleanAndShowMessage("Request cancelled by the user."); - } - - OntoUMLPlugin.setExportToGUFOWindowOpen(false); - } - } else { - OntoUMLPlugin.setExportToGUFOWindowOpen(false); - menu.canClosed(); - requestMenu.doStop(); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } -} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GitHubAccessController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GitHubAccessController.java index 74f16251..3d6eb75c 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GitHubAccessController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GitHubAccessController.java @@ -6,11 +6,7 @@ import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.GitHubRelease; import it.unibz.inf.ontouml.vp.model.GitHubReleaseAsset; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.nio.channels.Channels; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportController.java new file mode 100644 index 00000000..e7b07d4e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportController.java @@ -0,0 +1,136 @@ +package it.unibz.inf.ontouml.vp.controllers; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.action.VPAction; +import com.vp.plugin.action.VPActionController; +import it.unibz.inf.ontouml.vp.model.Configurations; +import it.unibz.inf.ontouml.vp.model.GufoExportOptions; +import it.unibz.inf.ontouml.vp.model.GufoTransformationServiceResult; +import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; +import it.unibz.inf.ontouml.vp.model.vp2ontouml.Uml2OntoumlTransformer; +import it.unibz.inf.ontouml.vp.utils.SimpleServiceWorker; +import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; +import java.awt.FileDialog; +import java.awt.Frame; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +/** + * Implementation of toolbar button Export to gUFO. + * + * @author Victor Viola + * @author Claudenir Fonseca + */ +public class GufoExportController implements VPActionController { + + private static final String MESSAGE_MODEL_EXPORTED = "Model exported successfully."; + + private Configurations configurations; + private ProjectConfigurations projectConfigurations; + private String fileFormat = ".ttl"; + private Path filePath; + + @Override + public void performAction(VPAction action) { + configurations = Configurations.getInstance(); + projectConfigurations = configurations.getProjectConfigurations(); + GufoExportDialogHandler exportDialog = new GufoExportDialogHandler(projectConfigurations); + exportDialog.showDialog(); + + if (exportDialog.wasCancelled()) { + ViewManagerUtils.log("Request cancelled by the user."); + return; + } + + fileFormat = !"Turtle".equals(projectConfigurations.getExportGUFOFormat()) ? ".nt" : ".ttl"; + filePath = getFilePath(); + + new SimpleServiceWorker(this::task).execute(); + } + + private List task(SimpleServiceWorker context) { + try { + if (filePath == null) { + context.cancel(true); + return List.of(); + } + + final String project = Uml2OntoumlTransformer.transformAndSerialize(); + final String options = new GufoExportOptions(projectConfigurations).toJson(); + final GufoTransformationServiceResult result = + OntoUMLServerAccessController.requestModelTransformationToGufo(project, options); + final String gufoFile = result != null ? result.getResult() : ""; + + if (!context.isCancelled()) { + Files.write(filePath, gufoFile.getBytes()); + saveFilePath(); + ViewManagerUtils.log(MESSAGE_MODEL_EXPORTED); + return List.of(MESSAGE_MODEL_EXPORTED); + } + + return List.of(); + } catch (IOException e) { + if (!context.isCancelled()) { + ViewManagerUtils.log(e.getMessage()); + } + + e.printStackTrace(); + return List.of(e.getMessage()); + } + } + + private Path getFilePath() { + final FileDialog fileDialog; + final Frame rootFrame = (Frame) ApplicationManager.instance().getViewManager().getRootFrame(); + final String suggestedFolderPath = projectConfigurations.getExportGUFOFolderPath(); + String suggestedFileName = projectConfigurations.getExportGUFOFilename(); + + if (suggestedFileName.isEmpty()) { + final String projectName = + ApplicationManager.instance().getProjectManager().getProject().getName(); + suggestedFileName = projectName + fileFormat; + } + + final String title = "Choose export file destination"; + fileDialog = new FileDialog(rootFrame, title, FileDialog.SAVE); + + fileDialog.setFile(suggestedFileName); + fileDialog.setDirectory(suggestedFolderPath); + fileDialog.setMultipleMode(false); + fileDialog.setFilenameFilter((dir, name) -> name != null && name.endsWith(fileFormat)); + fileDialog.setVisible(true); + + final String fileDirectory = fileDialog.getDirectory(); + final String fileName = fileDialog.getFile(); + + if (fileDirectory != null && fileName != null) { + return fileName.endsWith(fileFormat) + ? Paths.get(fileDirectory, fileName) + : Paths.get(fileDirectory, fileName + fileFormat); + } + + return null; + } + + private void saveFilePath() { + final Path directoryPath = filePath.getParent(); + final String directoryPathName = directoryPath.toAbsolutePath().getFileName().toString(); + final String filePathName = filePath.getFileName().toString(); + + projectConfigurations.setExportGUFOFolderPath(directoryPathName); + projectConfigurations.setExportGUFOFilename(filePathName); + configurations.save(); + } + + /** + * Called when the menu containing the button is accessed allowing for action manipulation, such + * as enable/disable or selecting the button. + * + *

OBS: DOES NOT apply to this class. + */ + @Override + public void update(VPAction action) {} +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportDialogHandler.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportDialogHandler.java new file mode 100644 index 00000000..0c82c997 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/GufoExportDialogHandler.java @@ -0,0 +1,96 @@ +package it.unibz.inf.ontouml.vp.controllers; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.ViewManager; +import com.vp.plugin.view.IDialog; +import com.vp.plugin.view.IDialogHandler; +import it.unibz.inf.ontouml.vp.OntoUMLPlugin; +import it.unibz.inf.ontouml.vp.model.Configurations; +import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; +import it.unibz.inf.ontouml.vp.views.GufoExportView; +import java.awt.Component; + +class GufoExportDialogHandler implements IDialogHandler { + + private IDialog dialog; + private final GufoExportView view; + private final ViewManager viewManager; + private boolean wasShown = false; + private boolean wasClosed = false; + private boolean wasCancelled = false; + + public GufoExportDialogHandler(ProjectConfigurations projectConfigurations) { + view = new GufoExportView(projectConfigurations); + viewManager = ApplicationManager.instance().getViewManager(); + + view.onExport( + e -> { + view.updateConfigurationsValues(projectConfigurations); + Configurations.getInstance().save(); + closeDialog(); + }); + view.onCancel( + e -> { + wasCancelled = true; + closeDialog(); + }); + } + + /** + * Called once before the dialog is shown. Developer should return the content of the dialog + * (similar to the content pane). + */ + @Override + public Component getComponent() { + return view; + } + + /** + * Called after the getComponent(). A dialog is created on Visual Paradigm internally (it still + * not shown out). Developer can set the outlook of the dialog on prepare(). + */ + @Override + public void prepare(IDialog dialog) { + this.dialog = dialog; + dialog.setTitle(OntoUMLPlugin.PLUGIN_NAME); + dialog.setModal(true); + dialog.setResizable(true); + dialog.setSize(view.getWidth(), view.getHeight() + 20); + dialog.pack(); + } + + /** Called when the dialog is shown. */ + @Override + public void shown() {} + + /** Called when the dialog is closed by the user clicking on the close button of the frame. */ + @Override + public boolean canClosed() { + wasCancelled = true; + wasClosed = true; + return true; + } + + public void showDialog() { + if (!wasClosed) { + wasShown = true; + viewManager.showDialog(this); + } + } + + public void closeDialog() { + if (wasClosed) { + System.out.println("Export dialog was already closed."); + } else if (!wasShown) { + System.out.println("Export dialog was never shown. Setting wasClosed to \"true\""); + } else { + System.out.println("Closing export dialog."); + dialog.close(); + } + wasClosed = true; + } + + public boolean wasCancelled() { + return wasCancelled; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonExportController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonExportController.java deleted file mode 100644 index 5d9a1405..00000000 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonExportController.java +++ /dev/null @@ -1,122 +0,0 @@ -package it.unibz.inf.ontouml.vp.controllers; - -import com.vp.plugin.ApplicationManager; -import com.vp.plugin.action.VPAction; -import com.vp.plugin.action.VPActionController; -import com.vp.plugin.view.IDialog; -import com.vp.plugin.view.IDialogHandler; -import it.unibz.inf.ontouml.vp.model.Configurations; -import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; -import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import it.unibz.inf.ontouml.vp.views.ProgressPanel; -import java.awt.*; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -/** - * Implementation toolbar button action responsible for exporting OntoUML model in JSON (according - * to OntoUML Schema). - * - * @author Claudenir Fonseca - */ -public class JsonExportController implements VPActionController { - - private ProgressPanel progressPanel; - private ProgressDialog loading; - private IDialog mainDialog; - - Thread thread; - - /** - * Performs model export in JSON format. - * - * @param action - */ - @Override - public void performAction(VPAction action) { - final Configurations configs = Configurations.getInstance(); - final ProjectConfigurations projectConfigurations = configs.getProjectConfigurations(); - - FileDialog fd = - new FileDialog( - (Frame) ApplicationManager.instance().getViewManager().getRootFrame(), - "Choose destination", - FileDialog.SAVE); - - String suggestedFolderPath = projectConfigurations.getExportFolderPath(); - String suggestedFileName = projectConfigurations.getExportFilename(); - - if (suggestedFileName.isEmpty()) { - String projectName = ApplicationManager.instance().getProjectManager().getProject().getName(); - suggestedFileName = projectName + ".json"; - } - - fd.setDirectory(suggestedFolderPath); - fd.setFile(suggestedFileName); - fd.setVisible(true); - - String fileDirectory = fd.getDirectory(); - - if (fileDirectory != null) { - - loading = new ProgressDialog(); - ApplicationManager.instance().getViewManager().showDialog(loading); - - try { - String fileName = fd.getFile(); - - if (!fileName.endsWith(".json")) fileName += ".json"; - - final String jsonModel = ModelElement.generateModel(true); - Files.write(Paths.get(fileDirectory, fileName), jsonModel.getBytes()); - projectConfigurations.setExportFolderPath(fileDirectory); - projectConfigurations.setExportFilename(fileName); - configs.save(); - ViewManagerUtils.cleanAndShowMessage("Model exported successfully."); - } catch (IOException e) { - ViewManagerUtils.cleanAndShowMessage("Model export failed."); - e.printStackTrace(); - } - - mainDialog.close(); - } - } - - /** - * Called when the menu containing the button is accessed allowing for action manipulation, such - * as enable/disable or selecting the button. - * - *

OBS: DOES NOT apply to this class. - */ - @Override - public void update(VPAction action) {} - - protected class ProgressDialog implements IDialogHandler { - - @Override - public Component getComponent() { - progressPanel = new ProgressPanel("Building model..."); - return progressPanel; - } - - @Override - public void prepare(IDialog dialog) { - mainDialog = dialog; - mainDialog.setTitle("Export to JSON"); - mainDialog.setModal(false); - mainDialog.setResizable(false); - dialog.setSize(progressPanel.getWidth(), progressPanel.getHeight() + 20); - progressPanel.setContainerDialog(mainDialog); - } - - @Override - public void shown() {} - - @Override - public boolean canClosed() { - return false; - } - } -} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonImportAndExportController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonImportAndExportController.java new file mode 100644 index 00000000..0defa523 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/JsonImportAndExportController.java @@ -0,0 +1,200 @@ +package it.unibz.inf.ontouml.vp.controllers; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.action.VPAction; +import com.vp.plugin.action.VPActionController; +import it.unibz.inf.ontouml.vp.model.Configurations; +import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; +import it.unibz.inf.ontouml.vp.model.ontouml2vp.Ontouml2UmlLoader; +import it.unibz.inf.ontouml.vp.model.vp2ontouml.Uml2OntoumlTransformer; +import it.unibz.inf.ontouml.vp.utils.SimpleServiceWorker; +import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; +import java.awt.*; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +/** + * Implementation toolbar button action responsible for exporting OntoUML model in JSON (according + * to OntoUML Schema). + * + * @author Claudenir Fonseca + */ +public class JsonImportAndExportController implements VPActionController { + + private static final String IMPORT_ACTION_ID = "it.unibz.inf.ontouml.vp.actions.JsonImportAction"; + private static final String PROJECT_IMPORT_ACTION_ID = "project.import.JsonImportAction"; + private static final String EXPORT_ACTION_ID = "it.unibz.inf.ontouml.vp.actions.JsonExportAction"; + private static final String PROJECT_EXPORT_ACTION_ID = "project.export.JsonExportAction"; + + private static final String FILE_FORMAT = ".json"; + + private static final String MESSAGE_IMPORT_WARNING = + "Warning: this action may override elements in your project. Do you wish to continue?"; + private static final String MESSAGE_MODEL_EXPORTED = "Model exported successfully."; + private static final String MESSAGE_MODEL_IMPORTED = "Model imported successfully."; + private static final String MESSAGE_MODEL_EXPORT_INVALID_FILE_ERROR = + "Unable to export: invalid file."; + private static final String MESSAGE_MODEL_IMPORT_INVALID_FILE_ERROR = + "Unable to import: invalid file."; + private static final String MESSAGE_MODEL_EXPORT_UNEXPECTED_ERROR = + "Unable to export: unexpected error."; + private static final String MESSAGE_MODEL_IMPORT_UNEXPECTED_ERROR = + "Unable to import: unexpected error."; + + private Configurations configs; + private ProjectConfigurations projectConfigurations; + private VPAction action; + private Path filePath; + + /** Called when a button is clicked. */ + @Override + public void performAction(VPAction action) { + this.action = action; + configs = Configurations.getInstance(); + projectConfigurations = configs.getProjectConfigurations(); + + if (shouldImport()) { + boolean shouldProceed = ViewManagerUtils.warningDialog(MESSAGE_IMPORT_WARNING); + if (!shouldProceed) return; + } + + filePath = getFilePath(); + + if (shouldImport()) { + new SimpleServiceWorker(this::importTask).execute(); + } else if (shouldExport()) { + new SimpleServiceWorker(this::exportTask).execute(); + } + } + + /** + * Called when the menu containing the button is accessed allowing for action manipulation, such + * as enable/disable or selecting the button. + * + *

OBS: DOES NOT apply to this class. + */ + @Override + public void update(VPAction action) {} + + private boolean shouldExport() { + return EXPORT_ACTION_ID.equals(action.getActionId()) + || PROJECT_EXPORT_ACTION_ID.equals(action.getActionId()); + } + + private boolean shouldImport() { + return IMPORT_ACTION_ID.equals(action.getActionId()) + || PROJECT_IMPORT_ACTION_ID.equals(action.getActionId()); + } + + private Path getFilePath() { + final FileDialog fileDialog; + final Frame rootFrame = (Frame) ApplicationManager.instance().getViewManager().getRootFrame(); + final String suggestedFolderPath = projectConfigurations.getExportFolderPath(); + String suggestedFileName = projectConfigurations.getExportFilename(); + + if (suggestedFileName.isEmpty()) { + final String projectName = + ApplicationManager.instance().getProjectManager().getProject().getName(); + suggestedFileName = projectName + ".json"; + } + + if (shouldExport()) { + final String title = "Choose export file destination"; + fileDialog = new FileDialog(rootFrame, title, FileDialog.SAVE); + } else if (shouldImport()) { + final String title = "Select import file "; + fileDialog = new FileDialog(rootFrame, title, FileDialog.LOAD); + } else { + throw new RuntimeException("Unexpected action: " + action.getActionId()); + } + + fileDialog.setFile(suggestedFileName); + fileDialog.setDirectory(suggestedFolderPath); + fileDialog.setMultipleMode(false); + fileDialog.setFilenameFilter((dir, name) -> name != null && name.endsWith(FILE_FORMAT)); + + fileDialog.setVisible(true); + + final String fileDirectory = fileDialog.getDirectory(); + final String fileName = fileDialog.getFile(); + + if (fileDirectory != null && fileName != null) { + return fileName.endsWith(FILE_FORMAT) + ? Paths.get(fileDirectory, fileName) + : Paths.get(fileDirectory, fileName + FILE_FORMAT); + } + + return null; + } + + private void saveFilePath() { + final Path directoryPath = filePath.getParent(); + final String directoryPathName = directoryPath.toAbsolutePath().getFileName().toString(); + final String filePathName = filePath.getFileName().toString(); + + projectConfigurations.setExportFolderPath(directoryPathName); + projectConfigurations.setExportFilename(filePathName); + configs.save(); + } + + private List importTask(SimpleServiceWorker context) { + try { + if (filePath == null) { + context.cancel(true); + return List.of(); + } + + final String importFileContents = Files.readString(filePath); + + if (!context.isCancelled()) { + Ontouml2UmlLoader.deserializeAndLoad(importFileContents, false, false); + saveFilePath(); + ViewManagerUtils.log(MESSAGE_MODEL_IMPORTED); + return List.of(MESSAGE_MODEL_IMPORTED); + } + + return List.of(); + } catch (IOException e) { + e.printStackTrace(); + ViewManagerUtils.log(MESSAGE_MODEL_IMPORT_INVALID_FILE_ERROR); + return List.of(MESSAGE_MODEL_IMPORT_INVALID_FILE_ERROR); + } catch (Exception e) { + e.printStackTrace(); + ViewManagerUtils.log(MESSAGE_MODEL_IMPORT_UNEXPECTED_ERROR); + return List.of(MESSAGE_MODEL_IMPORT_UNEXPECTED_ERROR); + } + } + + private List exportTask(SimpleServiceWorker context) { + try { + if (filePath == null) { + context.cancel(true); + return List.of(); + } + + final String exportFileContents = Uml2OntoumlTransformer.transformAndSerialize(); + + if (!context.isCancelled()) { + Files.write(filePath, exportFileContents.getBytes()); + saveFilePath(); + ViewManagerUtils.log(MESSAGE_MODEL_EXPORTED); + return List.of(MESSAGE_MODEL_EXPORTED); + } + + return List.of(); + } catch (IOException e) { + e.printStackTrace(); + ViewManagerUtils.log(MESSAGE_MODEL_EXPORT_INVALID_FILE_ERROR); + + return List.of(MESSAGE_MODEL_EXPORT_INVALID_FILE_ERROR); + } catch (Exception e) { + e.printStackTrace(); + ViewManagerUtils.log(MESSAGE_MODEL_EXPORT_UNEXPECTED_ERROR); + + return List.of(MESSAGE_MODEL_EXPORT_UNEXPECTED_ERROR); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModelVerificationController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModelVerificationController.java index 2536543e..25fb839f 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModelVerificationController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModelVerificationController.java @@ -3,13 +3,19 @@ import com.vp.plugin.ApplicationManager; import com.vp.plugin.action.VPAction; import com.vp.plugin.action.VPActionController; -import com.vp.plugin.view.IDialog; -import com.vp.plugin.view.IDialogHandler; -import it.unibz.inf.ontouml.vp.model.ServerRequest; -import it.unibz.inf.ontouml.vp.model.uml.ModelElement; +import com.vp.plugin.diagram.IBaseDiagramElement; +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.IDiagramUIModel; +import it.unibz.inf.ontouml.vp.model.ServiceIssue; +import it.unibz.inf.ontouml.vp.model.VerificationServiceResult; +import it.unibz.inf.ontouml.vp.model.vp2ontouml.Uml2OntoumlTransformer; +import it.unibz.inf.ontouml.vp.utils.SimpleServiceWorker; import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import it.unibz.inf.ontouml.vp.views.ProgressPanel; -import java.awt.Component; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * Implementation of toolbar button action responsible for performing model verification. @@ -19,27 +25,12 @@ */ public class ModelVerificationController implements VPActionController { - private ProgressPanel progressPanel; - private ProgressDialog loading; - private IDialog mainDialog; - ModelVerificationRequest request; + private static final String MODEL_VERIFICATION_ACTION = + "it.unibz.inf.ontouml.vp.actions.ModelVerificationAction"; + private static final String DIAGRAM_VERIFICATION_ACTION = + "it.unibz.inf.ontouml.vp.actions.DiagramVerificationAction"; - /** - * Performs OntoUML model verification. - * - * @param action - */ - @Override - public void performAction(VPAction action) { - - request = new ModelVerificationRequest(); - - loading = new ProgressDialog(); - ApplicationManager.instance().getViewManager().showDialog(loading); - - Thread thread = new Thread(request); - thread.start(); - } + private VPAction action; /** * Called when the menu containing the button is accessed allowing for action manipulation, such @@ -50,63 +41,67 @@ public void performAction(VPAction action) { @Override public void update(VPAction action) {} - protected class ProgressDialog implements IDialogHandler { + /** Performs OntoUML model verification. */ + @Override + public void performAction(VPAction action) { + this.action = action; + final SimpleServiceWorker worker = new SimpleServiceWorker(this::task); + worker.execute(); + } - @Override - public Component getComponent() { - progressPanel = new ProgressPanel(request); - return progressPanel; - } + private List task(SimpleServiceWorker context) { + try { + final String project = Uml2OntoumlTransformer.transformAndSerialize(); + final VerificationServiceResult result = + OntoUMLServerAccessController.requestModelVerification(project); - @Override - public void prepare(IDialog dialog) { - mainDialog = dialog; - mainDialog.setTitle("Verification Service"); - mainDialog.setModal(false); - mainDialog.setResizable(false); - dialog.setSize(progressPanel.getWidth(), progressPanel.getHeight() + 20); - progressPanel.setContainerDialog(mainDialog); - } + if (DIAGRAM_VERIFICATION_ACTION.equals(action.getActionId())) { + retainDiagramIssues(result); + } - @Override - public void shown() {} + if (!context.isCancelled()) { + ViewManagerUtils.log(result); + } + + return List.of(result.getMessage()); + } catch (IOException e) { + if (!context.isCancelled()) { + ViewManagerUtils.log(e.getMessage()); + } - @Override - public boolean canClosed() { - mainDialog.close(); - return true; + e.printStackTrace(); + return List.of(e.getMessage()); } } - public class ModelVerificationRequest extends ServerRequest { - - @Override - public void run() { - while (keepRunning()) { - try { - final String response = - OntoUMLServerAccessController.requestModelVerification( - ModelElement.generateModel(true), loading); - - if (keepRunning()) { - if (response != null) { - loading.canClosed(); - request.doStop(); - ViewManagerUtils.logVerificationResponse(response); - } else { - loading.canClosed(); - request.doStop(); - } - } else { - loading.canClosed(); - request.doStop(); - ViewManagerUtils.cleanAndShowMessage("Request cancelled by the user."); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } + private void retainDiagramIssues(VerificationServiceResult result) { + if (result == null) { + return; } + + final IDiagramUIModel activeDiagram = + ApplicationManager.instance().getDiagramManager().getActiveDiagram(); + final IDiagramElement[] diagramElements = activeDiagram.toDiagramElementArray(); + + if (diagramElements == null) { + result.setResult(null); + return; + } + + final List verificationIssues = result.getResult(); + final Set presentModelElementsIds = + Arrays.stream(diagramElements) + .map(IBaseDiagramElement::getModelElement) + .map(modelElement -> modelElement != null ? modelElement.getId() : null) + .collect(Collectors.toSet()); + final List filteredVerificationIssues = + verificationIssues.stream() + .filter( + issue -> + issue.getSource() != null + && presentModelElementsIds.contains(issue.getSource().getId())) + .collect(Collectors.toList()); + + result.setResult(filteredVerificationIssues); } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModularizationController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModularizationController.java new file mode 100644 index 00000000..3dc2b882 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ModularizationController.java @@ -0,0 +1,60 @@ +package it.unibz.inf.ontouml.vp.controllers; + +import com.vp.plugin.action.VPAction; +import com.vp.plugin.action.VPActionController; +import it.unibz.inf.ontouml.vp.model.ModularizationServiceResult; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml2vp.IProjectLoader; +import it.unibz.inf.ontouml.vp.model.vp2ontouml.Uml2OntoumlTransformer; +import it.unibz.inf.ontouml.vp.utils.SimpleServiceWorker; +import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; +import java.io.IOException; +import java.util.List; + +public class ModularizationController implements VPActionController { + + @Override + public void performAction(VPAction vpAction) { + final SimpleServiceWorker worker = new SimpleServiceWorker(this::task); + worker.execute(); + } + + @Override + public void update(VPAction vpAction) {} + + private List task(SimpleServiceWorker context) { + try { + System.out.println("Starting modularization service..."); + System.out.println("Serializing project..."); + final String serializedProject = Uml2OntoumlTransformer.transformAndSerialize(); + System.out.println(serializedProject); + System.out.println("Project serialized!"); + + System.out.println("Requesting diagrams from the modularization service..."); + final ModularizationServiceResult serviceResult = + OntoUMLServerAccessController.requestProjectModularization(serializedProject); + System.out.println("Request answered by modularization service!"); + + System.out.println(serviceResult.getIssues()); + + // Load project + System.out.println("Processing modularization service response..."); + Project modularizedProject = serviceResult.getResult(); + if (!context.isCancelled() && modularizedProject != null) { + IProjectLoader.load(modularizedProject, false, true); + ViewManagerUtils.log(serviceResult.getMessage()); + } + System.out.println("Modularization service response processed!"); + System.out.println("Modularization service concluded."); + + return List.of(serviceResult.getMessage()); + } catch (IOException e) { + if (!context.isCancelled()) { + ViewManagerUtils.log(e.getMessage()); + } + + e.printStackTrace(); + return List.of(e.getMessage()); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/OntoUMLServerAccessController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/OntoUMLServerAccessController.java index c69f06e7..6de3ca12 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/OntoUMLServerAccessController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/OntoUMLServerAccessController.java @@ -1,19 +1,17 @@ package it.unibz.inf.ontouml.vp.controllers; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.vp.plugin.view.IDialogHandler; +import com.fasterxml.jackson.databind.ObjectMapper; import it.unibz.inf.ontouml.vp.model.Configurations; +import it.unibz.inf.ontouml.vp.model.GufoTransformationServiceResult; +import it.unibz.inf.ontouml.vp.model.ModularizationServiceResult; import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; +import it.unibz.inf.ontouml.vp.model.ServiceResult; +import it.unibz.inf.ontouml.vp.model.VerificationServiceResult; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.SocketException; import java.net.URL; import java.util.stream.Collectors; @@ -29,244 +27,152 @@ public class OntoUMLServerAccessController { private static final String TRANSFORM_GUFO_SERVICE_ENDPOINT = "/v1/transform/gufo"; private static final String VERIFICATION_SERVICE_ENDPOINT = "/v1/verify"; + private static final String MODULARIZATION_SERVICE_ENDPOINT = "/v1/modularize"; private static final String USER_MESSAGE_BAD_REQUEST = - "There was a internal plugin error and the verification could not be completed."; - private static final String USER_MESSAGE_NOT_FOUND = "Unable to reach the server."; + "There was a internal plugin error and the service could not be completed."; + private static final String USER_MESSAGE_REQUEST_WITH_SYNTACTICAL_ERRORS = + "Unable to execute request on a project containing syntactical errors."; + private static final String USER_MESSAGE_NOT_FOUND = "Server not found."; + private static final String USER_MESSAGE_CONNECTION_ERROR = "Unable to reach the server."; private static final String USER_MESSAGE_INTERNAL_ERROR = "Internal server error."; - private static final String USER_MESSAGE_UNKNOWN_ERROR_REQUEST = - "Error sending model verification to the server."; private static final String USER_MESSAGE_UNKNOWN_ERROR_RESPONSE = - "Error receiving model verification response."; + "Error receiving service response."; - public static BufferedReader transformToGUFO( - String model, - String baseIRI, - String format, - String uriFormatBy, - String inverse, - String object, - String analysis, - String packages, - String elementMapping, - String packageMapping, - IDialogHandler loading) - throws Exception { - final JsonObject optionsObj = new JsonObject(); - - boolean createObjectProperty = !Boolean.parseBoolean(object); - boolean createInverses = Boolean.parseBoolean(inverse); - boolean preAnalysis = Boolean.parseBoolean(analysis); - boolean prefixPackages = Boolean.parseBoolean(packages); + private static String getServiceRequestBody(String project) { + return "{\"options\": null, \"project\": " + project + "}"; + } - optionsObj.addProperty("baseIRI", baseIRI); - optionsObj.addProperty("format", format); - optionsObj.addProperty("uriFormatBy", uriFormatBy); - optionsObj.addProperty("createInverses", createInverses); - optionsObj.addProperty("createObjectProperty", createObjectProperty); - optionsObj.addProperty("preAnalysis", preAnalysis); - optionsObj.addProperty("prefixPackages", prefixPackages); - optionsObj.add("customElementMapping", new Gson().fromJson(elementMapping, JsonObject.class)); - optionsObj.add("customPackageMapping", new Gson().fromJson(packageMapping, JsonObject.class)); + private static String getServiceRequestBody(String project, String options) { + return "{\"options\": " + options + ", \"project\": " + project + "}"; + } - final JsonObject bodyObj = new JsonObject(); - bodyObj.add("options", optionsObj); - bodyObj.add("model", new JsonParser().parse(model).getAsJsonObject()); + private static String getModularizationRequestUrl() { + final ProjectConfigurations config = Configurations.getInstance().getProjectConfigurations(); + return config.isCustomServerEnabled() + ? config.getServerURL() + MODULARIZATION_SERVICE_ENDPOINT + : ProjectConfigurations.DEFAULT_SERVER_URL + MODULARIZATION_SERVICE_ENDPOINT; + } - final GsonBuilder builder = new GsonBuilder(); - final Gson gson = builder.serializeNulls().setPrettyPrinting().create(); - final String body = gson.toJson(bodyObj); + private static String getVerificationRequestUrl() { + final ProjectConfigurations config = Configurations.getInstance().getProjectConfigurations(); + return config.isCustomServerEnabled() + ? config.getServerURL() + VERIFICATION_SERVICE_ENDPOINT + : ProjectConfigurations.DEFAULT_SERVER_URL + VERIFICATION_SERVICE_ENDPOINT; + } - final ProjectConfigurations configurations = - Configurations.getInstance().getProjectConfigurations(); - final String url; + private static String getTransformationToGufoRequestUrl() { + final ProjectConfigurations config = Configurations.getInstance().getProjectConfigurations(); + return config.isCustomServerEnabled() + ? config.getServerURL() + TRANSFORM_GUFO_SERVICE_ENDPOINT + : ProjectConfigurations.DEFAULT_SERVER_URL + TRANSFORM_GUFO_SERVICE_ENDPOINT; + } - if (configurations.isCustomServerEnabled()) { - url = configurations.getServerURL() + TRANSFORM_GUFO_SERVICE_ENDPOINT; - } else { - url = ProjectConfigurations.DEFAULT_SERVER_URL + TRANSFORM_GUFO_SERVICE_ENDPOINT; + private static > T parseResponse( + HttpURLConnection connection, Class _class) throws IOException { + if (connection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) { + return null; } - loading.shown(); - - try { - final HttpURLConnection request = request(url, body); - final BufferedReader responseReader = - request.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST - ? new BufferedReader(new InputStreamReader(request.getInputStream())) - : new BufferedReader(new InputStreamReader(request.getErrorStream())); - - loading.canClosed(); - - switch (request.getResponseCode()) { - case HttpURLConnection.HTTP_OK: - if (!request.getContentType().equals("text/html")) { - return responseReader; - } else { - if (ViewManagerUtils.exportToGUFOIssueDialogWithOption( - "Server not found.", HttpURLConnection.HTTP_NOT_FOUND)) - return transformToGUFO( - model, - baseIRI, - format, - uriFormatBy, - inverse, - object, - analysis, - packages, - elementMapping, - packageMapping, - loading); - - System.out.println(responseReader.lines().collect(Collectors.joining())); - new Exception("Server not found.").printStackTrace(); - return null; - } - case HttpURLConnection.HTTP_BAD_REQUEST: - ViewManagerUtils.exportToGUFOIssueDialog( - "Unable to transform the model due to an unexpected error.\n" - + "Please check the model for any syntactical errors.\n\n" - + "Warning: partially exporting models to gUFO may introduce syntactical" - + " errors."); - System.out.println(responseReader.lines().collect(Collectors.joining())); - new Exception( - "Unable to transform the model due to an unexpected error.\n" - + "Please check the model for any syntactical errors.\n\n" - + "Warning: partially exporting models to gUFO may introduce syntactical" - + " errors.") - .printStackTrace(); - return null; - case HttpURLConnection.HTTP_NOT_FOUND: - if (ViewManagerUtils.exportToGUFOIssueDialogWithOption( - "Server not found.", HttpURLConnection.HTTP_NOT_FOUND)) - return transformToGUFO( - model, - baseIRI, - format, - uriFormatBy, - inverse, - object, - analysis, - packages, - elementMapping, - packageMapping, - loading); - - System.out.println(responseReader.lines().collect(Collectors.joining())); - new Exception("Server not found.").printStackTrace(); - return null; - case HttpURLConnection.HTTP_INTERNAL_ERROR: - if (ViewManagerUtils.exportToGUFOIssueDialogWithOption( - "Server error.", HttpURLConnection.HTTP_INTERNAL_ERROR)) - return transformToGUFO( - model, - baseIRI, - format, - uriFormatBy, - inverse, - object, - analysis, - packages, - elementMapping, - packageMapping, - loading); - - System.out.println(responseReader.lines().collect(Collectors.joining())); - new Exception("Server error.").printStackTrace(); - return null; - default: - ViewManagerUtils.exportToGUFOIssueDialog("Unexpected error."); - throw new Exception("Unknown error"); - } - } catch (MalformedURLException e) { - ViewManagerUtils.exportToGUFOIssueDialog("Server error."); - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + if (!hasJsonContentType(connection)) { + throw new IOException(USER_MESSAGE_UNKNOWN_ERROR_RESPONSE); } - return null; + final BufferedReader reader = + new BufferedReader(new InputStreamReader(connection.getInputStream())); + final String json = reader.lines().parallel().collect(Collectors.joining("\n")); + return new ObjectMapper().readValue(json, _class); } - public static String requestModelVerification(String serializedModel, IDialogHandler loading) { - final ProjectConfigurations configurations = - Configurations.getInstance().getProjectConfigurations(); - final String url; - - if (configurations.isCustomServerEnabled()) { - url = configurations.getServerURL() + VERIFICATION_SERVICE_ENDPOINT; - } else { - url = ProjectConfigurations.DEFAULT_SERVER_URL + VERIFICATION_SERVICE_ENDPOINT; - } + private static boolean hasJsonContentType(HttpURLConnection connection) { + return connection.getContentType().contains("application/json"); + } - loading.shown(); + public static ModularizationServiceResult requestProjectModularization(String project) + throws IOException { + final String body = getServiceRequestBody(project); + final String url = getModularizationRequestUrl(); + final HttpURLConnection connection = request(url, body); - try { + return parseResponse(connection, ModularizationServiceResult.class); + } - final HttpURLConnection request = request(url, serializedModel); - final StringBuilder response = new StringBuilder(); - final BufferedReader reader = - request.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST - ? new BufferedReader(new InputStreamReader(request.getInputStream())) - : new BufferedReader(new InputStreamReader(request.getErrorStream())); + public static VerificationServiceResult requestModelVerification(String project) + throws IOException { + final String url = getVerificationRequestUrl(); + final String body = getServiceRequestBody(project); + final HttpURLConnection connection = request(url, body); - String line = null; + return parseResponse(connection, VerificationServiceResult.class); + } - while ((line = reader.readLine()) != null) { - response.append(line.trim()); - } + public static GufoTransformationServiceResult requestModelTransformationToGufo( + String project, String options) throws IOException { + final String url = getTransformationToGufoRequestUrl(); + final String body = getServiceRequestBody(project, options); + final HttpURLConnection connection = request(url, body); - reader.close(); + return parseResponse(connection, GufoTransformationServiceResult.class); + } - loading.canClosed(); + private static HttpURLConnection request(String url, String body) throws IOException { + try { + final HttpURLConnection connection = performRequest(url, body); - switch (request.getResponseCode()) { + switch (connection.getResponseCode()) { case HttpURLConnection.HTTP_OK: - if (!request.getContentType().equals("text/html")) { - return response.toString(); + return connection; + case HttpURLConnection.HTTP_BAD_REQUEST: + if (!url.contains("verify")) { + // failed because the project contains syntactical errors + throw new IOException(USER_MESSAGE_REQUEST_WITH_SYNTACTICAL_ERRORS); } else { - if (ViewManagerUtils.verificationFailedDialogWithOption( - USER_MESSAGE_NOT_FOUND, HttpURLConnection.HTTP_NOT_FOUND)) - return requestModelVerification(serializedModel, loading); + throw new IOException(USER_MESSAGE_BAD_REQUEST); } - case HttpURLConnection.HTTP_BAD_REQUEST: - ViewManagerUtils.verificationFailedDialog(USER_MESSAGE_BAD_REQUEST); - return null; case HttpURLConnection.HTTP_NOT_FOUND: - if (ViewManagerUtils.verificationFailedDialogWithOption( - USER_MESSAGE_NOT_FOUND, HttpURLConnection.HTTP_NOT_FOUND)) - return requestModelVerification(serializedModel, loading); - - return null; + throw new IOException(USER_MESSAGE_NOT_FOUND); case HttpURLConnection.HTTP_INTERNAL_ERROR: - if (ViewManagerUtils.verificationFailedDialogWithOption( - USER_MESSAGE_INTERNAL_ERROR, HttpURLConnection.HTTP_INTERNAL_ERROR)) - return requestModelVerification(serializedModel, loading); - - return null; + throw new IOException(USER_MESSAGE_INTERNAL_ERROR); default: - ViewManagerUtils.verificationFailedDialog(USER_MESSAGE_UNKNOWN_ERROR_RESPONSE); - return null; + throw new IOException(USER_MESSAGE_UNKNOWN_ERROR_RESPONSE); } - } catch (SocketException e) { - loading.canClosed(); - ViewManagerUtils.verificationFailedDialog(USER_MESSAGE_NOT_FOUND); - e.printStackTrace(); + throw new IOException(USER_MESSAGE_CONNECTION_ERROR); } catch (IOException e) { - loading.canClosed(); - ViewManagerUtils.verificationFailedDialog(USER_MESSAGE_UNKNOWN_ERROR_RESPONSE); - e.printStackTrace(); + throw e; } catch (Exception e) { - loading.canClosed(); - ViewManagerUtils.verificationFailedDialog(USER_MESSAGE_UNKNOWN_ERROR_REQUEST); - e.printStackTrace(); + throw new IOException(USER_MESSAGE_UNKNOWN_ERROR_RESPONSE); } - - return null; } - private static HttpURLConnection request(String urlString, String body) - throws MalformedURLException, IOException { + // public static GufoTransformationServiceResult requestProjectTransformationToGufo( + // String project, String options) { + // final String body = getServiceRequestBody(project, options); + // final String url = getTransformationToGufoRequestUrl(); + // + // try { + // final HttpURLConnection connection = performRequest(url, body); + // + // switch (connection.getResponseCode()) { + // case HttpURLConnection.HTTP_OK: + // if (hasJsonContentType(connection)) { + // return parseResponse(connection, GufoTransformationServiceResult.class); + // } + // case HttpURLConnection.HTTP_BAD_REQUEST: + // case HttpURLConnection.HTTP_NOT_FOUND: + // case HttpURLConnection.HTTP_INTERNAL_ERROR: + // default: + // System.err.println("Attention! Transformation request was not processed correctly"); + // System.err.println("Status Code: " + connection.getResponseCode()); + // } + // } catch (IOException ioException) { + // ioException.printStackTrace(); + // } + // + // return null; + // } + + private static HttpURLConnection performRequest(String urlString, String body) + throws IOException { final URL url = new URL(urlString); final HttpURLConnection request = (HttpURLConnection) url.openConnection(); diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReloadClassesController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReloadClassesController.java index c21dc404..def74bbd 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReloadClassesController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReloadClassesController.java @@ -1,123 +1,27 @@ package it.unibz.inf.ontouml.vp.controllers; import com.vp.plugin.ApplicationManager; -import com.vp.plugin.DiagramManager; import com.vp.plugin.action.VPAction; import com.vp.plugin.action.VPActionController; -import com.vp.plugin.diagram.IDiagramUIModel; -import com.vp.plugin.model.IPackage; -import com.vp.plugin.model.factory.IModelElementFactory; import it.unibz.inf.ontouml.vp.OntoUMLPlugin; -import it.unibz.inf.ontouml.vp.utils.Stereotype; -import java.util.List; +import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; public class ReloadClassesController implements VPActionController { @Override public void performAction(VPAction action) { - // OntoUMLPlugin.reload(); - // generateModel(); - reverseDirection(action); + reloadPlugin(); } @Override public void update(VPAction action) {} - private void reverseDirection(VPAction action) { + private void reloadPlugin() { + System.out.println("----------------------------------------"); + System.out.println("Reloading OntoUML Plugin..."); ApplicationManager app = ApplicationManager.instance(); app.reloadPluginClasses(OntoUMLPlugin.PLUGIN_ID); - - // DiagramManager dm = app.getDiagramManager(); - // IDiagramElement[] selectedElements = dm.getSelectedDiagramElements(); - // - // for (int i = 0; selectedElements != null && i < selectedElements.length; i++) { - // IDiagramElement diagramElement = selectedElements[i]; - // IModelElement element = diagramElement.getModelElement(); - // - // if (element == null || - // !IModelElementFactory.MODEL_TYPE_ASSOCIATION.equals(element.getModelType())) { - // continue; - // } - // - // IAssociation association = (IAssociation) element; - // Association.invertAssociation(association); - // IAssociationUIModel originalAssociationView = (IAssociationUIModel) diagramElement; - // IClass originalFrom = (IClass) association.getFrom(); - // IClass originalTo = (IClass) association.getTo(); - // IAssociationEnd originalFromEnd = (IAssociationEnd) association.getFromEnd(); - // IAssociationEnd originalToEnd = (IAssociationEnd) association.getToEnd(); - // - // association.setFrom(originalTo); - // association.setTo(originalFrom); - // - // Point[] points = originalAssociationView.getPoints(); - // IDiagramUIModel diagram = diagramElement.getDiagramUIModel(); - // IAssociationUIModel reverseAssociationView = (IAssociationUIModel) - // dm.createConnector(diagram, association, originalAssociationView.getToShape(), - // originalAssociationView.getFromShape(), null); - // diagramElement.deleteViewOnly(); - // - // if(points != null) { - // for (int j = points.length - 1; j >= 0; j--) { - // reverseAssociationView.addPoint(points[j]); - // } - // } - // reverseAssociationView.resetCaption(); - // IConnectorUIModel reverseAssociationView = (IConnectorUIModel) - // dm.createDiagramElement(diagram, association); - // reverseAssociationView.set - // } - } - - @SuppressWarnings("unused") - private void generateModel() { - final ApplicationManager app = ApplicationManager.instance(); - final DiagramManager dm = app.getDiagramManager(); - final IDiagramUIModel diagram = dm.getActiveDiagram(); - final IPackage pkg = (IPackage) diagram.getParentModel(); - final IModelElementFactory factory = IModelElementFactory.instance(); - - if (diagram == null || pkg == null) { - return; - } - - final List stereotypes = Stereotype.getOntoUMLClassStereotypeNames(); - - for (String sourceStereotype : stereotypes) { - final IPackage sourcePkg = factory.createPackage(); - sourcePkg.setName(sourceStereotype); - pkg.addChild(sourcePkg); - - for (String targetStereotype : stereotypes) { - // // Method getAllowedAssociations() was removed - // final List allowedAssociations = - // OntoUMLConstraintsManager.getAllowedAssociations(sourceStereotype, - // targetStereotype); - - // if(!allowedAssociations.isEmpty()) { - // final IClass source = factory.createClass(); - // final IClass target = factory.createClass(); - // - // source.setName(sourceStereotype + " as Source"); - // target.setName(targetStereotype + " as Target"); - // - // source.addStereotype(sourceStereotype); - // target.addStereotype(targetStereotype); - // - // sourcePkg.addChild(source); - // sourcePkg.addChild(target); - // - // for (String associationStereotype : allowedAssociations) { - // final IAssociation association = factory.createAssociation(); - // - // association.addStereotype(associationStereotype); - // association.setFrom(source); - // association.setTo(target); - // - // sourcePkg.addChild(association); - // } - // } - } - } + System.out.println("Plugin reloaded!"); + ViewManagerUtils.simpleDialog("Plugin reloaded!"); } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReportErrorController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReportErrorController.java index fb639ba6..951b589d 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReportErrorController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/ReportErrorController.java @@ -3,7 +3,7 @@ import com.vp.plugin.action.VPAction; import com.vp.plugin.action.VPActionController; import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import java.awt.Desktop; +import java.awt.*; import java.net.URI; public class ReportErrorController implements VPActionController { diff --git a/src/main/java/it/unibz/inf/ontouml/vp/controllers/UpdatePluginController.java b/src/main/java/it/unibz/inf/ontouml/vp/controllers/UpdatePluginController.java index a9f97256..180e642c 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/controllers/UpdatePluginController.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/controllers/UpdatePluginController.java @@ -7,11 +7,7 @@ import it.unibz.inf.ontouml.vp.model.GitHubRelease; import it.unibz.inf.ontouml.vp.model.GitHubReleaseAsset; import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.util.function.Predicate; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/listeners/DiagramListener.java b/src/main/java/it/unibz/inf/ontouml/vp/listeners/DiagramListener.java index 39b14a06..9adb1ea0 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/listeners/DiagramListener.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/listeners/DiagramListener.java @@ -46,8 +46,7 @@ public void diagramUIModelPropertyChanged( public void diagramUIModelRenamed(IDiagramUIModel diagram) {} private void smartPaint(IDiagramElement diagramElement) { - if (diagramElement != null - && diagramElement instanceof IClassUIModel + if (diagramElement instanceof IClassUIModel && Configurations.getInstance().getProjectConfigurations().isAutomaticColoringEnabled()) { SmartColoringUtils.paint((IClassUIModel) diagramElement); } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/listeners/IssueLogMenuListener.java b/src/main/java/it/unibz/inf/ontouml/vp/listeners/IssueLogMenuListener.java index 2915533a..839dc98a 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/listeners/IssueLogMenuListener.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/listeners/IssueLogMenuListener.java @@ -5,14 +5,14 @@ import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.ArrayList; +import java.util.List; import javax.swing.*; public final class IssueLogMenuListener extends MouseAdapter { - private ArrayList idModelElementList; + private List idModelElementList; private JList messageList; - public IssueLogMenuListener(ArrayList list, JList messages) { + public IssueLogMenuListener(List list, JList messages) { super(); idModelElementList = list; messageList = messages; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ModelListener.java b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ModelListener.java index bf45ec20..1fd86f35 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ModelListener.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ModelListener.java @@ -135,6 +135,7 @@ private void enforceAndPropagateRestrictedTo(PropertyChangeEvent event) { case Stereotype.COLLECTIVE: case Stereotype.QUANTITY: case Stereotype.RELATOR: + case Stereotype.MODE: case Stereotype.QUALITY: case Stereotype.TYPE: if (!newValue.equals(oldValue)) { @@ -142,7 +143,6 @@ private void enforceAndPropagateRestrictedTo(PropertyChangeEvent event) { propagateRestrictionsToDescendants(_class); } break; - case Stereotype.MODE: case Stereotype.CATEGORY: case Stereotype.ROLE_MIXIN: case Stereotype.PHASE_MIXIN: diff --git a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectListener.java b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectListener.java index 1ca10026..c73f31bd 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectListener.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectListener.java @@ -67,12 +67,12 @@ private void checkUpdates() { if (!upToDate) { System.out.println("New updates are available."); - ViewManagerUtils.simpleLog( + ViewManagerUtils.log( "New updates are available. Go to \"Update Plugin\" to get the latest version of the" + " OntoUML Plugin for Visual Paradigm."); } else { System.out.println("No new updates available."); - ViewManagerUtils.simpleLog( + ViewManagerUtils.log( "Your OntoUML Plugin for Visual Paradigm is up to date with our latest release."); } } else { diff --git a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectModelListener.java b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectModelListener.java index f207ed94..0b8a73eb 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectModelListener.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/listeners/ProjectModelListener.java @@ -1,11 +1,7 @@ package it.unibz.inf.ontouml.vp.listeners; import com.vp.plugin.ApplicationManager; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IGeneralization; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IProject; -import com.vp.plugin.model.IProjectModelListener; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import java.util.Iterator; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/Configurations.java b/src/main/java/it/unibz/inf/ontouml/vp/model/Configurations.java index ada7bbf6..68d29bae 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/Configurations.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/Configurations.java @@ -1,12 +1,6 @@ package it.unibz.inf.ontouml.vp.model; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSyntaxException; +import com.google.gson.*; import com.google.gson.annotations.Expose; import com.vp.plugin.ApplicationManager; import com.vp.plugin.model.IProject; @@ -14,7 +8,6 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.lang.reflect.Type; import java.nio.file.Files; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -174,18 +167,11 @@ public void save() { builder.registerTypeAdapter( ZonedDateTime.class, - new JsonDeserializer() { - - @Override - public ZonedDateTime deserialize( - JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - return ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()); - } - }); + (JsonDeserializer) + (json, typeOfT, context) -> + ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString())); builder.setPrettyPrinting(); - // builder.excludeFieldsWithoutExposeAnnotation(); final Gson gson = builder.create(); final String json = gson.toJson(this); diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/GufoExportOptions.java b/src/main/java/it/unibz/inf/ontouml/vp/model/GufoExportOptions.java new file mode 100644 index 00000000..0bc5eda2 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/GufoExportOptions.java @@ -0,0 +1,116 @@ +package it.unibz.inf.ontouml.vp.model; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; + +public class GufoExportOptions { + + private String baseIRI; + private String format; + private String uriFormatBy; + private boolean createInverses; + private boolean createObjectProperty; + private boolean preAnalysis; + private boolean prefixPackages; + private JsonNode customElementMapping; + private JsonNode customPackageMapping; + + public GufoExportOptions() {} + + public GufoExportOptions(ProjectConfigurations projectConfigurations) { + baseIRI = projectConfigurations.getExportGUFOIRI(); + format = projectConfigurations.getExportGUFOFormat(); + uriFormatBy = projectConfigurations.getExportGUFOURIFormat(); + createInverses = projectConfigurations.getExportGUFOInverseBox(); + createObjectProperty = projectConfigurations.getExportGUFOObjectBox(); + preAnalysis = projectConfigurations.getExportGUFOAnalysisBox(); + prefixPackages = projectConfigurations.getExportGUFOPackagesBox(); + + ObjectMapper mapper = new ObjectMapper(); + try { + customElementMapping = mapper.readTree(projectConfigurations.getExportGUFOElementMapping()); + customPackageMapping = mapper.readTree(projectConfigurations.getExportGUFOPackageMapping()); + } catch (IOException e) { + System.err.println("Unable to read project configurations."); + e.printStackTrace(); + } + } + + public String getBaseIRI() { + return baseIRI; + } + + public void setBaseIRI(String baseIRI) { + this.baseIRI = baseIRI; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getUriFormatBy() { + return uriFormatBy; + } + + public void setUriFormatBy(String uriFormatBy) { + this.uriFormatBy = uriFormatBy; + } + + public boolean isCreateInverses() { + return createInverses; + } + + public void setCreateInverses(boolean createInverses) { + this.createInverses = createInverses; + } + + public boolean isCreateObjectProperty() { + return createObjectProperty; + } + + public void setCreateObjectProperty(boolean createObjectProperty) { + this.createObjectProperty = createObjectProperty; + } + + public boolean isPreAnalysis() { + return preAnalysis; + } + + public void setPreAnalysis(boolean preAnalysis) { + this.preAnalysis = preAnalysis; + } + + public boolean isPrefixPackages() { + return prefixPackages; + } + + public void setPrefixPackages(boolean prefixPackages) { + this.prefixPackages = prefixPackages; + } + + public JsonNode getCustomElementMapping() { + return customElementMapping; + } + + public void setCustomElementMapping(JsonNode customElementMapping) { + this.customElementMapping = customElementMapping; + } + + public JsonNode getCustomPackageMapping() { + return customPackageMapping; + } + + public void setCustomPackageMapping(JsonNode customPackageMapping) { + this.customPackageMapping = customPackageMapping; + } + + public String toJson() throws JsonProcessingException { + return new ObjectMapper().writeValueAsString(this); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResult.java b/src/main/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResult.java new file mode 100644 index 00000000..66e74efc --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResult.java @@ -0,0 +1,19 @@ +package it.unibz.inf.ontouml.vp.model; + +import java.util.List; + +public class GufoTransformationServiceResult extends ServiceResult { + + public GufoTransformationServiceResult(String result, List issues) { + super(result, issues); + } + + public GufoTransformationServiceResult() { + super(); + } + + @Override + public String getMessage() { + return "The export request to GUFO has concluded"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResult.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResult.java new file mode 100644 index 00000000..60b72534 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResult.java @@ -0,0 +1,20 @@ +package it.unibz.inf.ontouml.vp.model; + +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import java.util.List; + +public class ModularizationServiceResult extends ServiceResult { + + public ModularizationServiceResult() { + super(); + } + + public ModularizationServiceResult(Project result, List issues) { + super(result, issues); + } + + @Override + public String getMessage() { + return "The modularization request has concluded"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/OntoumlElementReference.java b/src/main/java/it/unibz/inf/ontouml/vp/model/OntoumlElementReference.java new file mode 100644 index 00000000..52d4d041 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/OntoumlElementReference.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class OntoumlElementReference { + + private String id; + private String type; + + public OntoumlElementReference() { + this.id = null; + this.type = null; + } + + public OntoumlElementReference(String id, String type) { + this.id = id; + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ProjectConfigurations.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ProjectConfigurations.java index 9c4cc3ef..bd5c18e8 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/ProjectConfigurations.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ProjectConfigurations.java @@ -20,6 +20,7 @@ public class ProjectConfigurations { public static final boolean DEFAULT_IS_AUTOMATIC_MODELLING_ENABLED = true; public static final boolean DEFAULT_IGNORE_ASSOCIATION_INVERSION_WARNING = false; public static final String DEFAULT_SERVER_URL = "http://api.ontouml.org"; + // public static final String DEFAULT_SERVER_URL = "http://api.ontouml.org:3000"; public static final String DEFAULT_EXPORT_PATH = System.getProperty("user.home"); public static final String DEFAULT_EXPORT_FILENAME = ""; public static final String DEFAULT_GUFO_EXPORT_PATH = System.getProperty("user.home"); @@ -79,19 +80,19 @@ public class ProjectConfigurations { @SerializedName("exportGUFOInverseBox") @Expose() - private String exportGUFOInverseBox; + private boolean exportGUFOInverseBox; @SerializedName("exportGUFOObjectBox") @Expose() - private String exportGUFOObjectBox; + private boolean exportGUFOObjectBox; @SerializedName("exportGUFOAnalysisBox") @Expose() - private String exportGUFOAnalysisBox; + private boolean exportGUFOAnalysisBox; @SerializedName("exportGUFOPackagesBox") @Expose() - private String exportGUFOPackagesBox; + private boolean exportGUFOPackagesBox; @SerializedName("exportGUFOElementMapping") @Expose() @@ -312,35 +313,35 @@ public void setExportGUFOElementsPackageTree(HashSet exportGUFOElementsP this.exportGUFOElementsPackageTree = exportGUFOElementsPackageTree; } - public String getExportGUFOInverseBox() { + public boolean getExportGUFOInverseBox() { return exportGUFOInverseBox; } - public void setExportGUFOInverseBox(String exportGUFOInverseBox) { + public void setExportGUFOInverseBox(boolean exportGUFOInverseBox) { this.exportGUFOInverseBox = exportGUFOInverseBox; } - public String getExportGUFOObjectBox() { + public boolean getExportGUFOObjectBox() { return exportGUFOObjectBox; } - public void setExportGUFOObjectBox(String exportGUFOObjectBox) { + public void setExportGUFOObjectBox(boolean exportGUFOObjectBox) { this.exportGUFOObjectBox = exportGUFOObjectBox; } - public String getExportGUFOAnalysisBox() { + public boolean getExportGUFOAnalysisBox() { return exportGUFOAnalysisBox; } - public void setExportGUFOAnalysisBox(String exportGUFOAnalysisBox) { + public void setExportGUFOAnalysisBox(boolean exportGUFOAnalysisBox) { this.exportGUFOAnalysisBox = exportGUFOAnalysisBox; } - public String getExportGUFOPackagesBox() { + public boolean getExportGUFOPackagesBox() { return exportGUFOPackagesBox; } - public void setExportGUFOPackagesBox(String exportGUFOPackagesBox) { + public void setExportGUFOPackagesBox(boolean exportGUFOPackagesBox) { this.exportGUFOPackagesBox = exportGUFOPackagesBox; } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ServerRequest.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ServerRequest.java deleted file mode 100644 index d4aef0f8..00000000 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/ServerRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package it.unibz.inf.ontouml.vp.model; - -public class ServerRequest implements Runnable { - - private boolean doStop = false; - - public synchronized void doStop() { - this.doStop = true; - } - - protected synchronized boolean keepRunning() { - return this.doStop == false; - } - - @Override - public void run() {} -} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssue.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssue.java new file mode 100644 index 00000000..895e5edf --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssue.java @@ -0,0 +1,102 @@ +package it.unibz.inf.ontouml.vp.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.util.ArrayList; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonDeserialize(using = ServiceIssueDeserializer.class) +public class ServiceIssue { + + private String id; + private String code; + private String severity; + private String title; + private String description; + private OntoumlElementReference source; + private List context; + + public ServiceIssue() { + this.id = null; + this.code = null; + this.severity = null; + this.title = null; + this.description = null; + this.source = null; + this.context = new ArrayList<>(); + } + + public ServiceIssue( + String id, + String code, + String severity, + String title, + String description, + OntoumlElementReference source, + List context) { + this.id = id; + this.code = code; + this.severity = severity; + this.title = title; + this.description = description; + this.source = source; + this.context = context; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public OntoumlElementReference getSource() { + return source; + } + + public void setSource(OntoumlElementReference source) { + this.source = source; + } + + public List getContext() { + return context; + } + + public void setContext(List context) { + this.context = context != null ? context : new ArrayList<>(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssueDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssueDeserializer.java new file mode 100644 index 00000000..3d398725 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceIssueDeserializer.java @@ -0,0 +1,50 @@ +package it.unibz.inf.ontouml.vp.model; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; + +public class ServiceIssueDeserializer extends JsonDeserializer { + + @Override + public ServiceIssue deserialize( + JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + final ObjectCodec oc = jsonParser.getCodec(); + final JsonNode node = oc.readTree(jsonParser); + final JsonNode dataNode = node.get("data"); + final ServiceIssue issue = new ServiceIssue(); + + final String id = node.get("id") != null ? node.get("id").asText() : null; + final String code = node.get("code") != null ? node.get("code").asText() : null; + final String title = node.get("title") != null ? node.get("title").asText() : null; + final String description = + node.get("description") != null ? node.get("description").asText() : null; + final String severity = node.get("severity") != null ? node.get("severity").asText() : null; + + issue.setId(id); + issue.setCode(code); + issue.setTitle(title); + issue.setDescription(description); + issue.setSeverity(severity); + + if (dataNode != null) { + // TODO: process context field from verification issues + // TODO: process context element from GUFO transformation issues + final JsonNode sourceNode = dataNode.get("source"); + final ObjectMapper mapper = new ObjectMapper(); + + if (sourceNode != null) { + final String sourceId = sourceNode.get("id") != null ? sourceNode.get("id").asText() : null; + final String type = sourceNode.get("type") != null ? sourceNode.get("type").asText() : null; + final OntoumlElementReference source = new OntoumlElementReference(sourceId, type); + issue.setSource(source); + } + } + + return issue; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceResult.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceResult.java new file mode 100644 index 00000000..09135e16 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ServiceResult.java @@ -0,0 +1,41 @@ +package it.unibz.inf.ontouml.vp.model; + +import java.util.ArrayList; +import java.util.List; + +public abstract class ServiceResult { + + private T result; + private List issues; + + public ServiceResult() { + setResult(null); + setIssues(new ArrayList<>()); + } + + public ServiceResult(T result, List issues) { + this.result = result; + this.issues = issues; + } + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + public List getIssues() { + return issues; + } + + public void setIssues(List issues) { + this.issues = issues != null ? issues : new ArrayList<>(); + } + + /** + * @return - a message string to be displayed to the user after the service request is concluded. + */ + public abstract String getMessage(); +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResult.java b/src/main/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResult.java new file mode 100644 index 00000000..083bd861 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResult.java @@ -0,0 +1,42 @@ +package it.unibz.inf.ontouml.vp.model; + +import java.util.ArrayList; +import java.util.List; + +public class VerificationServiceResult extends ServiceResult> { + + public VerificationServiceResult() { + setResult(new ArrayList<>()); + } + + public VerificationServiceResult(List result, List issues) { + super(result, issues); + } + + @Override + public List getResult() { + return super.getResult(); + } + + @Override + public void setResult(List result) { + super.setResult(result != null ? result : new ArrayList<>()); + } + + @Override + public List getIssues() { + return super.getIssues(); + } + + @Override + public void setIssues(List issues) { + super.setIssues(issues); + } + + public String getMessage() { + int numberOfVerificationIssues = getResult().size(); + return numberOfVerificationIssues == 0 + ? "No syntactical issues were found." + : numberOfVerificationIssues + " syntactical issues were found."; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/DiagramElementContainer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/DiagramElementContainer.java new file mode 100644 index 00000000..7d35d9e4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/DiagramElementContainer.java @@ -0,0 +1,52 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import it.unibz.inf.ontouml.vp.model.ontouml.view.*; +import java.util.List; +import java.util.Optional; + +public interface DiagramElementContainer extends ElementContainer { + + default List getAllDiagramElements() { + return getAllContentsByType(ElementView.class); + } + + default List getAllConnectorViews() { + return getAllContentsByType(ConnectorView.class); + } + + default List getAllClassViews() { + return getAllContentsByType(ClassView.class); + } + + default List getAllPackageViews() { + return getAllContentsByType(PackageView.class); + } + + default List getAllRelationViews() { + return getAllContentsByType(RelationView.class); + } + + default List getAllGeneralizationViews() { + return getAllContentsByType(GeneralizationView.class); + } + + default List getAllGeneralizationSetViews() { + return getAllContentsByType(GeneralizationSetView.class); + } + + default Optional getClassViewById(String id) { + return getElementById(id, ClassView.class); + } + + default Optional getRelationViewById(String id) { + return getElementById(id, RelationView.class); + } + + default Optional getGeneralizationViewById(String id) { + return getElementById(id, GeneralizationView.class); + } + + default Optional getGeneralizationSetViewById(String id) { + return getElementById(id, GeneralizationSetView.class); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Element.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Element.java new file mode 100644 index 00000000..e5fb1f4e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Element.java @@ -0,0 +1,95 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import java.util.Optional; +import java.util.UUID; + +public abstract class Element implements Comparable { + String id; + MultilingualText name; + MultilingualText description; + + public Element(String id, MultilingualText name) { + this.id = id != null ? id : UUID.randomUUID().toString(); + this.name = name != null ? name : new MultilingualText(); + this.description = new MultilingualText(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + if (id == null) throw new NullPointerException("Cannot set null id."); + + this.id = id; + } + + public MultilingualText getName() { + return this.name; + } + + public Optional getNameIn(String language) { + return name.getText(language); + } + + public Optional getFirstName() { + return name.getText(); + } + + public void setName(MultilingualText name) { + this.name = name; + } + + public void addName(String languageTag, String value) { + this.name.putText(languageTag, value); + } + + public void addName(String value) { + this.name.putText(value); + } + + public void removeNameIn(String languageTag) { + this.name.removeTextIn(languageTag); + } + + public void removeAllNames() { + this.name.removeAll(); + } + + public MultilingualText getDescription() { + return this.description; + } + + public Optional getDescriptionIn(String language) { + return description.getText(language); + } + + public Optional getFirstDescription() { + return description.getText(); + } + + public void setDescription(MultilingualText description) { + this.description = description; + } + + public void addDescription(String languageTag, String value) { + this.description.putText(languageTag, value); + } + + public void addDescription(String value) { + this.description.putText(value); + } + + public void removeDescription(String languageTag) { + this.description.removeTextIn(languageTag); + } + + public void removeAllDescriptions() { + this.description.removeAll(); + } + + @Override + public int compareTo(Element element) { + return this.getFirstName().orElse("").compareTo(element.getFirstName().orElse("")); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ElementContainer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ElementContainer.java new file mode 100644 index 00000000..0dcb4aa0 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ElementContainer.java @@ -0,0 +1,34 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public interface ElementContainer { + + List getContents(); + + List getAllContents(); + + default List getAllContentsByType(Class type) { + return getAllContents().stream() + .filter(type::isInstance) + .map(type::cast) + .collect(Collectors.toList()); + } + + default Optional getElementById(String id, Class type) { + + List elements = + getAllContents().stream() + .filter(e -> type.isInstance(e) && id.equals(e.getId())) + .collect(Collectors.toList()); + + if (elements.size() == 1) return Optional.of(type.cast(elements.get(0))); + + if (elements.size() == 0) return Optional.empty(); + + throw new IllegalStateException( + "There is more than one instance of " + type.getName() + " with the same id!"); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ModelElementContainer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ModelElementContainer.java new file mode 100644 index 00000000..80f4b47b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/ModelElementContainer.java @@ -0,0 +1,216 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +public interface ModelElementContainer extends ElementContainer { + + default List getAllModelElements() { + return getAllContentsByType(ModelElement.class); + } + + default List getAllPackages() { + return getAllContentsByType(it.unibz.inf.ontouml.vp.model.ontouml.model.Package.class); + } + + default List getAllClasses() { + return getAllContentsByType(Class.class); + } + + default List getAllProperties() { + return getAllContentsByType(Property.class); + } + + default List getAllAttributes() { + return getAllProperties().stream().filter(Property::isAttribute).collect(Collectors.toList()); + } + + default List getAllLiterals() { + return getAllContentsByType(Literal.class); + } + + default List getAllRelations() { + return getAllContentsByType(Relation.class); + } + + default List getAllRelationEnds() { + return getAllContentsByType(Property.class).stream() + .filter(Property::isRelationEnd) + .collect(Collectors.toList()); + } + + default List getAllGeneralizations() { + return getAllContentsByType(Generalization.class); + } + + default List getAllGeneralizationSets() { + return getAllContentsByType(GeneralizationSet.class); + } + + default List getClassesByStereotype(ClassStereotype stereotype) { + if (stereotype == null) throw new NullPointerException("Input stereotype cannot be null!"); + + return getAllClasses().stream() + .filter( + c -> + c.getOntoumlStereotype().isPresent() + && c.getOntoumlStereotype().get() == stereotype) + .collect(Collectors.toList()); + } + + default List getRelationsByStereotype(RelationStereotype stereotype) { + if (stereotype == null) throw new NullPointerException("Input stereotype cannot be null!"); + + return getAllRelations().stream() + .filter( + c -> + c.getOntoumlStereotype().isPresent() + && c.getOntoumlStereotype().get() == stereotype) + .collect(Collectors.toList()); + } + + default List getAttributesByStereotype(PropertyStereotype stereotype) { + if (stereotype == null) throw new NullPointerException("Input stereotype cannot be null!"); + + return getAllAttributes().stream() + .filter( + c -> + c.getOntoumlStereotype().isPresent() + && c.getOntoumlStereotype().get() == stereotype) + .collect(Collectors.toList()); + } + + default List getAllTypes() { + return this.getClassesByStereotype(ClassStereotype.TYPE); + } + + default List getAllHistoricalRoles() { + return this.getClassesByStereotype(ClassStereotype.HISTORICAL_ROLE); + } + + default List getAllHistoricalRoleMixins() { + return this.getClassesByStereotype(ClassStereotype.HISTORICAL_ROLE_MIXIN); + } + + default List getAllEvents() { + return this.getClassesByStereotype(ClassStereotype.EVENT); + } + + default List getAllSituations() { + return this.getClassesByStereotype(ClassStereotype.SITUATION); + } + + default List getAllCategories() { + return this.getClassesByStereotype(ClassStereotype.CATEGORY); + } + + default List getAllMixins() { + return this.getClassesByStereotype(ClassStereotype.MIXIN); + } + + default List getAllRoleMixins() { + return this.getClassesByStereotype(ClassStereotype.ROLE_MIXIN); + } + + default List getAllPhaseMixin() { + return this.getClassesByStereotype(ClassStereotype.PHASE_MIXIN); + } + + default List getAllKinds() { + return this.getClassesByStereotype(ClassStereotype.KIND); + } + + default List getAllCollectives() { + return this.getClassesByStereotype(ClassStereotype.COLLECTIVE); + } + + default List getAllQuantities() { + return this.getClassesByStereotype(ClassStereotype.QUANTITY); + } + + default List getAllRelators() { + return this.getClassesByStereotype(ClassStereotype.RELATOR); + } + + default List getAllQualities() { + return this.getClassesByStereotype(ClassStereotype.QUALITY); + } + + default List getAllModes() { + return this.getClassesByStereotype(ClassStereotype.MODE); + } + + default List getAllSubkinds() { + return this.getClassesByStereotype(ClassStereotype.SUBKIND); + } + + default List getAllRoles() { + return this.getClassesByStereotype(ClassStereotype.ROLE); + } + + default List getAllPhases() { + return this.getClassesByStereotype(ClassStereotype.PHASE); + } + + default List getAllEnumerations() { + return this.getClassesByStereotype(ClassStereotype.ENUMERATION); + } + + default List getAllDatatypes() { + return this.getClassesByStereotype(ClassStereotype.DATATYPE); + } + + default List getAllPrimitiveDatatypes() { + return getAllDatatypes().stream() + .filter(d -> d.isPrimitiveDatatype()) + .collect(Collectors.toList()); + } + + default List getAllAbstracts() { + return this.getClassesByStereotype(ClassStereotype.ABSTRACT); + } + + default Optional getClassById(String id) { + return getElementById(id, Class.class); + } + + default Optional getRelationById(String id) { + return getElementById(id, Relation.class); + } + + default Optional getGeneralizationById(String id) { + return getElementById(id, Generalization.class); + } + + default Optional getGeneralizationSetById(String id) { + return getElementById(id, GeneralizationSet.class); + } + + default Optional getPropertyById(String id) { + return getElementById(id, Property.class); + } + + default Optional getPackageById(String id) { + return getElementById(id, Package.class); + } + + default Map getElementMap() throws IllegalStateException { + Map map = new HashMap<>(); + + for (OntoumlElement element : getAllContents()) { + String key = element.getId(); + if (map.containsKey(key)) { + throw new IllegalStateException("Duplicate ids!"); + } + map.put(key, element); + } + + return map; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualText.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualText.java new file mode 100644 index 00000000..f9b03532 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualText.java @@ -0,0 +1,114 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.MultilingualTextDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.MultilingualTextSerializer; +import java.util.*; + +@JsonSerialize(using = MultilingualTextSerializer.class) +@JsonDeserialize(using = MultilingualTextDeserializer.class) +public class MultilingualText { + private static String defaultLanguage = "en"; + private static String[] languagePreference = new String[] {defaultLanguage}; + + private SortedMap textMap = new TreeMap<>(); + + public MultilingualText(MultilingualText base) { + textMap.putAll(base.textMap); + } + + public MultilingualText(String languageTag, String value) { + this.putText(languageTag, value); + } + + public MultilingualText(String value) { + this.putText(value); + } + + public MultilingualText(Map multilingualTextMap) { + textMap.putAll(multilingualTextMap); + } + + public MultilingualText() {} + + public Map getMap() { + return Map.copyOf(textMap); + } + + public Optional getText() { + for (String language : languagePreference) { + if (textMap.containsKey(language)) return Optional.ofNullable(textMap.get(language)); + } + + if (textMap.size() > 0) return Optional.ofNullable(textMap.get(textMap.firstKey())); + + return Optional.empty(); + } + + public Optional getText(String language) { + if (textMap.containsKey(language)) return Optional.ofNullable(textMap.get(language)); + + return getText(); + } + + public boolean isEmpty() { + return this.textMap.isEmpty(); + } + + public int size() { + return this.textMap.size(); + } + + public void putText(String languageTag, String value) { + textMap.put(languageTag, value); + } + + public void putText(String value) { + putText(defaultLanguage, value); + } + + public Collection getTexts() { + return textMap.values(); + } + + public Collection getLanguages() { + + return textMap.keySet(); + } + + public boolean containsLanguage(String languageTag) { + return textMap.containsKey(languageTag); + } + + public void removeTextIn(String languageTag) { + textMap.remove(languageTag); + } + + public void removeAll() { + textMap.clear(); + } + + public static void setDefaultLanguage(String language) { + if (language == null) + throw new NullPointerException("Cannot set a null value as the default language."); + + MultilingualText.defaultLanguage = language; + } + + public static void setLanguagePreference(String[] languagePreference) { + if (languagePreference == null) + throw new NullPointerException("Cannot set a null preference array."); + + MultilingualText.languagePreference = languagePreference; + } + + @Override + public String toString() { + if (textMap.size() <= 1) { + return getText().orElse(null); + } + + return textMap.toString(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlElement.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlElement.java new file mode 100644 index 00000000..f1f35bda --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlElement.java @@ -0,0 +1,81 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public abstract class OntoumlElement extends Element { + + private OntoumlElement container; + private Project project; + + public OntoumlElement(OntoumlElement container, String id, MultilingualText name) { + super(id, name); + this.container = container; + + if (container != null) project = container.project; + } + + public OntoumlElement(String id, MultilingualText name) { + super(id, name); + } + + public Optional getContainer() { + return Optional.ofNullable(container); + } + + public void setContainer(OntoumlElement container) { + this.container = container; + Project project = container != null ? container.project : null; + setProject(project); + } + + public boolean hasContainer() { + return getContainer().isPresent(); + } + + public Optional getProject() { + return Optional.ofNullable(project); + } + + public boolean hasProject() { + return getProject().isEmpty(); + } + + /** Setting the project of an element propagates to all of its contents */ + public void setProject(Project project) { + this.project = project; + getAllContents().forEach(elem -> elem.setProject(project)); + } + + public List getContents(Predicate filter) { + if (filter == null) return getContents(); + + return getContents().stream().filter(filter).collect(Collectors.toList()); + } + + public abstract List getContents(); + + public List getAllContents() { + List children = getContents(); + + if (children.isEmpty()) return children; + + List childrenContents = + children.stream() + .flatMap(child -> child.getAllContents().stream()) + .collect(Collectors.toList()); + + childrenContents.addAll(children); + + return childrenContents; + } + + @Override + public String toString() { + return getType() + " { id: " + id + "(hash: " + hashCode() + "), name: " + getName() + "}"; + } + + public abstract String getType(); +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlUtils.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlUtils.java new file mode 100644 index 00000000..651ca6d7 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/OntoumlUtils.java @@ -0,0 +1,16 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import java.util.Collection; +import java.util.function.Predicate; + +public class OntoumlUtils { + + /** Adds all non-null elements of the origin collection to the destination collection. */ + public static void addIfNotNull(Collection destination, Collection origin) { + origin.stream().filter(x -> x != null).forEach(x -> destination.add(x)); + } + + public static boolean contains(Collection collection, Predicate condition) { + return collection.stream().anyMatch(condition); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Project.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Project.java new file mode 100644 index 00000000..7b4a06fd --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/Project.java @@ -0,0 +1,110 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.ProjectDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.ProjectSerializer; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@JsonSerialize(using = ProjectSerializer.class) +@JsonDeserialize(using = ProjectDeserializer.class) +public class Project extends OntoumlElement + implements ModelElementContainer, DiagramElementContainer { + private Package model; + private List diagrams = new ArrayList<>(); + + public Project(String id, MultilingualText name) { + super(null, id, name); + setProject(this); + } + + public Project(String id, String name) { + super(null, id, new MultilingualText(name)); + setProject(this); + } + + public Project(MultilingualText name) { + this(null, name); + } + + public Project() { + this(null, (MultilingualText) null); + } + + @Override + public String getType() { + return "Project"; + } + + public Optional getModel() { + return Optional.ofNullable(model); + } + + public Package createModel() { + return createModel(null, "Model"); + } + + public Package createModel(String modelName) { + return createModel(null, modelName); + } + + public Package createModel(String id, String modelName) { + Package model = new Package(id, modelName); + setModel(model); + return model; + } + + public void setModel(Package model) { + this.model = model; + + if (model != null) model.setContainer(this); + } + + public boolean hasModel() { + return getModel().isPresent(); + } + + public List getDiagrams() { + return new ArrayList<>(diagrams); + } + + public void addDiagram(Diagram diagram) { + if (diagram == null) return; + + diagram.setContainer(this); + diagrams.add(diagram); + } + + public void addDiagrams(List diagrams) { + if (diagrams == null) return; + + diagrams.forEach(d -> addDiagram(d)); + } + + public void setDiagrams(List diagrams) { + this.diagrams.clear(); + + if (diagrams == null) return; + + addDiagrams(diagrams); + } + + public boolean hasDiagram() { + return diagrams != null && diagrams.size() > 0; + } + + @Override + public List getContents() { + List contents = new ArrayList<>(); + + contents.addAll(diagrams); + + if (getModel().isPresent()) contents.add(getModel().get()); + + return contents; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializer.java new file mode 100644 index 00000000..8b9a39ce --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializer.java @@ -0,0 +1,50 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.*; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import java.io.IOException; +import java.util.List; + +public class ClassDeserializer extends JsonDeserializer { + + @Override + public Class deserialize(JsonParser parser, DeserializationContext context) throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Class clazz = new Class(); + + ElementDeserializer.deserialize(clazz, root, codec); + ModelElementDeserializer.deserialize(clazz, root, codec); + DecoratableDeserializer.deserialize(clazz, root, codec); + ClassifierDeserializer.deserialize(clazz, root, codec); + + Boolean isExtensional = deserializeNullableBooleanField(root, "isExtensional"); + clazz.setExtensional(isExtensional); + + Boolean isPowertype = deserializeNullableBooleanField(root, "isPowertype"); + clazz.setPowertype(isPowertype); + + Integer order = deserializeNullableIntegerField(root, "order"); + clazz.setOrder(order); + + String[] restrictedTo = deserializeNullableStringArrayField(root, "restrictedTo", codec); + if (restrictedTo != null) { + clazz.setRestrictedTo(restrictedTo); + } + + List literals = deserializeArrayField(root, "literals", Literal.class, codec); + if (literals != null) { + clazz.setLiterals(literals); + } + + return clazz; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializer.java new file mode 100644 index 00000000..1cd65cf4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializer.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; + +public class ClassViewDeserializer extends JsonDeserializer { + + @Override + public ClassView deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + ClassView view = new ClassView(); + + String id = root.get("id").asText(); + view.setId(id); + + Class element = deserializeObjectField(root, "modelElement", Class.class, codec); + view.setModelElement(element); + + Rectangle shape = deserializeObjectField(root, "shape", Rectangle.class, codec); + view.setShape(shape); + + return view; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassifierDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassifierDeserializer.java new file mode 100644 index 00000000..6e2f3588 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassifierDeserializer.java @@ -0,0 +1,31 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeBooleanField; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.io.IOException; +import java.util.List; + +public class ClassifierDeserializer { + + public static void deserialize(Classifier classifier, JsonNode root, ObjectCodec codec) + throws IOException { + + boolean isAbstract = deserializeBooleanField(root, "isAbstract"); + classifier.setAbstract(isAbstract); + + boolean isDerived = deserializeBooleanField(root, "isDerived"); + classifier.setDerived(isDerived); + + JsonNode propertiesNode = root.get("properties"); + if (propertiesNode != null && propertiesNode.isArray()) { + List properties = + propertiesNode.traverse(codec).readValueAs(new TypeReference>() {}); + classifier.setProperties(properties); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ConnectorViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ConnectorViewDeserializer.java new file mode 100644 index 00000000..a9e6692f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ConnectorViewDeserializer.java @@ -0,0 +1,41 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.*; +import java.io.IOException; +import java.util.List; + +public class ConnectorViewDeserializer { + + public static void deserialize(ConnectorView view, JsonNode root, ObjectCodec codec) + throws IOException { + + String id = root.get("id").asText(); + view.setId(id); + + Path path = deserializeObjectField(root, "shape", Path.class, codec); + view.setPath(path); + + ElementView source = deserializeConnectorEnd(root, "source", codec); + view.setSource(source); + + ElementView target = deserializeConnectorEnd(root, "target", codec); + view.setTarget(target); + } + + private static ElementView deserializeConnectorEnd( + JsonNode root, String fieldName, ObjectCodec codec) throws IOException { + + List> allowedTypes = + List.of(ClassView.class, RelationView.class); + + OntoumlElement source = + DeserializerUtils.deserializeObjectField(root, fieldName, allowedTypes, codec); + + return (source instanceof ElementView) ? (ElementView) source : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DecoratableDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DecoratableDeserializer.java new file mode 100644 index 00000000..d3c69755 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DecoratableDeserializer.java @@ -0,0 +1,17 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeNullableStringField; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Decoratable; +import java.io.IOException; + +public class DecoratableDeserializer { + + public static void deserialize(Decoratable decoratable, JsonNode root, ObjectCodec codec) + throws IOException { + String stereotype = deserializeNullableStringField(root, "stereotype"); + decoratable.setStereotype(stereotype); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DeserializerUtils.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DeserializerUtils.java new file mode 100644 index 00000000..a23627f4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DeserializerUtils.java @@ -0,0 +1,270 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class DeserializerUtils { + + public static boolean deserializeBooleanField(JsonNode containerNode, String fieldname) { + JsonNode booleanNode = containerNode.get(fieldname); + + if (booleanNode != null && booleanNode.isBoolean()) { + return booleanNode.asBoolean(); + } + + return false; + } + + public static String deserializeNullableStringField(JsonNode containerNode, String fieldname) { + JsonNode stringNode = containerNode.get(fieldname); + + if (stringNode != null && stringNode.isTextual()) { + return stringNode.asText(); + } + + return null; + } + + public static String[] deserializeNullableStringArrayField( + JsonNode containerNode, String fieldname, ObjectCodec codec) throws IOException { + JsonNode arrayNode = containerNode.get(fieldname); + + if (arrayNode != null && arrayNode.isArray()) { + return arrayNode.traverse(codec).readValueAs(String[].class); + } + + return new String[0]; + } + + public static Boolean deserializeNullableBooleanField(JsonNode containerNode, String fieldname) { + JsonNode booleanNode = containerNode.get(fieldname); + + if (booleanNode != null && booleanNode.isBoolean()) { + return booleanNode.asBoolean(); + } + + return null; + } + + public static Integer deserializeNullableIntegerField(JsonNode containerNode, String fieldname) { + JsonNode integerNode = containerNode.get(fieldname); + + if (integerNode != null && integerNode.canConvertToInt()) { + return integerNode.asInt(); + } + + return null; + } + + public static Double deserializeNullableDoubleField(JsonNode containerNode, String fieldname) { + JsonNode doubleNode = containerNode.get(fieldname); + + if (doubleNode != null && doubleNode.isNumber()) { + return doubleNode.asDouble(); + } + + return null; + } + + public static boolean isReferenceOf(JsonNode node, java.lang.Class referenceType) { + if (!node.isObject()) return false; + + String typeFieldValue = node.get("type").asText(); + + if (referenceType.equals(Class.class)) return "Class".equals(typeFieldValue); + else if (referenceType.equals(Relation.class)) return "Relation".equals(typeFieldValue); + else if (referenceType.equals(Property.class)) return "Property".equals(typeFieldValue); + else if (referenceType.equals(Generalization.class)) + return "Generalization".equals(typeFieldValue); + else if (referenceType.equals(GeneralizationSet.class)) + return "GeneralizationSet".equals(typeFieldValue); + else if (referenceType.equals(Package.class)) return "Package".equals(typeFieldValue); + else if (referenceType.equals(Literal.class)) return "Literal".equals(typeFieldValue); + else if (referenceType.equals(Project.class)) return "Project".equals(typeFieldValue); + else if (referenceType.equals(ClassView.class)) return "ClassView".equals(typeFieldValue); + else if (referenceType.equals(RelationView.class)) return "RelationView".equals(typeFieldValue); + else if (referenceType.equals(GeneralizationView.class)) + return "GeneralizationView".equals(typeFieldValue); + else if (referenceType.equals(GeneralizationSetView.class)) + return "GeneralizationSetView".equals(typeFieldValue); + else if (referenceType.equals(PackageView.class)) return "PackageView".equals(typeFieldValue); + else if (referenceType.equals(Path.class)) return "Path".equals(typeFieldValue); + else if (referenceType.equals(Rectangle.class)) return "Rectangle".equals(typeFieldValue); + else if (referenceType.equals(Text.class)) return "Text".equals(typeFieldValue); + + return false; + } + + public static java.lang.Class getClass(String typeName) { + switch (typeName) { + case "ClassView": + return ClassView.class; + case "RelationView": + return RelationView.class; + case "GeneralizationView": + return GeneralizationView.class; + case "GeneralizationSetView": + return GeneralizationSetView.class; + case "PackageView": + return PackageView.class; + case "Path": + return Path.class; + case "Rectangle": + return Rectangle.class; + case "Text": + return Text.class; + case "Class": + return Class.class; + case "Relation": + return Relation.class; + case "Generalization": + return Generalization.class; + case "GeneralizationSet": + return GeneralizationSet.class; + case "Package": + return Package.class; + case "Property": + return Property.class; + case "Literal": + return Literal.class; + case "Project": + return Project.class; + case "Diagram": + return Diagram.class; + } + + return null; + } + + /** + * Deserializes a node into the subclass of {@link OntoumlElement} that matches the "type" field + * of the JSON object + */ + private static OntoumlElement deserializeObject( + JsonNode node, + List> allowedTypes, + ObjectCodec codec) + throws IOException { + + if (node == null || !node.isObject()) return null; + + JsonNode typeNode = node.get("type"); + if (typeNode == null || !typeNode.isTextual()) return null; + + String typeNodeValue = typeNode.asText(); + java.lang.Class type = getClass(typeNodeValue); + + if (allowedTypes.contains(type)) { + return node.traverse(codec).readValueAs(type); + } + + throw new JsonParseException( + codec.treeAsTokens(node), "Cannot deserialize object! Wrong type."); + } + + private static T deserializeObject( + JsonNode node, java.lang.Class allowedType, ObjectCodec codec) throws IOException { + + OntoumlElement element = deserializeObject(node, List.of(allowedType), codec); + return castOrNull(element, allowedType); + } + + public static OntoumlElement deserializeObjectField( + JsonNode containerNode, + String fieldName, + List> allowedTypes, + ObjectCodec codec) + throws IOException { + + JsonNode node = containerNode.get(fieldName); + return deserializeObject(node, allowedTypes, codec); + } + + public static T deserializeObjectField( + JsonNode containerNode, String fieldName, java.lang.Class allowedType, ObjectCodec codec) + throws IOException { + + JsonNode node = containerNode.get(fieldName); + return deserializeObject(node, allowedType, codec); + } + + public static List deserializeArrayField( + JsonNode containerNode, + String fieldName, + List> allowedTypes, + ObjectCodec codec) + throws IOException { + + JsonNode arrayNode = containerNode.get(fieldName); + + if (arrayNode == null || arrayNode.isNull()) { + return List.of(); + } + + if (arrayNode.isArray()) { + List list = new ArrayList<>(); + Iterator iterator = arrayNode.elements(); + + while (iterator.hasNext()) { + JsonNode memberNode = iterator.next(); + OntoumlElement member = deserializeObject(memberNode, allowedTypes, codec); + if (member != null) list.add(member); + } + + return list; + } + + throw new JsonParseException(codec.treeAsTokens(arrayNode), "Cannot deserialize object array!"); + } + + public static List deserializeArrayField( + JsonNode containerNode, String fieldName, java.lang.Class allowedType, ObjectCodec codec) + throws IOException { + + JsonNode arrayNode = containerNode.get(fieldName); + + if (arrayNode == null || arrayNode.isNull()) { + return List.of(); + } + + if (arrayNode.isArray()) { + List list = new ArrayList<>(); + Iterator iterator = arrayNode.elements(); + + while (iterator.hasNext()) { + JsonNode memberNode = iterator.next(); + T member = deserializeObject(memberNode, allowedType, codec); + if (member != null) list.add(member); + } + + return list; + } + + throw new JsonParseException(codec.treeAsTokens(arrayNode), "Cannot deserialize object array!"); + } + + public static Classifier deserializeClassifierField( + JsonNode containerNode, String fieldName, ObjectCodec codec) throws IOException { + + OntoumlElement classifier = + deserializeObjectField( + containerNode, fieldName, List.of(Class.class, Relation.class), codec); + + return castOrNull(classifier, Classifier.class); + } + + public static T castOrNull(Object object, java.lang.Class type) { + return (type.isInstance(object)) ? type.cast(object) : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializer.java new file mode 100644 index 00000000..dcf9613e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializer.java @@ -0,0 +1,64 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.*; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.*; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +public class DiagramDeserializer extends JsonDeserializer { + + @Override + public Diagram deserialize(JsonParser parser, DeserializationContext context) throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Diagram diagram = new Diagram(); + + ElementDeserializer.deserialize(diagram, root, codec); + + ModelElement owner = deserializeOwner(root, codec); + diagram.setOwner(owner); + + List> contents = deserializeContents(root, codec); + diagram.setContents(contents); + + return diagram; + } + + private ModelElement deserializeOwner(JsonNode root, ObjectCodec codec) throws IOException { + OntoumlElement owner = + deserializeObjectField(root, "owner", List.of(Class.class, Package.class), codec); + return castOrNull(owner, ModelElement.class); + } + + private List> deserializeContents(JsonNode root, ObjectCodec codec) + throws IOException { + List contents = + deserializeArrayField( + root, + "contents", + List.of( + ClassView.class, + PackageView.class, + RelationView.class, + GeneralizationView.class, + GeneralizationSetView.class), + codec); + + return contents.stream() + .filter(x -> x instanceof ElementView) + .map(x -> (ElementView) x) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ElementDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ElementDeserializer.java new file mode 100644 index 00000000..257688df --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ElementDeserializer.java @@ -0,0 +1,32 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.Element; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.io.IOException; + +public class ElementDeserializer { + + public static void deserialize(Element element, JsonNode root, ObjectCodec codec) + throws IOException { + System.out.println("Deserializing type: " + root.get("type") + ""); + String id = root.get("id").asText(); + element.setId(id); + System.out.println("Deserialized id: " + id); + + JsonNode nameNode = root.get("name"); + if (nameNode != null) { + MultilingualText name = nameNode.traverse(codec).readValueAs(MultilingualText.class); + element.setName(name); + System.out.println("Deserialized name: " + name); + } + + JsonNode descNode = root.get("description"); + if (descNode != null) { + MultilingualText desc = descNode.traverse(codec).readValueAs(MultilingualText.class); + element.setDescription(desc); + System.out.println("Deserialized description: " + desc); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializer.java new file mode 100644 index 00000000..7defa653 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializer.java @@ -0,0 +1,34 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeClassifierField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import java.io.IOException; + +public class GeneralizationDeserializer extends JsonDeserializer { + + @Override + public Generalization deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Generalization gen = new Generalization(); + ElementDeserializer.deserialize(gen, root, codec); + ModelElementDeserializer.deserialize(gen, root, codec); + + Classifier general = deserializeClassifierField(root, "general", codec); + gen.setGeneral(general); + + Classifier specific = deserializeClassifierField(root, "specific", codec); + gen.setSpecific(specific); + + return gen; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializer.java new file mode 100644 index 00000000..36e56744 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializer.java @@ -0,0 +1,43 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.*; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import java.io.IOException; +import java.util.List; + +public class GeneralizationSetDeserializer extends JsonDeserializer { + + @Override + public GeneralizationSet deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + GeneralizationSet gs = new GeneralizationSet(); + ElementDeserializer.deserialize(gs, root, codec); + ModelElementDeserializer.deserialize(gs, root, codec); + + boolean isComplete = deserializeBooleanField(root, "isComplete"); + gs.setComplete(isComplete); + + boolean isDisjoint = deserializeBooleanField(root, "isDisjoint"); + gs.setDisjoint(isDisjoint); + + Class categorizer = deserializeObjectField(root, "categorizer", Class.class, codec); + gs.setCategorizer(categorizer); + + List generalizations = + deserializeArrayField(root, "generalizations", Generalization.class, codec); + gs.setGeneralizations(generalizations); + + return gs; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializer.java new file mode 100644 index 00000000..69252673 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializer.java @@ -0,0 +1,37 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationSetView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Text; +import java.io.IOException; + +public class GeneralizationSetViewDeserializer extends JsonDeserializer { + + @Override + public GeneralizationSetView deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + GeneralizationSetView view = new GeneralizationSetView(); + + String id = root.get("id").asText(); + view.setId(id); + + GeneralizationSet gs = + deserializeObjectField(root, "modelElement", GeneralizationSet.class, codec); + view.setModelElement(gs); + + Text shape = deserializeObjectField(root, "shape", Text.class, codec); + view.setShape(shape); + + return view; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializer.java new file mode 100644 index 00000000..e1559ac7 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializer.java @@ -0,0 +1,31 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; +import java.io.IOException; + +public class GeneralizationViewDeserializer extends JsonDeserializer { + + @Override + public GeneralizationView deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + GeneralizationView view = new GeneralizationView(); + + ConnectorViewDeserializer.deserialize(view, root, codec); + + Generalization stub = deserializeObjectField(root, "modelElement", Generalization.class, codec); + view.setModelElement(stub); + + return view; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/LiteralDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/LiteralDeserializer.java new file mode 100644 index 00000000..c0979386 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/LiteralDeserializer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import java.io.IOException; + +public class LiteralDeserializer extends JsonDeserializer { + + @Override + public Literal deserialize(JsonParser parser, DeserializationContext context) throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Literal literal = new Literal(); + ElementDeserializer.deserialize(literal, root, codec); + ModelElementDeserializer.deserialize(literal, root, codec); + + return literal; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ModelElementDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ModelElementDeserializer.java new file mode 100644 index 00000000..e90edc61 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ModelElementDeserializer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import java.io.IOException; +import java.util.Map; + +public class ModelElementDeserializer { + + public static void deserialize(ModelElement element, JsonNode root, ObjectCodec codec) + throws IOException { + + JsonNode node = root.get("propertyAssignments"); + + if (node != null && node.isObject()) { + Map propertyMap = + node.traverse(codec).readValueAs(new TypeReference>() {}); + + element.setPropertyAssignments(propertyMap); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializer.java new file mode 100644 index 00000000..5c21b0ae --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializer.java @@ -0,0 +1,41 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.io.IOException; +import java.util.Map; + +public class MultilingualTextDeserializer extends JsonDeserializer { + + @Override + public MultilingualText getNullValue(DeserializationContext ctxt) throws JsonMappingException { + return new MultilingualText(); + } + + @Override + public MultilingualText deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode node = codec.readTree(parser); + + if (node.isTextual()) return new MultilingualText(node.asText()); + + if (node.isObject()) { + Map textMap = + node.traverse(codec).readValueAs(new TypeReference>() {}); + + return new MultilingualText(textMap); + } + + if (node.isNull()) return new MultilingualText(); + + throw new JsonMappingException( + parser, "Multilingual text mus be either a string, null, or an object."); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializer.java new file mode 100644 index 00000000..aedc05a4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializer.java @@ -0,0 +1,76 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class PackageDeserializer extends JsonDeserializer { + + @Override + public Package deserialize(JsonParser parser, DeserializationContext context) throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Package pkg = new Package(); + ElementDeserializer.deserialize(pkg, root, codec); + ModelElementDeserializer.deserialize(pkg, root, codec); + deserializeContents(pkg, root, codec); + + return pkg; + } + + private void deserializeContents(Package pkg, JsonNode root, ObjectCodec codec) { + JsonNode contentsNode = root.get("contents"); + + if (contentsNode != null && contentsNode.isArray()) { + + List contents = new ArrayList<>(); + contentsNode + .elements() + .forEachRemaining( + contentNode -> { + if (!contentNode.isObject()) return; + + String type = contentNode.get("type").asText(); + java.lang.Class referenceType; + + switch (type) { + case "Package": + referenceType = Package.class; + break; + case "Class": + referenceType = Class.class; + break; + case "Relation": + referenceType = Relation.class; + break; + case "Generalization": + referenceType = Generalization.class; + break; + case "GeneralizationSet": + referenceType = GeneralizationSet.class; + break; + default: + return; + } + + try { + ModelElement content = contentNode.traverse(codec).readValueAs(referenceType); + contents.add(content); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + pkg.setContents(contents); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageViewDeserializer.java new file mode 100644 index 00000000..f52a7b49 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageViewDeserializer.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.PackageView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; + +public class PackageViewDeserializer extends JsonDeserializer { + + @Override + public PackageView deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + PackageView view = new PackageView(); + + String id = root.get("id").asText(); + view.setId(id); + + Package element = deserializeObjectField(root, "modelElement", Package.class, codec); + view.setModelElement(element); + + Rectangle shape = deserializeObjectField(root, "shape", Rectangle.class, codec); + view.setShape(shape); + + return view; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializer.java new file mode 100644 index 00000000..a0f4b091 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializer.java @@ -0,0 +1,53 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Point; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class PathDeserializer extends JsonDeserializer { + @Override + public Path deserialize(JsonParser parser, DeserializationContext context) throws IOException { + + JsonNode root = parser.readValueAsTree(); + Path path = new Path(); + + String id = root.get("id").asText(); + path.setId(id); + + List points = deserializePoints(root); + path.setPoints(points); + + return path; + } + + private List deserializePoints(JsonNode root) { + JsonNode arrayNode = root.get("points"); + if (arrayNode == null || !arrayNode.isArray()) return null; + + List points = new ArrayList<>(); + Iterator iterator = arrayNode.elements(); + while (iterator.hasNext()) { + JsonNode pointNode = iterator.next(); + + if (!pointNode.isObject()) continue; + + JsonNode xNode = pointNode.get("x"); + int x = (xNode != null) ? xNode.asInt(0) : 0; + + JsonNode yNode = pointNode.get("y"); + int y = (yNode != null) ? yNode.asInt(0) : 0; + + Point point = new Point(x, y); + points.add(point); + } + + return points; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializer.java new file mode 100644 index 00000000..a3e20f81 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializer.java @@ -0,0 +1,45 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeArrayField; +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import java.io.IOException; +import java.util.List; + +public class ProjectDeserializer extends JsonDeserializer { + + @Override + public Project deserialize(JsonParser parser, DeserializationContext context) throws IOException { + System.out.println("Deserializing project..."); + + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Project project = new Project(); + + ElementDeserializer.deserialize(project, root, codec); + + Package model = deserializeObjectField(root, "model", Package.class, codec); + project.setModel(model); + + List diagrams = deserializeArrayField(root, "diagrams", Diagram.class, codec); + project.setDiagrams(diagrams); + + try { + ReferenceResolver.resolveReferences(project); + } catch (Exception e) { + throw new JsonParseException(parser, "Cannot deserialize project", e); + } + + return project; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializer.java new file mode 100644 index 00000000..865ce9af --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializer.java @@ -0,0 +1,57 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.*; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.AggregationKind; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.io.IOException; +import java.util.List; + +public class PropertyDeserializer extends JsonDeserializer { + + @Override + public Property deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Property property = new Property(); + ElementDeserializer.deserialize(property, root, codec); + ModelElementDeserializer.deserialize(property, root, codec); + DecoratableDeserializer.deserialize(property, root, codec); + + boolean isDerived = deserializeBooleanField(root, "isDerived"); + property.setDerived(isDerived); + + boolean isReadOnly = deserializeBooleanField(root, "isReadOnly"); + property.setReadOnly(isReadOnly); + + boolean isOrdered = deserializeBooleanField(root, "isOrdered"); + property.setOrdered(isOrdered); + + String cardinality = deserializeNullableStringField(root, "cardinality"); + property.setCardinality(cardinality); + + Classifier propertyType = deserializeClassifierField(root, "propertyType", codec); + property.setPropertyType(propertyType); + + List subsettedProperties = + deserializeArrayField(root, "subsettedProperties", Property.class, codec); + property.setSubsettedProperties(subsettedProperties); + + List redefinedProperties = + deserializeArrayField(root, "redefinedProperties", Property.class, codec); + property.setRedefinedProperties(redefinedProperties); + + String aggregationKind = deserializeNullableStringField(root, "aggregationKind"); + property.setAggregationKind(AggregationKind.findByName(aggregationKind).orElse(null)); + + return property; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializer.java new file mode 100644 index 00000000..d68f65a2 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; + +public class RectangleDeserializer extends JsonDeserializer { + @Override + public Rectangle deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + + JsonNode root = parser.readValueAsTree(); + + Rectangle rectangle = new Rectangle(); + RectangularShapeDeserializer.deserialize(rectangle, root); + + return rectangle; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangularShapeDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangularShapeDeserializer.java new file mode 100644 index 00000000..ecfa4067 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangularShapeDeserializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeNullableIntegerField; + +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RectangularShape; + +public class RectangularShapeDeserializer { + + public static void deserialize(RectangularShape shape, JsonNode node) { + + String id = node.get("id").asText(); + shape.setId(id); + + Integer x = deserializeNullableIntegerField(node, "x"); + shape.setX(x); + + Integer y = deserializeNullableIntegerField(node, "y"); + shape.setY(y); + + Integer width = deserializeNullableIntegerField(node, "width"); + shape.setWidth(width); + + Integer height = deserializeNullableIntegerField(node, "height"); + shape.setHeight(height); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolver.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolver.java new file mode 100644 index 00000000..b70f1870 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolver.java @@ -0,0 +1,166 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ConnectorView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public class ReferenceResolver { + public static void resolveReferences(Project project) { + Map elementMap = project.getElementMap(); + + for (Property property : project.getAllProperties()) { + resolvePropertyType(elementMap, property); + resolveSubsettedProperties(elementMap, property); + resolveRedefinedProperties(elementMap, property); + } + + for (Generalization generalization : project.getAllGeneralizations()) { + resolveGeneral(elementMap, generalization); + resolveSpecific(elementMap, generalization); + } + + for (GeneralizationSet gs : project.getAllGeneralizationSets()) { + resolveCategorizer(elementMap, gs); + resolveGeneralizations(elementMap, gs); + } + + for (Diagram diagram : project.getDiagrams()) { + resolveOwner(elementMap, diagram); + } + + for (ElementView diagramElement : project.getAllDiagramElements()) { + resolveModelElement(elementMap, diagramElement); + } + + for (ConnectorView connectorView : project.getAllConnectorViews()) { + resolveSource(elementMap, connectorView); + resolveTarget(elementMap, connectorView); + } + } + + private static void resolveOwner(Map elementMap, Diagram diagram) { + ModelElement reference = diagram.getOwner(); + + if (reference == null) return; + + ModelElement source = resolve(elementMap, reference, ModelElement.class); + diagram.setOwner(source); + } + + private static void resolveSource(Map elementMap, ConnectorView element) { + ElementView reference = element.getSource(); + + if (reference == null) return; + + ElementView source = resolve(elementMap, reference, ElementView.class); + element.setSource(source); + } + + private static void resolveTarget(Map elementMap, ConnectorView element) { + ElementView reference = element.getTarget(); + + if (reference == null) return; + + ElementView source = resolve(elementMap, reference, ElementView.class); + element.setTarget(source); + } + + private static void resolveModelElement( + Map elementMap, ElementView element) { + ModelElement reference = element.getModelElement(); + + if (reference == null) return; + + ModelElement source = resolve(elementMap, reference, ModelElement.class); + element.setModelElement(source); + } + + private static void resolveGeneralizations( + Map elementMap, GeneralizationSet gs) { + + Set sources = new HashSet<>(); + + for (Generalization reference : gs.getGeneralizations()) + sources.add(resolve(elementMap, reference, Generalization.class)); + + gs.setGeneralizations(sources); + } + + private static void resolveCategorizer( + Map elementMap, GeneralizationSet gs) { + Optional reference = gs.getCategorizer(); + + if (reference.isEmpty()) return; + + Class source = resolve(elementMap, reference.get(), Class.class); + gs.setCategorizer(source); + } + + private static void resolveGeneral( + Map elementMap, Generalization generalization) { + Optional> reference = generalization.getGeneral(); + + if (reference.isEmpty()) return; + + Classifier source = resolve(elementMap, reference.get(), Classifier.class); + generalization.setGeneral(source); + } + + private static void resolveSpecific( + Map elementMap, Generalization generalization) { + Optional> reference = generalization.getSpecific(); + + if (reference.isEmpty()) return; + + Classifier source = resolve(elementMap, reference.get(), Classifier.class); + generalization.setSpecific(source); + } + + private static void resolvePropertyType( + Map elementMap, Property property) { + Optional> reference = property.getPropertyType(); + + if (reference.isEmpty()) return; + + Classifier source = resolve(elementMap, reference.get(), Classifier.class); + property.setPropertyType(source); + } + + private static void resolveSubsettedProperties( + Map elementMap, Property property) { + for (Property reference : property.getSubsettedProperties()) { + Property source = resolve(elementMap, reference, Property.class); + property.replaceSubsettedProperty(reference, source); + } + } + + private static void resolveRedefinedProperties( + Map elementMap, Property property) { + for (Property reference : property.getRedefinedProperties()) { + Property source = resolve(elementMap, reference, Property.class); + property.replaceRedefinedProperty(reference, source); + } + } + + private static T resolve( + Map elementMap, T reference, java.lang.Class referenceType) { + + OntoumlElement source = elementMap.get(reference.getId()); + + if (source == null) + throw new NullPointerException("Referenced element in property type does not exist!"); + + if (!referenceType.isInstance(source)) + throw new NullPointerException("Referenced element in property type is not a classifier!"); + + return referenceType.cast(source); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializer.java new file mode 100644 index 00000000..dafa6a08 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import java.io.IOException; + +public class RelationDeserializer extends JsonDeserializer { + + @Override + public Relation deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + Relation relation = new Relation(); + ElementDeserializer.deserialize(relation, root, codec); + ModelElementDeserializer.deserialize(relation, root, codec); + DecoratableDeserializer.deserialize(relation, root, codec); + ClassifierDeserializer.deserialize(relation, root, codec); + + return relation; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializer.java new file mode 100644 index 00000000..b810c3df --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializer.java @@ -0,0 +1,31 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeObjectField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; +import java.io.IOException; + +public class RelationViewDeserializer extends JsonDeserializer { + + @Override + public RelationView deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + ObjectCodec codec = parser.getCodec(); + JsonNode root = parser.readValueAsTree(); + + RelationView view = new RelationView(); + + ConnectorViewDeserializer.deserialize(view, root, codec); + + Relation stub = deserializeObjectField(root, "modelElement", Relation.class, codec); + view.setModelElement(stub); + + return view; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializer.java new file mode 100644 index 00000000..a0f9b94b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DeserializerUtils.deserializeNullableStringField; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Text; +import java.io.IOException; + +public class TextDeserializer extends JsonDeserializer { + @Override + public Text deserialize(JsonParser parser, DeserializationContext context) throws IOException { + + JsonNode root = parser.readValueAsTree(); + + Text text = new Text(); + + String value = deserializeNullableStringField(root, "value"); + text.setValue(value); + + RectangularShapeDeserializer.deserialize(text, root); + + return text; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/AggregationKind.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/AggregationKind.java new file mode 100644 index 00000000..7a5144d5 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/AggregationKind.java @@ -0,0 +1,26 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Optional; +import java.util.stream.Stream; + +public enum AggregationKind { + NONE("NONE"), + SHARED("SHARED"), + COMPOSITE("COMPOSITE"); + + final String name; + + AggregationKind(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Optional findByName(String name) { + return Stream.of(AggregationKind.values()) + .filter(nature -> nature.getName().equals(name)) + .findFirst(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Cardinality.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Cardinality.java new file mode 100644 index 00000000..eea9d2eb --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Cardinality.java @@ -0,0 +1,107 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Optional; + +public class Cardinality { + + private String cardinality; + private String lowerBound; + private String upperBound; + + public Cardinality(String lowerBound, String upperBound) { + String cardinalityString = + lowerBound.equals(upperBound) ? lowerBound : lowerBound + ".." + upperBound; + setValue(cardinalityString); + } + + public Cardinality(String cardinality) { + setValue(cardinality); + } + + public Cardinality() { + setValue("1"); + } + + public void setValue(String cardinality) { + this.cardinality = cardinality; + setBounds(); + } + + public Optional getValue() { + return Optional.ofNullable(cardinality); + } + + public Optional getLowerBound() { + return Optional.ofNullable(lowerBound); + } + + public Optional getUpperBound() { + return Optional.ofNullable(upperBound); + } + + public int getLowerBoundAsInt() { + return Integer.parseInt(lowerBound); + } + + public int getUpperBoundAsInt() { + return isUnbounded() ? Integer.MAX_VALUE : Integer.parseInt(upperBound); + } + + private void setBounds() { + if (cardinality == null) { + lowerBound = upperBound = null; + return; + } + + if (cardinality.equals("*")) { + lowerBound = "0"; + upperBound = "*"; + return; + } + + String[] bounds = cardinality.split("\\.\\."); + + if (bounds.length == 1) { + lowerBound = upperBound = cardinality; + return; + } + + if (bounds.length == 2) { + lowerBound = bounds[0]; + upperBound = bounds[1]; + return; + } + + lowerBound = upperBound = null; + } + + public boolean isLowerBoundValid() { + try { + return getLowerBoundAsInt() >= 0; + } catch (Exception ignored) { + return false; + } + } + + public boolean isUpperBoundValid() { + try { + return isUnbounded() || getUpperBoundAsInt() >= 1; + } catch (Exception ignored) { + return false; + } + } + + public boolean isUnbounded() { + return "*".equals(upperBound); + } + + public boolean isValid() { + try { + return isLowerBoundValid() + && isUpperBoundValid() + && getLowerBoundAsInt() <= getUpperBoundAsInt(); + } catch (Exception ignored) { + return false; + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Class.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Class.java new file mode 100644 index 00000000..1eb4e204 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Class.java @@ -0,0 +1,445 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlUtils; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.ClassDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.ClassSerializer; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@JsonSerialize(using = ClassSerializer.class) +@JsonDeserialize(using = ClassDeserializer.class) +public final class Class extends Classifier { + protected Boolean isExtensional; + protected Boolean isPowertype; + protected Integer order; + protected Set restrictedTo = new TreeSet<>(); + protected List literals = new ArrayList<>(); + + public Class(String id, MultilingualText name, ClassStereotype ontoumlStereotype) { + super(id, name, ontoumlStereotype); + } + + public Class(String id, MultilingualText name, String stereotypeName) { + this(id, name, (ClassStereotype) null); + setStereotype(stereotypeName); + } + + public Class(String id, String name, ClassStereotype stereotype) { + this(id, new MultilingualText(name), stereotype); + } + + public Class(String id, String name, String stereotype) { + this(id, new MultilingualText(name), stereotype); + } + + public Class(String name, ClassStereotype stereotype) { + this(null, name, stereotype); + } + + public Class(String name, String stereotype) { + this(null, name, stereotype); + } + + public Class(ClassStereotype stereotype) { + this(null, (MultilingualText) null, stereotype); + } + + public Class(String name) { + this(null, name, (ClassStereotype) null); + } + + public Class() { + this(null, (MultilingualText) null, (ClassStereotype) null); + } + + @Override + public String getType() { + return "Class"; + } + + public Optional isExtensional() { + return Optional.ofNullable(isExtensional); + } + + public void setExtensional(Boolean value) { + isExtensional = value; + } + + public Optional isPowertype() { + return Optional.ofNullable(isPowertype); + } + + public void setPowertype(Boolean value) { + isPowertype = value; + } + + public Optional getOrder() { + return Optional.ofNullable(order); + } + + public void setOrder(Integer value) { + order = value; + } + + public Set getRestrictedTo() { + return restrictedTo; + } + + public void setRestrictedTo(Collection restrictedTo) { + this.restrictedTo.clear(); + this.restrictedTo.addAll(restrictedTo); + } + + public void setRestrictedTo(String[] array) { + List natures = + Stream.of(array) + .map(Nature::findByName) + .flatMap(Optional::stream) + .collect(Collectors.toList()); + this.restrictedTo.clear(); + this.restrictedTo.addAll(natures); + } + + public void setRestrictedTo(Nature... restrictedTo) { + this.restrictedTo.clear(); + this.restrictedTo.addAll(Arrays.asList(restrictedTo)); + } + + public List getLiterals() { + return literals; + } + + public boolean hasLiterals() { + return literals != null && literals.size() > 0; + } + + public List createLiterals(String[] names) { + return Stream.of(names).map(name -> createLiteral(name)).collect(Collectors.toList()); + } + + public Literal createLiteral(String name) { + if (literals == null) literals = new ArrayList<>(); + + Literal literal = new Literal(name); + addLiteral(literal); + return literal; + } + + public void addLiteral(Literal literal) { + if (literals == null) literals = new ArrayList<>(); + + literal.setContainer(this); + literals.add(literal); + } + + public void setLiterals(Collection literals) { + literals.forEach(l -> l.setContainer(this)); + this.literals.clear(); + this.literals.addAll(literals); + } + + public boolean hasAttributes() { + return hasProperties(); + } + + public List getAttributes() { + return getProperties(); + } + + public void addAttribute(Property attribute) { + if (attribute == null) return; + + attribute.setContainer(this); + properties.add(attribute); + } + + public void setAttributes(Collection attributes) { + if (properties == null) properties = new ArrayList<>(); + else properties.clear(); + + if (attributes == null) return; + + attributes.forEach(a -> addAttribute(a)); + } + + public Property createAttribute(String name, Classifier type) { + return createAttribute(null, name, type); + } + + public Property createAttribute(String id, String name, Classifier type) { + Property attribute = new Property(id, name, type); + attribute.setContainer(this); + properties.add(attribute); + + return attribute; + } + + @Override + public void setStereotype(String stereotypeName) { + Optional stereotype = ClassStereotype.findByName(stereotypeName); + + stereotype.ifPresentOrElse( + s -> setOntoumlStereotype(stereotype.get()), () -> setCustomStereotype(stereotypeName)); + } + + @Override + public List getContents() { + List contents = new ArrayList<>(); + + if (hasAttributes()) OntoumlUtils.addIfNotNull(contents, getAttributes()); + + if (hasLiterals()) OntoumlUtils.addIfNotNull(contents, getLiterals()); + + return contents; + } + + public boolean restrictedToOverlaps(List natures) { + if (natures == null) return false; + + TreeSet natureSet = new TreeSet<>(natures); + natureSet.retainAll(restrictedTo); + return natureSet.size() > 0; + } + + public boolean restrictedToContainedIn(List natures) { + if (natures == null) return false; + + return natures.containsAll(restrictedTo); + } + + public boolean restrictedToContains(Nature nature) { + return restrictedToContains(Collections.singletonList(nature)); + } + + public boolean restrictedToContains(List natures) { + if (natures == null) return false; + + return restrictedTo.containsAll(natures); + } + + public boolean restrictedToEquals(Nature nature) { + return restrictedToEquals(Collections.singletonList(nature)); + } + + public boolean restrictedToEquals(List natures) { + if (natures == null) return false; + + if (restrictedTo.size() != natures.size()) return false; + + TreeSet naturesSet = new TreeSet<>(natures); + return restrictedTo.equals(naturesSet); + } + + public boolean isRestrictedToMoments() { + return restrictedTo.stream().allMatch(Nature::isMoment); + } + + public boolean isRestrictedToSubstantials() { + return restrictedTo.stream().allMatch(Nature::isSubstantial); + } + + public boolean isEnumeration() { + return hasStereotype(ClassStereotype.ENUMERATION); + } + + public boolean isRestrictedToEndurants() { + return restrictedTo.stream().allMatch(Nature::isEndurant); + } + + public boolean isRestrictedToFunctionalComplexes() { + return restrictedToEquals(Nature.FUNCTIONAL_COMPLEX); + } + + public boolean isRestrictedToCollectives() { + return restrictedToEquals(Nature.COLLECTIVE); + } + + public boolean isRestrictedToQuantity() { + return restrictedToEquals(Nature.QUANTITY); + } + + public boolean isRestrictedToIntrinsicMoments() { + return restrictedTo.stream().allMatch(Nature::isIntrinsicMoment); + } + + public boolean isRestrictedToExtrinsicMoments() { + return restrictedTo.stream().allMatch(Nature::isExtrinsicMoment); + } + + public boolean isRestrictedToRelators() { + return restrictedToEquals(Nature.RELATOR); + } + + public boolean isRestrictedToIntrinsicModes() { + return restrictedToEquals(Nature.INTRINSIC_MODE); + } + + public boolean isRestrictedToExtrinsicModes() { + return restrictedToEquals(Nature.EXTRINSIC_MODE); + } + + public boolean isRestrictedToQualities() { + return restrictedToEquals(Nature.QUALITY); + } + + public boolean isRestrictedToEvents() { + return restrictedToEquals(Nature.EVENT); + } + + public boolean isRestrictedToSituations() { + return restrictedToEquals(Nature.SITUATION); + } + + public boolean isRestrictedToTypes() { + return restrictedToEquals(Nature.TYPE); + } + + public boolean isRestrictedToAbstract() { + return restrictedToEquals(Nature.ABSTRACT); + } + + public boolean isDatatype() { + return hasStereotype(ClassStereotype.DATATYPE); + } + + public boolean isPrimitiveDatatype() { + return isDatatype() && !hasAttributes(); + } + + public static Class createKind(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.KIND); + clazz.setRestrictedTo(Nature.FUNCTIONAL_COMPLEX); + return clazz; + } + + public static Class createKind(String name) { + return createKind(null, name); + } + + public static Class createCollective(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.COLLECTIVE); + clazz.setRestrictedTo(Nature.COLLECTIVE); + return clazz; + } + + public static Class createQuantity(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.QUANTITY); + clazz.setRestrictedTo(Nature.QUANTITY); + return clazz; + } + + public static Class createRelator(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.RELATOR); + clazz.setRestrictedTo(Nature.RELATOR); + return clazz; + } + + public static Class createMode(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.MODE); + clazz.setRestrictedTo(Nature.INTRINSIC_MODE, Nature.EXTRINSIC_MODE); + return clazz; + } + + public static Class createMode(String name) { + return createMode(null, name); + } + + public static Class createQuality(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.QUALITY); + clazz.setRestrictedTo(Nature.QUALITY); + return clazz; + } + + public static Class createSubkind(String id, String name) { + return new Class(id, name, ClassStereotype.SUBKIND); + } + + public static Class createRole(String id, String name) { + return new Class(id, name, ClassStereotype.ROLE); + } + + public static Class createPhase(String id, String name) { + return new Class(id, name, ClassStereotype.PHASE); + } + + public static Class createHistoricalRole(String id, String name) { + return new Class(id, name, ClassStereotype.HISTORICAL_ROLE); + } + + public static Class createMixin(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.MIXIN); + clazz.setAbstract(true); + clazz.setRestrictedTo(Nature.SUBSTANTIAL_NATURES); + return clazz; + } + + public static Class createCategory(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.CATEGORY); + clazz.setAbstract(true); + clazz.setRestrictedTo(Nature.SUBSTANTIAL_NATURES); + return clazz; + } + + public static Class createRoleMixin(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.ROLE_MIXIN); + clazz.setAbstract(true); + clazz.setRestrictedTo(Nature.SUBSTANTIAL_NATURES); + return clazz; + } + + public static Class createPhaseMixin(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.PHASE_MIXIN); + clazz.setAbstract(true); + clazz.setRestrictedTo(Nature.SUBSTANTIAL_NATURES); + return clazz; + } + + public static Class createHistoricalRoleMixin(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.HISTORICAL_ROLE_MIXIN); + clazz.setAbstract(true); + clazz.setRestrictedTo(Nature.SUBSTANTIAL_NATURES); + return clazz; + } + + public static Class createEvent(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.EVENT); + clazz.setRestrictedTo(Nature.EVENT); + return clazz; + } + + public static Class createSituation(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.SITUATION); + clazz.setRestrictedTo(Nature.TYPE); + return clazz; + } + + public static Class createType(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.TYPE); + clazz.setRestrictedTo(Nature.FUNCTIONAL_COMPLEX); + return clazz; + } + + public static Class createAbstract(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.ABSTRACT); + clazz.setRestrictedTo(Nature.ABSTRACT); + return clazz; + } + + public static Class createDatatype(String id, String name) { + Class clazz = new Class(id, name, ClassStereotype.DATATYPE); + clazz.setRestrictedTo(Nature.ABSTRACT); + return clazz; + } + + public static Class createEnumeration(String id, String name, String... literals) { + Class enumeration = new Class(id, name, ClassStereotype.ENUMERATION); + enumeration.setRestrictedTo(Nature.ABSTRACT); + enumeration.createLiterals(literals); + return enumeration; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ClassStereotype.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ClassStereotype.java new file mode 100644 index 00000000..101df1d7 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ClassStereotype.java @@ -0,0 +1,158 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; + +public enum ClassStereotype implements Stereotype { + TYPE("type"), + HISTORICAL_ROLE("historicalRole"), + HISTORICAL_ROLE_MIXIN("historicalRoleMixin"), + EVENT("event"), + SITUATION("situation"), + CATEGORY("category"), + MIXIN("mixin"), + ROLE_MIXIN("roleMixin"), + PHASE_MIXIN("phaseMixin"), + KIND("kind"), + COLLECTIVE("collective"), + QUANTITY("quantity"), + RELATOR("relator"), + QUALITY("quality"), + MODE("mode"), + SUBKIND("subkind"), + ROLE("role"), + PHASE("phase"), + ENUMERATION("enumeration"), + DATATYPE("datatype"), + ABSTRACT("abstract"); + + public static final Collection SORTALS = + Set.of( + KIND, + QUANTITY, + COLLECTIVE, + RELATOR, + QUALITY, + MODE, + SUBKIND, + PHASE, + ROLE, + HISTORICAL_ROLE); + public static final Collection ULTIMATE_SORTALS = + Set.of(KIND, QUANTITY, COLLECTIVE, RELATOR, QUALITY, MODE); + public static final Collection BASE_SORTALS = + Set.of(SUBKIND, PHASE, ROLE, HISTORICAL_ROLE); + public static final Collection NON_SORTALS = + Set.of(CATEGORY, MIXIN, PHASE_MIXIN, ROLE_MIXIN, HISTORICAL_ROLE_MIXIN); + public static final Collection RIGIDS = + Set.of( + KIND, + QUANTITY, + COLLECTIVE, + RELATOR, + QUALITY, + MODE, + SUBKIND, + EVENT, + SITUATION, + TYPE, + ABSTRACT, + DATATYPE, + ENUMERATION); + public static final Collection ANTI_RIGIDS = + Set.of(ROLE, ROLE_MIXIN, PHASE, PHASE_MIXIN, HISTORICAL_ROLE, HISTORICAL_ROLE_MIXIN); + public static final Collection SEMI_RIGIDS = Set.of(MIXIN); + public static final Collection MOMENTS = Set.of(MODE, QUALITY, RELATOR); + public static final Collection SUBSTANTIALS = Set.of(KIND, QUANTITY, COLLECTIVE); + public static final Collection ENDURANTS = + Set.of( + KIND, + QUANTITY, + COLLECTIVE, + RELATOR, + QUALITY, + MODE, + SUBKIND, + PHASE, + ROLE, + HISTORICAL_ROLE, + CATEGORY, + MIXIN, + PHASE_MIXIN, + ROLE_MIXIN, + HISTORICAL_ROLE_MIXIN); + public static final Collection ABSTRACTS = + Set.of(ABSTRACT, DATATYPE, ENUMERATION); + + public final String stereotypeName; + + ClassStereotype(String name) { + this.stereotypeName = name; + } + + public boolean isNonSortal() { + return NON_SORTALS.contains(this); + } + + public boolean isSortal() { + return SORTALS.contains(this); + } + + public boolean isUltimateSortal() { + return ULTIMATE_SORTALS.contains(this); + } + + public boolean isBaseSortal() { + return BASE_SORTALS.contains(this); + } + + public boolean isRigid() { + return RIGIDS.contains(this); + } + + public boolean isAntiRigid() { + return ANTI_RIGIDS.contains(this); + } + + public boolean isSemiRigid() { + return SEMI_RIGIDS.contains(this); + } + + public boolean isAbstract() { + return ABSTRACTS.contains(this); + } + + public boolean isEndurant() { + return ENDURANTS.contains(this); + } + + public boolean isSubstantial() { + return SUBSTANTIALS.contains(this); + } + + public boolean isMoment() { + return MOMENTS.contains(this); + } + + public boolean isEvent() { + return this.equals(EVENT); + } + + public boolean isSituation() { + return this.equals(SITUATION); + } + + public boolean isType() { + return this.equals(TYPE); + } + + @Override + public String getStereotypeName() { + return stereotypeName; + } + + public static Optional findByName(String name) { + return Stereotype.findByName(ClassStereotype.class, name); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Classifier.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Classifier.java new file mode 100644 index 00000000..1112c33b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Classifier.java @@ -0,0 +1,115 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; + +public abstract class Classifier, S extends Stereotype> + extends Decoratable { + boolean isAbstract; + boolean isDerived; + List properties = new ArrayList<>(); + + public Classifier(String id, MultilingualText name, S ontoumlStereotype) { + super(id, name, ontoumlStereotype); + } + + public Classifier(String id, MultilingualText name, String stereotypeName) { + super(id, name, stereotypeName); + } + + public boolean isAbstract() { + return isAbstract; + } + + public void setAbstract(boolean anAbstract) { + isAbstract = anAbstract; + } + + public boolean isDerived() { + return isDerived; + } + + public void setDerived(boolean derived) { + isDerived = derived; + } + + public List getProperties() { + return properties; + } + + public void addProperty(Property property) { + if (property != null) { + property.setContainer(this); + properties.add(property); + } + } + + public void setProperties(Collection properties) { + this.properties.clear(); + + if (properties != null) properties.forEach(p -> addProperty(p)); + } + + public boolean hasProperties() { + return properties.size() > 0; + } + + public List getGeneralizations() { + return null; + } + + public List getGeneralizationSets() { + return null; + } + + public List getGeneralizationsWhereGeneral() { + return null; + } + + public List getGeneralizationsWhereSpecific() { + return null; + } + + public List getGeneralizationSetsWhereGeneral() { + return null; + } + + public List getGeneralizationSetsWhereSpecific() { + return null; + } + + public List getParents() { + return null; + } + + public List getChildren() { + return null; + } + + public List getAncestors() { + return null; + } + + public List getDescendants() { + return null; + } + + public List getFilteredAncestors(Predicate filter) { + return null; + } + + public List getFilteredDescendants(Predicate filter) { + return null; + } + + public static boolean areAbstract(Collection> classifiers) { + return classifiers.stream().allMatch(c -> c.isAbstract()); + } + + public static boolean areDerived(Collection> classifiers) { + return classifiers.stream().allMatch(c -> c.isDerived()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Decoratable.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Decoratable.java new file mode 100644 index 00000000..2901d3e2 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Decoratable.java @@ -0,0 +1,78 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.DecoratableSerializer; +import java.util.Optional; + +@JsonSerialize(using = DecoratableSerializer.class) +public abstract class Decoratable extends ModelElement { + private String customStereotype; + private S ontoumlStereotype; + + public Decoratable(String id, MultilingualText name, S ontoumlStereotype) { + super(id, name); + setOntoumlStereotype(ontoumlStereotype); + } + + public Decoratable(String id, MultilingualText name, String stereotypeName) { + super(id, name); + setStereotype(stereotypeName); + } + + public Optional getOntoumlStereotype() { + return Optional.ofNullable(ontoumlStereotype); + } + + public void setOntoumlStereotype(S ontoumlStereotype) { + this.ontoumlStereotype = ontoumlStereotype; + this.customStereotype = null; + } + + public boolean hasOntoumlStereotype() { + return getOntoumlStereotype().isPresent(); + } + + public Optional getCustomStereotype() { + return Optional.ofNullable(customStereotype); + } + + public void setCustomStereotype(String customStereotype) { + this.ontoumlStereotype = null; + this.customStereotype = customStereotype; + } + + public boolean hasCustomStereotype() { + return getCustomStereotype().isPresent(); + } + + public Optional getStereotype() { + String stereotype = + hasOntoumlStereotype() ? ontoumlStereotype.getStereotypeName() : customStereotype; + return Optional.ofNullable(stereotype); + } + + /** + * If the supplied stereotype string matches the name of an OntoUML stereotype, this method will + * set it. Otherwise, it will set a custom stereotype. + */ + public abstract void setStereotype(String stereotypeName); + + public void removeStereotype() { + ontoumlStereotype = null; + customStereotype = null; + } + + public boolean hasStereotype() { + return hasOntoumlStereotype() || hasCustomStereotype(); + } + + public boolean hasStereotype(S stereotype) { + return hasOntoumlStereotype() && this.ontoumlStereotype.equals(stereotype); + } + + public boolean hasStereotype(String stereotypeName) { + Optional stereotype = getStereotype(); + return stereotype.isPresent() && stereotype.get().equals(stereotypeName); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Generalization.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Generalization.java new file mode 100644 index 00000000..ac50f38c --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Generalization.java @@ -0,0 +1,79 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.GeneralizationDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.GeneralizationSerializer; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@JsonSerialize(using = GeneralizationSerializer.class) +@JsonDeserialize(using = GeneralizationDeserializer.class) +public class Generalization extends ModelElement { + + private Classifier general; + private Classifier specific; + + public , S extends Stereotype> Generalization( + String id, MultilingualText name, Classifier specific, Classifier general) { + super(id, name); + setGeneral(general); + setSpecific(specific); + } + + public , S extends Stereotype> Generalization( + String id, String name, Classifier specific, Classifier general) { + this(id, new MultilingualText(name), specific, general); + } + + public , S extends Stereotype> Generalization( + String id, Classifier specific, Classifier general) { + this(id, (MultilingualText) null, specific, general); + } + + public , S extends Stereotype> Generalization( + Classifier specific, Classifier general) { + this(null, (MultilingualText) null, specific, general); + } + + public Generalization() { + super(null, null); + } + + @Override + public String getType() { + return "Generalization"; + } + + @Override + public List getContents() { + return Collections.emptyList(); + } + + public Optional> getGeneral() { + return Optional.ofNullable(general); + } + + public void setGeneral(Classifier general) { + this.general = general; + } + + public Optional> getSpecific() { + return Optional.ofNullable(specific); + } + + public void setSpecific(Classifier specific) { + this.specific = specific; + } + + public boolean involvesClasses() { + return specific instanceof Class && general instanceof Class; + } + + public boolean involvesRelations() { + return specific instanceof Relation && general instanceof Relation; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/GeneralizationSet.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/GeneralizationSet.java new file mode 100644 index 00000000..d96ba881 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/GeneralizationSet.java @@ -0,0 +1,118 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlUtils; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.GeneralizationSetDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.GeneralizationSetSerializer; +import java.util.*; + +@JsonSerialize(using = GeneralizationSetSerializer.class) +@JsonDeserialize(using = GeneralizationSetDeserializer.class) +public class GeneralizationSet extends ModelElement { + + private boolean isDisjoint; + private boolean isComplete; + private Class categorizer; + private Set generalizations = new HashSet<>(); + + public GeneralizationSet( + String id, + MultilingualText name, + Class categorizer, + Collection generalizations) { + super(id, name); + OntoumlUtils.addIfNotNull(this.generalizations, generalizations); + this.categorizer = categorizer; + } + + public GeneralizationSet( + String id, String name, Class categorizer, Collection generalizations) { + this(id, new MultilingualText(name), categorizer, generalizations); + } + + public GeneralizationSet(String id, String name, Collection generalizations) { + this(id, new MultilingualText(name), null, generalizations); + } + + public GeneralizationSet(String id, String name, Generalization... generalizations) { + this(id, new MultilingualText(name), null, Arrays.asList(generalizations)); + } + + public GeneralizationSet( + MultilingualText name, Class categorizer, Collection generalizations) { + this(null, name, categorizer, generalizations); + } + + public GeneralizationSet(Class categorizer, Collection generalizations) { + this(null, (MultilingualText) null, categorizer, generalizations); + } + + public GeneralizationSet(String name, Collection generalizations) { + this(null, new MultilingualText(name), null, generalizations); + } + + public GeneralizationSet(Collection generalizations) { + this(null, (MultilingualText) null, null, generalizations); + } + + public GeneralizationSet(String name, Generalization... generalizations) { + this(null, new MultilingualText(name), null, Arrays.asList(generalizations)); + } + + public GeneralizationSet(Generalization... generalizations) { + this(null, generalizations); + } + + public boolean isDisjoint() { + return isDisjoint; + } + + public void setDisjoint(boolean disjoint) { + isDisjoint = disjoint; + } + + public boolean isComplete() { + return isComplete; + } + + public void setComplete(boolean complete) { + isComplete = complete; + } + + public Optional getCategorizer() { + return Optional.ofNullable(categorizer); + } + + public void setCategorizer(Class categorizer) { + this.categorizer = categorizer; + } + + public Set getGeneralizations() { + return new HashSet<>(generalizations); + } + + public void setGeneralizations(Collection generalizations) { + this.generalizations.clear(); + OntoumlUtils.addIfNotNull(this.generalizations, generalizations); + } + + public void addGeneralization(Generalization generalization) { + if (generalization == null) + throw new NullPointerException("Cannot add a null generalization to the generalization set."); + + this.generalizations.add(generalization); + } + + @Override + public List getContents() { + return Collections.emptyList(); + } + + @Override + public String getType() { + return "GeneralizationSet"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Literal.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Literal.java new file mode 100644 index 00000000..0465086b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Literal.java @@ -0,0 +1,37 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.LiteralDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.LiteralSerializer; +import java.util.Collections; +import java.util.List; + +@JsonSerialize(using = LiteralSerializer.class) +@JsonDeserialize(using = LiteralDeserializer.class) +public class Literal extends ModelElement { + + public Literal(String id, MultilingualText name) { + super(id, name); + } + + public Literal(String name) { + this(null, new MultilingualText(name)); + } + + public Literal() { + this(null); + } + + @Override + public String getType() { + return "Literal"; + } + + @Override + public List getContents() { + return Collections.emptyList(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ModelElement.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ModelElement.java new file mode 100644 index 00000000..6d04aaa8 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/ModelElement.java @@ -0,0 +1,80 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.ModelElementSerializer; +import java.util.Map; +import java.util.Optional; +import java.util.TreeMap; + +/** + * An element that is part of the abstract syntax of the language, such as a Package, a Class, a + * Relation, a Generalization, a GeneralizationSet, or a Property. + */ +@JsonSerialize(using = ModelElementSerializer.class) +public abstract class ModelElement extends OntoumlElement { + private Map propertyAssignments = new TreeMap<>(); + + public ModelElement(String id, MultilingualText name) { + super(id, name); + } + + public void setPropertyAssignments(Map map) { + if (map == null) + throw new IllegalArgumentException("Cannot set a null map as the property assignments."); + + this.propertyAssignments.putAll(map); + } + + public void addPropertyAssignment(String name, Object value) { + if (name == null) + throw new IllegalArgumentException("The name of a property assignment cannot be null."); + + propertyAssignments.put(name, value); + } + + public void removePropertyAssignment(String name) { + if (name == null) + throw new IllegalArgumentException("The name of a property assignment cannot be null."); + + propertyAssignments.remove(name); + } + + public void clearPropertyAssignments() { + propertyAssignments.clear(); + } + + public Optional getPropertyAssignment(String name) { + return Optional.ofNullable(propertyAssignments.get(name)); + } + + public Map getPropertyAssignments() { + return propertyAssignments != null ? new TreeMap<>(propertyAssignments) : new TreeMap<>(); + } + + public boolean hasPropertyAssignments() { + return propertyAssignments != null && propertyAssignments.size() > 0; + } + + /** + * Returns the root package (aka the model) in which the element is contained or itself if the + * element is the root package. Returns null if the element is not contained in any package. + */ + public Optional getRootPackage() { + Optional project = getProject(); + + if (project.isPresent()) return project.get().getModel(); + + OntoumlElement element = this; + Optional container = element.getContainer(); + + while (container.isPresent()) { + element = container.get(); + container = element.getContainer(); + } + + return element instanceof Package ? Optional.of((Package) element) : Optional.empty(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Nature.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Nature.java new file mode 100644 index 00000000..f872a64f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Nature.java @@ -0,0 +1,70 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +public enum Nature { + FUNCTIONAL_COMPLEX("functional-complex"), + COLLECTIVE("collective"), + QUANTITY("quantity"), + RELATOR("relator"), + INTRINSIC_MODE("intrinsic-mode"), + EXTRINSIC_MODE("extrinsic-mode"), + QUALITY("quality"), + EVENT("event"), + SITUATION("situation"), + TYPE("type"), + ABSTRACT("abstract"); + + public static final Collection ENDURANT_NATURES = + Set.of( + FUNCTIONAL_COMPLEX, + COLLECTIVE, + QUANTITY, + RELATOR, + EXTRINSIC_MODE, + INTRINSIC_MODE, + QUALITY); + public static final Collection SUBSTANTIAL_NATURES = + Set.of(FUNCTIONAL_COMPLEX, COLLECTIVE, QUANTITY); + public static final Collection MOMENT_NATURES = + Set.of(RELATOR, EXTRINSIC_MODE, INTRINSIC_MODE, QUALITY); + public static final Collection INTRINSIC_MOMENT_NATURES = Set.of(INTRINSIC_MODE, QUALITY); + public static final Collection EXTRINSIC_MOMENT_NATURES = Set.of(RELATOR, EXTRINSIC_MODE); + + public final String name; + + Nature(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean isEndurant() { + return ENDURANT_NATURES.contains(this); + } + + public boolean isSubstantial() { + return SUBSTANTIAL_NATURES.contains(this); + } + + public boolean isMoment() { + return MOMENT_NATURES.contains(this); + } + + public boolean isIntrinsicMoment() { + return INTRINSIC_MOMENT_NATURES.contains(this); + } + + public boolean isExtrinsicMoment() { + return EXTRINSIC_MOMENT_NATURES.contains(this); + } + + public static Optional findByName(String name) { + return Stream.of(Nature.values()).filter(nature -> nature.getName().equals(name)).findFirst(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Package.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Package.java new file mode 100644 index 00000000..d436862b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Package.java @@ -0,0 +1,328 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.ModelElementContainer; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlUtils; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.PackageDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.PackageSerializer; +import java.util.*; + +@JsonSerialize(using = PackageSerializer.class) +@JsonDeserialize(using = PackageDeserializer.class) +@JsonTypeName("Package") +public class Package extends ModelElement implements ModelElementContainer { + + List contents = new ArrayList<>(); + + public Package(String id, MultilingualText name) { + super(id, name); + } + + public Package(String id, String name) { + this(id, new MultilingualText(name)); + } + + public Package(String name) { + this(null, name); + } + + public Package() { + this(null, (MultilingualText) null); + } + + @Override + public String getType() { + return "Package"; + } + + @Override + public List getContents() { + List copiedContents = new ArrayList<>(); + + if (contents == null) return copiedContents; + + OntoumlUtils.addIfNotNull(copiedContents, contents); + return copiedContents; + } + + public T addContent(T child) { + if (child == null) throw new NullPointerException("Cannot add a null element to the package."); + + child.setContainer(this); + contents.add(child); + return child; + } + + public void addContents(Collection contents) { + if (contents == null) return; + contents.stream().filter(Objects::nonNull).forEach(x -> addContent(x)); + } + + public void setContents(Collection contents) { + this.contents.clear(); + addContents(contents); + } + + public boolean hasContents() { + return contents != null && contents.size() > 0; + } + + public Package createPackage() { + return createPackage(null, null); + } + + public Package createPackage(String name) { + return createPackage(null, name); + } + + public Package createPackage(String id, String name) { + return addContent(new Package(id, name)); + } + + public Class createClass() { + return createClass(null, null, (String) null); + } + + public Class createClass(String name) { + return createClass(null, name, (String) null); + } + + public Class createClass(String id, String name, ClassStereotype stereotype) { + return addContent(new Class(id, name, stereotype)); + } + + public Class createClass(String id, String name, String customStereotype) { + return addContent(new Class(id, name, customStereotype)); + } + + public Class createKind(String name) { + return createKind(null, name); + } + + public Class createKind(String id, String name) { + return addContent(Class.createKind(id, name)); + } + + public Class createCollective(String name) { + return createCollective(null, name); + } + + public Class createCollective(String id, String name) { + return addContent(Class.createCollective(id, name)); + } + + public Class createQuantity(String name) { + return createQuantity(null, name); + } + + public Class createQuantity(String id, String name) { + return addContent(Class.createQuantity(id, name)); + } + + public Class createRelator(String name) { + return createRelator(null, name); + } + + public Class createRelator(String id, String name) { + return addContent(Class.createRelator(id, name)); + } + + public Class createQuality(String name) { + return createQuality(null, name); + } + + public Class createQuality(String id, String name) { + return addContent(Class.createQuality(id, name)); + } + + public Class createMode(String name) { + return createMode(null, name); + } + + public Class createMode(String id, String name) { + return addContent(Class.createMode(id, name)); + } + + public Class createSubkind(String name) { + return createSubkind(null, name); + } + + public Class createSubkind(String id, String name) { + return addContent(Class.createSubkind(id, name)); + } + + public Class createRole(String name) { + return createRole(null, name); + } + + public Class createRole(String id, String name) { + return addContent(Class.createRole(id, name)); + } + + public Class createPhase(String name) { + return createPhase(null, name); + } + + public Class createPhase(String id, String name) { + return addContent(Class.createPhase(id, name)); + } + + public Class createRoleMixin(String name) { + return createRoleMixin(null, name); + } + + public Class createRoleMixin(String id, String name) { + return addContent(Class.createRoleMixin(id, name)); + } + + public Class createPhaseMixin(String name) { + return createPhaseMixin(null, name); + } + + public Class createPhaseMixin(String id, String name) { + return addContent(Class.createPhaseMixin(id, name)); + } + + public Class createMixin(String name) { + return createMixin(null, name); + } + + public Class createMixin(String id, String name) { + return addContent(Class.createMixin(id, name)); + } + + public Class createCategory(String name) { + return createCategory(null, name); + } + + public Class createCategory(String id, String name) { + return addContent(Class.createCategory(id, name)); + } + + public Class createEvent(String name) { + return createEvent(null, name); + } + + public Class createEvent(String id, String name) { + return addContent(Class.createEvent(id, name)); + } + + public Class createSituation(String name) { + return createSituation(null, name); + } + + public Class createSituation(String id, String name) { + return addContent(Class.createSituation(id, name)); + } + + public Class createHistoricalRole(String name) { + return createHistoricalRole(null, name); + } + + public Class createHistoricalRole(String id, String name) { + return addContent(Class.createHistoricalRole(id, name)); + } + + public Class createHistoricalRoleMixin(String name) { + return createHistoricalRoleMixin(null, name); + } + + public Class createHistoricalRoleMixin(String id, String name) { + return addContent(Class.createHistoricalRoleMixin(id, name)); + } + + public Class createType(String name) { + return createType(null, name); + } + + public Class createType(String id, String name) { + return addContent(Class.createType(id, name)); + } + + public Class createAbstract(String name) { + return createAbstract(null, name); + } + + public Class createAbstract(String id, String name) { + return addContent(Class.createAbstract(id, name)); + } + + public Class createDatatype(String name) { + return createDatatype(null, name); + } + + public Class createDatatype(String id, String name) { + return addContent(Class.createDatatype(id, name)); + } + + public Class createEnumeration(String[] literals) { + return createEnumeration(null, null, literals); + } + + public Class createEnumeration(String name, String[] literals) { + return createEnumeration(null, name, literals); + } + + public Class createEnumeration(String id, String name, String[] literals) { + return addContent(Class.createEnumeration(id, name, literals)); + } + + public Relation createRelation(Classifier source, Classifier target) { + return createRelation(null, null, null, source, target); + } + + public Relation createRelation(String name, Classifier source, Classifier target) { + return createRelation(null, name, null, source, target); + } + + public Relation createRelation( + String id, + String name, + RelationStereotype stereotype, + Classifier source, + Classifier target) { + return addContent(new Relation(id, name, stereotype, source, target)); + } + + public , S extends Stereotype> Generalization createGeneralization( + Classifier specific, Classifier general) { + return createGeneralization(null, specific, general); + } + + public , S extends Stereotype> Generalization createGeneralization( + String id, Classifier specific, Classifier general) { + return addContent(new Generalization(id, specific, general)); + } + + public GeneralizationSet createGeneralizationSet(Generalization... generalizations) { + return createGeneralizationSet(null, null, null, Arrays.asList(generalizations)); + } + + public GeneralizationSet createGeneralizationSet(Collection generalizations) { + return createGeneralizationSet(null, null, null, generalizations); + } + + public GeneralizationSet createGeneralizationSet( + String name, Collection generalizations) { + return createGeneralizationSet(null, name, null, generalizations); + } + + public GeneralizationSet createGeneralizationSet( + String name, Class categorizer, Collection generalizations) { + return createGeneralizationSet(null, name, categorizer, generalizations); + } + + public GeneralizationSet createGeneralizationSet( + String id, String name, Class categorizer, Collection generalizations) { + return addContent(new GeneralizationSet(id, name, categorizer, generalizations)); + } + + public boolean isRoot() { + return getContainer().isEmpty() + || getProject().isPresent() && getContainer().get().equals(getProject().get()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Property.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Property.java new file mode 100644 index 00000000..10ea6f38 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Property.java @@ -0,0 +1,237 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlUtils; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.PropertyDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.PropertySerializer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@JsonSerialize(using = PropertySerializer.class) +@JsonDeserialize(using = PropertyDeserializer.class) +public final class Property extends Decoratable { + private Cardinality cardinality = new Cardinality(); + private Classifier propertyType; + private List subsettedProperties = new ArrayList<>(); + private List redefinedProperties = new ArrayList<>(); + private AggregationKind aggregationKind; + private boolean isDerived; + private boolean isOrdered; + private boolean isReadOnly; + + public Property( + String id, + MultilingualText name, + PropertyStereotype ontoumlStereotype, + Classifier type) { + super(id, name, ontoumlStereotype); + setPropertyType(type); + } + + public Property(String id, MultilingualText name, String stereotypeName, Classifier type) { + super(id, name, stereotypeName); + setPropertyType(type); + } + + public Property(String id, MultilingualText name, Classifier type) { + this(id, name, (PropertyStereotype) null, type); + } + + public Property(String id, String name, Classifier type) { + this(id, new MultilingualText(name), (PropertyStereotype) null, type); + } + + public Property(String name, Classifier type) { + this(null, name, type); + } + + public Property(Classifier type) { + this(null, null, (PropertyStereotype) null, type); + + if (type != null && type.getFirstName().isPresent()) { + String propertyName = type.getFirstName().get().trim().toLowerCase(); + + addName(propertyName); + } + } + + public Property() { + this(null); + } + + @Override + public String getType() { + return "Property"; + } + + @Override + public void setStereotype(String stereotypeName) { + Optional stereotype = PropertyStereotype.findByName(stereotypeName); + + stereotype.ifPresentOrElse( + s -> setOntoumlStereotype(stereotype.get()), () -> setCustomStereotype(stereotypeName)); + } + + @Override + public List getContents() { + return Collections.emptyList(); + } + + public Cardinality getCardinality() { + return cardinality; + } + + public Optional getCardinalityValue() { + return cardinality.getValue(); + } + + public void setCardinality(Cardinality cardinality) { + if (cardinality == null) + throw new NullPointerException("Cannot set null cardinality object on property!"); + + this.cardinality = cardinality; + } + + public void setCardinality(String cardinality) { + this.cardinality.setValue(cardinality); + } + + public void setPropertyType(Classifier propertyType) { + this.propertyType = propertyType; + } + + public List getSubsettedProperties() { + return new ArrayList<>(subsettedProperties); + } + + public void setSubsettedProperties(List subsettedProperties) { + this.subsettedProperties.clear(); + if (subsettedProperties != null) + OntoumlUtils.addIfNotNull(this.subsettedProperties, subsettedProperties); + } + + public void addSubsettedProperty(Property property) { + if (property == null) + throw new NullPointerException( + "Cannot add a null value to the list of subsetted properties."); + + subsettedProperties.add(property); + } + + public void removeSubsettedProperty(Property property) { + subsettedProperties.remove(property); + } + + public void replaceSubsettedProperty(Property toReplace, Property replaceFor) { + int i = subsettedProperties.indexOf(toReplace); + if (i >= 0) { + subsettedProperties.set(i, replaceFor); + } + } + + public List getRedefinedProperties() { + return new ArrayList<>(redefinedProperties); + } + + public void setRedefinedProperties(List redefinedProperties) { + this.redefinedProperties.clear(); + if (redefinedProperties != null) + OntoumlUtils.addIfNotNull(this.redefinedProperties, redefinedProperties); + } + + public void addRedefinedProperty(Property property) { + if (property == null) + throw new NullPointerException( + "Cannot add a null value to the list of redefined properties."); + + redefinedProperties.add(property); + } + + public void removeRedefinedProperty(Property property) { + redefinedProperties.remove(property); + } + + public void replaceRedefinedProperty(Property toReplace, Property replaceFor) { + int i = redefinedProperties.indexOf(toReplace); + if (i >= 0) { + redefinedProperties.set(i, replaceFor); + } + } + + public Optional getAggregationKind() { + return Optional.ofNullable(aggregationKind); + } + + public void setAggregationKind(AggregationKind aggregationKind) { + this.aggregationKind = aggregationKind; + } + + public boolean isDerived() { + return isDerived; + } + + public void setDerived(boolean derived) { + isDerived = derived; + } + + public boolean isOrdered() { + return isOrdered; + } + + public void setOrdered(boolean ordered) { + isOrdered = ordered; + } + + public boolean isReadOnly() { + return isReadOnly; + } + + public void setReadOnly(boolean readOnly) { + isReadOnly = readOnly; + } + + public Optional> getPropertyType() { + return Optional.ofNullable(propertyType); + } + + public boolean isPropertyTypeClass() { + Optional> type = getPropertyType(); + return type.isPresent() && type.get() instanceof Class; + } + + public boolean isPropertyTypeRelation() { + Optional> type = getPropertyType(); + return type.isPresent() && type.get() instanceof Relation; + } + + public Class getPropertyTypeAsClass() { + if (!isPropertyTypeClass()) throw new IllegalCallerException("Property type is not a class."); + + return (Class) propertyType; + } + + public Relation getPropertyTypeAsRelation() { + if (!isPropertyTypeRelation()) + throw new IllegalCallerException("Property type is not a relation."); + + return (Relation) propertyType; + } + + public boolean isAggregationEnd() { + return aggregationKind == AggregationKind.COMPOSITE + || aggregationKind == AggregationKind.SHARED; + } + + public boolean isAttribute() { + return getContainer().orElse(null) instanceof Class; + } + + public boolean isRelationEnd() { + return getContainer().orElse(null) instanceof Relation; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/PropertyStereotype.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/PropertyStereotype.java new file mode 100644 index 00000000..f9422ce9 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/PropertyStereotype.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Optional; + +public enum PropertyStereotype implements Stereotype { + BEGIN("begin"), + END("end"); + + public final String stereotypeName; + + PropertyStereotype(String name) { + this.stereotypeName = name; + } + + @Override + public String getStereotypeName() { + return stereotypeName; + } + + public static Optional findByName(String name) { + return Stereotype.findByName(PropertyStereotype.class, name); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Relation.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Relation.java new file mode 100644 index 00000000..43aa2546 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Relation.java @@ -0,0 +1,890 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.RelationDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.RelationSerializer; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +@JsonSerialize(using = RelationSerializer.class) +@JsonDeserialize(using = RelationDeserializer.class) +@JsonTypeName("Relation") +public final class Relation extends Classifier { + + public Relation(String id, MultilingualText name, RelationStereotype ontoumlStereotype) { + super(id, name, ontoumlStereotype); + } + + public Relation(String id, MultilingualText name, String stereotypeName) { + super(id, name, stereotypeName); + } + + public Relation( + String id, + MultilingualText name, + RelationStereotype ontoumlStereotype, + Classifier source, + Classifier target) { + this(id, name, ontoumlStereotype); + createMemberEnd(source); + createMemberEnd(target); + } + + public Relation( + String id, + MultilingualText name, + String stereotypeName, + Classifier source, + Classifier target) { + this(id, name, stereotypeName); + createMemberEnd(source); + createMemberEnd(target); + } + + public Relation( + String id, + MultilingualText name, + RelationStereotype ontoumlStereotype, + List> participants) { + this(id, name, ontoumlStereotype); + participants.forEach(this::createMemberEnd); + } + + public Relation( + String id, + MultilingualText name, + String stereotypeName, + List> participants) { + this(id, name, stereotypeName); + participants.forEach(this::createMemberEnd); + } + + public Relation( + String id, + String name, + RelationStereotype ontoumlStereotype, + Classifier source, + Classifier target) { + this(id, new MultilingualText(name), ontoumlStereotype, source, target); + } + + public Relation( + String id, + String name, + String stereotypeName, + Classifier source, + Classifier target) { + this(id, new MultilingualText(name), stereotypeName, source, target); + } + + public Relation(String id, String name, Classifier source, Classifier target) { + this(id, new MultilingualText(name), (String) null, source, target); + } + + public Relation( + RelationStereotype ontoumlStereotype, Classifier source, Classifier target) { + this(null, (MultilingualText) null, ontoumlStereotype, source, target); + } + + public Relation(String stereotypeName, Classifier source, Classifier target) { + this(null, (MultilingualText) null, stereotypeName, source, target); + } + + public Relation(Classifier source, Classifier target) { + this(null, (MultilingualText) null, (RelationStereotype) null, source, target); + } + + public Relation() { + this(null, null, (RelationStereotype) null); + } + + @Override + public void setStereotype(String stereotypeName) { + Optional stereotype = RelationStereotype.findByName(stereotypeName); + + stereotype.ifPresentOrElse( + s -> setOntoumlStereotype(stereotype.get()), () -> setCustomStereotype(stereotypeName)); + } + + @Override + public List getContents() { + return List.copyOf(getProperties()); + } + + @Override + public String getType() { + return "Relation"; + } + + public void createMemberEnd(Classifier classifier) { + Property end = new Property(classifier); + end.setContainer(this); + properties.add(end); + } + + public int arity() { + return properties != null ? properties.size() : 0; + } + + public List getRelationEnds() { + return properties; + } + + public Property getSourceEnd() { + if (!isBinary()) + throw new IllegalCallerException("Can only retrieve source end of binary relation."); + + return properties.get(0); + } + + public Property getTargetEnd() { + if (!isBinary()) + throw new IllegalCallerException("Can only retrieve target end of binary relation."); + + return properties.get(1); + } + + public Property getMemberEnd(int position) { + if (position < 0 || position >= properties.size()) + throw new IndexOutOfBoundsException("Cannot retrieve end at position " + position + "."); + + return properties.get(position); + } + + public Property getDerivedRelationEnd() { + if (!fromRelationToClass()) + throw new IllegalCallerException( + "Can only retrieve the derived relation end of a derivation relation."); + + return getSourceEnd(); + } + + public Property getDerivingClassEnd() { + if (!fromRelationToClass()) + throw new IllegalCallerException( + "Can only retrieve the deriving class end of a derivation relation."); + + return getTargetEnd(); + } + + public Classifier getSource() { + Optional> source = getSourceEnd().getPropertyType(); + + if (source.isEmpty()) throw new NullPointerException("Source of the relation is null."); + + return source.get(); + } + + public Classifier getTarget() { + Optional> target = getTargetEnd().getPropertyType(); + + if (target.isEmpty()) throw new NullPointerException("Target of the relation is null."); + + return target.get(); + } + + public Classifier getMember(int position) { + Optional> member = getMemberEnd(position).getPropertyType(); + + if (member.isEmpty()) + throw new NullPointerException("Member at position " + position + " is null."); + + return member.get(); + } + + public Class getSourceClass() { + Classifier source = getSource(); + + if (!(source instanceof Class)) + throw new IllegalCallerException("Source of the relation is not a class."); + + return (Class) source; + } + + public Class getTargetClass() { + Classifier target = getTarget(); + + if (!(target instanceof Class)) + throw new IllegalCallerException("Target of the relation is not a class."); + + return (Class) target; + } + + public Class getMemberClass(int position) { + Classifier member = getMember(position); + + if (!(member instanceof Class)) + throw new IllegalCallerException("Target of the relation is not a class."); + + return (Class) member; + } + + public Relation getDerivedRelation() { + Optional> relation = getDerivedRelationEnd().getPropertyType(); + + if (relation.isEmpty()) throw new NullPointerException("The derived relation is null."); + + if (!(relation.get() instanceof Relation)) + throw new IllegalCallerException("The derived element is not a relation."); + + return (Relation) relation.get(); + } + + public Class getDerivingClass() { + Optional> _class = getDerivingClassEnd().getPropertyType(); + + if (_class.isEmpty()) + throw new NullPointerException("The class from which the relation is derived is null."); + + if (!(_class.get() instanceof Class)) + throw new IllegalCallerException( + "The element from which the relation is derived is not a class."); + + return (Class) _class.get(); + } + + public Optional getSourceOntoumlStereotype() { + return getSource().getOntoumlStereotype(); + } + + public Optional getTargetOntoumlStereotype() { + return getTarget().getOntoumlStereotype(); + } + + public Optional getSourceClassStereotype() { + return getSourceClass().getOntoumlStereotype(); + } + + public Optional getTargetClassStereotype() { + return getTargetClass().getOntoumlStereotype(); + } + + public Optional getMemberClassStereotype(int position) { + return getMemberClass(position).getOntoumlStereotype(); + } + + public Optional getDerivedRelationStereotype() { + return getDerivedRelation().getOntoumlStereotype(); + } + + public Optional getDerivingClassStereotype() { + return getDerivingClass().getOntoumlStereotype(); + } + + public Optional getSourceStereotype() { + return getSource().getStereotype(); + } + + public Optional getTargetStereotype() { + return getTarget().getStereotype(); + } + + public boolean isBinary() { + return arity() == 2; + } + + public boolean isTernary() { + return arity() == 3; + } + + public boolean holdsBetweenClasses() { + if (arity() < 2) return false; + return properties.stream().allMatch(p -> p.isPropertyTypeClass()); + } + + public boolean holdsBetweenRelations() { + if (arity() < 2) return false; + return properties.stream().allMatch(p -> p.isPropertyTypeRelation()); + } + + public boolean holdsBetweenClassAndRelation() { + if (arity() < 2) return false; + return properties.stream().anyMatch(p -> p.isPropertyTypeRelation()) + && properties.stream().anyMatch(p -> p.isPropertyTypeClass()); + } + + public boolean holdsBetweenEvents() { + if (arity() < 2) return false; + + return properties.stream() + .allMatch( + p -> p.isPropertyTypeClass() && p.getPropertyTypeAsClass().isRestrictedToEvents()); + } + + public boolean holdsBetweenMoments() { + if (arity() < 2) return false; + + return properties.stream() + .allMatch( + p -> p.isPropertyTypeClass() && p.getPropertyTypeAsClass().isRestrictedToMoments()); + } + + public boolean holdsBetweenSubstantials() { + if (arity() < 2) return false; + + return properties.stream() + .allMatch( + p -> + p.isPropertyTypeClass() && p.getPropertyTypeAsClass().isRestrictedToSubstantials()); + } + + public boolean isBinaryClassRelation() { + return isBinary() && holdsBetweenClasses(); + } + + public boolean fromRelationToClass() { + return isBinary() && getSource() instanceof Relation && getTarget() instanceof Class; + } + + public boolean isTernaryClassRelation() { + return isTernary() && holdsBetweenClasses(); + } + + public boolean isPartWholeRelation() { + return isBinaryClassRelation() && getTargetEnd().isAggregationEnd(); + } + + public boolean isExistentialDependency() { + return properties.stream().anyMatch(Property::isReadOnly); + } + + public boolean isSourceExistentiallyDependent() { + return getTargetEnd().isReadOnly(); + } + + public boolean isTargetExistentiallyDependent() { + return getSourceEnd().isReadOnly(); + } + + public boolean isBinaryExistentialDependency() { + return isSourceExistentiallyDependent() || isTargetExistentiallyDependent(); + } + + public boolean isExistentialDependence() { + Optional stereotype = getOntoumlStereotype(); + return stereotype.isPresent() && stereotype.get().isExistentialDependency(); + } + + public boolean isMaterial() { + return getOntoumlStereotype().orElse(null) == RelationStereotype.MATERIAL; + } + + public boolean isDerivation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.DERIVATION; + } + + public boolean isComparative() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.COMPARATIVE; + } + + public boolean isMediation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.MEDIATION; + } + + public boolean isCharacterization() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.CHARACTERIZATION; + } + + public boolean isExternalDependence() { + return isBinary() + && getOntoumlStereotype().orElse(null) == RelationStereotype.EXTERNAL_DEPENDENCE; + } + + public boolean isComponentOf() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.COMPONENT_OF; + } + + public boolean isMemberOf() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.MEMBER_OF; + } + + public boolean isSubCollectionOf() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.SUBCOLLECTION_OF; + } + + public boolean isSubQuantityOf() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.SUBQUANTITY_OF; + } + + public boolean isInstantiation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.INSTANTIATION; + } + + public boolean isTermination() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.TERMINATION; + } + + public boolean isParticipational() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.PARTICIPATIONAL; + } + + public boolean isParticipation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.PARTICIPATION; + } + + public boolean isHistoricalDependence() { + return isBinary() + && getOntoumlStereotype().orElse(null) == RelationStereotype.HISTORICAL_DEPENDENCE; + } + + public boolean isCreation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.CREATION; + } + + public boolean isManifestation() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.MANIFESTATION; + } + + public boolean isBringsAbout() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.BRINGS_ABOUT; + } + + public boolean isTriggers() { + return isBinary() && getOntoumlStereotype().orElse(null) == RelationStereotype.TRIGGERS; + } + + public boolean propertiesSatisfy(Predicate condition) { + return propertiesSatisfy(List.of(condition)); + } + + public boolean propertiesSatisfy(List> conditions) { + if (conditions == null) throw new NullPointerException("Conditions list cannot be null."); + + if (arity() != conditions.size()) { + throw new IllegalArgumentException( + "The number of conditions must be the same as that of properties of the relation."); + } + + for (int i = 0; i < conditions.size(); i++) { + if (!conditions.get(i).test(properties.get(i))) return false; + } + + return true; + } + + public Class getMediated() { + return getMediatedEnd().getPropertyTypeAsClass(); + } + + public Property getMediatedEnd() { + if (!isMediation()) + throw new IllegalCallerException("Can only retrieve mediated end of a mediation!"); + + return getTargetEnd(); + } + + public Class getRelator() { + return getRelatorEnd().getPropertyTypeAsClass(); + } + + public Property getRelatorEnd() { + if (!isMediation()) + throw new IllegalCallerException("Can only retrieve relator end of a mediation!"); + + return getSourceEnd(); + } + + public Class getBearer() { + return getBearerEnd().getPropertyTypeAsClass(); + } + + public Property getBearerEnd() { + if (!isCharacterization()) + throw new IllegalCallerException("Can only retrieve bearer end of a characterization!"); + + return getTargetEnd(); + } + + public Class getCharacterizer() { + return getCharacterizerEnd().getPropertyTypeAsClass(); + } + + public Property getCharacterizerEnd() { + if (!isCharacterization()) + throw new IllegalCallerException( + "Can only retrieve characterizer (.e.g Mode, Quality) end of a characterization!"); + + return getSourceEnd(); + } + + public Class getDependee() { + return getDependeeEnd().getPropertyTypeAsClass(); + } + + public Property getDependeeEnd() { + if (!isExternalDependence()) + throw new IllegalCallerException( + "Can only retrieve dependee end of an external dependence relation!"); + + return getTargetEnd(); + } + + public Class getDepender() { + return getDependerEnd().getPropertyTypeAsClass(); + } + + public Property getDependerEnd() { + if (!isExternalDependence()) + throw new IllegalCallerException( + "Can only retrieve depender end of an external dependence relation!"); + + return getSourceEnd(); + } + + public Class getHistoricalDependee() { + return getHistoricalDependeeEnd().getPropertyTypeAsClass(); + } + + public Property getHistoricalDependeeEnd() { + if (!isHistoricalDependence()) + throw new IllegalCallerException( + "Can only retrieve historical dependee end of a historical dependence relation!"); + + return getTargetEnd(); + } + + public Class getHistoricalDepender() { + return getHistoricalDependerEnd().getPropertyTypeAsClass(); + } + + public Property getHistoricalDependerEnd() { + if (!isExternalDependence()) + throw new IllegalCallerException( + "Can only retrieve historical depender end of an historical dependence relation!"); + + return getSourceEnd(); + } + + public Class getParticipant() { + return getParticipantEnd().getPropertyTypeAsClass(); + } + + public Property getParticipantEnd() { + if (!isParticipation()) + throw new IllegalCallerException( + "Can only retrieve participant end of a participation relation!"); + + return getTargetEnd(); + } + + public Class getParticipation() { + return getParticipationEnd().getPropertyTypeAsClass(); + } + + public Property getParticipationEnd() { + if (!isParticipation()) + throw new IllegalCallerException( + "Can only retrieve participation (aka event) end of a participation relation!"); + + return getSourceEnd(); + } + + public Class getCreated() { + return getCreatedEnd().getPropertyTypeAsClass(); + } + + public Property getCreatedEnd() { + if (!isCreation()) + throw new IllegalCallerException("Can only retrieve created end of a creation relation!"); + + return getTargetEnd(); + } + + public Class getCreationEvent() { + return getCreationEventEnd().getPropertyTypeAsClass(); + } + + public Property getCreationEventEnd() { + if (!isCreation()) + throw new IllegalCallerException( + "Can only retrieve creation event end of a creation relation!"); + + return getSourceEnd(); + } + + public Class getTerminated() { + return getTerminatedEnd().getPropertyTypeAsClass(); + } + + public Property getTerminatedEnd() { + if (!isTermination()) + throw new IllegalCallerException("Can only retrieve created end of a creation relation!"); + + return getTargetEnd(); + } + + public Class getTerminationEvent() { + return getTerminationEventEnd().getPropertyTypeAsClass(); + } + + public Property getTerminationEventEnd() { + if (!isTermination()) + throw new IllegalCallerException( + "Can only retrieve creation event end of a creation relation!"); + + return getSourceEnd(); + } + + public Class getManifested() { + return getManifestedEnd().getPropertyTypeAsClass(); + } + + public Property getManifestedEnd() { + if (!isManifestation()) + throw new IllegalCallerException("Can only retrieve created end of a creation relation!"); + + return getTargetEnd(); + } + + public Class getManifestation() { + return getManifestationEnd().getPropertyTypeAsClass(); + } + + public Property getManifestationEnd() { + if (!isManifestation()) + throw new IllegalCallerException( + "Can only retrieve creation event end of a creation relation!"); + + return getSourceEnd(); + } + + public Class getTriggered() { + return getTriggeredEnd().getPropertyTypeAsClass(); + } + + public Property getTriggeredEnd() { + if (!isTriggers()) + throw new IllegalCallerException("Can only retrieve created end of a creation relation!"); + + return getTargetEnd(); + } + + public Class getTriggeringSituation() { + return getTriggeringSituationEnd().getPropertyTypeAsClass(); + } + + public Property getTriggeringSituationEnd() { + if (!isTriggers()) + throw new IllegalCallerException( + "Can only retrieve creation event end of a creation relation!"); + + return getSourceEnd(); + } + + public Class getOutcomeSituation() { + return getOutcomeSituationEnd().getPropertyTypeAsClass(); + } + + public Property getOutcomeSituationEnd() { + if (!isBringsAbout()) + throw new IllegalCallerException("Can only retrieve created end of a creation relation!"); + + return getTargetEnd(); + } + + public Class getCause() { + return getCauseEnd().getPropertyTypeAsClass(); + } + + public Property getCauseEnd() { + if (!isBringsAbout()) + throw new IllegalCallerException( + "Can only retrieve creation event end of a creation relation!"); + + return getSourceEnd(); + } + + public Class getWhole() { + return getWholeEnd().getPropertyTypeAsClass(); + } + + public Property getWholeEnd() { + if (!isPartWholeRelation()) + throw new IllegalCallerException("Can only retrieve whole end of an externalDependence!"); + + return getTargetEnd(); + } + + public Class getPart() { + return getPartEnd().getPropertyTypeAsClass(); + } + + public Property getPartEnd() { + if (!isPartWholeRelation()) + throw new IllegalCallerException("Can only retrieve part end of an externalDependence!"); + + return getSourceEnd(); + } + + public Class getFunctionalComplex() { + return getFunctionalComplexEnd().getPropertyTypeAsClass(); + } + + public Property getFunctionalComplexEnd() { + if (!isComponentOf()) + throw new IllegalCallerException("Can only retrieve whole end of an externalDependence!"); + + return getWholeEnd(); + } + + public Class getFunctionalPart() { + return getFunctionalPartEnd().getPropertyTypeAsClass(); + } + + public Property getFunctionalPartEnd() { + if (!isComponentOf()) + throw new IllegalCallerException("Can only retrieve part end of an externalDependence!"); + + return getPartEnd(); + } + + public Class getCollectionWhole() { + return getCollectionWholeEnd().getPropertyTypeAsClass(); + } + + public Property getCollectionWholeEnd() { + if (!isMemberOf()) + throw new IllegalCallerException("Can only retrieve whole end of an externalDependence!"); + + return getWholeEnd(); + } + + public Class getCollectionMember() { + return getCollectionMemberEnd().getPropertyTypeAsClass(); + } + + public Property getCollectionMemberEnd() { + if (!isMemberOf()) + throw new IllegalCallerException("Can only retrieve part end of an externalDependence!"); + + return getPartEnd(); + } + + public Class getSuperCollection() { + return getSuperCollectionEnd().getPropertyTypeAsClass(); + } + + public Property getSuperCollectionEnd() { + if (!isSubCollectionOf()) + throw new IllegalCallerException("Can only retrieve whole end of an externalDependence!"); + + return getWholeEnd(); + } + + public Class getSubCollection() { + return getSubCollectionEnd().getPropertyTypeAsClass(); + } + + public Property getSubCollectionEnd() { + if (!isSubCollectionOf()) + throw new IllegalCallerException("Can only retrieve part end of an externalDependence!"); + + return getPartEnd(); + } + + public Class getSuperQuantity() { + return getSuperQuantityEnd().getPropertyTypeAsClass(); + } + + public Property getSuperQuantityEnd() { + if (!isSubCollectionOf()) + throw new IllegalCallerException("Can only retrieve whole end of an externalDependence!"); + + return getWholeEnd(); + } + + public Class getSubQuantity() { + return getSubQuantityEnd().getPropertyTypeAsClass(); + } + + public Property getSubQuantityEnd() { + if (!isSubCollectionOf()) + throw new IllegalCallerException("Can only retrieve part end of an externalDependence!"); + + return getPartEnd(); + } + + public Class getParticipationalWhole() { + return getParticipationalWholeEnd().getPropertyTypeAsClass(); + } + + public Property getParticipationalWholeEnd() { + if (!isParticipational()) + throw new IllegalCallerException( + "Can only retrieve participational whole end of a participational part-whole relation!"); + + return getWholeEnd(); + } + + public Class getParticipationalPart() { + return getParticipationalPartEnd().getPropertyTypeAsClass(); + } + + public Property getParticipationalPartEnd() { + if (!isParticipational()) + throw new IllegalCallerException( + "Can only retrieve participational part end of a participational part-whole relation!"); + + return getPartEnd(); + } + + public Class getCategorized() { + return getCategorizedEnd().getPropertyTypeAsClass(); + } + + public Property getCategorizedEnd() { + if (!isInstantiation()) + throw new IllegalCallerException( + "Can only retrieve categorized end of an instantiation relation!"); + + return getTargetEnd(); + } + + public Class getCategorizer() { + return getCategorizerEnd().getPropertyTypeAsClass(); + } + + public Property getCategorizerEnd() { + if (!isInstantiation()) + throw new IllegalCallerException( + "Can only retrieve categorizer end of an instantiation relation!"); + + return getSourceEnd(); + } + + public static Relation createRelation( + String id, String name, Classifier source, Classifier target) { + return new Relation(id, name, source, target); + } + + public static Relation createMaterial( + String id, String name, Classifier source, Classifier target) { + return new Relation(id, name, RelationStereotype.MATERIAL, source, target); + } + + public static Relation createMaterial( + String name, Classifier source, Classifier target) { + return createMaterial(null, name, source, target); + } + + public static Relation createComparative( + String id, String name, Classifier source, Classifier target) { + return new Relation(id, name, RelationStereotype.COMPARATIVE, source, target); + } + + public static Relation createDerivation( + String id, String name, Classifier source, Classifier target) { + return new Relation(id, name, RelationStereotype.DERIVATION, source, target); + } + + public static Relation createDerivation(Classifier source, Classifier target) { + return createDerivation(null, null, source, target); + } + + // TODO: Write additional factory methods. +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/RelationStereotype.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/RelationStereotype.java new file mode 100644 index 00000000..85d825fe --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/RelationStereotype.java @@ -0,0 +1,86 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; + +public enum RelationStereotype implements Stereotype { + MATERIAL("material"), + DERIVATION("derivation"), + COMPARATIVE("comparative"), + MEDIATION("mediation"), + CHARACTERIZATION("characterization"), + EXTERNAL_DEPENDENCE("externalDependence"), + COMPONENT_OF("componentOf"), + MEMBER_OF("memberOf"), + SUBCOLLECTION_OF("subCollectionOf"), + SUBQUANTITY_OF("subQuantityOf"), + INSTANTIATION("instantiation"), + TERMINATION("termination"), + PARTICIPATIONAL("participational"), + PARTICIPATION("participation"), + HISTORICAL_DEPENDENCE("historicalDependence"), + CREATION("creation"), + MANIFESTATION("manifestation"), + BRINGS_ABOUT("bringsAbout"), + TRIGGERS("triggers"); + + public static Collection EXISTENTIAL_DEPENDENCY_ON_SOURCE = + Set.of( + BRINGS_ABOUT, + CREATION, + MANIFESTATION, + PARTICIPATION, + PARTICIPATIONAL, + TERMINATION, + TRIGGERS); + + public static Collection EXISTENTIAL_DEPENDENCY_ON_TARGET = + Set.of( + BRINGS_ABOUT, + CHARACTERIZATION, + CREATION, + EXTERNAL_DEPENDENCE, + HISTORICAL_DEPENDENCE, + MEDIATION, + PARTICIPATIONAL); + + public static Collection EXISTENTIAL_DEPENDENCY = + Set.of( + BRINGS_ABOUT, + CHARACTERIZATION, + CREATION, + EXTERNAL_DEPENDENCE, + HISTORICAL_DEPENDENCE, + MANIFESTATION, + MEDIATION, + PARTICIPATION, + PARTICIPATIONAL, + TERMINATION, + TRIGGERS); + + public static Collection ALLOWS_HIGHER_ARITY = Set.of(MATERIAL); + + public final String stereotypeName; + + RelationStereotype(String name) { + this.stereotypeName = name; + } + + @Override + public String getStereotypeName() { + return stereotypeName; + } + + public static Optional findByName(String name) { + return Stereotype.findByName(RelationStereotype.class, name); + } + + public boolean isExistentialDependency() { + return EXISTENTIAL_DEPENDENCY.contains(this); + } + + public boolean isBinaryOnly() { + return !ALLOWS_HIGHER_ARITY.contains(this); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Stereotype.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Stereotype.java new file mode 100644 index 00000000..e1191c44 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/model/Stereotype.java @@ -0,0 +1,16 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.model; + +import java.util.EnumSet; +import java.util.Optional; + +public interface Stereotype { + + String getStereotypeName(); + + static & Stereotype> Optional findByName( + java.lang.Class enumeration, String name) { + return EnumSet.allOf(enumeration).stream() + .filter(value -> value.getStereotypeName().equals(name)) + .findFirst(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializer.java new file mode 100644 index 00000000..c8e35e7f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializer.java @@ -0,0 +1,38 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Nature; +import java.io.IOException; + +public class ClassSerializer extends JsonSerializer { + + @Override + public void serialize(Class clazz, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(clazz, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Class clazz, JsonGenerator jsonGen) throws IOException { + ClassifierSerializer.serializeFields(clazz, jsonGen); + Serializer.writeNullableBooleanField( + "isExtensional", clazz.isExtensional().orElse(null), jsonGen); + Serializer.writeNullableBooleanField("isPowertype", clazz.isPowertype().orElse(null), jsonGen); + Serializer.writeNullableNumberField("order", clazz.getOrder().orElse(null), jsonGen); + Serializer.writeNullableArrayField("literals", clazz.getLiterals(), jsonGen); + + if (!clazz.getRestrictedTo().isEmpty()) { + jsonGen.writeArrayFieldStart("restrictedTo"); + for (Nature nature : clazz.getRestrictedTo()) { + jsonGen.writeString(nature.getName()); + } + jsonGen.writeEndArray(); + } else { + jsonGen.writeNullField("restrictedTo"); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassViewSerializer.java new file mode 100644 index 00000000..0ff580f1 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassViewSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; +import java.io.IOException; + +public class ClassViewSerializer extends JsonSerializer { + + @Override + public void serialize(ClassView classView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(classView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(ClassView classView, JsonGenerator jsonGen) throws IOException { + NodeViewSerializer.serializeFields(classView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassifierSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassifierSerializer.java new file mode 100644 index 00000000..bea8373d --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassifierSerializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import java.io.IOException; + +public class ClassifierSerializer extends JsonSerializer> { + + @Override + public void serialize( + Classifier classifier, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(classifier, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Classifier classifier, JsonGenerator jsonGen) + throws IOException { + DecoratableSerializer.serializeFields(classifier, jsonGen); + jsonGen.writeBooleanField("isAbstract", classifier.isAbstract()); + jsonGen.writeBooleanField("isDerived", classifier.isDerived()); + Serializer.writeNullableArrayField("properties", classifier.getProperties(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ConnectorViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ConnectorViewSerializer.java new file mode 100644 index 00000000..6542423e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ConnectorViewSerializer.java @@ -0,0 +1,26 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ConnectorView; +import java.io.IOException; + +public class ConnectorViewSerializer extends JsonSerializer> { + + @Override + public void serialize( + ConnectorView connectorView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(connectorView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(ConnectorView connectorView, JsonGenerator jsonGen) + throws IOException { + DiagramElementSerializer.serializeFields(connectorView, jsonGen); + Serializer.writeNullableReferenceField("source", connectorView.getSource(), jsonGen); + Serializer.writeNullableReferenceField("target", connectorView.getTarget(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DecoratableSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DecoratableSerializer.java new file mode 100644 index 00000000..e997e057 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DecoratableSerializer.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Decoratable; +import java.io.IOException; + +public class DecoratableSerializer extends JsonSerializer> { + + @Override + public void serialize(Decoratable element, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(element, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Decoratable element, JsonGenerator jsonGen) throws IOException { + ModelElementSerializer.serializeFields(element, jsonGen); + jsonGen.writeObjectField("stereotype", element.getStereotype().orElse(null)); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramElementSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramElementSerializer.java new file mode 100644 index 00000000..3d46e712 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramElementSerializer.java @@ -0,0 +1,28 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.serialization.Serializer.writeNullableReferenceField; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import java.io.IOException; + +public class DiagramElementSerializer extends JsonSerializer> { + + @Override + public void serialize( + ElementView element, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(element, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(ElementView element, JsonGenerator jsonGen) throws IOException { + ElementSerializer.serializeId(element, jsonGen); + OntoumlElementSerializer.serializeType(element, jsonGen); + writeNullableReferenceField("modelElement", element.getModelElement(), jsonGen); + jsonGen.writeObjectField("shape", element.getShape()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramSerializer.java new file mode 100644 index 00000000..fcf76576 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/DiagramSerializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static it.unibz.inf.ontouml.vp.model.ontouml.serialization.Serializer.writeNullableReferenceField; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import java.io.IOException; + +public class DiagramSerializer extends JsonSerializer { + + @Override + public void serialize(Diagram diagram, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(diagram, jsonGen, provider); + jsonGen.writeEndObject(); + } + + static void serializeFields(Diagram diagram, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + OntoumlElementSerializer.serializeFields(diagram, jsonGen); + writeNullableReferenceField("owner", diagram.getOwner(), jsonGen); + jsonGen.writeObjectField("contents", diagram.getContents()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ElementSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ElementSerializer.java new file mode 100644 index 00000000..a63265cf --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ElementSerializer.java @@ -0,0 +1,28 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.Element; +import java.io.IOException; + +public class ElementSerializer extends JsonSerializer { + + @Override + public void serialize(Element element, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(element, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Element element, JsonGenerator jsonGen) throws IOException { + serializeId(element, jsonGen); + jsonGen.writeObjectField("name", element.getName()); + jsonGen.writeObjectField("description", element.getDescription()); + } + + static void serializeId(Element element, JsonGenerator jsonGen) throws IOException { + jsonGen.writeStringField("id", element.getId()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializer.java new file mode 100644 index 00000000..121d9d0e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import java.io.IOException; + +public class GeneralizationSerializer extends JsonSerializer { + + @Override + public void serialize(Generalization gen, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(gen, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Generalization gen, JsonGenerator jsonGen) throws IOException { + ModelElementSerializer.serializeFields(gen, jsonGen); + Serializer.writeNullableReferenceField("general", gen.getGeneral().orElse(null), jsonGen); + Serializer.writeNullableReferenceField("specific", gen.getSpecific().orElse(null), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializer.java new file mode 100644 index 00000000..7127f412 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import java.io.IOException; + +public class GeneralizationSetSerializer extends JsonSerializer { + + @Override + public void serialize(GeneralizationSet gs, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(gs, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(GeneralizationSet gs, JsonGenerator jsonGen) throws IOException { + ModelElementSerializer.serializeFields(gs, jsonGen); + jsonGen.writeBooleanField("isDisjoint", gs.isDisjoint()); + jsonGen.writeBooleanField("isComplete", gs.isComplete()); + Serializer.writeNullableReferenceField( + "categorizer", gs.getCategorizer().orElse(null), jsonGen); + Serializer.writeNullableReferenceArray("generalizations", gs.getGeneralizations(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetViewSerializer.java new file mode 100644 index 00000000..8f5a5b9f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetViewSerializer.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationSetView; +import java.io.IOException; + +public class GeneralizationSetViewSerializer extends JsonSerializer { + @Override + public void serialize( + GeneralizationSetView gsView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(gsView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(GeneralizationSetView gsView, JsonGenerator jsonGen) + throws IOException { + NodeViewSerializer.serializeFields(gsView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationViewSerializer.java new file mode 100644 index 00000000..94512c55 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationViewSerializer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; +import java.io.IOException; + +public class GeneralizationViewSerializer extends JsonSerializer { + + @Override + public void serialize( + GeneralizationView generalizationView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(generalizationView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(GeneralizationView generalizationView, JsonGenerator jsonGen) + throws IOException { + ConnectorViewSerializer.serializeFields(generalizationView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/LiteralSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/LiteralSerializer.java new file mode 100644 index 00000000..4256ad9b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/LiteralSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import java.io.IOException; + +public class LiteralSerializer extends JsonSerializer { + + @Override + public void serialize(Literal literal, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(literal, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Literal literal, JsonGenerator jsonGen) throws IOException { + ModelElementSerializer.serializeFields(literal, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ModelElementSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ModelElementSerializer.java new file mode 100644 index 00000000..519256ec --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ModelElementSerializer.java @@ -0,0 +1,29 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import java.io.IOException; + +public class ModelElementSerializer extends JsonSerializer { + + @Override + public void serialize( + ModelElement modelElement, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(modelElement, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(ModelElement modelElement, JsonGenerator jsonGen) throws IOException { + OntoumlElementSerializer.serializeFields(modelElement, jsonGen); + + if (modelElement.hasPropertyAssignments()) { + jsonGen.writeObjectField("propertyAssignments", modelElement.getPropertyAssignments()); + } else { + jsonGen.writeNullField("propertyAssignments"); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializer.java new file mode 100644 index 00000000..007aff66 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.io.IOException; + +public class MultilingualTextSerializer extends JsonSerializer { + + @Override + public void serialize(MultilingualText text, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + + if (text.isEmpty() || text.getText().isEmpty()) { + jsonGen.writeNull(); + return; + } + + if (text.size() == 1) { + jsonGen.writeString(text.getText().get()); + return; + } + + jsonGen.writeObject(text.getMap()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/NodeViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/NodeViewSerializer.java new file mode 100644 index 00000000..ed7a5201 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/NodeViewSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.NodeView; +import java.io.IOException; + +public class NodeViewSerializer extends JsonSerializer { + + @Override + public void serialize(NodeView nodeView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(nodeView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(NodeView nodeView, JsonGenerator jsonGen) throws IOException { + DiagramElementSerializer.serializeFields(nodeView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/OntoumlElementSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/OntoumlElementSerializer.java new file mode 100644 index 00000000..b6b308eb --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/OntoumlElementSerializer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import java.io.IOException; + +public class OntoumlElementSerializer extends JsonSerializer { + + @Override + public void serialize(OntoumlElement element, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(element, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(OntoumlElement element, JsonGenerator jsonGen) throws IOException { + ElementSerializer.serializeFields(element, jsonGen); + serializeType(element, jsonGen); + } + + static void serializeType(OntoumlElement element, JsonGenerator jsonGen) throws IOException { + jsonGen.writeStringField("type", element.getType()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializer.java new file mode 100644 index 00000000..c7922750 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializer.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.io.IOException; + +public class PackageSerializer extends JsonSerializer { + + @Override + public void serialize(Package pkg, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(pkg, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Package pkg, JsonGenerator jsonGen) throws IOException { + ModelElementSerializer.serializeFields(pkg, jsonGen); + Serializer.writeNullableArrayField("contents", pkg.getContents(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageViewSerializer.java new file mode 100644 index 00000000..f53d2226 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageViewSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.PackageView; +import java.io.IOException; + +public class PackageViewSerializer extends JsonSerializer { + + @Override + public void serialize(PackageView classView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(classView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(PackageView classView, JsonGenerator jsonGen) throws IOException { + NodeViewSerializer.serializeFields(classView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PathSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PathSerializer.java new file mode 100644 index 00000000..d8691ae9 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PathSerializer.java @@ -0,0 +1,34 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Point; +import java.io.IOException; + +public class PathSerializer extends JsonSerializer { + @Override + public void serialize(Path path, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(path, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Path path, JsonGenerator jsonGen) throws IOException { + ShapeSerializer.serializeFields(path, jsonGen); + + jsonGen.writeArrayFieldStart("points"); + + for (Point point : path.getPoints()) { + + jsonGen.writeStartObject(); + Serializer.writeNullableNumberField("x", point.getX(), jsonGen); + Serializer.writeNullableNumberField("y", point.getY(), jsonGen); + jsonGen.writeEndObject(); + } + + jsonGen.writeEndArray(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializer.java new file mode 100644 index 00000000..f065f161 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import java.io.IOException; + +public class ProjectSerializer extends JsonSerializer { + + @Override + public void serialize(Project project, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(project, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Project project, JsonGenerator jsonGen) throws IOException { + OntoumlElementSerializer.serializeFields(project, jsonGen); + jsonGen.writeObjectField("model", project.getModel().orElse(null)); + Serializer.writeNullableArrayField("diagrams", project.getDiagrams(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializer.java new file mode 100644 index 00000000..e338e452 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializer.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.io.IOException; + +public class PropertySerializer extends JsonSerializer { + @Override + public void serialize(Property property, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(property, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Property property, JsonGenerator jsonGen) throws IOException { + DecoratableSerializer.serializeFields(property, jsonGen); + jsonGen.writeBooleanField("isDerived", property.isDerived()); + jsonGen.writeBooleanField("isReadOnly", property.isReadOnly()); + jsonGen.writeBooleanField("isOrdered", property.isOrdered()); + Serializer.writeNullableStringField( + "cardinality", property.getCardinality().getValue().orElse(null), jsonGen); + Serializer.writeNullableReferenceField( + "propertyType", property.getPropertyType().orElse(null), jsonGen); + Serializer.writeNullableReferenceArray( + "subsettedProperties", property.getSubsettedProperties(), jsonGen); + Serializer.writeNullableReferenceArray( + "redefinedProperties", property.getRedefinedProperties(), jsonGen); + + if (property.getAggregationKind().isPresent()) + jsonGen.writeStringField("aggregationKind", property.getAggregationKind().get().getName()); + else jsonGen.writeNullField("aggregationKind"); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangleSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangleSerializer.java new file mode 100644 index 00000000..449b21b4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangleSerializer.java @@ -0,0 +1,21 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; + +public class RectangleSerializer extends JsonSerializer { + @Override + public void serialize(Rectangle rectangle, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(rectangle, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Rectangle rectangle, JsonGenerator jsonGen) throws IOException { + RectangularShapeSerializer.serializeFields(rectangle, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangularShapeSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangularShapeSerializer.java new file mode 100644 index 00000000..b022857c --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RectangularShapeSerializer.java @@ -0,0 +1,25 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RectangularShape; +import java.io.IOException; + +public class RectangularShapeSerializer extends JsonSerializer { + @Override + public void serialize(RectangularShape shape, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(shape, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(RectangularShape shape, JsonGenerator jsonGen) throws IOException { + ShapeSerializer.serializeFields(shape, jsonGen); + Serializer.writeNullableNumberField("x", shape.getX(), jsonGen); + Serializer.writeNullableNumberField("y", shape.getY(), jsonGen); + Serializer.writeNullableNumberField("width", shape.getWidth(), jsonGen); + Serializer.writeNullableNumberField("height", shape.getHeight(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializer.java new file mode 100644 index 00000000..143002ef --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import java.io.IOException; + +public class RelationSerializer extends JsonSerializer { + + @Override + public void serialize(Relation relation, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(relation, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Relation relation, JsonGenerator jsonGen) throws IOException { + ClassifierSerializer.serializeFields(relation, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationViewSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationViewSerializer.java new file mode 100644 index 00000000..e5bf852e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationViewSerializer.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; +import java.io.IOException; + +public class RelationViewSerializer extends JsonSerializer { + + @Override + public void serialize( + RelationView relationView, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(relationView, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(RelationView relationView, JsonGenerator jsonGen) throws IOException { + ConnectorViewSerializer.serializeFields(relationView, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/Serializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/Serializer.java new file mode 100644 index 00000000..bcb522e7 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/Serializer.java @@ -0,0 +1,74 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import java.io.IOException; +import java.util.Collection; + +public class Serializer { + public static void writeNullableStringField(String fieldName, String value, JsonGenerator jsonGen) + throws IOException { + + if (value != null) jsonGen.writeStringField(fieldName, value); + else jsonGen.writeNullField(fieldName); + } + + public static void writeNullableBooleanField( + String fieldName, Boolean value, JsonGenerator jsonGen) throws IOException { + + if (value != null) jsonGen.writeBooleanField(fieldName, value); + else jsonGen.writeNullField(fieldName); + } + + public static void writeNullableNumberField(String fieldName, Number value, JsonGenerator jsonGen) + throws IOException { + + if (value == null) { + jsonGen.writeNullField(fieldName); + return; + } + + if (value instanceof Integer) jsonGen.writeNumberField(fieldName, (Integer) value); + else if (value instanceof Double) jsonGen.writeNumberField(fieldName, (Double) value); + else if (value instanceof Long) jsonGen.writeNumberField(fieldName, (Long) value); + else if (value instanceof Float) jsonGen.writeNumberField(fieldName, (Float) value); + } + + public static void writeNullableArrayField( + String fieldName, Collection list, JsonGenerator jsonGen) throws IOException { + + if (list != null && !list.isEmpty()) jsonGen.writeObjectField(fieldName, list); + else jsonGen.writeNullField(fieldName); + } + + public static void writeNullableReferenceField( + String fieldName, OntoumlElement element, JsonGenerator jsonGen) throws IOException { + + if (element != null) { + jsonGen.writeObjectFieldStart(fieldName); + jsonGen.writeStringField("id", element.getId()); + jsonGen.writeStringField("type", element.getType()); + jsonGen.writeEndObject(); + } else { + jsonGen.writeNullField(fieldName); + } + } + + public static void writeNullableReferenceArray( + String fieldName, Collection elements, JsonGenerator jsonGen) + throws IOException { + + if (elements != null && !elements.isEmpty()) { + jsonGen.writeArrayFieldStart(fieldName); + for (OntoumlElement element : elements) { + jsonGen.writeStartObject(); + jsonGen.writeStringField("id", element.getId()); + jsonGen.writeStringField("type", element.getType()); + jsonGen.writeEndObject(); + } + jsonGen.writeEndArray(); + } else { + jsonGen.writeNullField(fieldName); + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ShapeSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ShapeSerializer.java new file mode 100644 index 00000000..52cb56f1 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ShapeSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Shape; +import java.io.IOException; + +public class ShapeSerializer extends JsonSerializer { + @Override + public void serialize(Shape shape, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(shape, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Shape shape, JsonGenerator jsonGen) throws IOException { + ElementSerializer.serializeId(shape, jsonGen); + OntoumlElementSerializer.serializeType(shape, jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/TextSerializer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/TextSerializer.java new file mode 100644 index 00000000..f8c48d26 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/TextSerializer.java @@ -0,0 +1,22 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Text; +import java.io.IOException; + +public class TextSerializer extends JsonSerializer { + @Override + public void serialize(Text text, JsonGenerator jsonGen, SerializerProvider provider) + throws IOException { + jsonGen.writeStartObject(); + serializeFields(text, jsonGen); + jsonGen.writeEndObject(); + } + + static void serializeFields(Text text, JsonGenerator jsonGen) throws IOException { + RectangularShapeSerializer.serializeFields(text, jsonGen); + Serializer.writeNullableStringField("value", text.getValue(), jsonGen); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ClassView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ClassView.java new file mode 100644 index 00000000..fcad5b08 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ClassView.java @@ -0,0 +1,33 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.ClassViewDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.ClassViewSerializer; + +@JsonSerialize(using = ClassViewSerializer.class) +@JsonDeserialize(using = ClassViewDeserializer.class) +public class ClassView extends NodeView { + public ClassView(String id, Class clazz) { + super(id, clazz); + } + + public ClassView(Class clazz) { + this(null, clazz); + } + + public ClassView() { + this(null, null); + } + + @Override + public String getType() { + return "ClassView"; + } + + @Override + Rectangle createShape() { + return new Rectangle(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ConnectorView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ConnectorView.java new file mode 100644 index 00000000..306e5a22 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ConnectorView.java @@ -0,0 +1,59 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import java.util.ArrayList; +import java.util.List; + +public abstract class ConnectorView extends ElementView { + private ElementView source; + private ElementView target; + + public ConnectorView(String id, T connector) { + super(id, connector); + } + + public ConnectorView(T connector) { + this(null, connector); + } + + public ConnectorView() { + this(null, null); + } + + @Override + public List getContents() { + List contents = new ArrayList<>(); + contents.add(getPath()); + return contents; + } + + @Override + Path createShape() { + return new Path(); + } + + public Path getPath() { + return getShape(); + } + + public void setPath(Path path) { + setShape(path); + } + + public ElementView getSource() { + return source; + } + + public void setSource(ElementView source) { + this.source = source; + } + + public ElementView getTarget() { + return target; + } + + public void setTarget(ElementView target) { + this.target = target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Diagram.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Diagram.java new file mode 100644 index 00000000..ba83fdb0 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Diagram.java @@ -0,0 +1,81 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.DiagramElementContainer; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.DiagramDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.DiagramSerializer; +import java.util.*; + +/** A set of {@link ElementView} instances use to describe a perspective of the OntoUML model. */ +@JsonSerialize(using = DiagramSerializer.class) +@JsonDeserialize(using = DiagramDeserializer.class) +public class Diagram extends DiagramElement implements DiagramElementContainer { + + private ModelElement owner; + private Set> contents = new HashSet<>(); + + @Override + public String getType() { + return "Diagram"; + } + + public Diagram(String id, MultilingualText name) { + super(id, name); + } + + public Diagram(String id, String name) { + super(id, new MultilingualText(name)); + } + + public Diagram() { + this(null, (MultilingualText) null); + } + + @Override + public List getContents() { + return new ArrayList<>(contents); + } + + public List getDiagramElements() { + return new ArrayList<>(contents); + } + + public void addElement(ElementView diagramElement) { + if (diagramElement == null) return; + + diagramElement.setContainer(this); + contents.add(diagramElement); + } + + public void addElements(Collection> diagramElements) { + if (diagramElements == null) return; + diagramElements.stream().filter(Objects::nonNull).forEach(e -> addElement(e)); + } + + public void addElements(ElementView[] diagramElements) { + if (diagramElements == null) return; + addElements(List.of(diagramElements)); + } + + public void setContents(Collection> diagramElements) { + this.contents.clear(); + if (diagramElements != null) addElements(diagramElements); + } + + public void setContents(ElementView[] diagramElements) { + if (diagramElements == null) return; + setContents(List.of(diagramElements)); + } + + public void setOwner(ModelElement owner) { + this.owner = owner; + } + + public ModelElement getOwner() { + return owner; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/DiagramElement.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/DiagramElement.java new file mode 100644 index 00000000..188e2dee --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/DiagramElement.java @@ -0,0 +1,17 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import java.awt.*; + +/** Element defined in the concrete syntax of the language */ +public abstract class DiagramElement extends OntoumlElement { + + public DiagramElement(String id, MultilingualText name) { + super(id, name); + } + + public DiagramElement(String id) { + super(id, null); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ElementView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ElementView.java new file mode 100644 index 00000000..9c0fa61f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/ElementView.java @@ -0,0 +1,44 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; + +/** + * A graphical representation of a {@link ModelElement} within a {@link Diagram} . + * + *

Each instance of a DiagramElement exists in one and only one Diagram. + * + *

Diagrams only have instances of DiagramElement as direct content (children). + */ +public abstract class ElementView extends DiagramElement { + + T modelElement; + S shape; + + public ElementView(String id, T modelElement) { + super(id); + this.shape = createShape(); + this.modelElement = modelElement; + } + + public ElementView(T modelElement) { + this(null, modelElement); + } + + public T getModelElement() { + return modelElement; + } + + public void setModelElement(T modelElement) { + this.modelElement = modelElement; + } + + public S getShape() { + return shape; + } + + public void setShape(S shape) { + if (shape != null) this.shape = shape; + } + + abstract S createShape(); +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationSetView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationSetView.java new file mode 100644 index 00000000..ff3f9b05 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationSetView.java @@ -0,0 +1,34 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.GeneralizationSetViewDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.GeneralizationSetViewSerializer; + +@JsonSerialize(using = GeneralizationSetViewSerializer.class) +@JsonDeserialize(using = GeneralizationSetViewDeserializer.class) +public class GeneralizationSetView extends NodeView { + + public GeneralizationSetView(String id, GeneralizationSet genSet) { + super(id, genSet); + } + + public GeneralizationSetView(GeneralizationSet genSet) { + this(null, genSet); + } + + public GeneralizationSetView() { + this(null, null); + } + + @Override + public String getType() { + return "GeneralizationSetView"; + } + + @Override + Text createShape() { + return new Text(""); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationView.java new file mode 100644 index 00000000..93332575 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/GeneralizationView.java @@ -0,0 +1,37 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.GeneralizationViewDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.GeneralizationViewSerializer; +import java.util.ArrayList; +import java.util.List; + +@JsonSerialize(using = GeneralizationViewSerializer.class) +@JsonDeserialize(using = GeneralizationViewDeserializer.class) +public class GeneralizationView extends ConnectorView { + + public GeneralizationView(String id, Generalization generalization) { + super(id, generalization); + } + + public GeneralizationView(Generalization generalization) { + this(null, generalization); + } + + public GeneralizationView() { + this(null, null); + } + + @Override + public List getContents() { + return new ArrayList<>(); + } + + @Override + public String getType() { + return "GeneralizationView"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/NodeView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/NodeView.java new file mode 100644 index 00000000..895b39f9 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/NodeView.java @@ -0,0 +1,59 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import java.util.Arrays; +import java.util.List; + +public abstract class NodeView + extends ElementView { + + public NodeView(String id, T element) { + super(id, element); + } + + public NodeView(T element) { + this(null, element); + } + + public NodeView() { + this(null, null); + } + + @Override + public List getContents() { + return Arrays.asList(shape); + } + + public int getX() { + return shape.getX(); + } + + public void setX(int x) { + shape.setX(x); + } + + public int getY() { + return shape.getY(); + } + + public void setY(int y) { + shape.setY(y); + } + + public int getWidth() { + return shape.width; + } + + public void setWidth(int width) { + shape.setWidth(width); + } + + public int getHeight() { + return shape.height; + } + + public void setHeight(int height) { + shape.setHeight(height); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/PackageView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/PackageView.java new file mode 100644 index 00000000..8ee1c77f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/PackageView.java @@ -0,0 +1,33 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.PackageViewDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.PackageViewSerializer; + +@JsonSerialize(using = PackageViewSerializer.class) +@JsonDeserialize(using = PackageViewDeserializer.class) +public class PackageView extends NodeView { + public PackageView(String id, Package pkg) { + super(id, pkg); + } + + public PackageView(Package clazz) { + this(null, clazz); + } + + public PackageView() { + this(null, null); + } + + @Override + public String getType() { + return "PackageView"; + } + + @Override + Rectangle createShape() { + return new Rectangle(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Path.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Path.java new file mode 100644 index 00000000..359b1f1b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Path.java @@ -0,0 +1,60 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.PathDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.PathSerializer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@JsonSerialize(using = PathSerializer.class) +@JsonDeserialize(using = PathDeserializer.class) +public class Path extends Shape { + List points = new ArrayList<>(); + + public Path(String id) { + super(id); + } + + public Path() { + this(null); + } + + @Override + public List getContents() { + return Collections.emptyList(); + } + + @Override + public String getType() { + return "Path"; + } + + public void moveTo(int x, int y) { + points.add(new Point(x, y)); + } + + public List getPoints() { + return points; + } + + public void setPoints(List points) { + this.points.clear(); + if (points != null) addPoints(points); + } + + public void addPoints(List points) { + if (points != null) points.forEach(p -> addPoint(p)); + } + + public void addPoint(Point point) { + if (point != null) points.add(point); + } + + @Override + public String toString() { + return points.toString(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Point.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Point.java new file mode 100644 index 00000000..64877b51 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Point.java @@ -0,0 +1,32 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +public class Point { + int x; + int y; + + public Point(Integer x, Integer y) { + setX(x); + setY(y); + } + + public int getX() { + return x; + } + + public void setX(Integer x) { + this.x = (x != null) ? x : 0; + } + + public int getY() { + return y; + } + + public void setY(Integer y) { + this.y = (y != null) ? y : 0; + } + + @Override + public String toString() { + return "(" + x + ", " + y + ')'; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Rectangle.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Rectangle.java new file mode 100644 index 00000000..0e293b36 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Rectangle.java @@ -0,0 +1,32 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.RectangleDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.RectangleSerializer; +import java.util.ArrayList; +import java.util.List; + +@JsonSerialize(using = RectangleSerializer.class) +@JsonDeserialize(using = RectangleDeserializer.class) +public class Rectangle extends RectangularShape { + + public Rectangle(String id) { + super(id); + } + + public Rectangle() { + this(null); + } + + @Override + public List getContents() { + return new ArrayList<>(); + } + + @Override + public String getType() { + return "Rectangle"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RectangularShape.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RectangularShape.java new file mode 100644 index 00000000..115a0592 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RectangularShape.java @@ -0,0 +1,59 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +public abstract class RectangularShape extends Shape { + Point topLeft = new Point(0, 0); + int width = 20; + int height = 10; + + public RectangularShape(String id, int width, int height) { + super(id); + this.width = width; + this.height = height; + } + + public RectangularShape(int width, int height) { + this(null, width, height); + this.width = width; + this.height = height; + } + + public RectangularShape(String id) { + super(id); + } + + public RectangularShape() { + super(null); + } + + public int getX() { + return topLeft.getX(); + } + + public void setX(Integer x) { + topLeft.setX(x); + } + + public int getY() { + return topLeft.getY(); + } + + public void setY(Integer y) { + topLeft.setY(y); + } + + public int getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = (width != null) ? width : 0; + } + + public int getHeight() { + return height; + } + + public void setHeight(Integer height) { + this.height = (height != null) ? height : 0; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RelationView.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RelationView.java new file mode 100644 index 00000000..2c95277b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/RelationView.java @@ -0,0 +1,54 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.RelationViewDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.RelationViewSerializer; +import java.util.List; + +@JsonSerialize(using = RelationViewSerializer.class) +@JsonDeserialize(using = RelationViewDeserializer.class) +public class RelationView extends ConnectorView { + + // private Text nameText = new Text(); + // private Text stereotypeText = new Text(); + // private Text sourceRoleText = new Text(); + // private Text sourceCardinalityText = new Text(); + // private Text targetRoleText = new Text(); + // private Text targetCardinalityText = new Text(); + + public RelationView(String id, Relation relation) { + super(id, relation); + } + + public RelationView(Relation relation) { + this(null, relation); + } + + public RelationView() { + super(null, null); + } + + @Override + public List getContents() { + List contents = super.getContents(); + + // contents.addAll( + // List.of( + // nameText, + // stereotypeText, + // sourceRoleText, + // sourceCardinalityText, + // targetRoleText, + // targetCardinalityText)); + + return contents; + } + + @Override + public String getType() { + return "RelationView"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Shape.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Shape.java new file mode 100644 index 00000000..ed4aa375 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Shape.java @@ -0,0 +1,8 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +public abstract class Shape extends DiagramElement { + + public Shape(String id) { + super(id); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Text.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Text.java new file mode 100644 index 00000000..f4058c41 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml/view/Text.java @@ -0,0 +1,46 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.view; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.deserialization.TextDeserializer; +import it.unibz.inf.ontouml.vp.model.ontouml.serialization.TextSerializer; +import java.util.ArrayList; +import java.util.List; + +@JsonSerialize(using = TextSerializer.class) +@JsonDeserialize(using = TextDeserializer.class) +public class Text extends RectangularShape { + String value; + + public Text(String id, String value) { + super(id); + this.value = value; + } + + public Text(String value) { + this(null, value); + } + + public Text() { + this(null, null); + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public List getContents() { + return new ArrayList<>(); + } + + @Override + public String getType() { + return "Text"; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationLoader.java new file mode 100644 index 00000000..be26a5b4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationLoader.java @@ -0,0 +1,100 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.*; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.utils.StereotypesManager; + +public class IAssociationLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IAssociation importElement(Relation fromRelation) { + logElementCreation(fromRelation); + + IAssociation toRelation = getOrCreateAssociation(fromRelation); + fromRelation.setId(toRelation.getId()); + + loadName(fromRelation, toRelation); + + loadSource(fromRelation, toRelation); + loadTarget(fromRelation, toRelation); + + boolean isDerived = fromRelation.isDerived(); + toRelation.setDerived(isDerived); + + boolean isAbstract = fromRelation.isAbstract(); + toRelation.setAbstract(isAbstract); + + fromRelation + .getStereotype() + .ifPresent(stereotype -> StereotypesManager.applyStereotype(toRelation, stereotype)); + + loadEndProperties(fromRelation.getSourceEnd(), (IAssociationEnd) toRelation.getFromEnd()); + loadEndProperties(fromRelation.getTargetEnd(), (IAssociationEnd) toRelation.getToEnd()); + + ITaggedValueLoader.loadTaggedValues(fromRelation, toRelation); + + return toRelation; + } + + private static void loadEndProperties(Property fromProperty, IAssociationEnd toProperty) { + loadName(fromProperty, toProperty); + + IMultiplicity detail = toProperty.getMultiplicityDetail(); + if (detail == null) { + detail = IModelElementFactory.instance().createMultiplicity(); + toProperty.setMultiplicityDetail(detail); + } + + boolean isDerived = fromProperty.isDerived(); + toProperty.setDerived(isDerived); + + boolean isReadOnly = fromProperty.isReadOnly(); + toProperty.setReadOnly(isReadOnly); + + boolean isOrdered = fromProperty.isOrdered(); + toProperty.getMultiplicityDetail().setOrdered(isOrdered); + + fromProperty + .getAggregationKind() + .map(agg -> agg.getName()) + .ifPresent(agg -> toProperty.setAggregationKind(agg)); + + fromProperty.getCardinalityValue().ifPresent(value -> toProperty.setMultiplicity(value)); + ITaggedValueLoader.loadTaggedValues(fromProperty, toProperty); + } + + private static void loadSource(Relation fromRelation, IAssociation toRelation) { + Classifier fromSource = fromRelation.getSource(); + IModelElement toSource = vpProject.getModelElementById(fromSource.getId()); + + if (toSource != null) toRelation.setFrom(toSource); + } + + private static void loadTarget(Relation fromRelation, IAssociation toRelation) { + Classifier fromTarget = fromRelation.getTarget(); + IModelElement toTarget = vpProject.getModelElementById(fromTarget.getId()); + + if (toTarget != null) toRelation.setTo(toTarget); + } + + private static IAssociation getOrCreateAssociation(Relation fromRelation) { + IModelElement toRelation = vpProject.getModelElementById(fromRelation.getId()); + + if (toRelation instanceof IAssociation) { + System.out.println("Relation " + fromRelation.getId() + " exists! Let's update it!"); + } else { + System.out.println("Relation " + fromRelation.getId() + " not found! Let's create it"); + toRelation = IModelElementFactory.instance().createAssociation(); + } + + return (IAssociation) toRelation; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationUIModelLoader.java new file mode 100644 index 00000000..0e55d0b5 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAssociationUIModelLoader.java @@ -0,0 +1,43 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIDiagramElement; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIModelElement; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.connector.IAssociationUIModel; +import com.vp.plugin.model.IAssociation; +import com.vp.plugin.model.IAssociationClass; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; +import java.awt.*; + +public class IAssociationUIModelLoader { + + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(IClassDiagramUIModel toDiagram, RelationView fromView) { + IModelElement toModelElement = getIModelElement(fromView); + + if (!(toModelElement instanceof IAssociation) + && !(toModelElement instanceof IAssociationClass)) { + System.out.println( + LoaderUtils.getIncompatibleMessage(fromView, toModelElement, IAssociation.class)); + return; + } + + IDiagramElement toSource = getIDiagramElement(toDiagram, fromView.getSource()); + IDiagramElement toTarget = getIDiagramElement(toDiagram, fromView.getTarget()); + + Point[] toPoints = IConnectorUIModelLoader.loadPoints(fromView); + + IAssociationUIModel toView = + (IAssociationUIModel) + diagramManager.createConnector(toDiagram, toModelElement, toSource, toTarget, toPoints); + + fromView.setId(toView.getId()); + toView.resetCaption(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAttributeLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAttributeLoader.java new file mode 100644 index 00000000..41f0acd3 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IAttributeLoader.java @@ -0,0 +1,99 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.*; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.*; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.AggregationKind; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.util.Optional; + +public class IAttributeLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static void importAttributes(Class fromClass) { + IClass toClass = getToClass(fromClass); + + if (toClass == null) return; + + fromClass.getAttributes().forEach(a -> importAttribute(toClass, a)); + } + + private static void importAttribute(IClass toClass, Property fromAttribute) { + logElementCreation(fromAttribute); + + IAttribute toAttribute = getOrCreateAttribute(toClass, fromAttribute); + fromAttribute.setId(toAttribute.getId()); + + IMultiplicity detail = toAttribute.getMultiplicityDetail(); + if (detail == null) { + detail = IModelElementFactory.instance().createMultiplicity(); + toAttribute.setMultiplicityDetail(detail); + } + + loadName(fromAttribute, toAttribute); + + boolean isDerived = fromAttribute.isDerived(); + toAttribute.setDerived(isDerived); + + boolean isOrdered = fromAttribute.isOrdered(); + toAttribute.getMultiplicityDetail().setOrdered(isOrdered); + + boolean isReadOnly = fromAttribute.isReadOnly(); + toAttribute.setReadOnly(isReadOnly); + + fromAttribute + .getAggregationKind() + .ifPresent( + agg -> { + int aggregationKind = getAggregationKind(agg); + toAttribute.setAggregation(aggregationKind); + }); + + fromAttribute.getCardinalityValue().ifPresent(value -> toAttribute.setMultiplicity(value)); + getPropertyType(fromAttribute).ifPresent(pType -> toAttribute.setType(pType)); + + ITaggedValueLoader.loadTaggedValues(fromAttribute, toAttribute); + } + + private static Optional getPropertyType(Property fromAttribute) { + Optional> fromPropertyTypeOp = fromAttribute.getPropertyType(); + + if (fromPropertyTypeOp.isPresent() && fromPropertyTypeOp.get() instanceof Class) { + Class fromPropertyType = (Class) fromPropertyTypeOp.get(); + String id = fromPropertyType.getId(); + return Optional.ofNullable(vpProject.getModelElementById(id)); + } + + return Optional.empty(); + } + + private static int getAggregationKind(AggregationKind agg) { + switch (agg.getName()) { + case "SHARED": + return 1; + case "COMPOSITE": + return 2; + case "NONE": + default: + return 0; + } + } + + private static IAttribute getOrCreateAttribute(IClass toClass, Property fromAttribute) { + IAttribute toAttribute = toClass.getAttributeByName(fromAttribute.getFirstName().orElse("")); + + if (toAttribute != null) { + System.out.println("Attribute " + fromAttribute.getId() + " exists! Let's update it!"); + } else { + System.out.println("Attribute " + fromAttribute.getId() + " not found! Let's create it"); + toAttribute = toClass.createAttribute(); + } + + return toAttribute; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassDiagramLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassDiagramLoader.java new file mode 100644 index 00000000..658e580d --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassDiagramLoader.java @@ -0,0 +1,94 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.IDiagramUIModel; +import com.vp.plugin.diagram.shape.IClassUIModel; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import java.util.stream.Stream; + +public class IClassDiagramLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(Diagram fromDiagram, boolean shouldOverride, boolean shouldAutoLayout) { + if (!shouldOverride && vpDiagramExists(fromDiagram)) return; + + IClassDiagramUIModel toDiagram = createIDiagram(fromDiagram); + transferDiagramProperties(fromDiagram, toDiagram); + + fromDiagram + .getAllClassViews() + .forEach(fromClassView -> IClassUIModelLoader.load(toDiagram, fromClassView)); + + fromDiagram + .getAllPackageViews() + .forEach(fromView -> IPackageUIModelLoader.load(toDiagram, fromView)); + + fromDiagram.getAllRelationViews().stream() + .filter(view -> view.getModelElement() != null) + .filter(view -> view.getModelElement().holdsBetweenClasses()) + .forEach(fromRelationView -> IAssociationUIModelLoader.load(toDiagram, fromRelationView)); + + fromDiagram.getAllRelationViews().stream() + .filter(view -> view.getModelElement() != null) + .filter(view -> !view.getModelElement().holdsBetweenClasses()) + .forEach(fromRelationView -> IAssociationUIModelLoader.load(toDiagram, fromRelationView)); + + fromDiagram + .getAllGeneralizationViews() + .forEach(fromGenView -> IGeneralizationUIModelLoader.load(toDiagram, fromGenView)); + + fromDiagram + .getAllGeneralizationSetViews() + .forEach(fromGsView -> IGeneralizationSetUIModelLoader.load(toDiagram, fromGsView)); + + // For information about auto layout for VP diagrams see the JavaDoc at + // https://www.visual-paradigm.com/support/documents/pluginjavadoc/index.html?com/vp/plugin/diagram/LayoutOption.html + // For custom options, I could not make the guide below work so far + // https://knowhow.visual-paradigm.com/openapi/layout-diagram/ + if (shouldAutoLayout) { + Stream.of(toDiagram.toDiagramElementArray()) + .filter(IClassUIModel.class::isInstance) + .map(IClassUIModel.class::cast) + .forEach(ele -> ele.fitSize()); + diagramManager.layout(toDiagram, DiagramManager.LAYOUT_ORTHOGONAL); + } + } + + private static void transferDiagramProperties(Diagram fromDiagram, IDiagramUIModel toDiagram) { + String fromOwnerId = fromDiagram.getOwner().getId(); + IModelElement toOwner = vpProject.getModelElementById(fromOwnerId); + + if (toOwner != null) toOwner.addSubDiagram(toDiagram); + + String name = fromDiagram.getFirstName().orElse("Unnamed diagram"); + toDiagram.setName(name); + } + + private static IClassDiagramUIModel createIDiagram(Diagram fromDiagram) { + IDiagramUIModel vpDiagram = vpProject.getDiagramById(fromDiagram.getId()); + + if (vpDiagram != null) { + System.out.println("Diagram " + fromDiagram.getId() + " exists! Let's override it!"); + vpDiagram.delete(); + } else { + System.out.println("Diagram " + fromDiagram.getId() + " not found! Let's create it"); + } + + IClassDiagramUIModel toDiagram = + (IClassDiagramUIModel) + diagramManager.createDiagram(DiagramManager.DIAGRAM_TYPE_CLASS_DIAGRAM); + fromDiagram.setId(toDiagram.getId()); + + return toDiagram; + } + + private static boolean vpDiagramExists(Diagram fromDiagram) { + return vpProject.getDiagramById(fromDiagram.getId()) != null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassLoader.java new file mode 100644 index 00000000..c7dcb0d3 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassLoader.java @@ -0,0 +1,71 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; +import static it.unibz.inf.ontouml.vp.model.uml.Class.*; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.*; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.utils.StereotypesManager; +import java.util.stream.Collectors; + +public class IClassLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IClass importElement(Class fromClass) { + + logElementCreation(fromClass); + + IClass toClass = getOrCreateClass(fromClass); + fromClass.setId(toClass.getId()); + + String name = fromClass.getFirstName().orElse("Unnamed Class"); + toClass.setName(name); + + boolean isAbstract = fromClass.isAbstract(); + toClass.setAbstract(isAbstract); + + boolean isDerived = fromClass.isDerived(); + setDerived(toClass, isDerived); + + fromClass.isExtensional().ifPresent(aBoolean -> setIsExtensional(toClass, aBoolean)); + fromClass.isPowertype().ifPresent(aBoolean -> setIsPowertype(toClass, aBoolean)); + fromClass.getOrder().ifPresent(anInteger -> setOrder(toClass, anInteger.toString())); + + String restrictedTo = getRestrictedToString(fromClass); + setRestrictedTo(toClass, restrictedTo); + + fromClass + .getStereotype() + .ifPresent(stereotype -> StereotypesManager.applyStereotype(toClass, stereotype)); + + ITaggedValueLoader.loadTaggedValues(fromClass, toClass); + + return toClass; + } + + private static void setDerived(IClass clazz, boolean isDerived) { + if (isDerived) clazz.setName("/" + clazz.getName()); + } + + private static String getRestrictedToString(Class clazz) { + return clazz.getRestrictedTo().stream() + .map(nature -> nature.name) + .collect(Collectors.joining(" ")); + } + + private static IClass getOrCreateClass(Class fromClass) { + IModelElement toClass = vpProject.getModelElementById(fromClass.getId()); + + if (toClass instanceof IClass) { + System.out.println("Class " + fromClass.getId() + " exists! Let's update it!"); + } else { + System.out.println("Class " + fromClass.getId() + " not found! Let's create it"); + toClass = IModelElementFactory.instance().createClass(); + } + + return (IClass) toClass; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassUIModelLoader.java new file mode 100644 index 00000000..b36eaa15 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IClassUIModelLoader.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIModelElement; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.shape.IClassUIModel; +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; + +public class IClassUIModelLoader { + + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(IClassDiagramUIModel toDiagram, ClassView fromView) { + IModelElement toModelElement = getIModelElement(fromView); + + if (!(toModelElement instanceof IClass) && !(toModelElement instanceof IDataType)) { + System.out.println( + LoaderUtils.getIncompatibleMessage(fromView, toModelElement, IClass.class)); + return; + } + + IClassUIModel toView = + (IClassUIModel) diagramManager.createDiagramElement(toDiagram, toModelElement); + fromView.setId(toView.getId()); + + toView.resetCaption(); + + toView.setX(fromView.getX()); + toView.setY(fromView.getY()); + toView.setWidth(fromView.getWidth()); + toView.setHeight(fromView.getHeight()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IConnectorUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IConnectorUIModelLoader.java new file mode 100644 index 00000000..4bc3bf6e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IConnectorUIModelLoader.java @@ -0,0 +1,13 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import it.unibz.inf.ontouml.vp.model.ontouml.view.ConnectorView; +import java.awt.*; + +public class IConnectorUIModelLoader { + + public static Point[] loadPoints(ConnectorView fromView) { + return fromView.getPath().getPoints().stream() + .map(p -> new Point((int) p.getX(), (int) p.getY())) + .toArray(Point[]::new); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IDataTypeLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IDataTypeLoader.java new file mode 100644 index 00000000..83e4f587 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IDataTypeLoader.java @@ -0,0 +1,67 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.IDataType; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import java.util.Optional; + +public class IDataTypeLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IDataType importElement(Class fromPrimitive) { + logElementCreation(fromPrimitive); + + IDataType toPrimitive = getOrCreateDataType(fromPrimitive); + fromPrimitive.setId(toPrimitive.getId()); + + loadName(fromPrimitive, toPrimitive); + + return toPrimitive; + } + + private static IDataType getOrCreateDataType(Class fromClass) { + IModelElement toDatatype = vpProject.getModelElementById(fromClass.getId()); + + if (toDatatype instanceof IDataType) { + System.out.println( + "Datatype " + + fromClass.getFirstName().orElse("") + + " (" + + fromClass.getId() + + ") exists. Let's update it!"); + } else { + + Optional toPrimitiveDatatype = + LoaderUtils.getAllDatatypes().stream() + .filter(d -> d.getName().equals(fromClass.getFirstName().orElse(""))) + .findFirst(); + + if (toPrimitiveDatatype.isEmpty()) { + toDatatype = IModelElementFactory.instance().createDataType(); + System.out.println( + "Datatype " + + fromClass.getFirstName().orElse("") + + " (" + + fromClass.getId() + + ") not found. Let's create it!"); + } else { + toDatatype = toPrimitiveDatatype.get(); + System.out.println( + "Datatype " + + fromClass.getFirstName().orElse("") + + " (" + + fromClass.getId() + + ") exists. Let's update it!"); + } + } + + return (IDataType) toDatatype; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IEnumerationLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IEnumerationLoader.java new file mode 100644 index 00000000..69582bcb --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IEnumerationLoader.java @@ -0,0 +1,28 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getToClass; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; + +import com.vp.plugin.model.IClass; +import com.vp.plugin.model.IEnumerationLiteral; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; + +public class IEnumerationLoader { + + public static void importLiterals(Class fromClass) { + if (!fromClass.isEnumeration()) return; + + IClass toClass = getToClass(fromClass); + + if (toClass == null) return; + + fromClass.getLiterals().forEach(l -> importLiteral(toClass, l)); + } + + public static void importLiteral(IClass toClass, Literal fromLiteral) { + IEnumerationLiteral toLiteral = toClass.createEnumerationLiteral(); + loadName(fromLiteral, toLiteral); + ITaggedValueLoader.loadTaggedValues(fromLiteral, toLiteral); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationLoader.java new file mode 100644 index 00000000..fc4fdb09 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationLoader.java @@ -0,0 +1,64 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.IGeneralization; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; + +public class IGeneralizationLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IGeneralization importElement(Generalization fromGeneralization) { + + logElementCreation(fromGeneralization); + + IGeneralization toGeneralization = getOrCreateGeneralization(fromGeneralization); + fromGeneralization.setId(toGeneralization.getId()); + + loadName(fromGeneralization, toGeneralization); + + loadGeneral(fromGeneralization, toGeneralization); + loadSpecific(fromGeneralization, toGeneralization); + + ITaggedValueLoader.loadTaggedValues(fromGeneralization, toGeneralization); + + return toGeneralization; + } + + private static void loadGeneral(Generalization fromGen, IGeneralization toGen) { + fromGen + .getGeneral() + .map(general -> general.getId()) + .map(id -> vpProject.getModelElementById(id)) + .ifPresent(general -> toGen.setFrom(general)); + } + + private static void loadSpecific(Generalization fromGen, IGeneralization toGen) { + fromGen + .getSpecific() + .map(specific -> specific.getId()) + .map(id -> vpProject.getModelElementById(id)) + .ifPresent(general -> toGen.setTo(general)); + } + + private static IGeneralization getOrCreateGeneralization(Generalization fromGeneralization) { + IModelElement toGeneralization = vpProject.getModelElementById(fromGeneralization.getId()); + + if (toGeneralization instanceof IGeneralization) { + System.out.println( + "Generalization " + fromGeneralization.getId() + " exists! Let's update it!"); + } else { + System.out.println( + "Generalization " + fromGeneralization.getId() + " not found! Let's create it"); + toGeneralization = IModelElementFactory.instance().createGeneralization(); + } + + return (IGeneralization) toGeneralization; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetLoader.java new file mode 100644 index 00000000..74b3e9a1 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetLoader.java @@ -0,0 +1,65 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.*; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; + +public class IGeneralizationSetLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IGeneralizationSet importElement(GeneralizationSet fromGs) { + + logElementCreation(fromGs); + + IGeneralizationSet toGs = getOrCreateGeneralizationSet(fromGs); + fromGs.setId(toGs.getId()); + + loadName(fromGs, toGs); + + toGs.setCovering(fromGs.isComplete()); + toGs.setDisjoint(fromGs.isDisjoint()); + + loadPowertype(fromGs, toGs); + loadGeneralizations(fromGs, toGs); + + ITaggedValueLoader.loadTaggedValues(fromGs, toGs); + + return toGs; + } + + private static void loadPowertype(GeneralizationSet fromGs, IGeneralizationSet toGs) { + fromGs + .getCategorizer() + .map(cat -> cat.getId()) + .map(id -> vpProject.getModelElementById(id)) + .filter(elem -> elem instanceof IClass) + .ifPresent(clazz -> toGs.setPowerType(clazz)); + } + + private static void loadGeneralizations(GeneralizationSet fromGs, IGeneralizationSet toGs) { + fromGs.getGeneralizations().stream() + .map(gen -> gen.getId()) + .map(id -> vpProject.getModelElementById(id)) + .filter(elem -> elem instanceof IGeneralization) + .map(elem -> (IGeneralization) elem) + .forEach(gen -> toGs.addGeneralization(gen)); + } + + private static IGeneralizationSet getOrCreateGeneralizationSet(GeneralizationSet fromGs) { + IModelElement toGs = vpProject.getModelElementById(fromGs.getId()); + + if (toGs instanceof IGeneralizationSet) { + System.out.println("GeneralizationSet " + fromGs.getId() + " exists! Let's update it!"); + } else { + System.out.println("GeneralizationSet " + fromGs.getId() + " not found! Let's create it"); + toGs = IModelElementFactory.instance().createGeneralizationSet(); + } + + return (IGeneralizationSet) toGs; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetUIModelLoader.java new file mode 100644 index 00000000..6e0565d0 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationSetUIModelLoader.java @@ -0,0 +1,39 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIModelElement; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.shape.IGeneralizationSetUIModel; +import com.vp.plugin.model.IGeneralizationSet; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationSetView; + +public class IGeneralizationSetUIModelLoader { + + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(IClassDiagramUIModel toDiagram, GeneralizationSetView fromView) { + IModelElement toModelElement = getIModelElement(fromView); + + if (!(toModelElement instanceof IGeneralizationSet)) { + System.out.println( + LoaderUtils.getIncompatibleMessage(fromView, toModelElement, IGeneralizationSet.class)); + return; + } + + IGeneralizationSetUIModel toView = + (IGeneralizationSetUIModel) diagramManager.createDiagramElement(toDiagram, toModelElement); + fromView.setId(toView.getId()); + + toView.setShowConstraints(true); + toView.setNotation(2); + toView.resetCaption(); + + toView.setX((int) fromView.getX()); + toView.setY((int) fromView.getY()); + toView.setWidth((int) fromView.getWidth()); + toView.setHeight((int) fromView.getHeight()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationUIModelLoader.java new file mode 100644 index 00000000..00e9c7c0 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IGeneralizationUIModelLoader.java @@ -0,0 +1,44 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIDiagramElement; +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIModelElement; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.connector.IGeneralizationUIModel; +import com.vp.plugin.diagram.shape.IClassUIModel; +import com.vp.plugin.model.IGeneralization; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; +import java.awt.*; + +public class IGeneralizationUIModelLoader { + + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(IClassDiagramUIModel toDiagram, GeneralizationView fromView) { + IModelElement toModelElement = getIModelElement(fromView); + + if (!(toModelElement instanceof IGeneralization)) { + System.out.println( + LoaderUtils.getIncompatibleMessage(fromView, toModelElement, IGeneralization.class)); + return; + } + + IClassUIModel vpSource = + getIDiagramElement(toDiagram, fromView.getSource(), IClassUIModel.class); + IClassUIModel vpTarget = + getIDiagramElement(toDiagram, fromView.getTarget(), IClassUIModel.class); + + Point[] points = IConnectorUIModelLoader.loadPoints(fromView); + + IGeneralizationUIModel toView = + (IGeneralizationUIModel) + diagramManager.createConnector(toDiagram, toModelElement, vpSource, vpTarget, points); + + fromView.setId(toView.getId()); + + toView.resetCaption(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageLoader.java new file mode 100644 index 00000000..a3ee0a41 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageLoader.java @@ -0,0 +1,39 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.logElementCreation; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.IHasChildrenBaseModelElement; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; + +public class IPackageLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static IHasChildrenBaseModelElement importElement(Package fromPackage) { + logElementCreation(fromPackage); + + IHasChildrenBaseModelElement toPackage = getOrCreatePackage(fromPackage); + fromPackage.setId(toPackage.getId()); + + ITaggedValueLoader.loadTaggedValues(fromPackage, toPackage); + + return toPackage; + } + + private static IHasChildrenBaseModelElement getOrCreatePackage(Package fromPackage) { + IModelElement toPackage = vpProject.getModelElementById(fromPackage.getId()); + + if (toPackage instanceof IHasChildrenBaseModelElement) { + System.out.println("Package " + fromPackage.getId() + " exists! Let's update it!"); + } else { + System.out.println("Package " + fromPackage.getId() + " not found! Let's create it"); + toPackage = IModelElementFactory.instance().createPackage(); + } + + return (IHasChildrenBaseModelElement) toPackage; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageUIModelLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageUIModelLoader.java new file mode 100644 index 00000000..3d97f52f --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IPackageUIModelLoader.java @@ -0,0 +1,36 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.getIModelElement; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.DiagramManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.IShapeUIModel; +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.view.PackageView; + +public class IPackageUIModelLoader { + + static DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager(); + + public static void load(IClassDiagramUIModel toDiagram, PackageView fromView) { + IModelElement toModelElement = getIModelElement(fromView); + + if (!(toModelElement instanceof IPackage) && !(toModelElement instanceof IModel)) { + System.out.println( + LoaderUtils.getIncompatibleMessage(fromView, toModelElement, IClass.class)); + return; + } + + IShapeUIModel toView = + (IShapeUIModel) diagramManager.createDiagramElement(toDiagram, toModelElement); + fromView.setId(toView.getId()); + + toView.resetCaption(); + + toView.setX(fromView.getX()); + toView.setY(fromView.getY()); + toView.setWidth(fromView.getWidth()); + toView.setHeight(fromView.getHeight()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IProjectLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IProjectLoader.java new file mode 100644 index 00000000..194d8091 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/IProjectLoader.java @@ -0,0 +1,105 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import static it.unibz.inf.ontouml.vp.model.ontouml2vp.LoaderUtils.loadName; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; + +public class IProjectLoader { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + public static void load( + Project project, boolean shouldOverrideDiagrams, boolean shouldAutoLayoutDiagrams) { + System.out.println("Loading model of project " + project.getId() + "..."); + importModel(project); + System.out.println("Model loaded!"); + System.out.println("Loading diagrams of project " + project.getId() + "..."); + project + .getDiagrams() + .forEach( + diagram -> + IClassDiagramLoader.load( + diagram, shouldOverrideDiagrams, shouldAutoLayoutDiagrams)); + System.out.println("Diagrams loaded!"); + } + + public static void importModel(Project fromProject) { + + fromProject.getAllPackages().stream() + .filter(pkg -> !pkg.isRoot()) + .forEach(pkg -> IPackageLoader.importElement(pkg)); + + fromProject.getAllClasses().stream() + .filter(c -> !c.isPrimitiveDatatype()) + .forEach(c -> IClassLoader.importElement(c)); + + fromProject.getAllPrimitiveDatatypes().forEach(d -> IDataTypeLoader.importElement(d)); + + // transform attributes + fromProject.getAllClasses().stream() + .filter(c -> c.hasAttributes()) + .forEach(c -> IAttributeLoader.importAttributes(c)); + + // transform literals + fromProject.getAllEnumerations().forEach(c -> IEnumerationLoader.importLiterals(c)); + + fromProject.getAllPackages().stream() + .filter(pkg -> !pkg.isRoot()) + .forEach(pkg -> transferContainerAndName(pkg)); + + fromProject.getAllClasses().forEach(pkg -> transferContainerAndName(pkg)); + + fromProject.getAllRelations().stream() + .filter(rel -> rel.holdsBetweenClasses()) + .forEach(rel -> System.out.println(rel)); + + // transform relations between classes + fromProject.getAllRelations().stream() + .filter(rel -> rel.holdsBetweenClasses()) + .forEach(rel -> IAssociationLoader.importElement(rel)); + + // transform relations between classes and relations + + // transform generalization + fromProject.getAllGeneralizations().forEach(gen -> IGeneralizationLoader.importElement(gen)); + + // transform generalization sets + fromProject + .getAllGeneralizationSets() + .forEach(gs -> IGeneralizationSetLoader.importElement(gs)); + } + + private static void transferContainerAndName(ModelElement fromElement) { + IModelElement toElement = vpProject.getModelElementById(fromElement.getId()); + + if (toElement == null) return; + + System.out.println( + "Transferring container and name of " + + fromElement.getType() + + " " + + fromElement.getFirstName().orElse(null) + + " (" + + fromElement.getId() + + ")"); + + fromElement + .getContainer() + .ifPresent( + container -> { + if ((container instanceof Package && !((Package) container).isRoot()) + || container instanceof Class) { + IModelElement toContainer = vpProject.getModelElementById(container.getId()); + toContainer.addChild(toElement); + } + }); + + loadName(fromElement, toElement); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/ITaggedValueLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/ITaggedValueLoader.java new file mode 100644 index 00000000..e7c84275 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/ITaggedValueLoader.java @@ -0,0 +1,26 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.ITaggedValue; +import com.vp.plugin.model.ITaggedValueContainer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; + +public class ITaggedValueLoader { + + static void loadTaggedValues(ModelElement fromElement, IModelElement toModelElement) { + ITaggedValueContainer taggedValueContainer = toModelElement.getTaggedValues(); + + fromElement + .getPropertyAssignments() + .forEach( + (key, value) -> { + ITaggedValue taggedValue = taggedValueContainer.createTaggedValue(); + taggedValue.setName(key); + + if (value instanceof Integer) taggedValue.setValue((Integer) value); + else if (value instanceof Float) taggedValue.setValue((Float) value); + else if (value instanceof Boolean) taggedValue.setValue((Boolean) value); + else if (value instanceof String) taggedValue.setValue((String) value); + }); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/LoaderUtils.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/LoaderUtils.java new file mode 100644 index 00000000..928b9b08 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/LoaderUtils.java @@ -0,0 +1,86 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.model.IClass; +import com.vp.plugin.model.IDataType; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IProject; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LoaderUtils { + + static IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + + static IDiagramElement getIDiagramElement(IClassDiagramUIModel vpDiagram, ElementView view) { + String targetId = view.getId(); + return vpDiagram.getDiagramElementById(targetId); + } + + static T getIDiagramElement( + IClassDiagramUIModel vpDiagram, ElementView view, java.lang.Class vpType) { + String targetId = view.getId(); + return vpType.cast(vpDiagram.getDiagramElementById(targetId)); + } + + static IModelElement getIModelElement(ElementView view) { + IProject vpProject = ApplicationManager.instance().getProjectManager().getProject(); + String modelElementId = view.getModelElement().getId(); + return vpProject.getModelElementById(modelElementId); + } + + static String getIncompatibleMessage( + ElementView fromView, IModelElement toModelElement, java.lang.Class expected) { + return "Skipped " + + fromView.getType() + + ": " + + fromView.getId() + + ". Incompatible model element (expected: " + + expected.getSimpleName() + + "; actual: " + + (toModelElement != null ? toModelElement.getModelType() : null) + + ")"; + } + + static String getModelElementImportingMessage(OntoumlElement fromElement) { + return "Importing " + + fromElement.getType() + + ": " + + fromElement.getFirstName().orElse("") + + " (" + + fromElement.getId() + + ")"; + } + + static void logElementCreation(OntoumlElement element) { + System.out.println(getModelElementImportingMessage(element)); + } + + static List getAllDatatypes() { + return Stream.of( + vpProject.toAllLevelModelElementArray(IModelElementFactory.MODEL_TYPE_DATA_TYPE)) + .filter(IDataType.class::isInstance) + .map(IDataType.class::cast) + .collect(Collectors.toList()); + } + + static IClass getToClass(Class fromClass) { + IModelElement toClass = IAttributeLoader.vpProject.getModelElementById(fromClass.getId()); + + if (toClass instanceof IClass) return (IClass) toClass; + + return null; + } + + static void loadName(ModelElement fromElement, IModelElement toElement) { + fromElement.getFirstName().ifPresent(name -> toElement.setName(name)); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/Ontouml2UmlLoader.java b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/Ontouml2UmlLoader.java new file mode 100644 index 00000000..b7f9573b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/ontouml2vp/Ontouml2UmlLoader.java @@ -0,0 +1,20 @@ +package it.unibz.inf.ontouml.vp.model.ontouml2vp; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import java.io.IOException; + +public class Ontouml2UmlLoader { + public static void deserializeAndLoad( + String json, boolean shouldOverrideDiagrams, boolean shouldAutoLayoutDiagrams) + throws IOException { + System.out.println("Deserializing project..."); + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Project project = mapper.readValue(json, Project.class); + System.out.println("Project " + project.getId() + " deserialized!"); + System.out.println("Loading project " + project.getId() + " into Visual Paradigm..."); + IProjectLoader.load(project, shouldOverrideDiagrams, shouldAutoLayoutDiagrams); + System.out.println("Project " + project.getId() + " loaded!"); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Association.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Association.java index c8f21101..9b2c3b48 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Association.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Association.java @@ -8,8 +8,6 @@ import com.vp.plugin.model.IAssociation; import com.vp.plugin.model.IAssociationEnd; import com.vp.plugin.model.IClass; -import it.unibz.inf.ontouml.vp.model.AssociationModelDescription; -import it.unibz.inf.ontouml.vp.model.PropertyDescription; import it.unibz.inf.ontouml.vp.utils.Stereotype; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/AssociationModelDescription.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/AssociationModelDescription.java similarity index 97% rename from src/main/java/it/unibz/inf/ontouml/vp/model/AssociationModelDescription.java rename to src/main/java/it/unibz/inf/ontouml/vp/model/uml/AssociationModelDescription.java index 888fa6f3..245870f9 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/AssociationModelDescription.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/AssociationModelDescription.java @@ -1,4 +1,4 @@ -package it.unibz.inf.ontouml.vp.model; +package it.unibz.inf.ontouml.vp.model.uml; import com.vp.plugin.ApplicationManager; import com.vp.plugin.DiagramManager; @@ -7,8 +7,7 @@ import com.vp.plugin.diagram.connector.IAssociationUIModel; import com.vp.plugin.model.IAssociation; import com.vp.plugin.model.IModelElement; -import it.unibz.inf.ontouml.vp.model.uml.Association; -import java.awt.Point; +import java.awt.*; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Class.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Class.java index 42f86493..da5dd0f2 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Class.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Class.java @@ -6,28 +6,11 @@ import com.google.gson.JsonParser; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import com.vp.plugin.model.IAttribute; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IDataType; -import com.vp.plugin.model.IEnumerationLiteral; -import com.vp.plugin.model.IGeneralization; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.ISimpleRelationship; -import com.vp.plugin.model.ITaggedValue; -import com.vp.plugin.model.ITaggedValueContainer; +import com.vp.plugin.model.*; import it.unibz.inf.ontouml.vp.utils.RestrictedTo; import it.unibz.inf.ontouml.vp.utils.Stereotype; import it.unibz.inf.ontouml.vp.utils.StereotypesManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -453,7 +436,7 @@ public static void setRestrictedTo(IClass _class, String restrictions) { return; } - System.out.println("WILL TRY TO SET VALUE: " + restrictions); + System.out.println("Class '" + _class.getName() + "': Setting restrictedTo to " + restrictions); Iterator values = _class.getTaggedValues().taggedValueIterator(); @@ -473,7 +456,8 @@ public static void setRestrictedTo(IClass _class, String restrictions) { value.setValue(newRestrictions); } - System.out.println("NEW VALUE: " + value.getValueAsText()); + System.out.println( + "Class '" + _class.getName() + "': restrictedTo set to " + value.getValueAsText()); return; } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/GeneralizationSet.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/GeneralizationSet.java index 06fdd2d2..471a7ec8 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/GeneralizationSet.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/GeneralizationSet.java @@ -3,7 +3,9 @@ import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import com.vp.plugin.model.*; +import com.vp.plugin.model.IGeneralization; +import com.vp.plugin.model.IGeneralizationSet; +import com.vp.plugin.model.IModelElement; import java.util.ArrayList; import java.util.HashSet; import java.util.List; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Model.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Model.java index fb0cf77c..752bc5b7 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Model.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Model.java @@ -4,16 +4,7 @@ import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import com.vp.plugin.ApplicationManager; -import com.vp.plugin.model.IAssociation; -import com.vp.plugin.model.IAssociationClass; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IDataType; -import com.vp.plugin.model.IGeneralization; -import com.vp.plugin.model.IGeneralizationSet; -import com.vp.plugin.model.IModel; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IPackage; -import com.vp.plugin.model.IProject; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/ModelElement.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/ModelElement.java index 2f94735a..903bcb6c 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/ModelElement.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/ModelElement.java @@ -6,15 +6,7 @@ import com.vp.plugin.DiagramManager; import com.vp.plugin.diagram.IDiagramElement; import com.vp.plugin.diagram.IDiagramUIModel; -import com.vp.plugin.model.IAssociation; -import com.vp.plugin.model.IAssociationEnd; -import com.vp.plugin.model.IAttribute; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IMultiplicity; -import com.vp.plugin.model.IStereotype; -import com.vp.plugin.model.ITaggedValue; -import com.vp.plugin.model.ITaggedValueContainer; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import it.unibz.inf.ontouml.vp.utils.StereotypesManager; import java.util.Arrays; @@ -157,10 +149,8 @@ public static JsonObject transformPropertyAssignments(IModelElement sourceElemen ITaggedValue[] lTaggedValues = lContainer.toTaggedValueArray(); List ignoredClassValues = Arrays.asList( - new String[] { - StereotypesManager.PROPERTY_RESTRICTED_TO, StereotypesManager.PROPERTY_IS_EXTENSIONAL, - StereotypesManager.PROPERTY_IS_POWERTYPE, StereotypesManager.PROPERTY_ORDER - }); + StereotypesManager.PROPERTY_RESTRICTED_TO, StereotypesManager.PROPERTY_IS_EXTENSIONAL, + StereotypesManager.PROPERTY_IS_POWERTYPE, StereotypesManager.PROPERTY_ORDER); for (int i = 0; lTaggedValues != null && i < lTaggedValues.length; i++) { if (ignoredClassValues.contains(lTaggedValues[i].getName())) { @@ -308,7 +298,7 @@ public static boolean isOrdered(IModelElement element) { { final IAttribute attribute = (IAttribute) element; final IMultiplicity multiplicity = attribute.getMultiplicityDetail(); - return multiplicity != null ? multiplicity.isOrdered() : false; + return multiplicity != null && multiplicity.isOrdered(); } default: @@ -396,9 +386,8 @@ public static void setReadOnly(IModelElement element, boolean isReadOnly) { } } - @SuppressWarnings("unchecked") - public static void forEachSelectedElement( - T element, Consumer consumer) { + // TODO: CHECKME! + static void forEachSelectedElement(T element, Consumer consumer) { if (element == null) { return; } @@ -420,7 +409,7 @@ public static void forEachSelectedElement( selectedElement -> selectedElement != null && selectedElementType.equals(selectedElement.getModelType())) - .forEach((Consumer) consumer); + .forEach((Consumer) consumer); ; } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Property.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Property.java index c3b221e2..f881d088 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Property.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/Property.java @@ -3,16 +3,12 @@ import com.google.gson.JsonObject; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import com.vp.plugin.model.IAssociationClass; -import com.vp.plugin.model.IAssociationEnd; -import com.vp.plugin.model.IAttribute; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IMultiplicity; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.stream.Stream; /** * Implementation of ModelElement to handle IAtrribute and IAssociationEnd objects to be serialized @@ -290,7 +286,7 @@ public void setOrdered(boolean isOrdered) { } public void setOrdered(IMultiplicity multiplicity) { - this.isOrdered = (multiplicity != null) ? multiplicity.isOrdered() : false; + this.isOrdered = multiplicity != null && multiplicity.isOrdered(); } public boolean isReadOnly() { @@ -322,7 +318,7 @@ public void addStereotype(String name) { } public void removeStereotype(String name) { - if (this.stereotypes != null && this.stereotypes.contains(name)) { + if (this.stereotypes != null) { this.stereotypes.remove(name); } } @@ -352,7 +348,7 @@ public void addSubsettedProperty(Reference ref) { } public void removeSubsettedProperty(Reference ref) { - if (this.subsettedProperties != null && this.subsettedProperties.contains(ref)) { + if (this.subsettedProperties != null) { this.subsettedProperties.remove(ref); } } @@ -374,7 +370,7 @@ public void addRedefinedProperty(Reference ref) { } public void removeRedefinedProperty(Reference ref) { - if (this.redefinedProperties != null && this.redefinedProperties.contains(ref)) { + if (this.redefinedProperties != null) { this.redefinedProperties.remove(ref); } } @@ -424,32 +420,32 @@ public String getType() { } public static void removeRedefinedProperties(IAssociationEnd associationEnd) { - final IAssociationEnd[] redefinedProperties = associationEnd.toRedefinedPropertyArray(); - - for (int i = 0; redefinedProperties != null && i < redefinedProperties.length; i++) { - associationEnd.removeRedefinedProperty(redefinedProperties[i]); - } + Stream.of(associationEnd.toRedefinedPropertyArray()) + .forEach(redefined -> associationEnd.removeRedefinedProperty(redefined)); } public static void removeSubsettedProperties(IAssociationEnd associationEnd) { - final IAssociationEnd[] subsettedProperties = associationEnd.toSubsettedPropertyArray(); - - for (int i = 0; subsettedProperties != null && i < subsettedProperties.length; i++) { - associationEnd.removeSubsettedProperty(subsettedProperties[i]); - } + Stream.of(associationEnd.toSubsettedPropertyArray()) + .forEach(subsetted -> associationEnd.removeSubsettedProperty(subsetted)); } public static void addRedefinedProperties( - IAssociationEnd associationEnd, IAssociationEnd[] redefinedProperties) { - for (int i = 0; redefinedProperties != null && i < redefinedProperties.length; i++) { - associationEnd.addRedefinedProperty(redefinedProperties[i]); - } + IAssociationEnd associationEnd, IModelElement[] redefinedProperties) { + + if (redefinedProperties == null || associationEnd == null) return; + + Stream.of(redefinedProperties) + .filter(prop -> prop instanceof IAssociationEnd || prop instanceof IAttribute) + .forEach(prop -> associationEnd.addRedefinedProperty((IAssociationEnd) prop)); } public static void addSubsettedProperties( - IAssociationEnd associationEnd, IAssociationEnd[] subsettedProperties) { - for (int i = 0; subsettedProperties != null && i < subsettedProperties.length; i++) { - associationEnd.addSubsettedProperty(subsettedProperties[i]); - } + IAssociationEnd associationEnd, IModelElement[] subsettedProperties) { + + if (subsettedProperties == null || associationEnd == null) return; + + Stream.of(subsettedProperties) + .filter(prop -> prop instanceof IAssociationEnd || prop instanceof IAttribute) + .forEach(prop -> associationEnd.addSubsettedProperty((IAssociationEnd) prop)); } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/PropertyDescription.java b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/PropertyDescription.java similarity index 89% rename from src/main/java/it/unibz/inf/ontouml/vp/model/PropertyDescription.java rename to src/main/java/it/unibz/inf/ontouml/vp/model/uml/PropertyDescription.java index 1b84033c..b62816e5 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/model/PropertyDescription.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/uml/PropertyDescription.java @@ -1,10 +1,9 @@ -package it.unibz.inf.ontouml.vp.model; +package it.unibz.inf.ontouml.vp.model.uml; import com.vp.plugin.model.IAssociationEnd; +import com.vp.plugin.model.IModelElement; import com.vp.plugin.model.IMultiplicity; import com.vp.plugin.model.ITaggedValueContainer; -import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import it.unibz.inf.ontouml.vp.model.uml.Property; public class PropertyDescription { @@ -16,8 +15,8 @@ public class PropertyDescription { final String name; // must invert final IMultiplicity multiplicityDetail; // must invert final ITaggedValueContainer taggedValues; // I don't know - final IAssociationEnd[] redefinedProperties; // must invert - final IAssociationEnd[] subsettedProperties; // must invert + final IModelElement[] redefinedProperties; // must invert + final IModelElement[] subsettedProperties; // must invert public PropertyDescription(IAssociationEnd associationEnd) { this.associationEnd = associationEnd; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAdapter.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAdapter.java new file mode 100644 index 00000000..6f81ffe1 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAdapter.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.ITaggedValue; +import com.vp.plugin.model.ITaggedValueContainer; + +public interface IAdapter { + boolean isEmpty(); + + IModelElement get(); + + default Object getValueOfTaggedValue(String taggedValueName) { + IModelElement element = get(); + ITaggedValueContainer container = element.getTaggedValues(); + + if (container == null) { + return null; + } + + ITaggedValue taggedValue = container.getTaggedValueByName(taggedValueName); + return taggedValue != null ? taggedValue.getValue() : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassTransformer.java new file mode 100644 index 00000000..413cb243 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassTransformer.java @@ -0,0 +1,35 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IAssociationClass; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; + +public class IAssociationClassTransformer { + public static ModelElement transform(IModelElement sourceElement) { + if (!(sourceElement instanceof IAssociationClass)) return null; + + IAssociationClass source = (IAssociationClass) sourceElement; + + Classifier fromClassifier = createClassifierStub(source.getFrom()); + Classifier toClassifier = createClassifierStub(source.getTo()); + + Relation target = Relation.createDerivation(null, null, fromClassifier, toClassifier); + + IModelElementTransformer.transform(source, target); + ITaggedValueTransformer.transform(source, target); + IStereotypeTransformer.transform(source, target); + + target.setDerived(true); + target.setAbstract(false); + + return target; + } + + private static Classifier createClassifierStub(IModelElement classifier) { + OntoumlElement targetType = ReferenceTransformer.transformStub(classifier); + return targetType instanceof Classifier ? (Classifier) targetType : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassUIModelTransformer.java new file mode 100644 index 00000000..3d50d6aa --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationClassUIModelTransformer.java @@ -0,0 +1,21 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.connector.IAssociationClassUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; + +public class IAssociationClassUIModelTransformer { + + public static RelationView transform(IDiagramElement sourceElement) { + if (!(sourceElement instanceof IAssociationClassUIModel)) return null; + + IAssociationClassUIModel source = (IAssociationClassUIModel) sourceElement; + RelationView target = new RelationView(); + + IDiagramElementTransformer.transform(source, target, Relation.class); + IConnectorTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationTransformer.java new file mode 100644 index 00000000..b636be66 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationTransformer.java @@ -0,0 +1,48 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IAssociation; +import com.vp.plugin.model.IAssociationEnd; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import java.util.List; + +public class IAssociationTransformer { + public static ModelElement transform(IModelElement sourceElement) { + if (!(sourceElement instanceof IAssociation)) return null; + + IAssociation source = (IAssociation) sourceElement; + Relation target = new Relation(); + + IModelElementTransformer.transform(source, target); + ITaggedValueTransformer.transform(source, target); + IStereotypeTransformer.transform(source, target); + + boolean isDerived = isDerived(source); + target.setDerived(isDerived); + + boolean isAbstract = source.isAbstract(); + target.setAbstract(isAbstract); + + Property sourceEnd = IPropertyTransformer.transform(getSourceEnd(source)); + Property targetEnd = IPropertyTransformer.transform(getTargetEnd(source)); + target.setProperties(List.of(sourceEnd, targetEnd)); + + return target; + } + + private static IAssociationEnd getSourceEnd(IAssociation association) { + return (IAssociationEnd) association.getFromEnd(); + } + + private static IAssociationEnd getTargetEnd(IAssociation association) { + return (IAssociationEnd) association.getToEnd(); + } + + private static boolean isDerived(IAssociation association) { + return association.isDerived() + || getSourceEnd(association).isDerived() + || getTargetEnd(association).isDerived(); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationUIModelTransformer.java new file mode 100644 index 00000000..edbf92bc --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IAssociationUIModelTransformer.java @@ -0,0 +1,24 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.connector.IAssociationUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; + +public class IAssociationUIModelTransformer { + public static RelationView transform(IDiagramElement sourceElement) { + + if (!(sourceElement instanceof IAssociationUIModel)) return null; + + IAssociationUIModel source = (IAssociationUIModel) sourceElement; + RelationView target = new RelationView(); + + IDiagramElementTransformer.transform(source, target, Relation.class); + IConnectorTransformer.transform(source, target); + + // TODO: investigate if we can access the labels associated to the association (e.g. + // stereotype+name, multiplicities) + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassAdapter.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassAdapter.java new file mode 100644 index 00000000..9c11dd48 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassAdapter.java @@ -0,0 +1,113 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.utils.StereotypesManager; + +public class IClassAdapter implements IAdapter { + + private IClass clazz; + private IDataType datatype; + + public IClassAdapter(IModelElement element) { + if (element instanceof IClass) { + clazz = (IClass) element; + datatype = null; + } else if (element instanceof IDataType) { + clazz = null; + datatype = (IDataType) element; + } else { + throw new IllegalArgumentException( + "Input element must be an instance of IClass or IDataType."); + } + } + + public IClassAdapter(IClass clazz) { + this.clazz = clazz; + this.datatype = null; + } + + public IClassAdapter(IDataType datatype) { + this.clazz = null; + this.datatype = datatype; + } + + @Override + public boolean isEmpty() { + return clazz == null && datatype == null; + } + + @Override + public IModelElement get() { + if (isClass()) return clazz; + if (isDatatype()) return datatype; + return null; + } + + private boolean isClass() { + return clazz != null; + } + + private boolean isDatatype() { + return datatype != null; + } + + public boolean isDerived() { + IModelElement element = get(); + return element.getName() != null && element.getName().trim().startsWith("/"); + } + + public String getName() { + IModelElement element = get(); + + if (isDerived()) { + return element.getName().trim().substring(1); + } + + return element.getName(); + } + + public Boolean isExtensional() { + Object value = getValueOfTaggedValue(StereotypesManager.PROPERTY_IS_EXTENSIONAL); + return value instanceof String ? Boolean.parseBoolean((String) value) : null; + } + + public Boolean isPowertype() { + Object value = getValueOfTaggedValue(StereotypesManager.PROPERTY_IS_POWERTYPE); + return value instanceof String ? Boolean.parseBoolean((String) value) : null; + } + + public Integer getOrder() { + Object value = getValueOfTaggedValue(StereotypesManager.PROPERTY_ORDER); + + Integer order = null; + + try { + order = value instanceof String ? Integer.parseInt((String) value) : null; + } catch (NumberFormatException ignored) { + System.out.println("Order is is an integer!"); + } + + return order; + } + + public String[] getRestrictedTo() { + if (isDatatype()) return new String[] {"abstract"}; + + Object value = getValueOfTaggedValue(StereotypesManager.PROPERTY_RESTRICTED_TO); + return value instanceof String ? ((String) value).split(" ") : null; + } + + public boolean isAbstract() { + return isClass() && clazz.isAbstract(); + } + + public IEnumerationLiteral[] toEnumerationLiteralArray() { + if (isClass()) return clazz.toEnumerationLiteralArray(); + return new IEnumerationLiteral[0]; + } + + public IAttribute[] toAttributeArray() { + if (isClass()) return clazz.toAttributeArray(); + return new IAttribute[0]; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassDiagramTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassDiagramTransformer.java new file mode 100644 index 00000000..b8b9cf3a --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassDiagramTransformer.java @@ -0,0 +1,77 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.IDiagramUIModel; +import com.vp.plugin.diagram.connector.IAssociationClassUIModel; +import com.vp.plugin.diagram.connector.IAssociationUIModel; +import com.vp.plugin.diagram.connector.IGeneralizationUIModel; +import com.vp.plugin.diagram.shape.IClassUIModel; +import com.vp.plugin.diagram.shape.IGeneralizationSetUIModel; +import com.vp.plugin.diagram.shape.IModelUIModel; +import com.vp.plugin.diagram.shape.IPackageUIModel; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import java.util.Arrays; + +public class IClassDiagramTransformer { + + public static Diagram transform(IDiagramUIModel sourceElement, Package root) { + if (!(sourceElement instanceof IClassDiagramUIModel)) return null; + + IClassDiagramUIModel source = (IClassDiagramUIModel) sourceElement; + + Diagram target = new Diagram(); + + String id = source.getId(); + target.setId(id); + + String name = source.getName(); + target.addName(name); + + String description = source.getDocumentation(); + target.addDescription(description); + + ModelElement owner = getOwner(source, root); + target.setOwner(owner); + + Arrays.stream(source.toDiagramElementArray()) + .map(e -> transfromIDiagramElement(e)) + .forEach(e -> target.addElement(e)); + + return target; + } + + private static ModelElement getOwner(IClassDiagramUIModel source, Package root) { + IModelElement owner = source.getParentModel(); + + if (owner == null) return root; + + return ReferenceTransformer.transformStub(owner); + } + + public static ElementView transfromIDiagramElement(IDiagramElement source) { + ElementView target = null; + + if (source instanceof IClassUIModel) { + target = IClassUIModelTransformer.transform(source); + } else if (source instanceof IAssociationUIModel) { + target = IAssociationUIModelTransformer.transform(source); + } else if (source instanceof IAssociationClassUIModel) { + target = IAssociationClassUIModelTransformer.transform(source); + } else if (source instanceof IGeneralizationUIModel) { + target = IGeneralizationUIModelTransformer.transform(source); + } else if (source instanceof IGeneralizationSetUIModel) { + target = IGeneralizationSetUIModelTransformer.transform(source); + } else if (source instanceof IPackageUIModel || source instanceof IModelUIModel) { + target = IPackageUIModelTransformer.transform(source); + } + + Trace.getInstance().put(source.getId(), source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassTransformer.java new file mode 100644 index 00000000..218fdcaa --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassTransformer.java @@ -0,0 +1,76 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IClass; +import com.vp.plugin.model.IDataType; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class IClassTransformer { + private static final List VP_PRIMITIVE_DATATYPES = + List.of( + "boolean", "byte", "char", "double", "float", "int", "long", "short", "string", "void"); + + public static Class transform(IModelElement sourceElement) { + if (!(sourceElement instanceof IClass) && !(sourceElement instanceof IDataType)) { + return null; + } + + if (sourceElement instanceof IDataType) { + IDataType sourceDatatype = (IDataType) sourceElement; + // sourceDatatype. + } + + IClassAdapter source = new IClassAdapter(sourceElement); + Class target = new Class(); + + IModelElementTransformer.transform(source.get(), target); + ITaggedValueTransformer.transform(source.get(), target); + IStereotypeTransformer.transform(source.get(), target); + + String name = source.getName(); + target.addName(name); + + boolean isAbstract = source.isAbstract(); + target.setAbstract(isAbstract); + + boolean isDerived = source.isDerived(); + target.setDerived(isDerived); + + Boolean isExtensional = source.isExtensional(); + target.setExtensional(isExtensional); + + Boolean isPowertype = source.isPowertype(); + target.setPowertype(isPowertype); + + Integer order = source.getOrder(); + target.setOrder(order); + + String[] restrictedTo = source.getRestrictedTo(); + if (restrictedTo != null) target.setRestrictedTo(restrictedTo); + + List attributes = transformAttributes(source); + target.setAttributes(attributes); + + List literals = transformLiterals(source); + target.setLiterals(literals); + + return target; + } + + public static List transformLiterals(IClassAdapter clazz) { + return Stream.of(clazz.toEnumerationLiteralArray()) + .map(IEnumerationLiteralTransformer::transform) + .collect(Collectors.toList()); + } + + public static List transformAttributes(IClassAdapter clazz) { + return Stream.of(clazz.toAttributeArray()) + .map(IPropertyTransformer::transform) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassUIModelTransformer.java new file mode 100644 index 00000000..4ae8905d --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IClassUIModelTransformer.java @@ -0,0 +1,20 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.shape.IClassUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; + +public class IClassUIModelTransformer { + public static ClassView transform(IDiagramElement sourceElement) { + if (!(sourceElement instanceof IClassUIModel)) return null; + + IClassUIModel source = (IClassUIModel) sourceElement; + ClassView target = new ClassView(); + + IDiagramElementTransformer.transform(source, target, Class.class); + IShapeTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IConnectorTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IConnectorTransformer.java new file mode 100644 index 00000000..33201f1d --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IConnectorTransformer.java @@ -0,0 +1,34 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IConnectorUIModel; +import com.vp.plugin.diagram.IDiagramElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ConnectorView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import java.util.Arrays; + +public class IConnectorTransformer { + + public static void transform(IConnectorUIModel source, ConnectorView target) { + + Path path = new Path(); + path.setId(source.getId() + "_path"); + Arrays.stream(source.getPoints()) + .forEachOrdered(p -> path.moveTo((int) p.getX(), (int) p.getY())); + target.setPath(path); + + IDiagramElement connectorSource = null; + if (source.getFromShape() != null) connectorSource = source.getFromShape(); + else if (source.getFromConnector() != null) connectorSource = source.getFromConnector(); + + ElementView connectorSourceStub = ReferenceTransformer.transformStub(connectorSource); + target.setSource(connectorSourceStub); + + IDiagramElement connectorTarget = null; + if (source.getToShape() != null) connectorTarget = source.getToShape(); + else if (source.getToConnector() != null) connectorTarget = source.getToConnector(); + + ElementView connectorTargetStub = ReferenceTransformer.transformStub(connectorTarget); + target.setTarget(connectorTargetStub); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IDiagramElementTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IDiagramElementTransformer.java new file mode 100644 index 00000000..906b4bf5 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IDiagramElementTransformer.java @@ -0,0 +1,27 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ElementView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Shape; + +public class IDiagramElementTransformer { + + public static void transform( + IDiagramElement source, ElementView target, Class type) { + + String id = source.getId(); + target.setId(id); + + T modelElement = getModelElement(source, type); + target.setModelElement(modelElement); + } + + private static T getModelElement(IDiagramElement view, Class type) { + IModelElement modelElement = view.getModelElement(); + ModelElement stub = ReferenceTransformer.transformStub(modelElement); + + return (type.isInstance(stub) ? type.cast(stub) : null); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IEnumerationLiteralTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IEnumerationLiteralTransformer.java new file mode 100644 index 00000000..1da3e85a --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IEnumerationLiteralTransformer.java @@ -0,0 +1,19 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IEnumerationLiteral; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; + +public class IEnumerationLiteralTransformer { + + public static Literal transform(IEnumerationLiteral source) { + if (source == null) { + return null; + } + + Literal target = new Literal(); + IModelElementTransformer.transform(source, target); + ITaggedValueTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetTransformer.java new file mode 100644 index 00000000..e99f0016 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetTransformer.java @@ -0,0 +1,65 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IClass; +import com.vp.plugin.model.IGeneralization; +import com.vp.plugin.model.IGeneralizationSet; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class IGeneralizationSetTransformer { + + public static ModelElement transform(IModelElement sourceElement) { + if (!(sourceElement instanceof IGeneralizationSet)) { + return null; + } + + IGeneralizationSet source = (IGeneralizationSet) sourceElement; + GeneralizationSet target = new GeneralizationSet(); + + IModelElementTransformer.transform(source, target); + ITaggedValueTransformer.transform(source, target); + + boolean isDisjoint = source.isDisjoint(); + target.setDisjoint(isDisjoint); + + boolean isComplete = source.isCovering(); + target.setComplete(isComplete); + + Class categorizer = transformCategorizer(source); + target.setCategorizer(categorizer); + + List generalizations = transformGeneralizations(source); + target.setGeneralizations(generalizations); + + return target; + } + + public static Class transformCategorizer(IGeneralizationSet genSet) { + IModelElement powertype = genSet.getPowerType(); + + if (!(powertype instanceof IClass)) { + return null; + } + + return (Class) ReferenceTransformer.transformStub(powertype); + } + + public static List transformGeneralizations(IGeneralizationSet genSet) { + IGeneralization[] generalizations = genSet.toGeneralizationArray(); + + if (generalizations == null) { + return new ArrayList<>(); + } + + return Stream.of(generalizations) + .map(g -> (Generalization) ReferenceTransformer.transformStub(g)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetUIModelTransformer.java new file mode 100644 index 00000000..014474f7 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationSetUIModelTransformer.java @@ -0,0 +1,21 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.shape.IGeneralizationSetUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationSetView; + +public class IGeneralizationSetUIModelTransformer { + + public static GeneralizationSetView transform(IDiagramElement sourceElement) { + if (!(sourceElement instanceof IGeneralizationSetUIModel)) return null; + + IGeneralizationSetUIModel source = (IGeneralizationSetUIModel) sourceElement; + GeneralizationSetView target = new GeneralizationSetView(); + + IDiagramElementTransformer.transform(source, target, GeneralizationSet.class); + IShapeTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationTransformer.java new file mode 100644 index 00000000..fbaabb9e --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationTransformer.java @@ -0,0 +1,43 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IGeneralization; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; + +public class IGeneralizationTransformer { + + public static Generalization transform(IModelElement sourceElement) { + if (!(sourceElement instanceof IGeneralization)) return null; + + IGeneralization source = (IGeneralization) sourceElement; + Generalization target = new Generalization(); + + IModelElementTransformer.transform(source, target); + ITaggedValueTransformer.transform(source, target); + + Classifier general = transformGeneral(source); + target.setGeneral(general); + + Classifier specific = transformSpecific(source); + target.setSpecific(specific); + + return target; + } + + public static Classifier transformGeneral(IGeneralization generalization) { + IModelElement general = generalization.getFrom(); + return (general != null) ? createClassifierStub(general) : null; + } + + public static Classifier transformSpecific(IGeneralization generalization) { + IModelElement specific = generalization.getTo(); + return (specific != null) ? createClassifierStub(specific) : null; + } + + private static Classifier createClassifierStub(IModelElement classifier) { + OntoumlElement targetType = ReferenceTransformer.transformStub(classifier); + return targetType instanceof Classifier ? (Classifier) targetType : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationUIModelTransformer.java new file mode 100644 index 00000000..666d0d62 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IGeneralizationUIModelTransformer.java @@ -0,0 +1,20 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.connector.IGeneralizationUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; + +public class IGeneralizationUIModelTransformer { + public static GeneralizationView transform(IDiagramElement sourceElement) { + if (!(sourceElement instanceof IGeneralizationUIModel)) return null; + + IGeneralizationUIModel source = (IGeneralizationUIModel) sourceElement; + GeneralizationView target = new GeneralizationView(); + + IDiagramElementTransformer.transform(source, target, Generalization.class); + IConnectorTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IModelElementTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IModelElementTransformer.java new file mode 100644 index 00000000..b6900376 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IModelElementTransformer.java @@ -0,0 +1,18 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.Element; + +public class IModelElementTransformer { + + public static void transform(IModelElement source, Element target) { + String id = source.getId(); + target.setId(id); + + String name = source.getName(); + target.addName(name); + + String description = source.getDescription(); + target.addDescription(description.isEmpty() ? null : description); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageTransformer.java new file mode 100644 index 00000000..ba883f5b --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageTransformer.java @@ -0,0 +1,21 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IModel; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IPackage; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; + +public class IPackageTransformer { + + public static ModelElement transform(IModelElement sourceElement) { + + if (!(sourceElement instanceof IPackage) && !(sourceElement instanceof IModel)) return null; + + Package target = new Package(); + IModelElementTransformer.transform(sourceElement, target); + ITaggedValueTransformer.transform(sourceElement, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageUIModelTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageUIModelTransformer.java new file mode 100644 index 00000000..1dc645c0 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPackageUIModelTransformer.java @@ -0,0 +1,23 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.shape.IBasePackageUIModel; +import com.vp.plugin.diagram.shape.IModelUIModel; +import com.vp.plugin.diagram.shape.IPackageUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.PackageView; + +public class IPackageUIModelTransformer { + public static PackageView transform(IDiagramElement sourceElement) { + if (!(sourceElement instanceof IPackageUIModel) && !(sourceElement instanceof IModelUIModel)) + return null; + + IBasePackageUIModel source = (IBasePackageUIModel) sourceElement; + PackageView target = new PackageView(); + + IDiagramElementTransformer.transform(source, target, Package.class); + IShapeTransformer.transform(source, target); + + return target; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IProjectTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IProjectTransformer.java new file mode 100644 index 00000000..f7ee15af --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IProjectTransformer.java @@ -0,0 +1,151 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import static it.unibz.inf.ontouml.vp.model.ontouml.deserialization.ReferenceResolver.resolveReferences; + +import com.vp.plugin.diagram.IClassDiagramUIModel; +import com.vp.plugin.model.*; +import com.vp.plugin.model.factory.IModelElementFactory; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class IProjectTransformer { + + public static Project transform(IProject sourceProject) { + Project targetProject = new Project(); + Trace.getInstance().put(sourceProject.getId(), sourceProject, targetProject); + + String name = sourceProject.getName(); + targetProject.addName(sourceProject.getName()); + + String id = sourceProject.getId(); + targetProject.setId(id); + + Package root = targetProject.createModel(id + "_root", name); + + List targetElements = + getElementStream(sourceProject) + .map(element -> transformModelElement(element)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + List targetDatatypes = + getUsedDatatypes(sourceProject).stream() + .map(element -> transformModelElement(element)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + targetElements.addAll(targetDatatypes); + + targetElements.forEach(element -> resolveContainer(element, root)); + resolveReferences(targetProject); + + List diagrams = transformDiagrams(sourceProject, root); + targetProject.setDiagrams(diagrams); + + return targetProject; + } + + private static List transformDiagrams(IProject source, Package root) { + return Stream.of(source.toDiagramArray()) + .filter(IClassDiagramUIModel.class::isInstance) + .map(diag -> IClassDiagramTransformer.transform(diag, root)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private static Stream getElementStream(IProject source) { + final String[] elementTypes = { + IModelElementFactory.MODEL_TYPE_PACKAGE, + IModelElementFactory.MODEL_TYPE_MODEL, + IModelElementFactory.MODEL_TYPE_CLASS, + IModelElementFactory.MODEL_TYPE_GENERALIZATION, + IModelElementFactory.MODEL_TYPE_GENERALIZATION_SET, + IModelElementFactory.MODEL_TYPE_ASSOCIATION, + IModelElementFactory.MODEL_TYPE_ASSOCIATION_CLASS, + }; + + IModelElement[] sourceContents = source.toAllLevelModelElementArray(elementTypes); + return Stream.of(sourceContents); + } + + private static void resolveContainer(ModelElement targetElement, Package root) { + Package targetContainer = getContainer(targetElement, root); + targetContainer.addContent(targetElement); + } + + private static Package getContainer(ModelElement targetElement, Package root) { + Object sourceElement = Trace.getInstance().getSource(targetElement.getId()); + IModelElement sourceParent = getSourceParent(sourceElement); + + if (sourceParent == null) { + return root; + } + + OntoumlElement targetParent = Trace.getInstance().getTarget(sourceParent); + return (targetParent instanceof Package) ? (Package) targetParent : root; + } + + private static IModelElement getSourceParent(Object element) { + // VP puts an association, associationclass and generalization inside the package of its source + if (element instanceof IRelationship) { + IModelElement from = ((IRelationship) element).getFrom(); + return from != null ? from.getParent() : null; + } + + if (element instanceof IModelElement) { + return ((IModelElement) element).getParent(); + } + + return null; + } + + public static ModelElement transformModelElement(IModelElement source) { + ModelElement target = null; + + if (source instanceof IClass || source instanceof IDataType) { + target = IClassTransformer.transform(source); + } else if (source instanceof IAssociation) { + target = IAssociationTransformer.transform(source); + } else if (source instanceof IAssociationClass) { + target = IAssociationClassTransformer.transform(source); + } else if (source instanceof IPackage || source instanceof IModel) { + target = IPackageTransformer.transform(source); + } else if (source instanceof IAttribute || source instanceof IAssociationEnd) { + target = IPropertyTransformer.transform(source); + } else if (source instanceof IGeneralization) { + target = IGeneralizationTransformer.transform(source); + } else if (source instanceof IGeneralizationSet) { + target = IGeneralizationSetTransformer.transform(source); + } + + Trace.getInstance().put(source.getId(), source, target); + + return target; + } + + public static List getAllAttributes(IProject project) { + IModelElement[] classes = + project.toAllLevelModelElementArray(IModelElementFactory.MODEL_TYPE_CLASS); + + return Stream.of(classes) + .map(IClass.class::cast) + .flatMap(clazz -> Stream.of(clazz.toAttributeArray())) + .collect(Collectors.toList()); + } + + public static Set getUsedDatatypes(IProject project) { + return getAllAttributes(project).stream() + .map(attr -> attr.getType()) + .filter(IDataType.class::isInstance) + .map(IDataType.class::cast) + .collect(Collectors.toSet()); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyAdapter.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyAdapter.java new file mode 100644 index 00000000..07747221 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyAdapter.java @@ -0,0 +1,111 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IAssociationEnd; +import com.vp.plugin.model.IAttribute; +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.IMultiplicity; +import java.util.Iterator; + +public class IPropertyAdapter implements IAdapter { + + IAttribute attribute; + IAssociationEnd associationEnd; + + public IPropertyAdapter(IAttribute attribute) { + this.attribute = attribute; + } + + public IPropertyAdapter(IAssociationEnd associationEnd) { + this.associationEnd = associationEnd; + } + + @Override + public boolean isEmpty() { + return attribute == null && associationEnd == null; + } + + @Override + public IModelElement get() { + if (isAttribute()) return attribute; + if (isAssociationEnd()) return associationEnd; + return null; + } + + public boolean isAttribute() { + return attribute != null; + } + + public boolean isAssociationEnd() { + return associationEnd != null; + } + + public IMultiplicity getMultiplicityDetail() { + return isAttribute() + ? attribute.getMultiplicityDetail() + : associationEnd.getMultiplicityDetail(); + } + + public boolean isOrdered() { + IMultiplicity multiplicity = getMultiplicityDetail(); + return multiplicity != null && multiplicity.isOrdered(); + } + + public boolean isReadOnly() { + if (isAttribute()) return attribute.isReadOnly(); + if (isAssociationEnd()) return associationEnd.isReadOnly(); + return false; + } + + public boolean isDerived() { + if (isAttribute()) return attribute.isDerived(); + if (isAssociationEnd()) return associationEnd.isDerived(); + return false; + } + + public String getMultiplicity() { + String multiplicity = null; + if (isAttribute()) multiplicity = attribute.getMultiplicity(); + if (isAssociationEnd()) multiplicity = associationEnd.getMultiplicity(); + + return "Unspecified".equals(multiplicity) ? null : multiplicity; + } + + public String getAggregationKind() { + if (isAttribute()) { + int value = attribute.getAggregation(); + switch (value) { + case 0: + return "NONE"; + case 1: + return "SHARED"; + case 2: + return "COMPOSITE"; + } + } + + if (isAssociationEnd()) { + return associationEnd.getAggregationKind(); + } + + return null; + } + + public IModelElement getTypeAsElement() { + if (isAttribute()) return attribute.getTypeAsElement(); + if (isAssociationEnd()) return associationEnd.getTypeAsElement(); + + return null; + } + + public Iterator subsettedPropertyIterator() { + if (isAttribute()) return attribute.subsettedPropertyIterator(); + if (isAssociationEnd()) return associationEnd.subsettedPropertyIterator(); + return null; + } + + public Iterator redefinedPropertyIterator() { + if (isAttribute()) return attribute.redefinedPropertyIterator(); + if (isAssociationEnd()) return associationEnd.redefinedPropertyIterator(); + return null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyTransformer.java new file mode 100644 index 00000000..fde15e6a --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IPropertyTransformer.java @@ -0,0 +1,110 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IAssociationEnd; +import com.vp.plugin.model.IAttribute; +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import it.unibz.inf.ontouml.vp.model.ontouml.model.AggregationKind; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class IPropertyTransformer { + + public static Property transform(IModelElement source) { + if (source instanceof IAttribute) { + return transform(new IPropertyAdapter((IAttribute) source)); + } + + if (source instanceof IAssociationEnd) { + return transform(new IPropertyAdapter((IAssociationEnd) source)); + } + + return null; + } + + public static Property transform(IPropertyAdapter source) { + if (source.isEmpty()) { + return null; + } + + Property target = new Property(); + + IModelElementTransformer.transform(source.get(), target); + ITaggedValueTransformer.transform(source.get(), target); + IStereotypeTransformer.transform(source.get(), target); + + boolean isDerived = source.isDerived(); + target.setDerived(isDerived); + + boolean isReadOnly = source.isReadOnly(); + target.setReadOnly(isReadOnly); + + boolean isOrdered = source.isOrdered(); + target.setOrdered(isOrdered); + + String cardinality = source.getMultiplicity(); + target.setCardinality(cardinality); + + AggregationKind aggregationKind = transformAggregationKind(source); + target.setAggregationKind(aggregationKind); + + Classifier propertyType = transformPropertyType(source); + target.setPropertyType(propertyType); + + List subsetted = transformSubsettedProperties(source); + target.setSubsettedProperties(subsetted); + + List redefined = transformRedefinedProperties(source); + target.setRedefinedProperties(redefined); + + return target; + } + + private static AggregationKind transformAggregationKind(IPropertyAdapter property) { + return AggregationKind.findByName(property.getAggregationKind()) + .orElseGet(() -> property.isAssociationEnd() ? AggregationKind.NONE : null); + } + + private static Classifier transformPropertyType(IPropertyAdapter property) { + IModelElement sourcePropertyType = property.getTypeAsElement(); + + if (sourcePropertyType == null) { + return null; + } + + OntoumlElement targetType = ReferenceTransformer.transformStub(sourcePropertyType); + return targetType instanceof Classifier ? (Classifier) targetType : null; + } + + private static List transformSubsettedProperties(IPropertyAdapter property) { + return transformProperties(property.subsettedPropertyIterator()); + } + + private static List transformRedefinedProperties(IPropertyAdapter property) { + return transformProperties(property.redefinedPropertyIterator()); + } + + private static List transformProperties(Iterator iterator) { + List targetProperties = new ArrayList<>(); + + while (iterator.hasNext()) { + Object source = iterator.next(); + + if (!isProperty(source)) { + continue; + } + + OntoumlElement target = ReferenceTransformer.transformStub((IModelElement) source); + targetProperties.add((Property) target); + } + + return targetProperties; + } + + public static boolean isProperty(Object object) { + return object instanceof IAttribute || object instanceof IAssociationEnd; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IShapeTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IShapeTransformer.java new file mode 100644 index 00000000..abdb89ec --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IShapeTransformer.java @@ -0,0 +1,17 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IShapeUIModel; +import it.unibz.inf.ontouml.vp.model.ontouml.view.NodeView; + +public class IShapeTransformer { + + public static void transform(IShapeUIModel source, NodeView target) { + target.setX(source.getX()); + target.setY(source.getY()); + + target.setWidth(source.getWidth()); + target.setHeight(source.getHeight()); + + target.getShape().setId(source.getId() + "_shape"); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IStereotypeTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IStereotypeTransformer.java new file mode 100644 index 00000000..d3b13e36 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/IStereotypeTransformer.java @@ -0,0 +1,58 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Decoratable; + +public class IStereotypeTransformer { + + public static void transform(IModelElement source, Decoratable target) { + String stereotype = null; + + if (source instanceof IClass + || source instanceof IAssociationClass + || source instanceof IAssociation + || source instanceof IAttribute + || source instanceof IAssociationEnd) stereotype = getFirstStereotype(source); + + if (source instanceof IDataType) stereotype = "datatype"; + + // if (source instanceof IClass) { + // stereotype = getFirstStereotype((IClass) source); + // } else if (source instanceof IAssociationClass) { + // stereotype = getFirstStereotype((IAssociationClass) source); + // } else if (source instanceof IAssociation) { + // stereotype = getFirstStereotype((IAssociation) source); + // } else if (source instanceof IAttribute) { + // stereotype = getFirstStereotype((IAttribute) source); + // } else if (source instanceof IAssociationEnd) { + // stereotype = getFirstStereotype((IAttribute) source); + // } + + target.setStereotype(stereotype); + } + + public static String getFirstStereotype(IModelElement element) { + IStereotype[] stereotypes = element.toStereotypeModelArray(); + return (stereotypes != null && stereotypes.length > 0) ? stereotypes[0].getName() : null; + } + + public static String getFirstStereotype(IClass clazz) { + return getFirst(clazz.toStereotypeArray()); + } + + public static String getFirstStereotype(IAssociationClass clazz) { + return getFirst(clazz.toStereotypeArray()); + } + + public static String getFirstStereotype(IAssociation association) { + return getFirst(association.toStereotypeArray()); + } + + public static String getFirstStereotype(IAttribute attribute) { + return getFirst(attribute.toStereotypeArray()); + } + + private static String getFirst(String[] array) { + return (array.length > 0) ? array[0] : null; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ITaggedValueTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ITaggedValueTransformer.java new file mode 100644 index 00000000..45662dc4 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ITaggedValueTransformer.java @@ -0,0 +1,87 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IModelElement; +import com.vp.plugin.model.ITaggedValue; +import com.vp.plugin.model.ITaggedValueContainer; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ModelElement; +import it.unibz.inf.ontouml.vp.utils.StereotypesManager; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Map; + +public class ITaggedValueTransformer { + + public static void transform(IModelElement source, ModelElement target) { + Map map = ITaggedValueTransformer.createTaggedValueMap(source); + target.setPropertyAssignments(map); + } + + private static Map createTaggedValueMap(IModelElement sourceElement) { + ITaggedValueContainer taggedValueContainer = sourceElement.getTaggedValues(); + if (taggedValueContainer == null) { + return new HashMap<>(); + } + + Map propertyAssignments = new HashMap<>(); + for (ITaggedValue taggedValue : taggedValueContainer.toTaggedValueArray()) { + // Skips tagged values embedded in OntoUML stereotypes, + // namely isExtensional, isPowertype, order. + if (!isTaggedValueUserDefined(taggedValue)) { + continue; + } + + Map.Entry pair = transformTaggedValue(taggedValue); + propertyAssignments.put(pair.getKey(), pair.getValue()); + } + + return propertyAssignments; + } + + private static Map.Entry transformTaggedValue(ITaggedValue taggedValue) { + String key = taggedValue.getName(); + Object value = taggedValue.getValue(); + + if (value == null) { + return new AbstractMap.SimpleEntry<>(key, null); + } + + switch (taggedValue.getType()) { + case 1: + value = ReferenceTransformer.transformStub(taggedValue.getValueAsElement()); + break; + case 5: + value = safeGetIntegerValue(taggedValue); + break; + case 6: + value = safeGetFloatValue(taggedValue); + break; + case 7: + value = Boolean.parseBoolean((String) taggedValue.getValue()); + break; + default: + value = taggedValue.getValueAsString(); + } + + return new AbstractMap.SimpleEntry<>(key, value); + } + + private static boolean isTaggedValueUserDefined(ITaggedValue taggedValue) { + return !StereotypesManager.CLASS_TAGGED_VALUES.contains(taggedValue.getName()); + } + + private static Integer safeGetIntegerValue(ITaggedValue taggedValue) { + try { + return Integer.parseInt((String) taggedValue.getValue()); + } catch (Exception e) { + return null; + } + } + + private static Float safeGetFloatValue(ITaggedValue taggedValue) { + try { + return Float.parseFloat((String) taggedValue.getValue()); + } catch (Exception e) { + return null; + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ReferenceTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ReferenceTransformer.java new file mode 100644 index 00000000..cfeec819 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/ReferenceTransformer.java @@ -0,0 +1,64 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.diagram.IDiagramElement; +import com.vp.plugin.diagram.connector.IAssociationClassUIModel; +import com.vp.plugin.diagram.connector.IAssociationUIModel; +import com.vp.plugin.diagram.connector.IGeneralizationUIModel; +import com.vp.plugin.diagram.shape.IClassUIModel; +import com.vp.plugin.diagram.shape.IGeneralizationSetUIModel; +import com.vp.plugin.diagram.shape.IModelUIModel; +import com.vp.plugin.diagram.shape.IPackageUIModel; +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import it.unibz.inf.ontouml.vp.model.ontouml.view.*; + +public class ReferenceTransformer { + public static ModelElement transformStub(IModelElement source) { + ModelElement stub = null; + + if (source instanceof IClass || source instanceof IDataType) { + stub = new Class(); + } else if (source instanceof IAssociation || source instanceof IAssociationClass) { + stub = new Relation(); + } else if (source instanceof IPackage || source instanceof IModel) { + stub = new Package(); + } else if (source instanceof IAttribute || source instanceof IAssociationEnd) { + stub = new Property(); + } else if (source instanceof IGeneralization) { + stub = new Generalization(); + } else if (source instanceof IGeneralizationSet) { + stub = new GeneralizationSet(); + } + + if (stub != null) { + stub.setId(source.getId()); + } + + return stub; + } + + public static ElementView transformStub(IDiagramElement source) { + ElementView stub = null; + + if (source instanceof IClassUIModel) { + stub = new ClassView(); + } else if (source instanceof IAssociationUIModel + || source instanceof IAssociationClassUIModel) { + stub = new RelationView(); + } else if (source instanceof IPackageUIModel || source instanceof IModelUIModel) { + stub = new PackageView(); + } else if (source instanceof IGeneralizationUIModel) { + stub = new GeneralizationView(); + } else if (source instanceof IGeneralizationSetUIModel) { + stub = new GeneralizationSetView(); + } + + if (stub != null) { + stub.setId(source.getId()); + } + + return stub; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Trace.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Trace.java new file mode 100644 index 00000000..42cf1aa8 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Trace.java @@ -0,0 +1,84 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.vp.plugin.model.IModelElement; +import it.unibz.inf.ontouml.vp.model.ontouml.OntoumlElement; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +public class Trace { + + private static Trace instance = null; + + public Map map; + + private Trace() { + initialize(); + } + + public void initialize() { + map = new HashMap<>(); + } + + public void put(String id, Object source, OntoumlElement target) { + map.put(id, new Correspondence(source, target)); + } + + public Object getSource(String id) { + Correspondence correspondence = map.get(id); + return correspondence != null ? correspondence.getSource() : null; + } + + public Object getSource(OntoumlElement target) { + return target != null ? getSource(target.getId()) : null; + } + + public OntoumlElement getTarget(String id) { + Correspondence correspondence = map.get(id); + return correspondence != null ? correspondence.getTarget() : null; + } + + public OntoumlElement getTarget(IModelElement source) { + return source != null ? getTarget(source.getId()) : null; + } + + public static Trace getInstance() { + if (instance == null) instance = new Trace(); + + return instance; + } + + @Override + public String toString() { + return map.entrySet().stream() + .map( + x -> + x.getKey() + + ": Source: " + + x.getValue().getSource().hashCode() + + " - Target: " + + x.getValue().getTarget().getType() + + " " + + x.getValue().getTarget().getFirstName().orElse("Unnamed") + + "\n") + .collect(Collectors.joining()); + } + + private static class Correspondence { + Object source; + OntoumlElement target; + + public Correspondence(Object source, OntoumlElement target) { + this.source = source; + this.target = target; + } + + public Object getSource() { + return source; + } + + public OntoumlElement getTarget() { + return target; + } + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Uml2OntoumlTransformer.java b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Uml2OntoumlTransformer.java new file mode 100644 index 00000000..9c2586fb --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/model/vp2ontouml/Uml2OntoumlTransformer.java @@ -0,0 +1,18 @@ +package it.unibz.inf.ontouml.vp.model.vp2ontouml; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import java.io.IOException; + +public class Uml2OntoumlTransformer { + + public static String transformAndSerialize() throws IOException { + final IProject source = ApplicationManager.instance().getProjectManager().getProject(); + Project target = IProjectTransformer.transform(source); + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + return mapper.writeValueAsString(target); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/utils/SimpleServiceWorker.java b/src/main/java/it/unibz/inf/ontouml/vp/utils/SimpleServiceWorker.java new file mode 100644 index 00000000..fa9d4b39 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/utils/SimpleServiceWorker.java @@ -0,0 +1,66 @@ +package it.unibz.inf.ontouml.vp.utils; + +import it.unibz.inf.ontouml.vp.views.ProgressDialogHandler; +import java.util.List; +import java.util.function.Function; +import javax.swing.SwingWorker; + +public class SimpleServiceWorker extends SwingWorker, String> { + + private final Function> task; + private final ProgressDialogHandler dialogHandler; + private static final String REQUEST_CANCELLED_MESSAGE = "Request cancelled by the user."; + + /** + * Constructs a SimpleServiceWorker object for handling pop-ups on service requests that don't + * require user input. + * + * @param task - a lambda that receives as arguments the worker context and returns a list + * containing a single string for conclusion or cancellation messages . Firing dialogs for + * concluded action is automatically handled. + */ + public SimpleServiceWorker(Function> task) { + this.task = task; + dialogHandler = new ProgressDialogHandler(); + + dialogHandler.onCancel( + e -> { + System.out.println(REQUEST_CANCELLED_MESSAGE); + cancel(true); + }); + } + + @Override + protected void done() { + dialogHandler.closeDialog(); + + if (isCancelled()) { + ViewManagerUtils.log(REQUEST_CANCELLED_MESSAGE); + return; + } + + try { + if (!get().isEmpty()) { + String message = get().get(0); + ViewManagerUtils.simpleDialog(message); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + protected List doInBackground() { + dialogHandler.showDialog(); + List messages; + + try { + messages = task.apply(this); + } catch (Exception e) { + e.printStackTrace(); + return List.of("The service request could not be concluded due to an internal error."); + } + + return messages; + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/utils/SmartColoringUtils.java b/src/main/java/it/unibz/inf/ontouml/vp/utils/SmartColoringUtils.java index 40f2e50e..94ad53a7 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/utils/SmartColoringUtils.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/utils/SmartColoringUtils.java @@ -3,14 +3,14 @@ import com.vp.plugin.diagram.IDiagramElement; import com.vp.plugin.diagram.shape.IClassUIModel; import com.vp.plugin.model.IClass; +import com.vp.plugin.model.IModelElement; import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.uml.Class; import it.unibz.inf.ontouml.vp.model.uml.ModelElement; -import java.awt.Color; +import java.awt.*; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * Implementation of the coloring feature @@ -33,16 +33,16 @@ public class SmartColoringUtils { private static final Color PURPLE = new Color(211, 211, 252); private static final Color GREY = new Color(224, 224, 224); - private static final Color COLOR_RELATOR = GREEN; - private static final Color COLOR_RELATOR_ALTERNATIVE = LIGHT_GREEN; - private static final Color COLOR_EXTRINSIC_MODE = GREEN; - private static final Color COLOR_EXTRINSIC_MODE_ALTERNATIVE = LIGHT_GREEN; private static final Color COLOR_FUNCTIONAL_COMPLEX = PINK; private static final Color COLOR_FUNCTIONAL_COMPLEX_ALTERNATIVE = LIGHT_PINK; private static final Color COLOR_COLLECTIVE = PINK; private static final Color COLOR_COLLECTIVE_ALTERNATIVE = LIGHT_PINK; private static final Color COLOR_QUANTITY = PINK; private static final Color COLOR_QUANTITY_ALTERNATIVE = LIGHT_PINK; + private static final Color COLOR_RELATOR = GREEN; + private static final Color COLOR_RELATOR_ALTERNATIVE = LIGHT_GREEN; + private static final Color COLOR_EXTRINSIC_MODE = BLUE; + private static final Color COLOR_EXTRINSIC_MODE_ALTERNATIVE = LIGHT_BLUE; private static final Color COLOR_INTRINSIC_MODE = BLUE; private static final Color COLOR_INTRINSIC_MODE_ALTERNATIVE = LIGHT_BLUE; private static final Color COLOR_QUALITY = BLUE; @@ -92,27 +92,35 @@ public class SmartColoringUtils { */ private static Color getColor(IClass _class) { final String stereotype = ModelElement.getUniqueStereotypeName(_class); - final List restrictedTo = Class.getRestrictedToList(_class); - final List allStereotypes = Stereotype.getOntoUMLClassStereotypeNames(); - if (restrictedTo.isEmpty()) { - return allStereotypes.contains(stereotype) ? COLOR_NON_SPECIFIC : null; + + if (!allStereotypes.contains(stereotype)) { + return null; } + final List restrictedTo = Class.getRestrictedToList(_class); final boolean isUltimateSortal = Stereotype.getUltimateSortalStereotypeNames().contains(stereotype); - if (restrictedTo.size() == 1) { - String nature = restrictedTo.get(0); - return isUltimateSortal ? mainColorMap.get(nature) : alternativeColorMap.get(nature); - } - final List differentColors = - restrictedTo.stream() - .map(s -> isUltimateSortal ? mainColorMap.get(s) : alternativeColorMap.get(s)) - .distinct() - .collect(Collectors.toList()); + if (restrictedTo.isEmpty()) { + return COLOR_NON_SPECIFIC; + } - return differentColors.size() == 1 ? differentColors.get(0) : COLOR_NON_SPECIFIC; + return restrictedTo.stream() + .map( + restriction -> + isUltimateSortal + ? mainColorMap.get(restriction) + : alternativeColorMap.get(restriction)) + .reduce( + null, + (previousColor, currentColor) -> { + if (previousColor == null) { + return currentColor; + } else { + return previousColor.equals(currentColor) ? currentColor : COLOR_NON_SPECIFIC; + } + }); } /** @@ -141,11 +149,13 @@ public static void paint(IClass _class) { } public static void paint(IClassUIModel classDiagramElement) { - final IClass _class = - classDiagramElement.getModelElement() instanceof IClass - ? (IClass) classDiagramElement.getModelElement() - : null; - final Color defaultColor = getColor(_class); + if (classDiagramElement == null) return; + + IModelElement modelElement = classDiagramElement.getModelElement(); + + if (!(modelElement instanceof IClass)) return; + + final Color defaultColor = getColor((IClass) modelElement); if (defaultColor != null) { classDiagramElement.getFillColor().setColor1(defaultColor); diff --git a/src/main/java/it/unibz/inf/ontouml/vp/utils/StereotypesManager.java b/src/main/java/it/unibz/inf/ontouml/vp/utils/StereotypesManager.java index abe9899b..46246d4c 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/utils/StereotypesManager.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/utils/StereotypesManager.java @@ -1,20 +1,9 @@ package it.unibz.inf.ontouml.vp.utils; import com.vp.plugin.ApplicationManager; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IProject; -import com.vp.plugin.model.IStereotype; -import com.vp.plugin.model.ITaggedValue; -import com.vp.plugin.model.ITaggedValueContainer; -import com.vp.plugin.model.ITaggedValueDefinition; -import com.vp.plugin.model.ITaggedValueDefinitionContainer; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; public class StereotypesManager { @@ -26,10 +15,9 @@ public class StereotypesManager { public static final String PROPERTY_IS_POWERTYPE = "isPowertype"; public static final String PROPERTY_ORDER = "order"; - public static List getOntoUMLTaggedValues() { - return Arrays.asList( - PROPERTY_RESTRICTED_TO, PROPERTY_IS_EXTENSIONAL, PROPERTY_IS_POWERTYPE, PROPERTY_ORDER); - } + public static Set CLASS_TAGGED_VALUES = + Set.of( + PROPERTY_RESTRICTED_TO, PROPERTY_IS_EXTENSIONAL, PROPERTY_IS_POWERTYPE, PROPERTY_ORDER); /** Method to be called whenever a project is opened to properly install all stereotypes. */ public static void generate() { @@ -171,7 +159,7 @@ public static void applyStereotype(IModelElement element, String stereotypeName) return; } - System.out.println("\nStereotype: " + stereotype.getName()); + System.out.println("Applying stereotype: " + stereotype.getName()); ITaggedValueDefinitionContainer definitionContainer = stereotype.getTaggedValueDefinitions(); if (definitionContainer != null) { Iterator iterator = definitionContainer.taggedValueDefinitionIterator(); @@ -198,7 +186,7 @@ public static void applyStereotype(IModelElement element, String stereotypeName) // 1. Saves and deletes tagged values associated to a stereotype for (ITaggedValue tv : taggedValues) { final boolean isAllowedTag = tv.getName().equals("allowed"); - final boolean isOntoUMLTag = getOntoUMLTaggedValues().contains(tv.getName()); + final boolean isOntoUMLTag = CLASS_TAGGED_VALUES.contains(tv.getName()); final boolean isAssociatedToStereotype = tv.getTagDefinition() != null; if (isAllowedTag) { diff --git a/src/main/java/it/unibz/inf/ontouml/vp/utils/ViewManagerUtils.java b/src/main/java/it/unibz/inf/ontouml/vp/utils/ViewManagerUtils.java index 0f2fdabb..7e479fe2 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/utils/ViewManagerUtils.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/utils/ViewManagerUtils.java @@ -1,16 +1,9 @@ package it.unibz.inf.ontouml.vp.utils; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; import com.vp.plugin.ApplicationManager; import com.vp.plugin.DiagramManager; import com.vp.plugin.ViewManager; -import com.vp.plugin.diagram.IClassDiagramUIModel; import com.vp.plugin.diagram.IDiagramElement; -import com.vp.plugin.diagram.IDiagramUIModel; import com.vp.plugin.model.IModelElement; import com.vp.plugin.model.IProject; import it.unibz.inf.ontouml.vp.OntoUMLPlugin; @@ -18,6 +11,8 @@ import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.GitHubRelease; import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; +import it.unibz.inf.ontouml.vp.model.ServiceIssue; +import it.unibz.inf.ontouml.vp.model.VerificationServiceResult; import it.unibz.inf.ontouml.vp.views.HTMLEnabledMessage; import java.io.File; import java.net.HttpURLConnection; @@ -47,8 +42,6 @@ public class ViewManagerUtils { public static final String SCOPE_PLUGIN = "OntoUML"; - public static final String SCOPE_VERIFICATION = "Verification Log"; - public static final String SCOPE_DEVELOPMENT_LOG = "DevLog"; public static final String SIMPLE_LOGO = "simple_logo"; public static final String SIMPLE_LOGO_FILENAME = "ontouml-simple-logo.png"; @@ -73,35 +66,40 @@ public class ViewManagerUtils { public static final String ATTRIBUTE_LOGO = "attribute"; public static final String ATTRIBUTE_LOGO_FILENAME = "attribute.png"; - public static void simpleLog(String message) { - ApplicationManager.instance().getViewManager().showMessage(message); - } - - public static void simpleDialog(String title, String message) { + public static void simpleDialog(String message) { ApplicationManager.instance() .getViewManager() .showConfirmDialog( null, message, - title, + OntoUMLPlugin.PLUGIN_NAME, JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, new ImageIcon(getFilePath(SIMPLE_LOGO))); } + public static boolean warningDialog(String message) { + final ViewManager vm = ApplicationManager.instance().getViewManager(); + int selectedOption = + vm.showConfirmDialog( + vm.getRootFrame(), + message, + SCOPE_PLUGIN, + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + new ImageIcon((getFilePath(SIMPLE_LOGO)))); + return JOptionPane.YES_OPTION == selectedOption; + } + public static void cleanAndShowMessage(String message) { ApplicationManager.instance() .getViewManager() .removeMessagePaneComponent(OntoUMLPlugin.PLUGIN_ID); - ArrayList messageList = new ArrayList(); + ArrayList messageList = new ArrayList<>(); messageList.add(timestamp() + message); JList list = new JList<>(messageList.toArray()); - JScrollPane parentContainer = new JScrollPane(list); - ApplicationManager.instance() - .getViewManager() - .showMessagePaneComponent( - OntoUMLPlugin.PLUGIN_ID, ViewManagerUtils.SCOPE_PLUGIN, parentContainer); + log(list); } private static String timestamp() { @@ -163,222 +161,51 @@ public static String getFilePath(String imageName) { } } - public static void logDiagramVerificationResponse(String responseMessage) { - ArrayList errorList = new ArrayList(); - ArrayList idModelElementList = new ArrayList(); - - try { - JsonArray response = (JsonArray) new JsonParser().parse(responseMessage).getAsJsonArray(); + public static void log(VerificationServiceResult result) { + final List verificationIssues = + result != null ? result.getResult() : new ArrayList<>(); + final List issuesList = new ArrayList<>(); + final List ontoumlElementIdList = new ArrayList<>(); + final int errorCount = verificationIssues.size(); - final int errorCount = errorCountInCurrentDiagram(responseMessage); - final String diagramName = getCurrentClassDiagramName(); - - verificationDiagramConcludedDialog(errorCount, diagramName); - - if (errorCount == 0) { - errorList.add("No issues were found in diagram \"" + diagramName + "\"."); - } - - for (JsonElement elem : response) { - final JsonObject error = elem.getAsJsonObject(); - final String id = error.getAsJsonObject("source").get("id").getAsString(); - - if (isElementInCurrentDiagram(id)) { - final StringBuilder errorMessage = new StringBuilder(); - errorMessage.append( - !error.get("severity").isJsonNull() - ? error.get("severity").getAsString().toUpperCase() - : ""); - errorMessage.append(": "); - errorMessage.append( - !error.get("title").isJsonNull() ? error.get("title").getAsString() : ""); - errorMessage.append(" "); - errorMessage.append( - !error.get("description").isJsonNull() ? error.get("description").getAsString() : ""); - - errorList.add(timestamp() + errorMessage.toString()); - idModelElementList.add(id); - } - } - - JList list = new JList<>(errorList.toArray()); - IssueLogMenuListener listener = new IssueLogMenuListener(idModelElementList, list); - list.addMouseListener(listener); - list.addMouseMotionListener(listener); - - JScrollPane parentContainer = new JScrollPane(list); - ApplicationManager.instance() - .getViewManager() - .showMessagePaneComponent(OntoUMLPlugin.PLUGIN_ID, SCOPE_PLUGIN, parentContainer); - - } catch (JsonSyntaxException e) { - verificationServerErrorDialog(responseMessage); + if (errorCount == 0) { + issuesList.add("No syntactical issues were found."); } - } - - public static void logVerificationResponse(String responseMessage) { - ArrayList errorList = new ArrayList(); - ArrayList idModelElementList = new ArrayList(); - try { - JsonArray response = (JsonArray) new JsonParser().parse(responseMessage).getAsJsonArray(); - final int errorCount = response.size(); - - verificationConcludedDialog(errorCount); - - if (errorCount == 0) { - errorList.add("No issues were found in your project."); - } - - for (JsonElement elem : response) { - final JsonObject error = elem.getAsJsonObject(); - final String id = error.getAsJsonObject("source").get("id").getAsString(); - - final StringBuilder errorMessage = new StringBuilder(); - errorMessage.append( - !error.get("severity").isJsonNull() - ? error.get("severity").getAsString().toUpperCase() - : ""); - errorMessage.append(": "); - errorMessage.append( - !error.get("title").isJsonNull() ? error.get("title").getAsString() : ""); - errorMessage.append(" "); - errorMessage.append( - !error.get("description").isJsonNull() ? error.get("description").getAsString() : ""); - - errorList.add(timestamp() + errorMessage.toString()); - idModelElementList.add(id); - } - JList list = new JList<>(errorList.toArray()); - IssueLogMenuListener listener = new IssueLogMenuListener(idModelElementList, list); - list.addMouseListener(listener); - list.addMouseMotionListener(listener); - - JScrollPane parentContainer = new JScrollPane(list); - ApplicationManager.instance() - .getViewManager() - .showMessagePaneComponent(OntoUMLPlugin.PLUGIN_ID, SCOPE_PLUGIN, parentContainer); - - } catch (JsonSyntaxException e) { - verificationServerErrorDialog(responseMessage); + for (ServiceIssue issue : verificationIssues) { + final String message = + timestamp() + + issue.getSeverity().toUpperCase() + + ": " + + issue.getTitle() + + " " + + issue.getDescription(); + issuesList.add(message); + ontoumlElementIdList.add(issue.getSource().getId()); } - } - private static void verificationServerErrorDialog(String userMessage) { - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - userMessage, - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.ERROR_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - } - - private static void verificationConcludedDialog(int nIssues) { - if (nIssues > 0) { - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - "Issues found in your project: " - + nIssues - + ".\n" - + "For details, click on the \"Show Message\" icon on the bottom right corner of" - + " the app.", - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - } else { - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - "No issues were found in your project.", - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.INFORMATION_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - } - } + JList list = new JList<>(issuesList.toArray()); + IssueLogMenuListener listener = new IssueLogMenuListener(ontoumlElementIdList, list); + list.addMouseListener(listener); + list.addMouseMotionListener(listener); - private static void verificationDiagramConcludedDialog(int nIssues, String diagramName) { - if (nIssues > 0) { - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - "Issues found in diagram \"" - + diagramName - + "\": " - + nIssues - + ".\n" - + "For details, click on the \"Show Message\" icon on the bottom right corner of" - + " the app.", - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - } else { - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - "No issues were found in diagram \"" - + diagramName - + "\".\n" - + "Other issues may still exist in your project.", - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.INFORMATION_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - } + log(list); } - public static void verificationFailedDialog(String msg) { + public static void log(JList list) { + JScrollPane parentContainer = new JScrollPane(list); ApplicationManager.instance() .getViewManager() - .showConfirmDialog( - null, - msg, - "Verification Service", - JOptionPane.DEFAULT_OPTION, - JOptionPane.ERROR_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); + .showMessagePaneComponent(OntoUMLPlugin.PLUGIN_ID, SCOPE_PLUGIN, parentContainer); } - public static boolean verificationFailedDialogWithOption(String msg, int httpCode) { - final ProjectConfigurations configurations = - Configurations.getInstance().getProjectConfigurations(); - - if (configurations.isCustomServerEnabled() - && (httpCode == HttpURLConnection.HTTP_NOT_FOUND - || httpCode == HttpURLConnection.HTTP_INTERNAL_ERROR)) { - - int option = - ApplicationManager.instance() - .getViewManager() - .showConfirmDialog( - null, - msg + "\nDo you want to retry using the default server?", - "Verification Service", - JOptionPane.YES_NO_OPTION, - JOptionPane.INFORMATION_MESSAGE, - new ImageIcon(getFilePath(SIMPLE_LOGO))); - - if (option == JOptionPane.OK_OPTION) { - configurations.setCustomServerEnabled(false); - return true; - } else { - return false; - } + public static void log(List list) { + JList jList = new JList<>(list.toArray()); + log(jList); + } - } else { - verificationFailedDialog(msg); - return false; - } + public static void log(String message) { + log(List.of(message)); } public static void exportToGUFOIssueDialog(String msg) { @@ -425,82 +252,6 @@ public static boolean exportToGUFOIssueDialogWithOption(String msg, int httpCode } } - private static String getCurrentClassDiagramName() { - final IDiagramUIModel[] diagramArray = - ApplicationManager.instance().getProjectManager().getProject().toDiagramArray(); - - if (diagramArray == null) { - return null; - } - - for (IDiagramUIModel diagram : diagramArray) { - if (diagram instanceof IClassDiagramUIModel && diagram.isOpened()) { - return diagram.getName(); - } - } - - return null; - } - - private static String getCurrentClassDiagramId() { - final IDiagramUIModel[] diagramArray = - ApplicationManager.instance().getProjectManager().getProject().toDiagramArray(); - - if (diagramArray == null) { - return null; - } - - for (IDiagramUIModel diagram : diagramArray) { - if (diagram instanceof IClassDiagramUIModel && diagram.isOpened()) { - return diagram.getId(); - } - } - - return null; - } - - private static IDiagramUIModel getCurrentClassDiagram() { - - return ApplicationManager.instance() - .getProjectManager() - .getProject() - .getDiagramById(getCurrentClassDiagramId()); - } - - private static boolean isElementInCurrentDiagram(String id) { - - if (getCurrentClassDiagram() == null) { - return false; - } - - for (IDiagramElement element : getCurrentClassDiagram().toDiagramElementArray()) { - if (element.getModelElement().getId().equals(id)) { - return true; - } - } - - return false; - } - - private static int errorCountInCurrentDiagram(String responseMessage) { - int errorCount = 0; - - try { - JsonArray response = (JsonArray) new JsonParser().parse(responseMessage).getAsJsonArray(); - - for (JsonElement elem : response) { - if (isElementInCurrentDiagram( - elem.getAsJsonObject().getAsJsonObject("source").get("id").getAsString())) { - errorCount++; - } - } - } catch (JsonSyntaxException e) { - return 0; - } - - return errorCount; - } - public static boolean isElementInAnyDiagram(String elementId) { final IProject project = ApplicationManager.instance().getProjectManager().getProject(); final IModelElement element = project.getModelElementById(elementId); @@ -541,7 +292,7 @@ public static void highlightDiagramElement(String modelElementId) { } firstView = firstView == null ? diagramElement : firstView; - activeView = diagramElement.getDiagramUIModel().isOpened() ? diagramElement : activeView; + activeView = diagramElement.getDiagramUIModel().isOpened() ? diagramElement : null; masterView = diagramElement.isMasterView() ? diagramElement : masterView; if (activeView != null) { @@ -608,7 +359,6 @@ public static GitHubRelease updateDialog() { "\n" + "Be aware that \"alpha\" releases provide experimental new features that may not" + " be fully integrated to the plugin."); - msg.append("\n\nThe procedure may take a couple of seconds."); } else { options = new String[3]; options[0] = "Cancel"; @@ -617,10 +367,9 @@ public static GitHubRelease updateDialog() { initialSelection = options[2]; - msg.append( - "The latest stable release of the plugin is the version " - + lastestRelease.getTagName() - + "."); + msg.append("The latest stable release of the plugin is the version ") + .append(lastestRelease.getTagName()) + .append("."); msg.append( "\n" + "To install this update, click on \"Install latest release\", or click on" @@ -629,8 +378,8 @@ public static GitHubRelease updateDialog() { "\n" + "Be aware that \"alpha\" releases are provide experimental new features that may" + " present some issues."); - msg.append("\n\nThe procedure may take a couple of seconds."); } + msg.append("\n\nThe procedure may take a couple of seconds."); final ViewManager vm = ApplicationManager.instance().getViewManager(); int selectedOption = @@ -671,20 +420,18 @@ public static void updateSuccessDialog() { public static void updateErrorDialog() { final ViewManager vm = ApplicationManager.instance().getViewManager(); - final StringBuilder builder = new StringBuilder(); - builder.append("Something went wrong during the update. Please verify your connection.
"); - builder.append( - "In case your plugin becomes unavailable, you may find instructions at " + + "In case your plugin becomes unavailable, you may find instructions at " + OntoUMLPlugin.PLUGIN_REPO - + ".
"); - builder.append( - "In this page you can also report this error and help us to improve our plugin."); - + + ".
" + + "In this page you can also report this error and help us to improve our plugin."; vm.showConfirmDialog( null, - new HTMLEnabledMessage(builder.toString()), + new HTMLEnabledMessage(message), "Plugin Update Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, @@ -705,7 +452,7 @@ private static GitHubRelease selectReleaseToInstall() { String releaseTagName = release.getTagName(); releaseTagName = - installedReleaseTagName != null && releaseTagName.equals(installedReleaseTagName) + releaseTagName.equals(installedReleaseTagName) ? releaseTagName + " (installed version)" : releaseTagName; @@ -713,7 +460,7 @@ private static GitHubRelease selectReleaseToInstall() { }); ViewManager vm = ApplicationManager.instance().getViewManager(); - List keys = new ArrayList(map.keySet()); + List keys = new ArrayList<>(map.keySet()); keys.sort(Comparator.reverseOrder()); Object[] keysArray = new String[keys.size()]; keys.toArray(keysArray); diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/GUFOExportView.java b/src/main/java/it/unibz/inf/ontouml/vp/views/GufoExportView.java similarity index 93% rename from src/main/java/it/unibz/inf/ontouml/vp/views/GUFOExportView.java rename to src/main/java/it/unibz/inf/ontouml/vp/views/GufoExportView.java index da0d4b2f..b2acb0a8 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/GUFOExportView.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/GufoExportView.java @@ -13,16 +13,14 @@ import com.vp.plugin.model.IProject; import com.vp.plugin.model.factory.IModelElementFactory; import com.vp.plugin.view.IDialog; -import it.unibz.inf.ontouml.vp.OntoUMLPlugin; -import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.ProjectConfigurations; -import it.unibz.inf.ontouml.vp.model.ServerRequest; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.HashMap; @@ -43,7 +41,7 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; -public class GUFOExportView extends JPanel { +public class GufoExportView extends JPanel { private static final long serialVersionUID = 1L; private JTextField IRItxt; @@ -72,8 +70,7 @@ public class GUFOExportView extends JPanel { private IDialog _dialog; - private boolean isToExport; - private boolean isOpen; + private boolean wasCancelled = false; private HashSet elementsPackageTree = new HashSet<>(); private HashSet elementsDiagramTree = new HashSet<>(); @@ -81,7 +78,7 @@ public class GUFOExportView extends JPanel { private IModelElement[] elementsMapping; private IModelElement[] packagesMapping; - public GUFOExportView(ProjectConfigurations configurations, ServerRequest request) { + public GufoExportView(ProjectConfigurations configurations) { setSize(new Dimension(680, 550)); setLayout(new GridLayout(1, 1)); @@ -92,8 +89,8 @@ public GUFOExportView(ProjectConfigurations configurations, ServerRequest reques JPanel packageMappingPanel = new JPanel(); mainTabbedPane.add(mainPanel, "Basic Settings"); - mainTabbedPane.add(elementMappingPanel, "Element Mapping"); - mainTabbedPane.add(packageMappingPanel, "Package Mapping"); + mainTabbedPane.add(elementMappingPanel, "Element Correspondence"); + mainTabbedPane.add(packageMappingPanel, "Package Correspondence"); JPanel optionsPanelLeft = new JPanel(); JPanel optionsPanelRight = new JPanel(); @@ -214,9 +211,10 @@ public GUFOExportView(ProjectConfigurations configurations, ServerRequest reques objectBox = new JComboBox<>(objectBoxString); ((JLabel) objectBox.getRenderer()).setHorizontalAlignment(JLabel.CENTER); - String[] analysisBoxString = {"true", "false"}; + String[] analysisBoxString = {"false", "true"}; analysisBox = new JComboBox<>(analysisBoxString); ((JLabel) analysisBox.getRenderer()).setHorizontalAlignment(JLabel.CENTER); + analysisBox.setSelectedItem("true"); String[] packagesBoxString = {"false", "true"}; packagesBox = new JComboBox<>(packagesBoxString); @@ -282,6 +280,10 @@ public GUFOExportView(ProjectConfigurations configurations, ServerRequest reques packageTree = new JCheckBoxTree("package"); diagramTree = new JCheckBoxTree("diagram"); + // TODO: enable selection trees + packageTree.setEnabled(false); + diagramTree.setEnabled(false); + JScrollPane scrollableTextAreaPackage = new JScrollPane(packageTree); JScrollPane scrollableTextAreaDiagram = new JScrollPane(diagramTree); @@ -318,29 +320,6 @@ public GUFOExportView(ProjectConfigurations configurations, ServerRequest reques btnExport.setPreferredSize(new Dimension(80, 35)); btnCancel.setPreferredSize(new Dimension(80, 35)); - btnExport.addActionListener( - actionEvent -> { - if (tabbedPane.getSelectedIndex() == 0) saveSelectedElements("Package Tree"); - else saveSelectedElements("Diagram Tree"); - - updateConfigurationsValues(configurations); - Configurations.getInstance().save(); - isToExport = true; - isOpen = false; - _dialog.close(); - Thread thread = new Thread(request); - thread.start(); - }); - - btnCancel.addActionListener( - actionEvent -> { - isToExport = false; - isOpen = false; - request.doStop(); - _dialog.close(); - OntoUMLPlugin.setExportToGUFOWindowOpen(false); - }); - GridBagConstraints gbc_buttonsPanel = new GridBagConstraints(); gbc_buttonsPanel.fill = GridBagConstraints.HORIZONTAL; gbc_buttonsPanel.insets = new Insets(2, 2, 2, 15); @@ -721,12 +700,8 @@ protected JComponent makeTextPanel(String text) { return panel; } - public boolean getIsToExport() { - return isToExport; - } - - public boolean getIsOpen() { - return isOpen; + public boolean getWasCancelled() { + return wasCancelled; } private static String[] getLanguagesCode() { @@ -754,14 +729,17 @@ public void setContainerDialog(IDialog dialog) { } /** Updates project configurations with components' information. */ - private void updateConfigurationsValues(ProjectConfigurations configurations) { + public void updateConfigurationsValues(ProjectConfigurations configurations) { + if (tabbedPane.getSelectedIndex() == 0) saveSelectedElements("Package Tree"); + else saveSelectedElements("Diagram Tree"); + configurations.setExportGUFOIRI(IRItxt.getText()); configurations.setExportGUFOFormat(formatBox.getSelectedItem().toString()); configurations.setExportGUFOURIFormat(uriFormatBox.getSelectedItem().toString()); - configurations.setExportGUFOInverseBox(inverseBox.getSelectedItem().toString()); - configurations.setExportGUFOObjectBox(objectBox.getSelectedItem().toString()); - configurations.setExportGUFOAnalysisBox(analysisBox.getSelectedItem().toString()); - configurations.setExportGUFOPackagesBox(packagesBox.getSelectedItem().toString()); + configurations.setExportGUFOInverseBox("true".equals(inverseBox.getSelectedItem())); + configurations.setExportGUFOObjectBox("true".equals(objectBox.getSelectedItem())); + configurations.setExportGUFOAnalysisBox("true".equals(analysisBox.getSelectedItem())); + configurations.setExportGUFOPackagesBox("true".equals(packagesBox.getSelectedItem())); configurations.setExportGUFOElementMapping(getTableElementMapping()); configurations.setExportGUFOPackageMapping(getTablePackageMapping()); @@ -794,17 +772,12 @@ private void updateComponentsValues(ProjectConfigurations configurations) { if (configurations.getExportGUFOElementsDiagramTree() != null) diagramTree.setNodesCheck(configurations.getExportGUFOElementsDiagramTree()); - if (configurations.getExportGUFOInverseBox() != null) - inverseBox.setSelectedItem(configurations.getExportGUFOInverseBox()); - - if (configurations.getExportGUFOObjectBox() != null) - objectBox.setSelectedItem(configurations.getExportGUFOObjectBox()); - - if (configurations.getExportGUFOAnalysisBox() != null) - analysisBox.setSelectedItem(configurations.getExportGUFOAnalysisBox()); - - if (configurations.getExportGUFOPackagesBox() != null) - packagesBox.setSelectedItem(configurations.getExportGUFOPackagesBox()); + // "false" is add first, so its index is 0. This is a cheap workaround due to issue on string + // comparison, let's just use check boxes next time + inverseBox.setSelectedIndex(configurations.getExportGUFOInverseBox() ? 1 : 0); + objectBox.setSelectedIndex(configurations.getExportGUFOObjectBox() ? 1 : 0); + analysisBox.setSelectedIndex(configurations.getExportGUFOAnalysisBox() ? 1 : 0); + packagesBox.setSelectedIndex(configurations.getExportGUFOPackagesBox() ? 1 : 0); } private void saveSelectedElements(String tree) { @@ -845,8 +818,7 @@ public HashSet getSavedElements() { } public String getTableElementMapping() { - HashMap>> results = - new HashMap>>(); + HashMap>> results = new HashMap<>(); String elementId = ""; for (int row = 0; row < table.getRowCount(); row++) { @@ -881,6 +853,7 @@ public String getTableElementMapping() { content.put(language, text); } + // TODO: replace Gson with fasterxml Gson gson = new Gson(); String json = gson.toJson(results); @@ -923,6 +896,7 @@ public String getTablePackageMapping() { content.put("uri", uri); } + // TODO: replace Gson with fasterxml Gson gson = new Gson(); String json = gson.toJson(results); @@ -1001,4 +975,24 @@ public static String getDisplayName(Object obj) { return "Element"; } + + public void onExport(ActionListener onExportAction) { + ActionListener[] currentListeners = btnExport.getActionListeners(); + + for (int i = 0; currentListeners != null && i < currentListeners.length; i++) { + btnExport.removeActionListener(currentListeners[i]); + } + + btnExport.addActionListener(onExportAction); + } + + public void onCancel(ActionListener onCancelAction) { + ActionListener[] currentListeners = btnCancel.getActionListeners(); + + for (int i = 0; currentListeners != null && i < currentListeners.length; i++) { + btnCancel.removeActionListener(currentListeners[i]); + } + + btnCancel.addActionListener(onCancelAction); + } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/HTMLEnabledMessage.java b/src/main/java/it/unibz/inf/ontouml/vp/views/HTMLEnabledMessage.java index fc778588..44214c26 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/HTMLEnabledMessage.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/HTMLEnabledMessage.java @@ -1,11 +1,8 @@ package it.unibz.inf.ontouml.vp.views; import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import java.awt.Color; -import java.awt.Desktop; -import java.awt.Font; -import javax.swing.JEditorPane; -import javax.swing.JLabel; +import java.awt.*; +import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/JCheckBoxTree.java b/src/main/java/it/unibz/inf/ontouml/vp/views/JCheckBoxTree.java index 5c4e527a..e849f0e1 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/JCheckBoxTree.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/JCheckBoxTree.java @@ -4,44 +4,14 @@ import com.vp.plugin.diagram.IClassDiagramUIModel; import com.vp.plugin.diagram.IDiagramElement; import com.vp.plugin.diagram.IDiagramUIModel; -import com.vp.plugin.model.IAssociation; -import com.vp.plugin.model.IAssociationClass; -import com.vp.plugin.model.IAssociationEnd; -import com.vp.plugin.model.IAttribute; -import com.vp.plugin.model.IClass; -import com.vp.plugin.model.IDataType; -import com.vp.plugin.model.IGeneralization; -import com.vp.plugin.model.IGeneralizationSet; -import com.vp.plugin.model.IModel; -import com.vp.plugin.model.IModelElement; -import com.vp.plugin.model.IPackage; -import com.vp.plugin.model.IProject; +import com.vp.plugin.model.*; import com.vp.plugin.model.factory.IModelElementFactory; import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import java.awt.BorderLayout; -import java.awt.Component; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.EventObject; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import javax.swing.ImageIcon; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTree; +import java.awt.*; +import java.util.*; +import javax.swing.*; import javax.swing.event.EventListenerList; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.DefaultTreeSelectionModel; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; +import javax.swing.tree.*; public class JCheckBoxTree extends JTree { @@ -205,6 +175,9 @@ else if (obj instanceof IAssociationClass) checkBox.setSelected(cn.isSelected); checkBox.setText(getNameNode(node)); + // TODO: enable checkboxes + checkBox.setEnabled(false); + checkBox.setOpaque(cn.isSelected && cn.hasChildren && !cn.allChildrenSelected); return this; @@ -212,7 +185,7 @@ else if (obj instanceof IAssociationClass) } private String getNameNode(ElementNode node) { - return GUFOExportView.getDisplayName(node.getUserObject()); + return GufoExportView.getDisplayName(node.getUserObject()); } public JCheckBoxTree(String type) { diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressDialogHandler.java b/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressDialogHandler.java new file mode 100644 index 00000000..23c49151 --- /dev/null +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressDialogHandler.java @@ -0,0 +1,74 @@ +package it.unibz.inf.ontouml.vp.views; + +import com.vp.plugin.ApplicationManager; +import com.vp.plugin.view.IDialog; +import com.vp.plugin.view.IDialogHandler; +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.util.function.Consumer; +import javax.swing.SwingUtilities; + +public class ProgressDialogHandler implements IDialogHandler { + + private ProgressPanel _progressPanel; + private IDialog _dialog; + private boolean wasShown = false; + private boolean wasClosed = false; + + public ProgressDialogHandler() { + _progressPanel = new ProgressPanel(); + onCancel(e -> System.out.println("Cancelling dialog with default behaviour.")); + } + + @Override + public Component getComponent() { + return _progressPanel; + } + + @Override + public void prepare(IDialog dialog) { + _dialog = dialog; + + _dialog.setSize(_progressPanel.getSize()); + _dialog.setModal(true); + _dialog.setResizable(false); + _dialog.pack(); + } + + @Override + public void shown() { + wasShown = true; + _progressPanel.startUpdatingProgressBarString(() -> wasClosed); + } + + @Override + public boolean canClosed() { + return false; + } + + public void showDialog() { + if (wasClosed) + System.out.println("The progress dialog was already closed and cannot be shown."); + else if (wasShown) + System.out.println("The progress dialog is already visible and cannot be shown twice."); + else { + SwingUtilities.invokeLater( + () -> ApplicationManager.instance().getViewManager().showDialog(this)); + } + } + + public void closeDialog() { + if (wasShown && !wasClosed) { + _dialog.close(); + } + wasClosed = true; + } + + public void onCancel(Consumer cancelAction) { + _progressPanel.setCancelAction( + e -> { + cancelAction.accept(e); + closeDialog(); + }); + } +} diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressPanel.java b/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressPanel.java index b3ba5636..bbc31b0f 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressPanel.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/ProgressPanel.java @@ -1,60 +1,79 @@ package it.unibz.inf.ontouml.vp.views; -import com.vp.plugin.view.IDialog; -import it.unibz.inf.ontouml.vp.model.ServerRequest; -import it.unibz.inf.ontouml.vp.utils.ViewManagerUtils; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.event.ActionEvent; +import java.awt.Component; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; +import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; +import javax.swing.SwingWorker; public class ProgressPanel extends JPanel { private static final long serialVersionUID = 1L; - private JLabel label; - private JProgressBar progressBar; - private JButton btnCancel; - private IDialog _dialog; + private final JProgressBar progressBar; + private final JButton btnCancel; - public ProgressPanel(String text) { - setSize(new Dimension(200, 100)); + public ProgressPanel() { + super(); + setSize(200, 200); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - label = new JLabel(); - label.setText(text); + JLabel label = new JLabel("Loading"); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + add(label); progressBar = new JProgressBar(); - progressBar.setIndeterminate(true); + progressBar.setStringPainted(true); + progressBar.setAlignmentX(Component.CENTER_ALIGNMENT); + add(progressBar); - GridBagConstraints constraints = new GridBagConstraints(); - constraints.anchor = GridBagConstraints.CENTER; - - add(label, constraints); - add(progressBar, constraints); + btnCancel = new JButton("Cancel"); + btnCancel.setAlignmentX(Component.CENTER_ALIGNMENT); + add(btnCancel); } - public ProgressPanel(ServerRequest request) { - this("Contacting Server..."); + public void startUpdatingProgressBarString(Supplier shouldStop) { + new SwingWorker, String>() { + protected void process(List chunks) { + String latest = chunks.get(chunks.size() - 1); + progressBar.setString(latest); + } - btnCancel = new JButton("Cancel"); - btnCancel.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - request.doStop(); - _dialog.close(); - ViewManagerUtils.cleanAndShowMessage("Request cancelled by the user."); - } - }); + protected List doInBackground() throws Exception { + List circles = + new ArrayList<>(Arrays.asList("\u25F4", "\u25F7", "\u25F6", "\u25F5")); + int index = 0; - add(btnCancel); + while (!shouldStop.get() || isCancelled()) { + publish(circles.get(index)); + index = (index + 1) % circles.size(); + Thread.sleep(200); + } + + return circles; + } + }.execute(); + } + + public void setValue(int value) { + progressBar.setValue(value); + progressBar.setString("Completed " + value + "%"); } - public void setContainerDialog(IDialog dialog) { - this._dialog = dialog; + public void setCancelAction(ActionListener cancelAction) { + ActionListener[] listeners = btnCancel.getActionListeners(); + + for (int i = 0; listeners != null && i < listeners.length; i++) { + btnCancel.removeActionListener(listeners[i]); + } + + btnCancel.addActionListener(cancelAction); } } diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/SelectRestrictionsView.java b/src/main/java/it/unibz/inf/ontouml/vp/views/SelectRestrictionsView.java index a676740a..2611c88f 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/SelectRestrictionsView.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/SelectRestrictionsView.java @@ -5,15 +5,9 @@ import it.unibz.inf.ontouml.vp.model.Configurations; import it.unibz.inf.ontouml.vp.model.uml.Class; import it.unibz.inf.ontouml.vp.utils.RestrictedTo; -import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.GridLayout; +import java.awt.*; import java.util.List; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; +import javax.swing.*; import javax.swing.border.EmptyBorder; public class SelectRestrictionsView implements IDialogHandler { diff --git a/src/main/java/it/unibz/inf/ontouml/vp/views/SetOrderView.java b/src/main/java/it/unibz/inf/ontouml/vp/views/SetOrderView.java index cf5e0e65..64eed9a4 100644 --- a/src/main/java/it/unibz/inf/ontouml/vp/views/SetOrderView.java +++ b/src/main/java/it/unibz/inf/ontouml/vp/views/SetOrderView.java @@ -4,19 +4,12 @@ import com.vp.plugin.view.IDialog; import com.vp.plugin.view.IDialogHandler; import it.unibz.inf.ontouml.vp.OntoUMLPlugin; -import java.awt.Component; -import java.awt.FlowLayout; -import java.awt.Image; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.nio.file.Paths; -import javax.swing.BoxLayout; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; +import javax.swing.*; import javax.swing.border.EmptyBorder; public class SetOrderView implements IDialogHandler { diff --git a/src/main/resources/icons/toolbar/add-views-18dp.png b/src/main/resources/icons/toolbar/add-views-18dp.png new file mode 100644 index 00000000..60cdb2a1 Binary files /dev/null and b/src/main/resources/icons/toolbar/add-views-18dp.png differ diff --git a/src/main/resources/plugin.xml b/src/main/resources/plugin.xml index d09c52eb..3d062c8d 100644 --- a/src/main/resources/plugin.xml +++ b/src/main/resources/plugin.xml @@ -1,618 +1,806 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="it.unibz.inf.ontouml.vp" + description="OntoUML Plugin Visual Paradigm v0.3.0" + provider="University of Bolzano" + class="it.unibz.inf.ontouml.vp.OntoUMLPlugin"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResultDeserializationTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResultDeserializationTest.java new file mode 100644 index 00000000..fd566552 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/GufoTransformationServiceResultDeserializationTest.java @@ -0,0 +1,108 @@ +package it.unibz.inf.ontouml.vp.model; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class GufoTransformationServiceResultDeserializationTest { + + static ObjectMapper mapper; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + } + + @Test + void shouldDeserializeEmptyResult() throws IOException { + final String emptyResult1 = "{\n" + " \"result\": null,\n" + " \"issues\": []\n" + "}"; + final String emptyResult2 = "{\n" + " \"result\": null,\n" + " \"issues\": null\n" + "}"; + final String emptyResult3 = "{\n" + " \"result\": null\n" + "}"; + final List emptyResults = Arrays.asList(emptyResult1, emptyResult2, emptyResult3); + + for (String emptyResult : emptyResults) { + GufoTransformationServiceResult serviceResult = + mapper.readValue(emptyResult, GufoTransformationServiceResult.class); + + assertThat(serviceResult).isNotEqualTo(null); + assertThat(serviceResult.getResult()).isNull(); + assertThat(serviceResult.getIssues()).isEmpty(); + } + } + + @Test + void shouldDeserializeGufoOntology() throws IOException { + final String json = + "{\n" + + " \"result\": \"@prefix : .\\n" + + "@prefix gufo: .\\n" + + "@prefix rdf: .\\n" + + "@prefix rdfs: .\\n" + + "@prefix owl: .\\n" + + "@prefix xsd: .\\n" + + "\\n" + + " rdf:type owl:Ontology;\\n" + + " owl:imports gufo:.\\n" + + ":Class rdf:type owl:Class, gufo:Kind, owl:NamedIndividual;\\n" + + " rdfs:subClassOf gufo:FunctionalComplex;\\n" + + " rdfs:label \\\"Class\\\"@en.\\n" + + ":Class2 rdf:type owl:Class, gufo:SubKind, owl:NamedIndividual;\\n" + + " rdfs:label \\\"Class2\\\"@en.\\n" + + ":Class3 rdf:type owl:Class, gufo:Kind, owl:NamedIndividual;\\n" + + " rdfs:subClassOf gufo:Relator;\\n" + + " rdfs:label \\\"Class3\\\"@en.\\n" + + ":Class2 rdfs:subClassOf :Class.\\n" + + ":classMediatesClass3 rdf:type owl:ObjectProperty;\\n" + + " rdfs:domain :Class;\\n" + + " rdfs:range :Class3;\\n" + + " rdfs:subPropertyOf gufo:mediates.\\n" + + ":Class rdfs:subClassOf [\\n" + + " rdf:type owl:Restriction;\\n" + + " owl:onProperty :classMediatesClass3;\\n" + + " owl:minQualifiedCardinality \\\"1\\\"^^xsd:nonNegativeInteger;\\n" + + " owl:onClass :Class3\\n" + + "].\\n" + + "\",\n" + + " \"issues\": [\n" + + " {\n" + + " \"id\": \"3yjrith5k0vkm3pi9zs\",\n" + + " \"code\": \"missing_relation_name\",\n" + + " \"title\": \"Missing relation name\",\n" + + " \"description\": \"Missing name on «mediation» relation between classes" + + " \\\"[object Object]\\\" and \\\"[object Object]\\\".\",\n" + + " \"severity\": \"warning\",\n" + + " \"data\": {\n" + + " \"element\": {\n" + + " \"id\": \"7PKr2.6GAqACHQXQ\",\n" + + " \"name\": null\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + "}"; + final GufoTransformationServiceResult serviceResult = + mapper.readValue(json, GufoTransformationServiceResult.class); + + assertThat(serviceResult).isNotNull(); + assertThat(serviceResult.getResult()).isInstanceOf(String.class); + assertThat(serviceResult.getIssues()).isNotEmpty(); + assertThat(serviceResult.getIssues().get(0)).isInstanceOf(ServiceIssue.class); + + final ServiceIssue issue = serviceResult.getIssues().get(0); + assertThat(issue.getId()).isEqualTo("3yjrith5k0vkm3pi9zs"); + assertThat(issue.getCode()).isEqualTo("missing_relation_name"); + assertThat(issue.getTitle()).isEqualTo("Missing relation name"); + assertThat(issue.getDescription()) + .isEqualTo( + "Missing name on «mediation» relation between classes \"[object Object]\" and" + + " \"[object Object]\"."); + assertThat(issue.getSeverity()).isEqualTo("warning"); + assertThat(issue.getSource()).isNull(); + assertThat(issue.getContext()).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResultDeserializationTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResultDeserializationTest.java new file mode 100644 index 00000000..6c2f68ed --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ModularizationServiceResultDeserializationTest.java @@ -0,0 +1,360 @@ +package it.unibz.inf.ontouml.vp.model; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class ModularizationServiceResultDeserializationTest { + + static ObjectMapper mapper; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + } + + @Test + void shouldDeserializeEmptyResult() throws IOException { + final String emptyResult1 = "{\n" + " \"result\": null,\n" + " \"issues\": []\n" + "}"; + final String emptyResult2 = "{\n" + " \"result\": null,\n" + " \"issues\": null\n" + "}"; + final String emptyResult3 = "{\n" + " \"result\": null\n" + "}"; + final List emptyResults = Arrays.asList(emptyResult1, emptyResult2, emptyResult3); + + for (String emptyResult : emptyResults) { + ModularizationServiceResult serviceResult = + mapper.readValue(emptyResult, ModularizationServiceResult.class); + + assertThat(serviceResult).isNotEqualTo(null); + assertThat(serviceResult.getResult()).isNull(); + assertThat(serviceResult.getIssues()).isEmpty(); + } + } + + @Test + void shouldDeserializeModularizedProject() throws IOException { + final String json = + "{\n" + + " \"result\": {\n" + + " \"model\": {\n" + + " \"contents\": [\n" + + " {\n" + + " \"stereotype\": \"kind\",\n" + + " \"restrictedTo\": [\n" + + " \"functional-complex\"\n" + + " ],\n" + + " \"properties\": null,\n" + + " \"literals\": null,\n" + + " \"isAbstract\": false,\n" + + " \"isDerived\": false,\n" + + " \"isExtensional\": false,\n" + + " \"isPowertype\": false,\n" + + " \"order\": \"1\",\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"mNir2.6GAqACHQWX\",\n" + + " \"name\": \"Class\",\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"stereotype\": \"subkind\",\n" + + " \"restrictedTo\": [\n" + + " \"functional-complex\"\n" + + " ],\n" + + " \"properties\": null,\n" + + " \"literals\": null,\n" + + " \"isAbstract\": false,\n" + + " \"isDerived\": false,\n" + + " \"isExtensional\": false,\n" + + " \"isPowertype\": false,\n" + + " \"order\": \"1\",\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWv\",\n" + + " \"name\": \"Class2\",\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"stereotype\": \"relator\",\n" + + " \"restrictedTo\": [\n" + + " \"relator\"\n" + + " ],\n" + + " \"properties\": null,\n" + + " \"literals\": null,\n" + + " \"isAbstract\": false,\n" + + " \"isDerived\": false,\n" + + " \"isExtensional\": false,\n" + + " \"isPowertype\": false,\n" + + " \"order\": \"1\",\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"P3Kr2.6GAqACHQXK\",\n" + + " \"name\": \"Class3\",\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"general\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"mNir2.6GAqACHQWX\"\n" + + " },\n" + + " \"specific\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWv\"\n" + + " },\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Generalization\",\n" + + " \"id\": \"H1yr2.6GAqACHQW1\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"stereotype\": \"mediation\",\n" + + " \"properties\": [\n" + + " {\n" + + " \"stereotype\": null,\n" + + " \"cardinality\": \"0..*\",\n" + + " \"propertyType\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"mNir2.6GAqACHQWX\"\n" + + " },\n" + + " \"subsettedProperties\": null,\n" + + " \"redefinedProperties\": null,\n" + + " \"aggregationKind\": \"NONE\",\n" + + " \"isDerived\": false,\n" + + " \"isOrdered\": false,\n" + + " \"isReadOnly\": false,\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Property\",\n" + + " \"id\": \"AvKr2.6GAqACHQXS\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"stereotype\": null,\n" + + " \"cardinality\": \"1\",\n" + + " \"propertyType\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"P3Kr2.6GAqACHQXK\"\n" + + " },\n" + + " \"subsettedProperties\": null,\n" + + " \"redefinedProperties\": null,\n" + + " \"aggregationKind\": \"NONE\",\n" + + " \"isDerived\": false,\n" + + " \"isOrdered\": false,\n" + + " \"isReadOnly\": true,\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Property\",\n" + + " \"id\": \"QvKr2.6GAqACHQXV\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " }\n" + + " ],\n" + + " \"isAbstract\": false,\n" + + " \"isDerived\": false,\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Relation\",\n" + + " \"id\": \"7PKr2.6GAqACHQXQ\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " }\n" + + " ],\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Package\",\n" + + " \"id\": \"Pz4r2.6GAqACHQBO_root\",\n" + + " \"name\": \"untitled\",\n" + + " \"description\": null\n" + + " },\n" + + " \"diagrams\": [\n" + + " {\n" + + " \"owner\": {\n" + + " \"type\": \"Package\",\n" + + " \"id\": \"Pz4r2.6GAqACHQBO_root\"\n" + + " },\n" + + " \"contents\": [\n" + + " {\n" + + " \"modelElement\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWv\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"width\": 88,\n" + + " \"height\": 40,\n" + + " \"x\": 198,\n" + + " \"y\": 231,\n" + + " \"type\": \"Rectangle\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWu_shape\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWu\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"source\": {\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"CNir2.6GAqACHQWW\"\n" + + " },\n" + + " \"target\": {\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"Y1yr2.6GAqACHQWu\"\n" + + " },\n" + + " \"modelElement\": {\n" + + " \"type\": \"Generalization\",\n" + + " \"id\": \"H1yr2.6GAqACHQW1\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"type\": \"Path\",\n" + + " \"id\": \"0Nyr2.6GAqACHQW2_path\",\n" + + " \"name\": null,\n" + + " \"description\": null,\n" + + " \"points\": [\n" + + " {\n" + + " \"x\": 238,\n" + + " \"y\": 179\n" + + " },\n" + + " {\n" + + " \"x\": 238,\n" + + " \"y\": 230\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"type\": \"GeneralizationView\",\n" + + " \"id\": \"0Nyr2.6GAqACHQW2\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"modelElement\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"mNir2.6GAqACHQWX\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"width\": 80,\n" + + " \"height\": 40,\n" + + " \"x\": 198,\n" + + " \"y\": 138,\n" + + " \"type\": \"Rectangle\",\n" + + " \"id\": \"CNir2.6GAqACHQWW_shape\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"CNir2.6GAqACHQWW\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"modelElement\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"P3Kr2.6GAqACHQXK\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"width\": 81,\n" + + " \"height\": 40,\n" + + " \"x\": 467,\n" + + " \"y\": 138,\n" + + " \"type\": \"Rectangle\",\n" + + " \"id\": \"33Kr2.6GAqACHQXJ_shape\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"33Kr2.6GAqACHQXJ\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"source\": {\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"33Kr2.6GAqACHQXJ\"\n" + + " },\n" + + " \"target\": {\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"CNir2.6GAqACHQWW\"\n" + + " },\n" + + " \"modelElement\": {\n" + + " \"type\": \"Relation\",\n" + + " \"id\": \"7PKr2.6GAqACHQXQ\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"type\": \"Path\",\n" + + " \"id\": \"a_.r2.6GAqACHQZv_path\",\n" + + " \"name\": null,\n" + + " \"description\": null,\n" + + " \"points\": [\n" + + " {\n" + + " \"x\": 466,\n" + + " \"y\": 158\n" + + " },\n" + + " {\n" + + " \"x\": 279,\n" + + " \"y\": 158\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"type\": \"RelationView\",\n" + + " \"id\": \"a_.r2.6GAqACHQZv\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " }\n" + + " ],\n" + + " \"type\": \"Diagram\",\n" + + " \"id\": \"mtCr2.6GAqACHQWL\",\n" + + " \"name\": \"Class Diagram1\",\n" + + " \"description\": null\n" + + " },\n" + + " {\n" + + " \"owner\": {\n" + + " \"type\": \"Package\",\n" + + " \"id\": \"Pz4r2.6GAqACHQBO_root\"\n" + + " },\n" + + " \"contents\": [\n" + + " {\n" + + " \"modelElement\": {\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"P3Kr2.6GAqACHQXK\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"width\": 100,\n" + + " \"height\": 50,\n" + + " \"x\": 40,\n" + + " \"y\": 40,\n" + + " \"type\": \"Rectangle\",\n" + + " \"id\": \"3yjrith5k0vkm3qglf0\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " },\n" + + " \"type\": \"ClassView\",\n" + + " \"id\": \"3yjrith5k0vkm3qglez\",\n" + + " \"name\": null,\n" + + " \"description\": null\n" + + " }\n" + + " ],\n" + + " \"type\": \"Diagram\",\n" + + " \"id\": \"3yjrith5k0vkm3qgley\",\n" + + " \"name\": \"Cluster of Class3\",\n" + + " \"description\": null\n" + + " }\n" + + " ],\n" + + " \"type\": \"Project\",\n" + + " \"id\": \"Pz4r2.6GAqACHQBO\",\n" + + " \"name\": \"untitled\",\n" + + " \"description\": null\n" + + " },\n" + + " \"issues\": null\n" + + "}"; + final ModularizationServiceResult serviceResult = + mapper.readValue(json, ModularizationServiceResult.class); + + assertThat(serviceResult).isNotNull(); + assertThat(serviceResult.getResult()).isInstanceOf(Project.class); + assertThat(serviceResult.getIssues()).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResultDeserializationTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResultDeserializationTest.java new file mode 100644 index 00000000..2fda8548 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/VerificationServiceResultDeserializationTest.java @@ -0,0 +1,92 @@ +package it.unibz.inf.ontouml.vp.model; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class VerificationServiceResultDeserializationTest { + + static ObjectMapper mapper; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + } + + @Test + void shouldDeserializeEmptyResult() throws IOException { + final String emptyResult1 = "{\n" + " \"result\": [],\n" + " \"issues\": []\n" + "}"; + final String emptyResult2 = "{\n" + " \"result\": null,\n" + " \"issues\": null\n" + "}"; + final String emptyResult3 = "{\n" + " \"result\": []\n" + "}"; + final String emptyResult4 = "{\n" + " \"issues\": []\n" + "}"; + final List emptyResults = + Arrays.asList(emptyResult1, emptyResult2, emptyResult3, emptyResult4); + + for (String emptyResult : emptyResults) { + VerificationServiceResult serviceResult = + mapper.readValue(emptyResult, VerificationServiceResult.class); + + assertThat(serviceResult).isNotEqualTo(null); + + assertThat(serviceResult.getResult()).isEmpty(); + assertThat(serviceResult.getIssues()).isEmpty(); + } + } + + @Test + void shouldDeserializeVerificationIssues() throws IOException { + final String json = + "{\n" + + " \"result\": [\n" + + " {\n" + + " \"code\": \"class_invalid_ontouml_stereotype\",\n" + + " \"title\": \"No valid OntoUML stereotype\",\n" + + " \"description\": \"The class Class must have a unique OntoUML stereotype.\",\n" + + " \"severity\": \"error\",\n" + + " \"data\": {\n" + + " \"source\": {\n" + + " \"stereotype\": \"kindy\",\n" + + " \"restrictedTo\": [\n" + + " \"functional-complex\"\n" + + " ],\n" + + " \"properties\": null,\n" + + " \"literals\": null,\n" + + " \"isAbstract\": false,\n" + + " \"isDerived\": false,\n" + + " \"isExtensional\": false,\n" + + " \"isPowertype\": false,\n" + + " \"order\": \"1\",\n" + + " \"propertyAssignments\": {},\n" + + " \"type\": \"Class\",\n" + + " \"id\": \"leM15.6GAqACHQWX\",\n" + + " \"name\": \"Class\",\n" + + " \"description\": null\n" + + " },\n" + + " \"context\": []\n" + + " }\n" + + " }\n" + + " ]\n" + + "}"; + final VerificationServiceResult serviceResult = + mapper.readValue(json, VerificationServiceResult.class); + + assertThat(serviceResult).isNotEqualTo(null); + assertThat(serviceResult.getResult()).isNotEmpty(); + assertThat(serviceResult.getResult().get(0)).isInstanceOf(ServiceIssue.class); + + final ServiceIssue issue = serviceResult.getResult().get(0); + assertThat(issue.getId()).isNull(); + assertThat(issue.getCode()).isEqualTo("class_invalid_ontouml_stereotype"); + assertThat(issue.getTitle()).isEqualTo("No valid OntoUML stereotype"); + assertThat(issue.getDescription()) + .isEqualTo("The class Class must have a unique OntoUML stereotype."); + assertThat(issue.getSeverity()).isEqualTo("error"); + assertThat(issue.getSource().getId()).isEqualTo("leM15.6GAqACHQWX"); + assertThat(issue.getContext()).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/CardinalityTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/CardinalityTest.java new file mode 100644 index 00000000..fb7f02a8 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/CardinalityTest.java @@ -0,0 +1,125 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.Cardinality; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class CardinalityTest { + + @Test + @DisplayName("A cardinality of \"1\" should be valid") + void OneShouldBeValid() { + Cardinality c = new Cardinality("1"); + assertThat(c.isValid()).isTrue(); + } + + @Test + @DisplayName("A cardinality of \"1\" sets lowerBound and upperBound to 1") + void oneShouldSetLowerUpperBounds() { + Cardinality c = new Cardinality("1"); + assertThat(c.getLowerBound()).hasValue("1"); + assertThat(c.getUpperBound()).hasValue("1"); + assertThat(c.getLowerBoundAsInt()).isEqualTo(1); + assertThat(c.getUpperBoundAsInt()).isEqualTo(1); + } + + @Test + @DisplayName("A cardinality of \"1..1\" should be valid") + void oneToOneShouldBeValid() { + Cardinality c = new Cardinality("1..1"); + assertThat(c.isValid()).isTrue(); + } + + @Test + @DisplayName("A cardinality of \"1..1\" sets lowerBound and upperBound to 1") + void oneToOneShouldSetLowerUpperBounds() { + Cardinality c = new Cardinality("1..1"); + assertThat(c.getLowerBound()).hasValue("1"); + assertThat(c.getUpperBound()).hasValue("1"); + assertThat(c.getLowerBoundAsInt()).isEqualTo(1); + assertThat(c.getUpperBoundAsInt()).isEqualTo(1); + } + + @Test + @DisplayName("A cardinality of \"1..*\" should be valid") + void oneToManyShouldBeValid() { + Cardinality c = new Cardinality("1..*"); + assertThat(c.isValid()).isTrue(); + } + + @Test + @DisplayName( + "A cardinality of \"1..*\" sets lowerBound to 1 and upperBound to */Integer.MAX_VALUE") + void oneToManyShouldSetLowerUpperBounds() { + Cardinality c = new Cardinality("1..*"); + assertThat(c.getLowerBound()).hasValue("1"); + assertThat(c.getUpperBound()).hasValue("*"); + assertThat(c.getLowerBoundAsInt()).isEqualTo(1); + assertThat(c.getUpperBoundAsInt()).isEqualTo(Integer.MAX_VALUE); + } + + @Test + @DisplayName("A cardinality of \"0..*\" should be valid") + void zeroToManyShouldBeValid() { + Cardinality c = new Cardinality("0..*"); + assertThat(c.isValid()).isTrue(); + } + + @Test + @DisplayName("A cardinality of \"0..*\" sets lowerBound to 0 and upperBound to Integer.MAX_VALUE") + void zeroToManyShouldSetLowerUpperBounds() { + Cardinality c = new Cardinality("0..*"); + assertThat(c.getLowerBound()).hasValue("0"); + assertThat(c.getUpperBound()).hasValue("*"); + assertThat(c.getLowerBoundAsInt()).isEqualTo(0); + assertThat(c.getUpperBoundAsInt()).isEqualTo(Integer.MAX_VALUE); + } + + @Test + @DisplayName("A cardinality of \"1..3\" should be valid") + void zeroToThreeShouldBeValid() { + Cardinality c = new Cardinality("1..3"); + assertThat(c.isValid()).isTrue(); + } + + @Test + @DisplayName("A cardinality of \"1..3\" sets lowerBound to 1 and upperBound to 3") + void oneToThreeShouldSetLowerUpperBounds() { + Cardinality c = new Cardinality("1..3"); + assertThat(c.getLowerBound()).hasValue("1"); + assertThat(c.getUpperBound()).hasValue("3"); + assertThat(c.getLowerBoundAsInt()).isEqualTo(1); + assertThat(c.getUpperBoundAsInt()).isEqualTo(3); + } + + @Test + @DisplayName("A cardinality of \"a..b\" should NOT be valid") + void cardinalitiesWithLettersAreInvalid() { + Cardinality c = new Cardinality("a..b"); + assertThat(c.isValid()).isFalse(); + } + + @Test + @DisplayName( + "An invalid cardinality of \"a..b\" should still set lower and upper if in the correct" + + " pattern") + void invalidCardinalitySetsLowerUpper() { + Cardinality c = new Cardinality("a..b"); + assertThat(c.getLowerBound()).hasValue("a"); + assertThat(c.getUpperBound()).hasValue("b"); + } + + @Test + @DisplayName( + "An invalid cardinality of \"a..b\" should throw exceptions on getLowerBoundAsInt() and" + + " getUpperBoundAsInt()") + void invalidCardinalityShouldThrowExceptionOnGetAsInt() { + Cardinality c = new Cardinality("a..b"); + assertThrows(NumberFormatException.class, () -> c.getLowerBoundAsInt()); + assertThrows(NumberFormatException.class, () -> c.getUpperBoundAsInt()); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassStereotypeTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassStereotypeTest.java new file mode 100644 index 00000000..55ce07ea --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassStereotypeTest.java @@ -0,0 +1,40 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth8.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.ClassStereotype; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ClassStereotypeTest { + + @Test + @DisplayName("Should find class stereotype by name: mode") + void findMode() { + assertThat(ClassStereotype.findByName("mode")).hasValue(ClassStereotype.MODE); + } + + @Test + @DisplayName("Should find class stereotype by name: roleMixin") + void findRoleMixin() { + assertThat(ClassStereotype.findByName("roleMixin")).hasValue(ClassStereotype.ROLE_MIXIN); + } + + @Test + @DisplayName("Should find class stereotype by name: event") + void findEvent() { + assertThat(ClassStereotype.findByName("event")).hasValue(ClassStereotype.EVENT); + } + + @Test + @DisplayName("Should not find stereotype if not correctly capitalied") + void shouldNotFindRoleMixin() { + assertThat(ClassStereotype.findByName("RoleMixin")).isEmpty(); + } + + @Test + @DisplayName("Should not find stereotype names with spaces") + void shouldNotFindWithSpaces() { + assertThat(ClassStereotype.findByName("phase Mixin")).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassTest.java new file mode 100644 index 00000000..481947a0 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ClassTest.java @@ -0,0 +1,51 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class ClassTest { + + @Test + void shouldReturnAttributesAsContent() { + Class person = Class.createKind("c1", "Person"); + Property name = person.createAttribute("p1", "name", null); + Property age = person.createAttribute("p2", "age", null); + + List contents = person.getContents(); + assertThat(contents).hasSize(2); + assertThat(contents).isEqualTo(List.of(name, age)); + } + + @Test + void shouldReturnLiteralsAsContent() { + Class color = Class.createEnumeration("c1", "Color"); + Literal red = color.createLiteral("red"); + Literal blue = color.createLiteral("blue"); + + List contents = color.getContents(); + assertThat(contents).hasSize(2); + assertThat(contents).isEqualTo(List.of(red, blue)); + } + + @Test + void shouldBePrimitiveDatatype() { + Class primitive = Class.createDatatype("1", "string"); + assertThat(primitive.isPrimitiveDatatype()).isTrue(); + } + + @Test + void shouldNotBePrimitiveDatatype() { + Class color = Class.createDatatype("1", "color"); + Class number = Class.createDatatype("1", "number"); + color.createAttribute("red", number); + color.createAttribute("green", number); + color.createAttribute("blue", number); + + assertThat(color.isPrimitiveDatatype()).isFalse(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualTextTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualTextTest.java new file mode 100644 index 00000000..9957e772 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/MultilingualTextTest.java @@ -0,0 +1,86 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class MultilingualTextTest { + MultilingualText text = new MultilingualText(); + + @Test + @DisplayName("Should retrieve text in the correct language") + void getTextItalian() { + text.putText("en", "Hello"); + text.putText("it", "Ciao"); + + Optional value = text.getText("it"); + assertThat(value).isPresent(); + assertThat(value).hasValue("Ciao"); + } + + @Test + @DisplayName("If the requested language does not exist, getText() should return the English text") + void shouldGetEnglishOnMissing() { + text.putText("en", "Hello"); + text.putText("it", "Ciao"); + + Optional value = text.getText("pt"); + assertThat(value).isPresent(); + assertThat(value).hasValue("Hello"); + } + + @Test + @DisplayName( + "If the requested language does not exist and there is no English text, getText() should" + + " retrieve text in the first available language (in alphabetical order)") + void shouldGetFirstLangaugeOnMissing() { + text.putText("pt", "Oi"); + text.putText("it", "Ciao"); + + Optional value = text.getText("es"); + assertThat(value).isPresent(); + assertThat(value).hasValue("Ciao"); + } + + @Test + @DisplayName("If no language is specified, getText() should return the English text") + void shouldGetEnglishByDefault() { + text.putText("cz", "Ahoj"); + text.putText("en", "Hello"); + text.putText("it", "Ciao"); + + Optional value = text.getText(); + assertThat(value).isPresent(); + assertThat(value).hasValue("Hello"); + } + + @Test + @DisplayName( + "If no language is specified, and there is no English text, getText() should retrieve text" + + " in the first available language (in alphabetical order)") + void shouldGetFirstLangaugeByDefault() { + text.putText("pt", "Oi"); + text.putText("es", "Hola"); + text.putText("it", "Ciao"); + + Optional value = text.getText(); + assertThat(value).isPresent(); + assertThat(value).hasValue("Hola"); + } + + @Test + @DisplayName("Constructor clones multilingual text") + void constructorShouldClone() { + text.putText("it", "Ciao"); + MultilingualText clone = new MultilingualText(text); + + Optional value = clone.getText("it"); + assertThat(value).isPresent(); + assertThat(value).hasValue("Ciao"); + assertThat(clone.getLanguages()).hasSize(1); + assertThat(clone.getLanguages()).contains("it"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/PackageTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/PackageTest.java new file mode 100644 index 00000000..cf067aed --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/PackageTest.java @@ -0,0 +1,131 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PackageTest { + Project project = new Project(); + Package model = project.createModel(); + Package pkg = model.createPackage(); + Class clazz = model.createClass(); + Relation relation = model.createRelation(clazz, clazz); + Generalization generalization = model.createGeneralization(clazz, clazz); + GeneralizationSet genSet = model.createGeneralizationSet(generalization); + + @Test + @DisplayName("createClass() should set the caller as the container of the new class.") + void shouldPropagateCallerAsContainer() { + assertThat(clazz.getContainer()).hasValue(model); + } + + @Test + @DisplayName("createClass() should set propagate the caller's project to the new class.") + void shouldPropagateCallerAsProject() { + assertThat(clazz.getProject()).hasValue(project); + } + + @Test + @DisplayName("createClass() should create a class without attributes.") + void shouldHaveNoAttributes() { + assertThat(clazz.getAttributes()).hasSize(0); + } + + @Test + @DisplayName("createEnumeration() should create a class with the Enumeration stereotype.") + void shouldHaveEnumerationStereotype() { + Class clazz = model.createEnumeration(new String[] {"Red", "Blue", "Green"}); + assertThat(clazz.getOntoumlStereotype()).hasValue(ClassStereotype.ENUMERATION); + } + + @Test + @DisplayName("createEnumeration() should create a class with the Enumeration stereotype.") + void shouldCreateLiterals() { + Class clazz = model.createEnumeration(new String[] {"Red", "Blue", "Green"}); + List literals = clazz.getLiterals(); + + assertThat(literals).hasSize(3); + assertThat(literals).containsNoDuplicates(); + + assertThat(literals.stream().map(l -> l.getFirstName().orElse(""))) + .containsExactly("Red", "Blue", "Green"); + } + + @Test + @DisplayName("createRelation() should set the caller as the container of the new class.") + void shouldPropagateCallerAsContainerOfRelation() { + assertThat(relation.getContainer()).hasValue(model); + ; + } + + @Test + @DisplayName("createRelation() should set propagate the caller's project to the new class.") + void shouldPropagateCallerAsProjectOfRelation() { + assertThat(relation.getProject()).hasValue(project); + ; + } + + @Test + @DisplayName("createRelation() should create a class without attributes.") + void shouldCreateBinaryRelation() { + assertThat(relation.getProperties()).hasSize(2); + } + + @Test + @DisplayName("createPackage() should set the caller as the container of the new class.") + void shouldPropagateCallerAsContainerOfPackage() { + assertThat(pkg.getContainer()).hasValue(model); + } + + @Test + @DisplayName("createPackage() should set propagate the caller's project to the new class.") + void shouldPropagateCallerAsProjectOfPackage() { + assertThat(pkg.getProject()).hasValue(project); + } + + @Test + @DisplayName("createGeneralization() should set the caller as the container of the new class.") + void shouldPropagateCallerAsContainerOfGeneralization() { + assertThat(generalization.getContainer()).hasValue(model); + } + + @Test + @DisplayName("createGeneralization() should set propagate the caller's project to the new class.") + void shouldPropagateCallerAsProjectOfGeneralization() { + assertThat(generalization.getProject()).hasValue(project); + } + + @Test + @DisplayName("createGeneralizationSet() should set the caller as the container of the new class.") + void shouldPropagateCallerAsContainerOfGeneralizationSet() { + assertThat(genSet.getContainer()).hasValue(model); + } + + @Test + @DisplayName( + "createGeneralizationSet() should set propagate the caller's project to the new class.") + void shouldPropagateCallerAsProjectOfGeneralizationSet() { + assertThat(genSet.getProject()).hasValue(project); + } + + @Test + void getContentsShouldReturnChildren() { + assertThat(model.getContents()).containsExactly(pkg, clazz, relation, generalization, genSet); + } + + @Test + void modelShouldBeRoot() { + assertThat(model.isRoot()).isTrue(); + } + + @Test + void childPackageShouldNotBeRoot() { + assertThat(pkg.isRoot()).isFalse(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ProjectTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ProjectTest.java new file mode 100644 index 00000000..6eff0a4d --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/ProjectTest.java @@ -0,0 +1,109 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ProjectTest { + Project project = new Project(); + Package model = project.createModel(); + + @Test + @DisplayName("Upon construction, the project field of a Project instance is the instance itself.") + void getProjectOnProejct() { + assertThat(project.getProject()).hasValue(project); + } + + @Test + @DisplayName("createModel() should create and return a new Package.") + void createModelShouldReturnNewPackage() { + assertThat(model).isNotNull(); + } + + @Test + @DisplayName("createModel() should create a new Package and set it as the project model.") + void createModelShouldSetProjectModel() { + assertThat(project.getModel()).hasValue(model); + } + + @Test + @DisplayName("createModel() should create a Package with the caller as its container.") + void createdModelShouldHaveCallerAsContainer() { + assertThat(model.getContainer()).hasValue(project); + } + + @Test + @DisplayName("createModel() should create a Package with the caller as its project.") + void createdModelShouldHaveCallerAsProject() { + assertThat(model.getProject()).hasValue(project); + } + + @Test + @DisplayName("setModel() should set the container of the argument.") + void setModelShouldSetContainerOfArgument() { + Package anotherModel = new Package(); + project.setModel(anotherModel); + + assertThat(anotherModel.getContainer()).hasValue(project); + } + + @Test + @DisplayName("setModel() should set the project of the argument.") + void setModelShouldSetProjectOfArgument() { + Package anotherModel = new Package(); + project.setModel(anotherModel); + + assertThat(anotherModel.getProject()).hasValue(project); + } + + @Test + @DisplayName( + "setModel() should propagate the caller as the project of the all direct contents of the" + + " argument.") + void setModelShouldPropagateProject() { + Package anotherModel = new Package(); + Package firstChild = anotherModel.createPackage(); + Package secondChild = anotherModel.createPackage(); + + project.setModel(anotherModel); + + assertThat(firstChild.getProject()).hasValue(project); + assertThat(secondChild.getProject()).hasValue(project); + } + + @Test + @DisplayName( + "setModel() should propagate the caller as the project of the all direct/indirect contents" + + " of the argument.") + void setModelShouldPropagateProjectToAll() { + Package anotherModel = new Package(); + Class c1 = anotherModel.createClass(); + Property p1 = c1.createAttribute("name", c1); + + Package pk1 = anotherModel.createPackage(); + Class c2 = pk1.createEnumeration(new String[] {"Red", "Blue", "Green"}); + Generalization g1 = pk1.createGeneralization(c1, c2); + Relation r1 = pk1.createRelation(c1, c2); + + Package pk2 = pk1.createPackage(); + + project.setModel(anotherModel); + + Stream.of(c1, c2, p1, g1, r1, pk2) + .forEach(element -> assertThat(element.getProject()).hasValue(project)); + } + + @Test + void getAllContentsShouldReturnClassAttributes() { + Class person = model.createKind("c1", "Person"); + Property name = person.createAttribute("p1", "name", null); + + assertThat(project.getAllContents()).contains(name); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationStereotypeTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationStereotypeTest.java new file mode 100644 index 00000000..527cb452 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationStereotypeTest.java @@ -0,0 +1,42 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth8.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.RelationStereotype; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class RelationStereotypeTest { + + @Test + @DisplayName("Should find relation stereotype by name: material") + void findMode() { + assertThat(RelationStereotype.findByName("material")).hasValue(RelationStereotype.MATERIAL); + } + + @Test + @DisplayName("Should find relation stereotype by name: externalDependence") + void findRoleMixin() { + assertThat(RelationStereotype.findByName("externalDependence")) + .hasValue(RelationStereotype.EXTERNAL_DEPENDENCE); + } + + @Test + @DisplayName("Should find relation stereotype by name: componentOf") + void findEvent() { + assertThat(RelationStereotype.findByName("componentOf")) + .hasValue(RelationStereotype.COMPONENT_OF); + } + + @Test + @DisplayName("Should not find relation stereotype if not correctly capitalized") + void shouldNotFindRoleMixin() { + assertThat(RelationStereotype.findByName("MATERIAL")).isEmpty(); + } + + @Test + @DisplayName("Should not find relation stereotype if spaces are included") + void shouldNotFindWithSpaces() { + assertThat(RelationStereotype.findByName("component Of")).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationTest.java new file mode 100644 index 00000000..cc412a12 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/RelationTest.java @@ -0,0 +1,44 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class RelationTest { + + @Test + void shouldReturnEndsAsContent() { + Class person = Class.createKind("Person"); + Relation knows = Relation.createMaterial("knows", person, person); + + List contents = knows.getContents(); + assertThat(contents).hasSize(2); + + contents.forEach( + element -> { + assertThat(element).isInstanceOf(Property.class); + }); + } + + @Test + void shouldHoldBetweenClasses() { + Class person = Class.createKind("Person"); + Relation knows = Relation.createMaterial("knows", person, person); + + assertThat(knows.holdsBetweenClasses()).isTrue(); + } + + @Test + void shouldNotHoldBetweenClasses() { + Class person = Class.createKind("Person"); + Relation loves = Relation.createMaterial("loves", person, person); + Class love = Class.createMode("Love"); + Relation derivation = Relation.createDerivation(love, loves); + + assertThat(derivation.holdsBetweenClasses()).isFalse(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/StereotypeTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/StereotypeTest.java new file mode 100644 index 00000000..470656c0 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/StereotypeTest.java @@ -0,0 +1,57 @@ +package it.unibz.inf.ontouml.vp.model.ontouml; + +import static com.google.common.truth.Truth8.assertThat; + +import it.unibz.inf.ontouml.vp.model.ontouml.model.ClassStereotype; +import it.unibz.inf.ontouml.vp.model.ontouml.model.PropertyStereotype; +import it.unibz.inf.ontouml.vp.model.ontouml.model.RelationStereotype; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Stereotype; +import org.junit.jupiter.api.Test; + +class StereotypeTest { + + @Test + void findKindByName() { + assertThat(Stereotype.findByName(ClassStereotype.class, "kind")).hasValue(ClassStereotype.KIND); + } + + @Test + void findRoleMixinByName() { + assertThat(Stereotype.findByName(ClassStereotype.class, "roleMixin")) + .hasValue(ClassStereotype.ROLE_MIXIN); + } + + @Test + void findMaterialByName() { + assertThat(Stereotype.findByName(RelationStereotype.class, "material")) + .hasValue(RelationStereotype.MATERIAL); + } + + @Test + void findExternalDependenceByName() { + assertThat(Stereotype.findByName(RelationStereotype.class, "externalDependence")) + .hasValue(RelationStereotype.EXTERNAL_DEPENDENCE); + } + + @Test + void findBeginByName() { + assertThat(Stereotype.findByName(PropertyStereotype.class, "begin")) + .hasValue(PropertyStereotype.BEGIN); + } + + @Test + void findEndByName() { + assertThat(Stereotype.findByName(PropertyStereotype.class, "end")) + .hasValue(PropertyStereotype.END); + } + + @Test + void findByNameCaseSensitive() { + assertThat(Stereotype.findByName(ClassStereotype.class, "Kind")).isEmpty(); + } + + @Test + void findByNameSpaceSensitive() { + assertThat(Stereotype.findByName(RelationStereotype.class, "role Mixin")).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializerTest.java new file mode 100644 index 00000000..3ec72b85 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassDeserializerTest.java @@ -0,0 +1,217 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ClassStereotype; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Literal; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Nature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import java.io.IOException; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ClassDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"c1\",\n" + + " \"name\" : \n{" + + " \"en\" : \"My Class\",\n" + + " \"pt\" : \"Minha Classe\"\n" + + " },\n" + + " \"description\" : \n{" + + " \"en\" : \"My description.\",\n" + + " \"pt\" : \"Minha descrição.\"\n" + + " },\n" + + " \"type\" : \"Class\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : \"category\",\n" + + " \"isAbstract\" : true,\n" + + " \"isDerived\" : true,\n" + + " \"properties\" : [ {\n" + + " \"id\" : \"a1\",\n" + + " \"name\" : \"name\",\n" + + " \"description\" : null,\n" + + " \"type\" : \"Property\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : null,\n" + + " \"isDerived\" : true,\n" + + " \"isReadOnly\" : true,\n" + + " \"isOrdered\" : true,\n" + + " \"cardinality\" : \"1..*\",\n" + + " \"propertyType\" : {\n" + + " \"id\" : \"ref1\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"subsettedProperties\" : null,\n" + + " \"redefinedProperties\" : null,\n" + + " \"aggregationKind\" : null\n" + + " },{\n" + + " \"id\" : \"a2\",\n" + + " \"name\" : \"age\",\n" + + " \"description\" : null,\n" + + " \"type\" : \"Property\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : null,\n" + + " \"isDerived\" : false,\n" + + " \"isReadOnly\" : false,\n" + + " \"isOrdered\" : false,\n" + + " \"cardinality\" : \"1\",\n" + + " \"propertyType\" : {\n" + + " \"id\" : \"ref2\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"subsettedProperties\" : null,\n" + + " \"redefinedProperties\" : null,\n" + + " \"aggregationKind\" : null\n" + + " } ],\n" + + " \"isExtensional\" : true,\n" + + " \"isPowertype\" : true,\n" + + " \"order\" : 1,\n" + + " \"literals\" : [{" + + " \"id\": \"l1\"," + + " \"type\": \"Literal\"," + + " \"name\": \"red\"," + + " \"description\": \"null\"," + + " \"propertyAssignments\": \"null\"" + + " }],\n" + + " \"restrictedTo\" : [ \"functional-complex\", \"collective\", \"quantity\" ]\n" + + "}"; + + static ObjectMapper mapper; + static Class clazz; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + clazz = mapper.readValue(json, Class.class); + } + + @Test + void shouldDeserializeReference() throws IOException { + String jsonReference = "{ \"id\": \"c1\", \"type\":\"Class\"}"; + Class clazz = mapper.readValue(jsonReference, Class.class); + + assertThat(clazz.getId()).isEqualTo("c1"); + assertThat(clazz.getFirstName()).isEmpty(); + assertThat(clazz.getStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeId() { + assertThat(clazz.getId()).isEqualTo("c1"); + } + + @Test + void shouldDeserializeName() { + assertThat(clazz.getNameIn("en")).hasValue("My Class"); + assertThat(clazz.getNameIn("pt")).hasValue("Minha Classe"); + } + + @Test + void shouldDeserializeDescription() { + assertThat(clazz.getDescriptionIn("pt")).hasValue("Minha descrição."); + assertThat(clazz.getDescriptionIn("en")).hasValue("My description."); + } + + @Test + void shouldDeserializeIsAbstract() { + assertThat(clazz.isAbstract()).isTrue(); + } + + @Test + void shouldDeserializeIsDerived() { + assertThat(clazz.isDerived()).isTrue(); + } + + @Test + void shouldDeserializeIsExtensional() { + assertThat(clazz.isExtensional()).hasValue(true); + } + + @Test + void shouldDeserializeIsPowertype() { + assertThat(clazz.isPowertype()).hasValue(true); + } + + @Test + void shouldDeserializeOrder() { + assertThat(clazz.getOrder()).hasValue(1); + } + + @Test + void shouldDeserializeRestrictedTo() { + assertThat(clazz.getRestrictedTo()) + .containsExactly(Nature.FUNCTIONAL_COMPLEX, Nature.COLLECTIVE, Nature.QUANTITY); + } + + @Test + void shouldDeserializeAllProperties() { + List properties = clazz.getProperties(); + assertThat(properties).hasSize(2); + } + + @Test + void shouldDeserializePropertiesInTheCorrectOrder() { + List properties = clazz.getProperties(); + Property a1 = properties.get(0); + assertThat(a1.getId()).isEqualTo("a1"); + Property a2 = properties.get(1); + assertThat(a2.getId()).isEqualTo("a2"); + } + + @Test + void shouldDeserializePropertyData() { + List properties = clazz.getProperties(); + Property a1 = properties.get(0); + assertThat(a1.getId()).isEqualTo("a1"); + assertThat(a1.isDerived()).isTrue(); + assertThat(a1.isOrdered()).isTrue(); + assertThat(a1.isReadOnly()).isTrue(); + assertThat(a1.getFirstName()).hasValue("name"); + assertThat(a1.getCardinality().getValue()).hasValue("1..*"); + assertThat(a1.getPropertyType()).isPresent(); + assertThat(a1.getPropertyType().get().getId()).isEqualTo("ref1"); + } + + @Test + void shouldDeserializeLiterals() { + assertThat(clazz.getLiterals()).hasSize(1); + + Literal literal = clazz.getLiterals().get(0); + assertThat(literal.getId()).isEqualTo("l1"); + assertThat(literal.getFirstName()).hasValue("red"); + } + + @Test + void shouldDeserializeOntoumlStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"c1\",\n" + + " \"type\": \"Class\",\n" + + " \"stereotype\": \"kind\"\n" + + "}"; + + Class clazz = mapper.readValue(json, Class.class); + assertThat(clazz.getOntoumlStereotype()).hasValue(ClassStereotype.KIND); + assertThat(clazz.getCustomStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeCustomStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"c1\",\n" + + " \"type\": \"Class\",\n" + + " \"stereotype\": \"custom\"\n" + + "}"; + + Class clazz = mapper.readValue(json, Class.class); + assertThat(clazz.getOntoumlStereotype()).isEmpty(); + assertThat(clazz.getCustomStereotype()).hasValue("custom"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializerTest.java new file mode 100644 index 00000000..58c71c6c --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ClassViewDeserializerTest.java @@ -0,0 +1,104 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ClassViewDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static String json = + "{\n" + + " \"id\": \"cv1\",\n" + + " \"type\": \"ClassView\",\n" + + " \"modelElement\": {\n" + + " \"id\": \"cl1\",\n" + + " \"type\": \"Class\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"id\": \"re1\",\n" + + " \"type\": \"Rectangle\",\n" + + " \"x\": 813,\n" + + " \"y\": 72,\n" + + " \"width\": 95,\n" + + " \"height\": 40\n" + + " }\n" + + "}"; + + static ClassView view; + static Rectangle shape; + + @BeforeAll + static void beforeAll() throws IOException { + view = mapper.readValue(json, ClassView.class); + shape = view.getShape(); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"1\", \"type\": \"ClassView\"}"; + ClassView view = mapper.readValue(json, ClassView.class); + + assertThat(view.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializeId() { + assertThat(view.getId()).isEqualTo("cv1"); + } + + @Test + void shouldDeserializeModelElement() { + assertThat(view.getModelElement().getId()).isEqualTo("cl1"); + } + + @Test + void shouldDeserializeX() { + assertThat(view.getX()).isEqualTo(813); + } + + @Test + void shouldDeserializeY() { + assertThat(view.getY()).isEqualTo(72); + } + + @Test + void shouldDeserializeWidth() { + assertThat(view.getWidth()).isEqualTo(95); + } + + @Test + void shouldDeserializeHeight() { + assertThat(view.getHeight()).isEqualTo(40); + } + + @Test + void shouldDeserializeShape() { + assertThat(shape.getId()).isEqualTo("re1"); + } + + @Test + void shouldDeserializeShapeX() { + assertThat(shape.getX()).isEqualTo(813); + } + + @Test + void shouldDeserializeShapeY() { + assertThat(shape.getY()).isEqualTo(72); + } + + @Test + void shouldDeserializeShapeWidth() { + assertThat(shape.getWidth()).isEqualTo(95); + } + + @Test + void shouldDeserializeShapeHeight() { + assertThat(shape.getHeight()).isEqualTo(40); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializerTest.java new file mode 100644 index 00000000..eb374ef9 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/DiagramDeserializerTest.java @@ -0,0 +1,181 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Diagram; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class DiagramDeserializerTest { + + static String json = + "{\n" + + " \"id\": \"d1\",\n" + + " \"name\": \"My Diagram\",\n" + + " \"description\": \"My diagram used for testing.\",\n" + + " \"type\": \"Diagram\",\n" + + " \"contents\": [\n" + + " {\n" + + " \"id\": \"cv1\",\n" + + " \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c1\", \"type\": \"Class\" },\n" + + " \"shape\": {\n" + + " \"id\": \"re1\",\n" + + " \"type\": \"Rectangle\",\n" + + " \"x\": 813,\n" + + " \"y\": 72,\n" + + " \"width\": 95,\n" + + " \"height\": 40\n" + + " }\n" + + " },\n" + + " {\n" + + " \"id\": \"cv2\",\n" + + " \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c2\", \"type\": \"Class\" },\n" + + " \"shape\": {\n" + + " \"id\": \"re2\",\n" + + " \"type\": \"Rectangle\",\n" + + " \"x\": 608,\n" + + " \"y\": 234,\n" + + " \"width\": 89,\n" + + " \"height\": 50\n" + + " }\n" + + " },\n" + + " {\n" + + " \"id\": \"cv3\",\n" + + " \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c3\", \"type\": \"Class\" },\n" + + " \"shape\": {\n" + + " \"id\": \"iqX7Nu6GAqACBBip_shape\",\n" + + " \"type\": \"Rectangle\",\n" + + " \"x\": 550,\n" + + " \"y\": 72,\n" + + " \"width\": 91,\n" + + " \"height\": 40\n" + + " }\n" + + " },\n" + + " {\n" + + " \"id\": \"rv1\",\n" + + " \"type\": \"RelationView\",\n" + + " \"modelElement\": { \"id\": \"r1\", \"type\": \"Relation\" },\n" + + " \"shape\": {\n" + + " \"id\": \"pa1\",\n" + + " \"type\": \"Path\",\n" + + " \"points\": [\n" + + " { \"x\": 100, \"y\": 20 },\n" + + " { \"x\": 100, \"y\": 200 }\n" + + " ]\n" + + " },\n" + + " \"source\": { \"id\": \"cv2\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv3\", \"type\": \"ClassView\" }\n" + + " },\n" + + " {\n" + + " \"id\": \"gv1\",\n" + + " \"type\": \"GeneralizationView\",\n" + + " \"modelElement\": { \"id\": \"g1\", \"type\": \"Generalization\" },\n" + + " \"shape\": {\n" + + " \"id\": \"pa2\",\n" + + " \"type\": \"Path\",\n" + + " \"points\": [\n" + + " { \"x\": 270, \"y\": 118 },\n" + + " { \"x\": 270, \"y\": 168 }\n" + + " ]\n" + + " },\n" + + " \"source\": { \"id\": \"cv1\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv2\", \"type\": \"ClassView\" }\n" + + " },\n" + + " {\n" + + " \"id\": \"gv2\",\n" + + " \"type\": \"GeneralizationView\",\n" + + " \"modelElement\": { \"id\": \"g2\", \"type\": \"Generalization\" },\n" + + " \"shape\": {\n" + + " \"id\": \"pa3\",\n" + + " \"type\": \"Path\",\n" + + " \"points\": [\n" + + " { \"x\": 270, \"y\": 118 },\n" + + " { \"x\": 270, \"y\": 168 }\n" + + " ]\n" + + " },\n" + + " \"source\": {\n" + + " \"id\": \"cv1\",\n" + + " \"type\": \"ClassView\"\n" + + " },\n" + + " \"target\": {\n" + + " \"id\": \"cv3\",\n" + + " \"type\": \"ClassView\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"id\": \"gsv1\",\n" + + " \"type\": \"GeneralizationSetView\",\n" + + " \"modelElement\": { \"id\": \"gs1\", \"type\": \"GeneralizationSet\" },\n" + + " \"shape\": {\n" + + " \"id\": \"tx1\",\n" + + " \"type\": \"Text\",\n" + + " \"x\": 130,\n" + + " \"y\": 109,\n" + + " \"width\": 78,\n" + + " \"height\": 42\n" + + " }\n" + + " }\n" + + " ]\n" + + "}"; + + static ObjectMapper mapper; + static Diagram diagram; + + @BeforeAll + static void beforeAll() throws IOException { + mapper = new ObjectMapper(); + diagram = mapper.readValue(json, Diagram.class); + } + + @Test + void shouldDeserializeId() { + assertThat(diagram.getId()).isEqualTo("d1"); + } + + @Test + void shouldDeserializeName() { + assertThat(diagram.getFirstName()).hasValue("My Diagram"); + } + + @Test + void shouldDeserializDescription() { + assertThat(diagram.getFirstDescription()).hasValue("My diagram used for testing."); + } + + @Test + void shouldDeserializeContents() { + assertThat(diagram.getContents()).hasSize(7); + } + + @Test + void shouldDeserializeClasses() { + List views = + diagram.getContents().stream() + .filter(ClassView.class::isInstance) + .map(ClassView.class::cast) + .collect(Collectors.toList()); + + assertThat(views).hasSize(3); + + ClassView classView = + views.stream().filter(v -> v.getId().equals("cv1")).findFirst().orElse(null); + assertThat(classView).isNotNull(); + + Rectangle rectangle = classView.getShape(); + assertThat(rectangle).isNotNull(); + + assertThat(rectangle.getId()).isEqualTo("re1"); + assertThat(rectangle.getX()).isEqualTo(813); + assertThat(rectangle.getWidth()).isEqualTo(95); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializerTest.java new file mode 100644 index 00000000..23b0e40b --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationDeserializerTest.java @@ -0,0 +1,81 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Classifier; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import java.io.IOException; +import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class GeneralizationDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"g1\",\n" + + " \"type\" : \"Generalization\",\n" + + " \"name\" : {\n" + + " \"en\" : \"My Generalization\",\n" + + " \"pt\" : \"Minha Generalization\"\n" + + " },\n" + + " \"description\" : {\n" + + " \"pt\" : \"Minha descrição.\",\n" + + " \"en\" : \"My description.\"\n" + + " },\n" + + " \"general\" : {\n" + + " \"id\" : \"c1\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"specific\" : {\n" + + " \"id\" : \"c2\",\n" + + " \"type\" : \"Class\"\n" + + " }\n" + + "}"; + + static ObjectMapper mapper; + static Generalization gen; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + gen = mapper.readValue(json, Generalization.class); + } + + @Test + void shouldDeserializeId() { + assertThat(gen.getId()).isEqualTo("g1"); + } + + @Test + void shouldDeserializeName() { + assertThat(gen.getNameIn("en")).hasValue("My Generalization"); + assertThat(gen.getNameIn("pt")).hasValue("Minha Generalization"); + } + + @Test + void shouldDeserializeDescription() { + assertThat(gen.getDescriptionIn("en")).hasValue("My description."); + assertThat(gen.getDescriptionIn("pt")).hasValue("Minha descrição."); + } + + @Test + void shouldDeserializeGeneral() { + Optional> general = gen.getGeneral(); + + assertThat(general).isPresent(); + assertThat(general.get().getId()).isEqualTo("c1"); + assertThat(general.get().getFirstName()).isEmpty(); + } + + @Test + void shouldDeserializeSpecific() { + Optional> specific = gen.getSpecific(); + + assertThat(specific).isPresent(); + assertThat(specific.get().getId()).isEqualTo("c2"); + assertThat(specific.get().getFirstName()).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializerTest.java new file mode 100644 index 00000000..9ce5891a --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetDeserializerTest.java @@ -0,0 +1,91 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import java.io.IOException; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class GeneralizationSetDeserializerTest { + + String json = + "{\n" + + " \"id\" : \"gs1\",\n" + + " \"name\" : null,\n" + + " \"description\" : null,\n" + + " \"type\" : \"GeneralizationSet\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"isDisjoint\" : true,\n" + + " \"isComplete\" : true,\n" + + " \"categorizer\" : {\n" + + " \"id\" : \"c1\",\n" + + " \"type\" : \"Class\"\n" + + " }," + + " \"generalizations\" : [ {\n" + + " \"id\" : \"g1\",\n" + + " \"type\" : \"Generalization\"\n" + + " }, {\n" + + " \"id\" : \"g2\",\n" + + " \"type\" : \"Generalization\"\n" + + " } ]\n" + + "} ]"; + + ObjectMapper mapper; + GeneralizationSet gs; + + @BeforeEach + void setUp() throws IOException { + mapper = new ObjectMapper(); + gs = mapper.readValue(json, GeneralizationSet.class); + } + + @Test + void shouldDeserializeId() { + assertThat(gs.getId()).isEqualTo("gs1"); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"gs1\", \"type\": \"GeneralizationSet\"}"; + GeneralizationSet gs = mapper.readValue(json, GeneralizationSet.class); + assertThat(gs.getId()).isEqualTo("gs1"); + } + + @Test + void shouldDeserializeIsComplete() { + assertThat(gs.isComplete()).isTrue(); + } + + @Test + void shouldDeserializeIsDisjoint() { + assertThat(gs.isDisjoint()).isTrue(); + } + + @Test + void shouldDeserializeGeneralizations() { + Set generalizations = gs.getGeneralizations(); + + assertThat(generalizations).hasSize(2); + + Set ids = + generalizations.stream().map(Generalization::getId).collect(Collectors.toSet()); + + assertThat(ids).containsExactly("g1", "g2"); + } + + @Test + void shouldDeserializeCategorizer() { + Optional categorizer = gs.getCategorizer(); + + assertThat(categorizer).isPresent(); + assertThat(categorizer.get().getId()).isEqualTo("c1"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializerTest.java new file mode 100644 index 00000000..9e11431a --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationSetViewDeserializerTest.java @@ -0,0 +1,104 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationSetView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Text; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class GeneralizationSetViewDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static String json = + "{\n" + + " \"id\": \"gsv1\",\n" + + " \"type\": \"GeneralizationSetView\",\n" + + " \"modelElement\": {\n" + + " \"id\": \"gs1\",\n" + + " \"type\": \"GeneralizationSet\"\n" + + " },\n" + + " \"shape\": {\n" + + " \"id\": \"tx1\",\n" + + " \"type\": \"Text\",\n" + + " \"x\": 417,\n" + + " \"y\": 191,\n" + + " \"width\": 60,\n" + + " \"height\": 20\n" + + " }\n" + + "}"; + + static GeneralizationSetView view; + static Text shape; + + @BeforeAll + static void beforeAll() throws IOException { + view = mapper.readValue(json, GeneralizationSetView.class); + shape = view.getShape(); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"1\", \"type\": \"GeneralizationSetView\"}"; + GeneralizationSetView view = mapper.readValue(json, GeneralizationSetView.class); + + assertThat(view.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializeId() { + assertThat(view.getId()).isEqualTo("gsv1"); + } + + @Test + void shouldDeserializeModelElement() { + assertThat(view.getModelElement().getId()).isEqualTo("gs1"); + } + + @Test + void shouldDeserializeX() { + assertThat(view.getX()).isEqualTo(417); + } + + @Test + void shouldDeserializeY() { + assertThat(view.getY()).isEqualTo(191); + } + + @Test + void shouldDeserializeWidth() { + assertThat(view.getWidth()).isEqualTo(60); + } + + @Test + void shouldDeserializeHeight() { + assertThat(view.getHeight()).isEqualTo(20); + } + + @Test + void shouldDeserializeShape() { + assertThat(shape.getId()).isEqualTo("tx1"); + } + + @Test + void shouldDeserializeShapeX() { + assertThat(shape.getX()).isEqualTo(417); + } + + @Test + void shouldDeserializeShapeY() { + assertThat(shape.getY()).isEqualTo(191); + } + + @Test + void shouldDeserializeShapeWidth() { + assertThat(shape.getWidth()).isEqualTo(60); + } + + @Test + void shouldDeserializeShapeHeight() { + assertThat(shape.getHeight()).isEqualTo(20); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializerTest.java new file mode 100644 index 00000000..95081df6 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/GeneralizationViewDeserializerTest.java @@ -0,0 +1,90 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Point; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class GeneralizationViewDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static String json = + "{\n" + + " \"id\": \"rv1\",\n" + + " \"type\": \"GeneralizationView\",\n" + + " \"modelElement\": { \"id\": \"re1\", \"type\": \"Generalization\" },\n" + + " \"shape\": {\n" + + " \"id\": \"pa1\",\n" + + " \"type\": \"Path\",\n" + + " \"points\": [\n" + + " { \"x\": 100, \"y\": 40 },\n" + + " { \"x\": 150, \"y\": 42 }\n" + + " ]\n" + + " },\n" + + " \"source\": { \"id\": \"cv1\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv2\", \"type\": \"ClassView\" }\n" + + "}"; + + static GeneralizationView view; + static Path shape; + + @BeforeAll + static void beforeAll() throws IOException { + view = mapper.readValue(json, GeneralizationView.class); + shape = view.getShape(); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"1\", \"type\": \"GeneralizationView\"}"; + GeneralizationView view = mapper.readValue(json, GeneralizationView.class); + + assertThat(view.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializeId() { + assertThat(view.getId()).isEqualTo("rv1"); + } + + @Test + void shouldDeserializeModelElement() { + assertThat(view.getModelElement().getId()).isEqualTo("re1"); + } + + @Test + void shouldDeserializeSource() { + assertThat(view.getSource().getId()).isEqualTo("cv1"); + } + + @Test + void shouldDeserializeTarget() { + assertThat(view.getTarget().getId()).isEqualTo("cv2"); + } + + @Test + void shouldDeserializeShape() { + assertThat(shape.getId()).isEqualTo("pa1"); + } + + @Test + void shouldDeserializePoints() { + assertThat(shape.getPoints()).hasSize(2); + } + + @Test + void shouldDeserializePointsData() { + Point firstPoint = shape.getPoints().get(0); + assertThat(firstPoint.getX()).isEqualTo(100); + assertThat(firstPoint.getY()).isEqualTo(40); + + Point secondPoint = shape.getPoints().get(1); + assertThat(secondPoint.getX()).isEqualTo(150); + assertThat(secondPoint.getY()).isEqualTo(42); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializerTest.java new file mode 100644 index 00000000..15af9543 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/MultilingualTextDeserializerTest.java @@ -0,0 +1,46 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +class MultilingualTextDeserializerTest { + + @Test + void deserializeObject() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String json = "{\"en\":\"My Project\", \"pt\": \"Meu Projeto\" }"; + MultilingualText element = mapper.readValue(json, MultilingualText.class); + + assertThat(element.getLanguages()).containsExactly("en", "pt"); + assertThat(element.getText("en")).hasValue("My Project"); + assertThat(element.getText("pt")).hasValue("Meu Projeto"); + } + + @Test + void deserializeString() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String json = "\"My Project\""; + MultilingualText element = mapper.readValue(json, MultilingualText.class); + + assertThat(element.getLanguages()).containsExactly("en"); + assertThat(element.getText("en")).hasValue("My Project"); + } + + @Test + void deserializeNull() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + + String json = "null"; + MultilingualText element = mapper.readValue(json, MultilingualText.class); + + assertThat(element.getLanguages()).isEmpty(); + assertThat(element.getText("en")).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializerTest.java new file mode 100644 index 00000000..29f3ae3f --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PackageDeserializerTest.java @@ -0,0 +1,135 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class PackageDeserializerTest { + + static String json = + "{\n" + + " \"id\": \"pk1\",\n" + + " \"name\": \"My Package\",\n" + + " \"description\": \"My description.\",\n" + + " \"type\": \"Package\",\n" + + " \"propertyAssignments\": {\n" + + " \"uri\": \"http://example.com/MyPackage\"\n" + + " },\n" + + " \"contents\": [\n" + + " { \"id\": \"c1\", \"type\": \"Class\", \"name\": \"Agent\" },\n" + + " { \"id\": \"r1\", \"type\": \"Relation\", \"name\": \"knows\" },\n" + + " { \"id\": \"g1\", \"type\": \"Generalization\", \"name\": \"PersonToAgent\" },\n" + + " { \"id\": \"gs1\", \"type\": \"GeneralizationSet\", \"name\": \"AgentNature\" },\n" + + " { " + + " \"id\": \"pk2\"," + + " \"type\": \"Package\"," + + " \"name\": \"Subpackage\"," + + " \"contents\": [\n" + + " { \"id\": \"c2\", \"type\": \"Class\", \"name\": \"Person\" }" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + + static ObjectMapper mapper; + static Package pkg; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + pkg = mapper.readValue(json, Package.class); + } + + @Test + void shouldDeserializeId() { + assertThat(pkg.getId()).isEqualTo("pk1"); + } + + @Test + void shouldDeserializeName() { + assertThat(pkg.getNameIn("en")).hasValue("My Package"); + } + + @Test + void shouldDeserializeDescription() { + assertThat(pkg.getDescriptionIn("en")).hasValue("My description."); + } + + @Test + void shouldDeserializePropertyAssignments() { + Optional pAssignment = pkg.getPropertyAssignment("uri"); + assertThat(pAssignment).hasValue("http://example.com/MyPackage"); + } + + @Test + void shouldDeserializeContents() { + assertThat(pkg.getContents()).hasSize(5); + } + + @Test + void shouldDeserializeClassInContents() { + OntoumlElement element = pkg.getContents().get(0); + assertThat(element).isInstanceOf(Class.class); + assertThat(element.getId()).isEqualTo("c1"); + assertThat(element.getFirstName()).hasValue("Agent"); + } + + @Test + void shouldDeserializeRelationInContents() { + OntoumlElement element = pkg.getContents().get(1); + assertThat(element).isInstanceOf(Relation.class); + assertThat(element.getId()).isEqualTo("r1"); + assertThat(element.getFirstName()).hasValue("knows"); + } + + @Test + void shouldDeserializeGeneralizationInContents() { + OntoumlElement element = pkg.getContents().get(2); + assertThat(element).isInstanceOf(Generalization.class); + assertThat(element.getId()).isEqualTo("g1"); + assertThat(element.getFirstName()).hasValue("PersonToAgent"); + } + + @Test + void shouldDeserializeGeneralizationSetInContents() { + OntoumlElement element = pkg.getContents().get(3); + assertThat(element).isInstanceOf(GeneralizationSet.class); + assertThat(element.getId()).isEqualTo("gs1"); + assertThat(element.getFirstName()).hasValue("AgentNature"); + } + + @Test + void shouldDeserializePackageInContents() { + OntoumlElement element = pkg.getContents().get(4); + assertThat(element).isInstanceOf(Package.class); + assertThat(element.getId()).isEqualTo("pk2"); + assertThat(element.getFirstName()).hasValue("Subpackage"); + } + + @Test + void shouldDeserializeSubPackageContents() { + OntoumlElement element = pkg.getContents().get(4); + assertThat(element).isInstanceOf(Package.class); + + List contents = element.getContents(); + assertThat(contents).hasSize(1); + assertThat(contents.get(0)).isInstanceOf(Class.class); + assertThat(contents.get(0).getId()).isEqualTo("c2"); + } + + @Test + void shouldResolveContainer() { + OntoumlElement element = pkg.getContents().get(0); + assertThat(element.getContainer()).hasValue(pkg); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializerTest.java new file mode 100644 index 00000000..00318102 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PathDeserializerTest.java @@ -0,0 +1,85 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Point; +import java.io.IOException; +import java.util.List; +import org.junit.jupiter.api.Test; + +class PathDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + + Path path; + String json; + + @Test + void shouldDeserializeId() throws IOException { + json = "{\"id\": \"1\", \"type\": \"Path\"}"; + path = mapper.readValue(json, Path.class); + + assertThat(path.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializePointWithDoubleCoordinates() throws IOException { + json = + "{\"id\": \"1\"," + + "\"type\": \"Path\"," + + "\"points\": [" + + "{\"x\": \"10\", \"y\": \"20\"}" + + "] }"; + path = mapper.readValue(json, Path.class); + + List points = path.getPoints(); + assertThat(points).hasSize(1); + + Point point = points.get(0); + assertThat(point.getX()).isEqualTo(10); + assertThat(point.getY()).isEqualTo(20); + } + + @Test + void shouldDeserializePointWithIntegerCoordinates() throws IOException { + json = + "{\"id\": \"1\"," + + "\"type\": \"Path\"," + + "\"points\": [" + + "{\"x\": \"5\", \"y\": \"15\"}" + + "] }"; + path = mapper.readValue(json, Path.class); + + List points = path.getPoints(); + assertThat(points).hasSize(1); + + Point point = points.get(0); + assertThat(point.getX()).isEqualTo(5); + assertThat(point.getY()).isEqualTo(15); + } + + @Test + void shouldDeserializeMultiplePoints() throws IOException { + json = + "{\"id\": \"1\"," + + "\"type\": \"Path\"," + + "\"points\": [" + + "{\"x\": \"10\", \"y\": \"20\"}," + + "{\"x\": \"10\", \"y\": \"100\"}" + + "] }"; + path = mapper.readValue(json, Path.class); + + List points = path.getPoints(); + assertThat(points).hasSize(2); + + Point first = points.get(0); + assertThat(first.getX()).isEqualTo(10); + assertThat(first.getY()).isEqualTo(20); + + Point second = points.get(1); + assertThat(second.getX()).isEqualTo(10); + assertThat(second.getY()).isEqualTo(100); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializerTest.java new file mode 100644 index 00000000..5dfc00d9 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ProjectDeserializerTest.java @@ -0,0 +1,89 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.io.IOException; +import java.util.Optional; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ProjectDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"proj1\",\n" + + " \"name\" : {\n" + + " \"en\" : \"My Project\",\n" + + " \"pt\" : \"Meu Projeto\"\n" + + " },\n" + + " \"description\" : {\n" + + " \"it\" : \"Il miglior progetto in modellazione concettuale.\",\n" + + " \"en\" : \"The best conceptual modeling project.\"\n" + + " }, \"type\" : \"Project\", \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"name\": \"Model\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " { \"id\": \"c1\", \"type\": \"Class\", \"name\": \"Agent\" },\n" + + " { \"id\": \"c2\", \"type\": \"Class\", \"name\": \"Person\" },\n" + + " { \"id\": \"r1\", \"type\": \"Relation\", \"name\": \"knows\" },\n" + + " { \"id\": \"g1\", \"type\": \"Generalization\", \"name\": \"PersonToAgent\"" + + " },\n" + + " { \"id\": \"gs1\", \"type\": \"GeneralizationSet\", \"name\": \"AgentNature\"" + + " }\n" + + " ]\n" + + " }, \"diagrams\": null}"; + + static ObjectMapper mapper; + static Project project; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + project = mapper.readValue(json, Project.class); + } + + @Test + void shouldDeserializeId() { + assertThat(project.getId()).isEqualTo("proj1"); + } + + @Test + void shouldDeserializeName() { + assertThat(project.getNameIn("en")).hasValue("My Project"); + assertThat(project.getNameIn("pt")).hasValue("Meu Projeto"); + } + + @Test + void shouldDeserializeDescription() { + assertThat(project.getDescriptionIn("en")).hasValue("The best conceptual modeling project."); + assertThat(project.getDescriptionIn("it")) + .hasValue("Il miglior progetto in modellazione concettuale."); + } + + @Test + void shouldDeserializeModel() { + Optional model = project.getModel(); + assertThat(model).isPresent(); + assertThat(model.get().getId()).isEqualTo("pk1"); + assertThat(model.get().getFirstName()).hasValue("Model"); + } + + @Test + void shouldDeserializeModelContents() { + Package model = project.getModel().orElse(new Package()); + Stream idStream = model.getContents().stream().map(Element::getId); + assertThat(idStream).containsExactly("c1", "c2", "r1", "g1", "gs1"); + } + + @Test + void shouldDeserializeDiagrams() { + assertThat(project.getDiagrams()).isEmpty(); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyAssignmentsDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyAssignmentsDeserializerTest.java new file mode 100644 index 00000000..7b38dbe6 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyAssignmentsDeserializerTest.java @@ -0,0 +1,80 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class PropertyAssignmentsDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"1\",\n" + + " \"type\" : \"Class\",\n" + + " \"propertyAssignments\" : {\n" + + " \"authors\" : [ \"Tiago\", \"Davi\" ],\n" + + " \"weights\" : [ 10, 20 ],\n" + + " \"isLiked\" : true,\n" + + " \"score\" : 10,\n" + + " \"source\" : null,\n" + + " \"uri\" : \"https://schema.org/Car\",\n" + + " \"value\" : 8.9\n" + + " }\n" + + "}"; + + static ObjectMapper mapper; + static Class clazz; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + clazz = mapper.readValue(json, Class.class); + } + + @Test + void shouldDeserializeStringProperty() { + assertThat(clazz.getPropertyAssignment("uri")).hasValue("https://schema.org/Car"); + } + + @Test + void shouldDeserializeIntegerProperty() { + assertThat(clazz.getPropertyAssignment("score")).hasValue(10); + } + + @Test + void shouldDeserializeFloatProperty() { + assertThat(clazz.getPropertyAssignment("value")).hasValue(8.9); + } + + @Test + void shouldDeserializeBooleanProperty() { + assertThat(clazz.getPropertyAssignment("isLiked")).hasValue(true); + } + + @Test + void shouldDeserializeNullProperty() { + assertThat(clazz.getPropertyAssignment("source")).isEmpty(); + } + + @Test + void shouldDeserializStringArrayProperty() { + Optional value = clazz.getPropertyAssignment("authors"); + assertThat(value).isPresent(); + assertThat(value.get()).isInstanceOf(List.class); + assertThat(value.get()).isEqualTo(List.of("Tiago", "Davi")); + } + + @Test + void shouldDeserializIntegerArrayProperty() { + Optional value = clazz.getPropertyAssignment("weights"); + assertThat(value).isPresent(); + assertThat(value.get()).isInstanceOf(List.class); + assertThat(value.get()).isEqualTo(List.of(10, 20)); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializerTest.java new file mode 100644 index 00000000..ab3ae9eb --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/PropertyDeserializerTest.java @@ -0,0 +1,143 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.AggregationKind; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import it.unibz.inf.ontouml.vp.model.ontouml.model.PropertyStereotype; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class PropertyDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"p1\",\n" + + " \"name\" : \"birthName\",\n" + + " \"description\" : null,\n" + + " \"type\" : \"Property\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : null,\n" + + " \"isDerived\" : true,\n" + + " \"isReadOnly\" : true,\n" + + " \"isOrdered\" : true,\n" + + " \"cardinality\" : \"1..*\",\n" + + " \"propertyType\" : {\n" + + " \"id\" : \"c1\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"subsettedProperties\" : [ {\n" + + " \"id\" : \"p2\",\n" + + " \"type\" : \"Property\"\n" + + " } ],\n" + + " \"redefinedProperties\" : [ {\n" + + " \"id\" : \"p3\",\n" + + " \"type\" : \"Property\"\n" + + " } ],\n" + + " \"aggregationKind\" : \"COMPOSITE\"\n" + + "}"; + + static ObjectMapper mapper; + static Property property; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + property = mapper.readValue(json, Property.class); + } + + @Test + void shouldDeserializeReference() throws IOException { + String jsonReference = "{ \"id\": \"p1\", \"type\":\"Property\"}"; + Property reference = mapper.readValue(jsonReference, Property.class); + + assertThat(reference.getId()).isEqualTo("p1"); + assertThat(reference.getFirstName()).isEmpty(); + assertThat(reference.getStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeId() { + assertThat(property.getId()).isEqualTo("p1"); + } + + @Test + void shouldDeserializeIsDerived() { + assertThat(property.isDerived()).isTrue(); + } + + @Test + void shouldDeserializeIsReadOnly() { + assertThat(property.isReadOnly()).isTrue(); + } + + @Test + void shouldDeserializeIsOrdered() { + assertThat(property.isOrdered()).isTrue(); + } + + @Test + void shouldDeserializeCardinality() { + assertThat(property.getCardinalityValue()).hasValue("1..*"); + } + + @Test + void shouldDeserializePropertyType() { + assertThat(property.getPropertyType()).isPresent(); + assertThat(property.getPropertyType().get()).isInstanceOf(Class.class); + assertThat(property.getPropertyType().get().getId()).isEqualTo("c1"); + } + + @Test + void shouldDeserializeSubsettedProperties() { + assertThat(property.getSubsettedProperties()).hasSize(1); + + Property subsetted = property.getSubsettedProperties().get(0); + assertThat(subsetted.getId()).isEqualTo("p2"); + } + + @Test + void shouldDeserializeRedefinedProperties() { + assertThat(property.getRedefinedProperties()).hasSize(1); + + Property redefined = property.getRedefinedProperties().get(0); + assertThat(redefined.getId()).isEqualTo("p3"); + } + + @Test + void shouldDeserializeAggregationKind() { + assertThat(property.getAggregationKind()).hasValue(AggregationKind.COMPOSITE); + } + + @Test + void shouldDeserializeOntoumlStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"p1\",\n" + + " \"type\": \"Property\",\n" + + " \"stereotype\": \"begin\"\n" + + "}"; + + Property property = mapper.readValue(json, Property.class); + assertThat(property.getOntoumlStereotype()).hasValue(PropertyStereotype.BEGIN); + assertThat(property.getCustomStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeCustomStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"p1\",\n" + + " \"type\": \"Property\",\n" + + " \"stereotype\": \"custom\"\n" + + "}"; + + Property property = mapper.readValue(json, Property.class); + assertThat(property.getOntoumlStereotype()).isEmpty(); + assertThat(property.getCustomStereotype()).hasValue("custom"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializerTest.java new file mode 100644 index 00000000..9d19de4d --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RectangleDeserializerTest.java @@ -0,0 +1,62 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Rectangle; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class RectangleDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static Rectangle rectangle; + static String json = + "{\n" + + " \"id\": \"r1\",\n" + + " \"type\": \"Rectangle\",\n" + + " \"x\": 406,\n" + + " \"y\": 285,\n" + + " \"width\": 84,\n" + + " \"height\": 40\n" + + "}"; + + @BeforeAll + static void beforeAll() throws IOException { + rectangle = mapper.readValue(json, Rectangle.class); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"1\", \"type\": \"Rectangle\"}"; + Rectangle rectangle = mapper.readValue(json, Rectangle.class); + + assertThat(rectangle.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializeId() { + assertThat(rectangle.getId()).isEqualTo("r1"); + } + + @Test + void shouldDeserializeX() { + assertThat(rectangle.getX()).isEqualTo(406); + } + + @Test + void shouldDeserializeY() { + assertThat(rectangle.getY()).isEqualTo(285); + } + + @Test + void shouldDeserializeWidth() { + assertThat(rectangle.getWidth()).isEqualTo(84); + } + + @Test + void shouldDeserializeHeight() { + assertThat(rectangle.getHeight()).isEqualTo(40); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolverTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolverTest.java new file mode 100644 index 00000000..96fc3887 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/ReferenceResolverTest.java @@ -0,0 +1,376 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.truth.Truth8; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.view.ClassView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.GeneralizationView; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +public class ReferenceResolverTest { + ObjectMapper mapper = new ObjectMapper(); + + @Test + void shouldResolvePropertyTypeReferences() throws IOException { + String json = + "{\n" + + " \"type\": \"Project\",\n" + + " \"id\": \"pj1\",\n" + + " \"model\": {\n" + + " \"id\": \"pk2\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " {\n" + + " \"id\": \"c1\",\n" + + " \"type\": \"Class\",\n" + + " \"properties\": [\n" + + " {\n" + + " \"id\": \"att1\",\n" + + " \"type\": \"Property\",\n" + + " \"propertyType\": { \"id\": \"c2\", \"type\": \"Class\" }\n" + + " }\n" + + " ]\n" + + " },\n" + + " { \"id\": \"c2\", \"type\": \"Class\" }\n" + + " ]\n" + + " }\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + Class type = project.getClassById("c2").orElse(null); + assertThat(type).isNotNull(); + + Property prop = project.getPropertyById("att1").orElse(null); + assertThat(prop).isNotNull(); + + Truth8.assertThat(prop.getPropertyType()).hasValue(type); + } + + @Test + void shouldResolveSubsettingRedefiningReferences() throws IOException { + String json = + "{\n" + + " \"type\": \"Project\",\n" + + " \"id\": \"pj1\",\n" + + " \"model\": {\n" + + " \"id\": \"pk2\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " {\n" + + " \"id\": \"c1\",\n" + + " \"type\": \"Class\",\n" + + " \"properties\": [\n" + + " {\n" + + " \"id\": \"att1\",\n" + + " \"type\": \"Property\",\n" + + " \"propertyType\": { \"id\": \"c2\", \"type\": \"Class\" }\n" + + " },\n" + + " {\n" + + " \"id\": \"att2\",\n" + + " \"type\": \"Property\",\n" + + " \"propertyType\": { \"id\": \"c2\", \"type\": \"Class\" },\n" + + " \"subsettedProperties\": [ {\"id\": \"att1\", \"type\": \"Property\"}" + + " ],\n" + + " \"redefinedProperties\": [ {\"id\": \"att1\", \"type\": \"Property\"}" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " { \"id\": \"c2\", \"type\": \"Class\" }\n" + + " ]\n" + + " },\n" + + " \"diagrams\": null\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + Property name = project.getPropertyById("att1").orElse(null); + assertThat(name).isNotNull(); + + Property nickname = project.getPropertyById("att2").orElse(null); + assertThat(nickname).isNotNull(); + + assertThat(nickname.getSubsettedProperties()).containsExactly(name); + assertThat(nickname.getRedefinedProperties()).containsExactly(name); + } + + @Test + void shouldResolveGeneralSpecificReferences() throws IOException { + String json = + "{\n" + + " \"id\": \"pj1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " {\n" + + " \"id\": \"c1\",\n" + + " \"name\": \"Agent\",\n" + + " \"type\": \"Class\"\n" + + " },\n" + + " {\n" + + " \"id\": \"c2\",\n" + + " \"name\": \"Person\",\n" + + " \"type\": \"Class\"\n" + + " },\n" + + " {\n" + + " \"id\": \"g1\",\n" + + " \"type\": \"Generalization\",\n" + + " \"general\": {\n" + + " \"id\": \"c1\",\n" + + " \"type\": \"Class\"\n" + + " },\n" + + " \"specific\": {\n" + + " \"id\": \"c2\",\n" + + " \"type\": \"Class\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + Class agent = project.getClassById("c1").orElse(null); + assertThat(agent).isNotNull(); + + Class person = project.getClassById("c2").orElse(null); + assertThat(person).isNotNull(); + + Generalization gen = project.getGeneralizationById("g1").orElse(null); + assertThat(gen).isNotNull(); + + Truth8.assertThat(gen.getGeneral()).hasValue(agent); + Truth8.assertThat(gen.getSpecific()).hasValue(person); + } + + @Test + void shouldResolveCategorizerReference() throws IOException { + String json = + "{\n" + + " \"id\": \"pr1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " { \"id\": \"c4\", \"name\": \"AgentType\", \"type\": \"Class\" },\n" + + " {\n" + + " \"id\": \"gs1\",\n" + + " \"type\": \"GeneralizationSet\",\n" + + " \"categorizer\": { \"id\": \"c4\", \"type\": \"Class\" }\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + Class agentType = project.getClassById("c4").orElse(null); + assertThat(agentType).isNotNull(); + + GeneralizationSet gs = project.getGeneralizationSetById("gs1").orElse(null); + assertThat(gs).isNotNull(); + + Truth8.assertThat(gs.getCategorizer()).hasValue(agentType); + } + + @Test + void shouldResolveGeneralizationsReferences() throws IOException { + String json = + "{\n" + + " \"id\": \"pr1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " { \"id\": \"c1\", \"name\": \"Agent\", \"type\": \"Class\" },\n" + + " { \"id\": \"c2\", \"name\": \"Person\", \"type\": \"Class\" },\n" + + " { \"id\": \"c3\", \"name\": \"Organization\", \"type\": \"Class\" },\n" + + " { \n" + + " \"id\": \"g1\",\n" + + " \"type\": \"Generalization\",\n" + + " \"general\": { \"id\": \"c1\", \"type\": \"Class\" },\n" + + " \"specific\": { \"id\": \"c2\", \"type\": \"Class\" }\n" + + " },\n" + + " {\n" + + " \"id\": \"g2\",\n" + + " \"type\": \"Generalization\",\n" + + " \"general\": { \"id\": \"c1\", \"type\": \"Class\" },\n" + + " \"specific\": { \"id\": \"c3\", \"type\": \"Class\" }\n" + + " },\n" + + " {\n" + + " \"id\": \"gs1\",\n" + + " \"type\": \"GeneralizationSet\",\n" + + " \"generalizations\": [\n" + + " { \"id\": \"g2\", \"type\": \"Generalization\" },\n" + + " { \"id\": \"g1\", \"type\": \"Generalization\" }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + Generalization g1 = project.getGeneralizationById("g1").orElse(null); + assertThat(g1).isNotNull(); + + Generalization g2 = project.getGeneralizationById("g2").orElse(null); + assertThat(g2).isNotNull(); + + GeneralizationSet gs = project.getGeneralizationSetById("gs1").orElse(null); + assertThat(gs).isNotNull(); + + assertThat(gs.getGeneralizations()).containsExactly(g1, g2); + } + + @Test + void shouldResolveClassViewReference() throws IOException { + String json = + "{\n" + + " \"id\": \"pj1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [ { \"id\": \"c1\", \"name\": \"Agent\", \"type\": \"Class\"} ]\n" + + " },\n" + + " \"diagrams\": [ { \n" + + " \"id\": \"dg1\", \n" + + " \"name\": \"Class Diagram1\", \n" + + " \"type\": \"Diagram\",\n" + + " \"contents\": [ {\n" + + " \"id\": \"cv1\",\n" + + " \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c1\", \"type\": \"Class\" }\n" + + " } ]\n" + + " } ]\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + ClassView cv1 = project.getClassViewById("cv1").orElse(null); + assertThat(cv1).isNotNull(); + + Class c1 = project.getClassById("c1").orElse(null); + assertThat(c1).isNotNull(); + + assertThat(cv1.getModelElement()).isEqualTo(c1); + } + + @Test + void shouldResolveRelationViewReferences() throws IOException { + String json = + "{\n" + + " \"id\": \"pj1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " { \"id\": \"c1\", \"name\": \"Person\", \"type\": \"Class\" },\n" + + " { \"id\": \"re1\", \"name\": \"knows\", \"type\": \"Relation\",\n" + + " \"properties\": [\n" + + " { \"id\": \"pr1\", \"name\": \"knower\", \"type\": \"Property\",\n" + + " \"propertyType\": { \"id\": \"c1\", \"type\": \"Class\" } },\n" + + " { \"id\": \"pr2\", \"name\": \"known\", \"type\": \"Property\",\n" + + " \"propertyType\": { \"id\": \"c1\", \"type\": \"Class\" } } ] }\n" + + " ]\n" + + " },\n" + + " \"diagrams\": [\n" + + " { \"id\": \"dg1\", \"name\": \"Class Diagram1\", \"type\": \"Diagram\",\n" + + " \"contents\": [\n" + + " { \"id\": \"cv1\", \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c1\", \"type\": \"Class\" } },\n" + + " { \"id\": \"rv1\", \"type\": \"RelationView\",\n" + + " \"modelElement\": { \"id\": \"re1\", \"type\": \"Relation\" },\n" + + " \"source\": { \"id\": \"cv1\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv1\", \"type\": \"ClassView\" } }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + RelationView rv1 = project.getRelationViewById("rv1").orElse(null); + assertThat(rv1).isNotNull(); + assertThat(rv1.getSource().getModelElement().getFirstName()).hasValue("Person"); + assertThat(rv1.getTarget().getModelElement().getFirstName()).hasValue("Person"); + + ClassView cv1 = project.getClassViewById("cv1").orElse(null); + assertThat(cv1).isNotNull(); + + assertThat(rv1.getSource()).isEqualTo(cv1); + assertThat(rv1.getTarget()).isEqualTo(cv1); + + Relation r1 = project.getRelationById("re1").orElse(null); + assertThat(r1).isNotNull(); + + assertThat(rv1.getModelElement()).isEqualTo(r1); + } + + @Test + void shouldResolveGeneralizationViewReferences() throws IOException { + String json = + "{\n" + + " \"id\": \"pj1\",\n" + + " \"type\": \"Project\",\n" + + " \"model\": {\n" + + " \"id\": \"pk1\",\n" + + " \"type\": \"Package\",\n" + + " \"contents\": [\n" + + " { \"id\": \"c1\", \"name\": \"Agent\", \"type\": \"Class\" },\n" + + " { \"id\": \"c2\", \"name\": \"Person\", \"type\": \"Class\" },\n" + + " { \"id\": \"g1\", \"type\": \"Generalization\",\n" + + " \"general\": { \"id\": \"c1\", \"type\": \"Class\" },\n" + + " \"specific\": { \"id\": \"c2\", \"type\": \"Class\" } }\n" + + " ]\n" + + " },\n" + + " \"diagrams\": [\n" + + " { \"id\": \"dg1\", \"type\": \"Diagram\",\n" + + " \"contents\": [\n" + + " { \"id\": \"cv1\", \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c1\", \"type\": \"Class\" } },\n" + + " { \"id\": \"cv2\", \"type\": \"ClassView\",\n" + + " \"modelElement\": { \"id\": \"c2\", \"type\": \"Class\" } },\n" + + " { \"id\": \"gv1\", \"type\": \"GeneralizationView\",\n" + + " \"modelElement\": { \"id\": \"g1\", \"type\": \"Generalization\" },\n" + + " \"source\": { \"id\": \"cv1\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv2\", \"type\": \"ClassView\" } }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + + Project project = mapper.readValue(json, Project.class); + + GeneralizationView gv = project.getGeneralizationViewById("gv1").orElse(null); + assertThat(gv).isNotNull(); + assertThat(gv.getSource().getModelElement().getFirstName()).hasValue("Agent"); + assertThat(gv.getTarget().getModelElement().getFirstName()).hasValue("Person"); + + ClassView cv1 = project.getClassViewById("cv1").orElse(null); + assertThat(cv1).isNotNull(); + ClassView cv2 = project.getClassViewById("cv2").orElse(null); + assertThat(cv2).isNotNull(); + + assertThat(gv.getSource()).isEqualTo(cv1); + assertThat(gv.getTarget()).isEqualTo(cv2); + + Generalization g1 = project.getGeneralizationById("g1").orElse(null); + assertThat(g1).isNotNull(); + assertThat(gv.getModelElement()).isEqualTo(g1); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializerTest.java new file mode 100644 index 00000000..5980ac1c --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationDeserializerTest.java @@ -0,0 +1,178 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class RelationDeserializerTest { + + static String json = + "{\n" + + " \"id\" : \"r1\",\n" + + " \"name\" : \n{" + + " \"en\" : \"My Relation\",\n" + + " \"pt\" : \"Minha Relação\"\n" + + " },\n" + + " \"description\" : \n{" + + " \"en\" : \"My description.\",\n" + + " \"pt\" : \"Minha descrição.\"\n" + + " },\n" + + " \"type\" : \"Relation\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : \"material\",\n" + + " \"isAbstract\" : true,\n" + + " \"isDerived\" : true,\n" + + " \"properties\" : [ {\n" + + " \"id\" : \"p1\",\n" + + " \"name\" : \"person\",\n" + + " \"description\" : null,\n" + + " \"type\" : \"Property\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : null,\n" + + " \"isDerived\" : false,\n" + + " \"isReadOnly\" : false,\n" + + " \"isOrdered\" : false,\n" + + " \"cardinality\" : \"1..*\",\n" + + " \"propertyType\" : {\n" + + " \"id\" : \"c1\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"subsettedProperties\" : null,\n" + + " \"redefinedProperties\" : null,\n" + + " \"aggregationKind\" : null\n" + + " }, {\n" + + " \"id\" : \"p2\",\n" + + " \"name\" : \"car\",\n" + + " \"description\" : null,\n" + + " \"type\" : \"Property\",\n" + + " \"propertyAssignments\" : null,\n" + + " \"stereotype\" : null,\n" + + " \"isDerived\" : false,\n" + + " \"isReadOnly\" : false,\n" + + " \"isOrdered\" : false,\n" + + " \"cardinality\" : \"0..*\",\n" + + " \"propertyType\" : {\n" + + " \"id\" : \"c2\",\n" + + " \"type\" : \"Class\"\n" + + " },\n" + + " \"subsettedProperties\" : null,\n" + + " \"redefinedProperties\" : null,\n" + + " \"aggregationKind\" : null\n" + + " } ]\n" + + "}"; + + static ObjectMapper mapper; + static Relation relation; + + @BeforeAll + static void setUp() throws IOException { + mapper = new ObjectMapper(); + relation = mapper.readValue(json, Relation.class); + } + + @Test + void shouldDeserializeReference() throws IOException { + String jsonReference = "{ \"id\": \"r1\", \"type\":\"Relation\"}"; + Relation relation = mapper.readValue(jsonReference, Relation.class); + + assertThat(relation.getId()).isEqualTo("r1"); + assertThat(relation.getFirstName()).isEmpty(); + assertThat(relation.getStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeId() { + assertThat(relation.getId()).isEqualTo("r1"); + } + + @Test + void shouldDeserializeName() { + assertThat(relation.getNameIn("en")).hasValue("My Relation"); + assertThat(relation.getNameIn("pt")).hasValue("Minha Relação"); + } + + @Test + void shouldDeserializeDescription() { + assertThat(relation.getDescriptionIn("en")).hasValue("My description."); + assertThat(relation.getDescriptionIn("pt")).hasValue("Minha descrição."); + } + + @Test + void shouldDeserializeIsAbstract() { + assertThat(relation.isAbstract()).isTrue(); + } + + @Test + void shouldDeserializeIsDerived() { + assertThat(relation.isDerived()).isTrue(); + } + + @Test + void shouldDeserializeEnds() { + assertThat(relation.getProperties()).hasSize(2); + assertThat(relation.getProperties().get(0).getId()).isEqualTo("p1"); + assertThat(relation.getProperties().get(1).getId()).isEqualTo("p2"); + } + + @Test + void shouldDeserializeSourceEnd() { + Property sourceEnd = relation.getSourceEnd(); + assertThat(sourceEnd.getId()).isEqualTo("p1"); + assertThat(sourceEnd.getFirstName()).hasValue("person"); + } + + @Test + void shouldDeserializeTargetEnd() { + Property targetEnd = relation.getTargetEnd(); + assertThat(targetEnd.getId()).isEqualTo("p2"); + assertThat(targetEnd.getFirstName()).hasValue("car"); + } + + @Test + void shouldDeserializeSource() { + Classifier source = relation.getSource(); + assertThat(source.getId()).isEqualTo("c1"); + assertThat(source).isInstanceOf(Class.class); + } + + @Test + void shouldDeserializeTarget() { + Classifier target = relation.getTarget(); + assertThat(target.getId()).isEqualTo("c2"); + assertThat(target).isInstanceOf(Class.class); + } + + @Test + void shouldDeserializeOntoumlStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"r1\",\n" + + " \"type\": \"Relation\",\n" + + " \"stereotype\": \"material\"\n" + + "}"; + + Relation relation = mapper.readValue(json, Relation.class); + assertThat(relation.getOntoumlStereotype()).hasValue(RelationStereotype.MATERIAL); + assertThat(relation.getCustomStereotype()).isEmpty(); + } + + @Test + void shouldDeserializeCustomStereotype() throws IOException { + String json = + "{\n" + + " \"id\": \"r1\",\n" + + " \"type\": \"Relation\",\n" + + " \"stereotype\": \"custom\"\n" + + "}"; + + Relation relation = mapper.readValue(json, Relation.class); + assertThat(relation.getOntoumlStereotype()).isEmpty(); + assertThat(relation.getCustomStereotype()).hasValue("custom"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializerTest.java new file mode 100644 index 00000000..b5e8782a --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/RelationViewDeserializerTest.java @@ -0,0 +1,90 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Path; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Point; +import it.unibz.inf.ontouml.vp.model.ontouml.view.RelationView; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class RelationViewDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static String json = + "{\n" + + " \"id\": \"rv1\",\n" + + " \"type\": \"RelationView\",\n" + + " \"modelElement\": { \"id\": \"re1\", \"type\": \"Relation\" },\n" + + " \"shape\": {\n" + + " \"id\": \"pa1\",\n" + + " \"type\": \"Path\",\n" + + " \"points\": [\n" + + " { \"x\": 642, \"y\": 92 },\n" + + " { \"x\": 812, \"y\": 93 }\n" + + " ]\n" + + " },\n" + + " \"source\": { \"id\": \"cv1\", \"type\": \"ClassView\" },\n" + + " \"target\": { \"id\": \"cv2\", \"type\": \"ClassView\" }\n" + + "}"; + + static RelationView view; + static Path shape; + + @BeforeAll + static void beforeAll() throws IOException { + view = mapper.readValue(json, RelationView.class); + shape = view.getShape(); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"1\", \"type\": \"RelationView\"}"; + RelationView view = mapper.readValue(json, RelationView.class); + + assertThat(view.getId()).isEqualTo("1"); + } + + @Test + void shouldDeserializeId() { + assertThat(view.getId()).isEqualTo("rv1"); + } + + @Test + void shouldDeserializeModelElement() { + assertThat(view.getModelElement().getId()).isEqualTo("re1"); + } + + @Test + void shouldDeserializeSource() { + assertThat(view.getSource().getId()).isEqualTo("cv1"); + } + + @Test + void shouldDeserializeTarget() { + assertThat(view.getTarget().getId()).isEqualTo("cv2"); + } + + @Test + void shouldDeserializeShape() { + assertThat(shape.getId()).isEqualTo("pa1"); + } + + @Test + void shouldDeserializePoints() { + assertThat(shape.getPoints()).hasSize(2); + } + + @Test + void shouldDeserializePointsData() { + Point firstPoint = shape.getPoints().get(0); + assertThat(firstPoint.getX()).isEqualTo(642); + assertThat(firstPoint.getY()).isEqualTo(92); + + Point secondPoint = shape.getPoints().get(1); + assertThat(secondPoint.getX()).isEqualTo(812); + assertThat(secondPoint.getY()).isEqualTo(93); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializerTest.java new file mode 100644 index 00000000..e128f2bb --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/deserialization/TextDeserializerTest.java @@ -0,0 +1,68 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.deserialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.unibz.inf.ontouml.vp.model.ontouml.view.Text; +import java.io.IOException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class TextDeserializerTest { + + static ObjectMapper mapper = new ObjectMapper(); + static Text text; + static String json = + "{\n" + + " \"id\": \"t1\",\n" + + " \"type\": \"Text\",\n" + + " \"x\": 130,\n" + + " \"y\": 109,\n" + + " \"value\": \"Hello World!\",\n" + + " \"width\": 78,\n" + + " \"height\": 42\n" + + "}"; + + @BeforeAll + static void beforeAll() throws IOException { + text = mapper.readValue(json, Text.class); + } + + @Test + void shouldDeserializeReference() throws IOException { + String json = "{\"id\": \"t1\", \"type\": \"Text\"}"; + Text text = mapper.readValue(json, Text.class); + + assertThat(text.getId()).isEqualTo("t1"); + } + + @Test + void shouldDeserializeId() { + assertThat(text.getId()).isEqualTo("t1"); + } + + @Test + void shouldDeserializeX() { + assertThat(text.getX()).isEqualTo(130); + } + + @Test + void shouldDeserializeY() { + assertThat(text.getY()).isEqualTo(109); + } + + @Test + void shouldDeserializeValue() { + assertThat(text.getValue()).isEqualTo("Hello World!"); + } + + @Test + void shouldDeserializeWidth() { + assertThat(text.getWidth()).isEqualTo(78); + } + + @Test + void shouldDeserializeHeight() { + assertThat(text.getHeight()).isEqualTo(42); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializerTest.java new file mode 100644 index 00000000..019e5ddb --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ClassSerializerTest.java @@ -0,0 +1,129 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.ClassStereotype; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Nature; +import org.junit.jupiter.api.Test; + +public class ClassSerializerTest { + + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Class cl = new Class("1", "Person", (String) null); + + @Test + void shouldSerializeId() throws JsonProcessingException { + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"id\" : \"1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"type\" : \"Class\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + cl.addName("pt", "Pessoa"); + cl.addName("en", "Person"); + + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt\" : \"Pessoa\""); + assertThat(json).contains("\"en\" : \"Person\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + cl.addDescription("pt", "Única espécie animal de primata bípede do género Homo ainda viva."); + cl.addDescription("en", "Only bipedal primate animal species of the genus Homo still alive."); + + String json = mapper.writeValueAsString(cl); + + assertThat(json).contains("\"description\" : {"); + assertThat(json) + .contains("\"pt\" : \"Única espécie animal de primata bípede do género Homo ainda viva.\""); + assertThat(json) + .contains( + "\"en\" : \"Only bipedal primate animal species of the genus Homo still alive.\""); + } + + @Test + void shouldSerializeOntoumlStereotype() throws JsonProcessingException { + cl.setOntoumlStereotype(ClassStereotype.KIND); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"stereotype\" : \"kind\""); + } + + @Test + void shouldSerializeCustomStereotype() throws JsonProcessingException { + cl.setCustomStereotype("custom"); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"stereotype\" : \"custom\""); + } + + @Test + void shouldSerializeIsAbstract() throws JsonProcessingException { + cl.setAbstract(true); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"isAbstract\" : true"); + } + + @Test + void shouldSerializeIsDerived() throws JsonProcessingException { + cl.setDerived(true); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"isDerived\" : true"); + } + + @Test + void shouldSerializeEmptyAttributesAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"properties\" : null"); + } + + @Test + void shouldSerializeAttributes() throws JsonProcessingException { + cl.createAttribute("a1", "father", cl); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"properties\" : [ {"); + assertThat(json).contains("\"id\" : \"a1\""); + assertThat(json).contains("\"name\" : \"father\""); + } + + @Test + void shouldSerializeEmptyLiteralsAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"literals\" : null"); + } + + @Test + void shouldSerializeLiterals() throws JsonProcessingException { + cl = Class.createEnumeration("1", "Color", "red", "green", "blue"); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"literals\" : [ {"); + assertThat(json).contains("\"type\" : \"Literal\""); + assertThat(json).contains("\"name\" : \"red\""); + assertThat(json).contains("\"name\" : \"green\""); + assertThat(json).contains("\"name\" : \"blue\""); + } + + @Test + void shouldSerializeEmptyRestrictedToAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"restrictedTo\" : null"); + } + + @Test + void shouldSerializeRestrictedTo() throws JsonProcessingException { + cl = new Class("1", "Person"); + cl.setRestrictedTo(Nature.FUNCTIONAL_COMPLEX); + String json = mapper.writeValueAsString(cl); + assertThat(json).contains("\"restrictedTo\" : [ \"functional-complex\" ]"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializerTest.java new file mode 100644 index 00000000..df5254e4 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSerializerTest.java @@ -0,0 +1,68 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import org.junit.jupiter.api.Test; + +public class GeneralizationSerializerTest { + + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Class specificClass = new Class("c1", (String) null, (String) null); + Class generalClass = new Class("c2", (String) null, (String) null); + Generalization g = new Generalization("g1", specificClass, generalClass); + + @Test + void shouldSerializeId() throws JsonProcessingException { + String json = mapper.writeValueAsString(g); + assertThat(json).contains("\"id\" : \"g1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + String json = mapper.writeValueAsString(g); + assertThat(json).contains("\"type\" : \"Generalization\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + g.addName("pt", "Minha generalização"); + g.addName("en", "My generalization"); + String json = mapper.writeValueAsString(g); + + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt\" : \"Minha generalização\""); + assertThat(json).contains("\"en\" : \"My generalization\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + g.addDescription("pt", "Minha descrição."); + g.addDescription("en", "My description."); + String json = mapper.writeValueAsString(g); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"pt\" : \"Minha descrição.\""); + assertThat(json).contains("\"en\" : \"My description.\""); + } + + @Test + void shouldSerializeGeneralReference() throws JsonProcessingException { + mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(g); + + assertThat(json).contains("\"general\":{\"id\":\"c2\",\"type\":\"Class\"}"); + } + + @Test + void shouldSerializeSpecificReference() throws JsonProcessingException { + mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(g); + + assertThat(json).contains("\"specific\":{\"id\":\"c1\",\"type\":\"Class\"}"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializerTest.java new file mode 100644 index 00000000..da61fa70 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/GeneralizationSetSerializerTest.java @@ -0,0 +1,100 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Generalization; +import it.unibz.inf.ontouml.vp.model.ontouml.model.GeneralizationSet; +import org.junit.jupiter.api.Test; + +public class GeneralizationSetSerializerTest { + + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Class specificClass1 = new Class("sc1", (String) null, (String) null); + Class specificClass2 = new Class("sc2", (String) null, (String) null); + Class generalClass = new Class("gc1", (String) null, (String) null); + Generalization g1 = new Generalization("g1", specificClass1, generalClass); + Generalization g2 = new Generalization("g2", specificClass2, generalClass); + GeneralizationSet gs = new GeneralizationSet("gs1", (String) null, g1, g2); + + @Test + void shouldSerializeId() throws JsonProcessingException { + String json = mapper.writeValueAsString(gs); + assertThat(json).contains("\"id\" : \"gs1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + String json = mapper.writeValueAsString(gs); + assertThat(json).contains("\"type\" : \"GeneralizationSet\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + gs.addName("pt", "Meu conjunto de generalizações"); + gs.addName("en", "My generalization set"); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt\" : \"Meu conjunto de generalizações\""); + assertThat(json).contains("\"en\" : \"My generalization set\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + gs.addDescription("pt", "Minha descrição."); + gs.addDescription("en", "My description."); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"pt\" : \"Minha descrição.\""); + assertThat(json).contains("\"en\" : \"My description.\""); + } + + @Test + void shouldSerializeIsDisjoint() throws JsonProcessingException { + gs.setDisjoint(true); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"isDisjoint\" : true"); + } + + @Test + void shouldSerializeIsComplete() throws JsonProcessingException { + gs.setComplete(true); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"isComplete\" : true"); + } + + @Test + void shouldSerializeEmptyCategorizerAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"categorizer\" : null"); + } + + @Test + void shouldSerializeCategorizer() throws JsonProcessingException { + Class categorizer = new Class("cat", (String) null, (String) null); + gs.setCategorizer(categorizer); + + mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"categorizer\":{\"id\":\"cat\",\"type\":\"Class\"}"); + } + + @Test + void shouldSerializeGeneralizationReferences() throws JsonProcessingException { + mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(gs); + + assertThat(json).contains("\"generalizations\":["); + assertThat(json).contains("{\"id\":\"g1\",\"type\":\"Generalization\"}"); + assertThat(json).contains("{\"id\":\"g2\",\"type\":\"Generalization\"}"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializerTest.java new file mode 100644 index 00000000..7eac3059 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/MultilingualTextSerializerTest.java @@ -0,0 +1,46 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.MultilingualText; +import java.io.IOException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class MultilingualTextSerializerTest { + static ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + @Test + @DisplayName("should serialize empty text object as null") + void serializeEmptyObjectAsNull() throws IOException { + MultilingualText text = new MultilingualText(); + String json = mapper.writeValueAsString(text); + assertThat(json).isEqualTo("null"); + } + + @Test + @DisplayName("should serialize text object with a single value as a string") + void serializeSingleValuedObjectAsString() throws IOException { + MultilingualText text = new MultilingualText("Person"); + String json = mapper.writeValueAsString(text); + assertThat(json).isEqualTo("\"Person\""); + } + + @Test + @DisplayName( + "should serialize text object with a multiple value as an object whose fields are the" + + " languages") + void serializeMultiValuedObjectAsObject() throws IOException { + MultilingualText text = new MultilingualText(); + text.putText("en", "Person"); + text.putText("pt", "Pessoa"); + text.putText("it", "Persona"); + + String json = mapper.writeValueAsString(text); + assertThat(json).contains("\"en\" : \"Person\""); + assertThat(json).contains("\"pt\" : \"Pessoa\""); + assertThat(json).contains("\"it\" : \"Persona\""); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializerTest.java new file mode 100644 index 00000000..b7de1135 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PackageSerializerTest.java @@ -0,0 +1,90 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import org.junit.jupiter.api.Test; + +public class PackageSerializerTest { + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Package pkg = new Package("pk1", "Package"); + + @Test + void shouldSerializeId() throws JsonProcessingException { + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"id\" : \"pk1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"type\" : \"Package\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + pkg.addName("en", "My Reference Ontology"); + pkg.addName("es", "Mi ontología de referencia"); + + String json = mapper.writeValueAsString(pkg); + + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"en\" : \"My Reference Ontology\""); + assertThat(json).contains("\"es\" : \"Mi ontología de referencia\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + pkg.addDescription("en", "The ontology about all things that could exist."); + pkg.addDescription("es", "La ontología sobre todas las cosas que podrían existir."); + + String json = mapper.writeValueAsString(pkg); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"en\" : \"The ontology about all things that could exist.\""); + assertThat(json) + .contains("\"es\" : \"La ontología sobre todas las cosas que podrían existir.\""); + } + + @Test + void shouldSerializeEmptyDescriptionAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"description\" : null"); + } + + @Test + void shouldSerializePropertyAssignments() throws JsonProcessingException { + pkg.addPropertyAssignment("acronym", "UFO-X"); + pkg.addPropertyAssignment("numberOfContributors", 100); + + String json = mapper.writeValueAsString(pkg); + + assertThat(json).contains("\"propertyAssignments\" : {"); + assertThat(json).contains("\"acronym\" : \"UFO-X\""); + assertThat(json).contains("\"numberOfContributors\" : 100"); + } + + @Test + void shouldSerializeEmptyPropertyAssignmentsAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"propertyAssignments\" : null"); + } + + @Test + void shouldSerializeContents() throws JsonProcessingException { + pkg.createClass("c1", "Person", (String) null); + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"contents\" : ["); + assertThat(json).contains("\"id\" : \"c1\""); + assertThat(json).contains("\"name\" : \"Person\""); + } + + @Test + void shouldSerializeEmptyContentsAsNull() throws JsonProcessingException { + String json = mapper.writeValueAsString(pkg); + assertThat(json).contains("\"contents\" : null"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializerTest.java new file mode 100644 index 00000000..dd6746bd --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/ProjectSerializerTest.java @@ -0,0 +1,49 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.Project; +import org.junit.jupiter.api.Test; + +public class ProjectSerializerTest { + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Project project = new Project("1", (String) null); + + @Test + void shouldSerializeId() throws JsonProcessingException { + String json = mapper.writeValueAsString(project); + assertThat(json).contains("\"id\" : \"1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + String json = mapper.writeValueAsString(project); + assertThat(json).contains("\"type\" : \"Project\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + project.addName("pt-br", "Meu Projeto"); + project.addName("en", "My Project"); + + String json = mapper.writeValueAsString(project); + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt-br\" : \"Meu Projeto\""); + assertThat(json).contains("\"en\" : \"My Project\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + project.addDescription("it", "Il miglior progetto in modellazione concettuale."); + project.addDescription("en", "The best conceptual modeling project."); + + String json = mapper.writeValueAsString(project); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"it\" : \"Il miglior progetto in modellazione concettuale.\""); + assertThat(json).contains("\"en\" : \"The best conceptual modeling project.\""); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializerTest.java new file mode 100644 index 00000000..ae905b09 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/PropertySerializerTest.java @@ -0,0 +1,151 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Property; +import org.junit.jupiter.api.Test; + +public class PropertySerializerTest { + + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + Property property = new Property("p1", (String) null, null); + String json = mapper.writeValueAsString(property); + + public PropertySerializerTest() throws JsonProcessingException {} + + @Test + void shouldSerializeId() throws JsonProcessingException { + assertThat(json).contains("\"id\" : \"p1\""); + } + + @Test + void shouldSerializeType() throws JsonProcessingException { + assertThat(json).contains("\"type\" : \"Property\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + property.addName("pt", "Minha propriedade"); + property.addName("en", "My property"); + json = mapper.writeValueAsString(property); + + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt\" : \"Minha propriedade\""); + assertThat(json).contains("\"en\" : \"My property\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + property.addDescription("pt", "Minha descrição."); + property.addDescription("en", "My description."); + json = mapper.writeValueAsString(property); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"pt\" : \"Minha descrição.\""); + assertThat(json).contains("\"en\" : \"My description.\""); + } + + @Test + void shouldSerializeEmptyPropertyTypeAsNull() throws JsonProcessingException { + assertThat(json).contains("\"propertyType\" : null"); + } + + @Test + void shouldSerializePropertyTypeReference() throws JsonProcessingException { + Class clazz = new Class("c1", (String) null, (String) null); + property.setPropertyType(clazz); + + mapper = new ObjectMapper(); + json = mapper.writeValueAsString(property); + + assertThat(json).contains("\"propertyType\":{\"id\":\"c1\",\"type\":\"Class\"}"); + } + + @Test + void shouldSerializeIsDerived() throws JsonProcessingException { + property.setDerived(true); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"isDerived\" : true"); + } + + @Test + void shouldSerializeIsOrdered() throws JsonProcessingException { + property.setOrdered(true); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"isOrdered\" : true"); + } + + @Test + void shouldSerializeIsReadOnly() throws JsonProcessingException { + property.setReadOnly(true); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"isReadOnly\" : true"); + } + + @Test + void shouldSerializeCardinality() throws JsonProcessingException { + property.setCardinality("2..5"); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"cardinality\" : \"2..5\""); + } + + @Test + void shouldSerializeCardinalityOfOne() throws JsonProcessingException { + property.setCardinality("1"); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"cardinality\" : \"1\""); + } + + @Test + void shouldSerializeCardinalityOfZeroToMany() throws JsonProcessingException { + property.setCardinality("0..*"); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"cardinality\" : \"0..*\""); + } + + @Test + void shouldSerializeInvalidCardinality() throws JsonProcessingException { + property.setCardinality("a..b"); + json = mapper.writeValueAsString(property); + assertThat(json).contains("\"cardinality\" : \"a..b\""); + } + + @Test + void shouldSerializeEmptySubsettedPropertiesAsNull() throws JsonProcessingException { + assertThat(json).contains("\"subsettedProperties\" : null"); + } + + @Test + void shouldSerializeSubsettedProperties() throws JsonProcessingException { + Class person = Class.createKind("c1", "Person"); + + Property property = new Property("p1", "ancestor", person); + Property subProperty = new Property("p2", "father", person); + + subProperty.addSubsettedProperty(property); + + mapper = new ObjectMapper(); + json = mapper.writeValueAsString(subProperty); + + assertThat(json).contains("\"subsettedProperties\":[{\"id\":\"p1\",\"type\":\"Property\"}"); + } + + @Test + void shouldSerializeRedefinedProperties() throws JsonProcessingException { + Class person = Class.createKind("c1", "Person"); + + Property property = new Property("p1", "ancestor", person); + Property subProperty = new Property("p2", "father", person); + + subProperty.addRedefinedProperty(property); + + mapper = new ObjectMapper(); + json = mapper.writeValueAsString(subProperty); + + assertThat(json).contains("\"redefinedProperties\":[{\"id\":\"p1\",\"type\":\"Property\"}"); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializerTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializerTest.java new file mode 100644 index 00000000..74e69e57 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/RelationSerializerTest.java @@ -0,0 +1,101 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import static com.google.common.truth.Truth.assertThat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Relation; +import it.unibz.inf.ontouml.vp.model.ontouml.model.RelationStereotype; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class RelationSerializerTest { + ObjectMapper mapper; + Class clazz; + Relation relation; + String json; + + @BeforeEach + void setUp() throws JsonProcessingException { + mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + clazz = new Class("c1", (String) null, (String) null); + relation = new Relation("r1", "my relation", clazz, clazz); + json = mapper.writeValueAsString(relation); + } + + @Test + void shouldSerializeId() { + assertThat(json).contains("\"id\" : \"r1\""); + } + + @Test + void shouldSerializeType() { + assertThat(json).contains("\"type\" : \"Relation\""); + } + + @Test + void shouldSerializeName() throws JsonProcessingException { + relation.addName("pt", "Minha relação"); + relation.addName("en", "My relation"); + json = mapper.writeValueAsString(relation); + + assertThat(json).contains("\"name\" : {"); + assertThat(json).contains("\"pt\" : \"Minha relação\""); + assertThat(json).contains("\"en\" : \"My relation\""); + } + + @Test + void shouldSerializeDescription() throws JsonProcessingException { + relation.addDescription("pt", "Minha descrição."); + relation.addDescription("en", "My description."); + json = mapper.writeValueAsString(relation); + + assertThat(json).contains("\"description\" : {"); + assertThat(json).contains("\"pt\" : \"Minha descrição.\""); + assertThat(json).contains("\"en\" : \"My description.\""); + } + + @Test + void shouldSerializeOntoumlStereotype() throws JsonProcessingException { + relation.setOntoumlStereotype(RelationStereotype.MATERIAL); + json = mapper.writeValueAsString(relation); + assertThat(json).contains("\"stereotype\" : \"material\""); + } + + @Test + void shouldSerializeCustomStereotype() throws JsonProcessingException { + relation.setCustomStereotype("custom"); + json = mapper.writeValueAsString(relation); + assertThat(json).contains("\"stereotype\" : \"custom\""); + } + + @Test + void shouldSerializeIsAbstract() throws JsonProcessingException { + relation.setAbstract(true); + json = mapper.writeValueAsString(relation); + assertThat(json).contains("\"isAbstract\" : true"); + } + + @Test + void shouldSerializeIsDerived() throws JsonProcessingException { + relation.setDerived(true); + String json = mapper.writeValueAsString(relation); + assertThat(json).contains("\"isDerived\" : true"); + } + + @Test + void shouldSerializeEnds() throws JsonProcessingException { + relation.getSourceEnd().setId("p0"); + relation.getSourceEnd().addName("source"); + relation.getTargetEnd().setId("p1"); + relation.getTargetEnd().addName("target"); + + mapper = new ObjectMapper(); + json = mapper.writeValueAsString(relation); + + assertThat(json).contains("\"properties\":[{\"id\":\"p0\""); + assertThat(json).contains(",{\"id\":\"p1\""); + } +} diff --git a/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/SerializationTest.java b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/SerializationTest.java new file mode 100644 index 00000000..2fccd696 --- /dev/null +++ b/src/test/java/it/unibz/inf/ontouml/vp/model/ontouml/serialization/SerializationTest.java @@ -0,0 +1,69 @@ +package it.unibz.inf.ontouml.vp.model.ontouml.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import it.unibz.inf.ontouml.vp.model.ontouml.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.*; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Class; +import it.unibz.inf.ontouml.vp.model.ontouml.model.Package; +import java.io.File; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +public class SerializationTest { + ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + @Test + void buildAndSerializeModel() throws IOException { + Project project = new Project(); + project.addName("pt", "Meu Project"); + project.addName("en", "My Project"); + project.addDescription("it", "Il miglior progetto in modellazione concettuale."); + project.addDescription("en", "The best conceptual modeling project."); + + Package model = project.createModel("pk1", "My Model"); + Package pkg = model.createPackage("pk2", "My Module"); + + Class agent = model.createCategory("c1", "Agent"); + Class person = model.createKind("c2", "Person"); + Class organization = model.createKind("c3", "Organization"); + Class agentType = model.createType("c4", "AgentType"); + + Class car = pkg.createKind("Car"); + Class string = pkg.createDatatype("string"); + Class number = pkg.createDatatype("number"); + + Property name = agent.createAttribute("name", string); + name.setCardinality("1..*"); + + Property birthName = person.createAttribute("birthName", string); + birthName.addRedefinedProperty(name); + + Property nickname = person.createAttribute("nickname", string); + nickname.addSubsettedProperty(name); + + Property age = person.createAttribute("age", number); + age.setCardinality("1"); + + car.addPropertyAssignment("uri", "https://schema.org/Car"); + car.addPropertyAssignment("score", 10); + car.addPropertyAssignment("value", 8.9); + car.addPropertyAssignment("isLiked", false); + car.addPropertyAssignment("author", new String[] {"Tiago", "Davi"}); + car.addPropertyAssignment("source", null); + + Relation owns = model.createRelation("owns", person, car); + owns.getSourceEnd().setCardinality("1..*"); + owns.getTargetEnd().setCardinality("0..*"); + + Generalization g1 = model.createGeneralization("g1", person, agent); + Generalization g2 = model.createGeneralization("g2", organization, agent); + + GeneralizationSet genSet = model.createGeneralizationSet(g1, g2); + genSet.setCategorizer(agentType); + genSet.setDisjoint(true); + genSet.setComplete(true); + + mapper.writeValue(new File("target/serializedModel.json"), project); + } +}