diff --git a/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/Activator.java b/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/Activator.java index 3a8f64684..4b23ccda9 100644 --- a/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/Activator.java +++ b/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/Activator.java @@ -123,4 +123,24 @@ public static IStatus createErrorStatus(String message, Throwable e) { } } + public static void logError(String message) { + IStatus status = new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logWarning(String message) { + IStatus status = new Status(IStatus.WARNING, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logInfo(String message) { + IStatus status = new Status(IStatus.INFO, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logError(String message, Throwable e) { + IStatus status = new Status(IStatus.INFO, plugin.getBundle().getSymbolicName(), message, e); + plugin.getLog().log(status); + } + } diff --git a/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/wizards/imports/DatabaseImportWizard.java b/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/wizards/imports/DatabaseImportWizard.java index afdd6bdfe..37f832a20 100644 --- a/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/wizards/imports/DatabaseImportWizard.java +++ b/addons/scaffolding/plugins/org.obeonetwork.database.ui/src/org/obeonetwork/database/ui/wizards/imports/DatabaseImportWizard.java @@ -11,6 +11,7 @@ package org.obeonetwork.database.ui.wizards.imports; import static java.util.stream.Collectors.toList; +import static org.obeonetwork.database.ui.Activator.*; import java.lang.reflect.InvocationTargetException; import java.sql.Connection; @@ -24,7 +25,9 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; @@ -47,7 +50,6 @@ import org.obeonetwork.dsl.database.reverse.source.DataSourceException; import org.obeonetwork.dsl.database.reverse.utils.JdbcUtils; import org.obeonetwork.utils.common.ui.services.SiriusUIUtils; -import org.eclipse.jdt.core. IJavaProject; public class DatabaseImportWizard extends Wizard implements IImportWizard { @@ -81,7 +83,6 @@ public boolean performFinish() { } } - String filename = mainPage.getModelFilePath(); boolean result = DatabaseImportHelper.importDatabaseIntoModel(databaseInfos, filename, mainPage.getReferencedFiles()); if (result == true) { @@ -107,8 +108,9 @@ protected void execute(IProgressMonitor monitor) throws CoreException, Invocatio } }); PlatformUI.getWorkbench().getProgressService().run(false, false, new WorkspaceModifyOperation(ResourcesPlugin.getWorkspace().getRoot()) { - @Override + @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { + @SuppressWarnings("deprecation") ModelingProject enclosingModelingProject = ModelingProject.asModelingProject(enclosingProject).get(); activateViewpoints(enclosingModelingProject, monitor); } @@ -116,13 +118,18 @@ protected void execute(IProgressMonitor monitor) throws CoreException, Invocatio PlatformUI.getWorkbench().getProgressService().run(false, false, new WorkspaceModifyOperation(ResourcesPlugin.getWorkspace().getRoot()) { @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { + @SuppressWarnings("deprecation") ModelingProject enclosingModelingProject = ModelingProject.asModelingProject(enclosingProject).get(); Session session = enclosingModelingProject.getSession(); + logInfo("Creating representations."); List representations = createRepresentations(session, generatedFile, monitor); - + logInfo(String.format("%d representations created.", representations.size())); + // Open representations + logInfo("Opening representations."); for (DRepresentation representation : representations) { DialectUIManager.INSTANCE.openEditor(session, representation, monitor); } + logInfo("Done opening representations."); } }); } catch (InvocationTargetException e) { @@ -156,24 +163,29 @@ private void activateViewpoints(ModelingProject enclosingModelingProject, IProgr } private List createRepresentations(Session session, IFile semanticResourceFile, IProgressMonitor monitor) { - List representations = new ArrayList<>(); - URI semanticResourceURI = URI.createPlatformResourceURI(semanticResourceFile.getFullPath().toString(), true); Resource semanticResource = session.getSemanticResources().stream().filter(r -> r.getURI() == semanticResourceURI).findAny().orElse(null); + List contexts = new ArrayList<>(); + List representationDescriptionIds = new ArrayList<>(); + List databases = semanticResource.getContents().stream() .filter(DataBase.class::isInstance).map(DataBase.class::cast) .collect(toList()); for(DataBase database : databases) { - representations.add(SiriusUIUtils.createRepresentation(session, database, IDatabaseViewpointConstants.DATABASE_DIAGRAM_ID, monitor)); + contexts.add(database); + representationDescriptionIds.add(IDatabaseViewpointConstants.DATABASE_DIAGRAM_ID); } - List schemas = databases.stream().flatMap(db -> db.getSchemas().stream()).collect(toList()); + List schemas = databases.stream() + .flatMap(db -> db.getSchemas().stream()) + .collect(toList()); for(Schema schema : schemas) { - representations.add(SiriusUIUtils.createRepresentation(session, schema, IDatabaseViewpointConstants.SCHEMA_DIAGRAM_ID, monitor)); + contexts.add(schema); + representationDescriptionIds.add(IDatabaseViewpointConstants.SCHEMA_DIAGRAM_ID); } - return representations; + return SiriusUIUtils.createRepresentations(session, contexts, representationDescriptionIds, monitor); } /* (non-Javadoc) diff --git a/commons/is/plugins/org.obeonetwork.dsl.is/src/org/obeonetwork/dsl/is/ui/wizards/AbstractISNewModelWizard.java b/commons/is/plugins/org.obeonetwork.dsl.is/src/org/obeonetwork/dsl/is/ui/wizards/AbstractISNewModelWizard.java index 7713ebdec..6a15a87c1 100644 --- a/commons/is/plugins/org.obeonetwork.dsl.is/src/org/obeonetwork/dsl/is/ui/wizards/AbstractISNewModelWizard.java +++ b/commons/is/plugins/org.obeonetwork.dsl.is/src/org/obeonetwork/dsl/is/ui/wizards/AbstractISNewModelWizard.java @@ -26,6 +26,7 @@ import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOResourceNode; +import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EObject; @@ -36,6 +37,7 @@ import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.wizard.Wizard; +import org.eclipse.sirius.business.api.dialect.command.CreateRepresentationCommand; import org.eclipse.sirius.business.api.modelingproject.ModelingProject; import org.eclipse.sirius.business.api.session.Session; import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager; @@ -65,8 +67,6 @@ abstract public class AbstractISNewModelWizard extends Wizard implements INewWiz private Resource createdResource; - private Collection createdRepresentations = new ArrayList<>(); - public AbstractISNewModelWizard(String windowTitle, ImageDescriptor imageDescriptor) { setWindowTitle(windowTitle); this.imageDescriptor = imageDescriptor; @@ -125,37 +125,35 @@ protected String extractNameFromTargetResourceName(String fileExtension) { protected void initRepresentations(final Session session, Collection initialObjects, IProgressMonitor monitor) { if (session != null) { + CompoundCommand createRepresentationsCompoundCommand = new CompoundCommand(); Map> mapDescIDs = getRepresentationDescriptionsIDToBeCreated(); if (!mapDescIDs.isEmpty()) { - for (EObject object : initialObjects) { - Collection descIDs = mapDescIDs.get(object.eClass()); + for (EObject context : initialObjects) { + Collection descIDs = mapDescIDs.get(context.eClass()); for (String descID : descIDs) { - RepresentationDescription desc = SessionUtils.getRepresentationDescription(session, object, descID); - if (desc != null) { + RepresentationDescription representationDescription = SessionUtils.getRepresentationDescription(session, context, descID); + if (representationDescription != null) { // Get name for the representation - String representationName = getRepresentationName(desc, object); - // and create representation - DRepresentation newRepresentation = SiriusUIUtils.createRepresentation(session, desc, representationName, object, monitor); - if (newRepresentation != null) { - createdRepresentations.add(newRepresentation); - } - } - } - // Open representations - for (DRepresentation createdRepresentation : createdRepresentations) { - if (shouldOpenRepresentation(createdRepresentation)) { - openRepresentation(session, createdRepresentation, monitor); + String representationName = getRepresentationName(representationDescription, context); + // Create representation + createRepresentationsCompoundCommand.append(new CreateRepresentationCommand(session, representationDescription, context, representationName, monitor)); } } } } + if(!createRepresentationsCompoundCommand.getCommandList().isEmpty()) { + SiriusUIUtils.executeCreateRepresentationCommand(createRepresentationsCompoundCommand, session); + // Open created representations if needed + createRepresentationsCompoundCommand.getCommandList().stream() + .map(CreateRepresentationCommand.class::cast) + .map(CreateRepresentationCommand::getCreatedRepresentation) + .filter(newRepresentation -> newRepresentation != null) + .filter(newRepresentation -> shouldOpenRepresentation(newRepresentation)) + .forEach(newRepresentation -> DialectUIManager.INSTANCE.openEditor(session, newRepresentation, monitor)); + } } } - protected void openRepresentation(final Session session, DRepresentation representation, IProgressMonitor monitor) { - DialectUIManager.INSTANCE.openEditor(session, representation, monitor); - } - protected boolean isDataValid(ModelingProject targetModelingProject, Object targetContainer, String targetResourceName, IProgressMonitor monitor) { if (targetContainer instanceof IProject) { // We have to check the case of a resource creation at the root of diff --git a/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/Activator.java b/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/Activator.java index 3e18ceff2..9c0cc6ce4 100644 --- a/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/Activator.java +++ b/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/Activator.java @@ -10,31 +10,55 @@ *******************************************************************************/ package org.obeonetwork.utils.common.ui; -import org.osgi.framework.BundleActivator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; -public class Activator implements BundleActivator { - - private static BundleContext context; - - static BundleContext getContext() { - return context; - } +public class Activator extends AbstractUIPlugin { + // The plug-in ID + public static final String PLUGIN_ID = "org.obeonetwork.utils.common.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ - public void start(BundleContext bundleContext) throws Exception { - Activator.context = bundleContext; + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ - public void stop(BundleContext bundleContext) throws Exception { - Activator.context = null; + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static void logError(String message) { + IStatus status = new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logWarning(String message) { + IStatus status = new Status(IStatus.WARNING, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logInfo(String message) { + IStatus status = new Status(IStatus.INFO, plugin.getBundle().getSymbolicName(), message); + plugin.getLog().log(status); + } + + public static void logError(String message, Throwable e) { + IStatus status = new Status(IStatus.INFO, plugin.getBundle().getSymbolicName(), message, e); + plugin.getLog().log(status); } } diff --git a/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/services/SiriusUIUtils.java b/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/services/SiriusUIUtils.java index 3f976c48c..fa49f4a0f 100644 --- a/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/services/SiriusUIUtils.java +++ b/commons/utils/plugins/org.obeonetwork.utils.common.ui/src/org/obeonetwork/utils/common/ui/services/SiriusUIUtils.java @@ -10,8 +10,14 @@ *******************************************************************************/ package org.obeonetwork.utils.common.ui.services; +import static java.util.stream.Collectors.toList; +import static org.obeonetwork.utils.common.ui.Activator.logInfo; +import static org.obeonetwork.utils.common.ui.Activator.logWarning; + import java.lang.reflect.InvocationTargetException; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Optional; import org.eclipse.core.runtime.IProgressMonitor; @@ -23,6 +29,8 @@ import org.eclipse.eef.properties.ui.api.EEFTabContents; import org.eclipse.eef.properties.ui.api.EEFTabbedPropertySheetPage; import org.eclipse.eef.properties.ui.api.IEEFTabDescriptor; +import org.eclipse.emf.common.command.AbstractCommand; +import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.RecordingCommand; @@ -87,23 +95,70 @@ protected void doExecute() { } } - public static DRepresentation createRepresentation(Session session, RepresentationDescription description, String name, EObject context, IProgressMonitor monitor) { - // Ensure that there is no save in progress. - // Otherwise when the representation is added to the resource CreateRepresentationCommand can be problematic. - // Indeed, during the save the eSetDeliver is disabled at some point (ResourceSaveDiagnose.hasDifferentSerialization), - // preventing any adapter to be added to the new representation. + /** + * Executes the given {@link CreateRepresentationCommand} or compound of {@link CreateRepresentationCommand}s.
+ *

+ * Joins on the save session job family to make sure that no session save is in progress.
+ * Otherwise, when the representation is added to the resource, + * CreateRepresentationCommand can be problematic. + * At some point during the save, the eSetDeliver is disabled + * (ResourceSaveDiagnose.hasDifferentSerialization), preventing any adapter from + * being added to the new representation. + *

+ *

+ * Warning: This induce the following risk. If no dialect editors are open, + * SaveSessionWhenNoDialectEditorsListener saves the session each time a command + * is executed on the stack. Creating multiple representations with multiple + * commands executed separately and at once may therefore cause a deadlock situation + * (SAFRAN-1134). This is why this method accepts a compound of {@link CreateRepresentationCommand}s. + *

+ + * @param command + * @param session + */ + public static void executeCreateRepresentationCommand(AbstractCommand command, Session session) { + logInfo("Joining on Sirius save session job family."); try { Job.getJobManager().join(SaveSessionJob.FAMILY, new NullProgressMonitor()); } catch (OperationCanceledException | InterruptedException e) { - // Ignore. The join is just here to avoid to have a save in progress. + logWarning(String.format("Join Sirius save session jobs aborted for '%s'.", command.getLabel())); } - - CreateRepresentationCommand cmd = new CreateRepresentationCommand(session, description, context, name, monitor); - session.getTransactionalEditingDomain().getCommandStack().execute(cmd); - return cmd.getCreatedRepresentation(); + logInfo("Joining on Sirius save session job family passed."); + logInfo(String.format("Executing command '%s'.", command.getLabel())); + session.getTransactionalEditingDomain().getCommandStack().execute(command); + logInfo(String.format("Command '%s' executed.", command.getLabel())); + } + + public static DRepresentation createRepresentation(Session session, EObject context, RepresentationDescription representationDescription, String title, IProgressMonitor monitor) { + CreateRepresentationCommand command = new CreateRepresentationCommand(session, representationDescription, context, title, monitor); + executeCreateRepresentationCommand(command, session); + return command.getCreatedRepresentation(); } public static DRepresentation createRepresentation(Session session, EObject context, String representationDescriptionId, IProgressMonitor monitor) { + CreateRepresentationCommand command = createRepresentationCommand(session, context, representationDescriptionId, monitor); + executeCreateRepresentationCommand(command, session); + return command.getCreatedRepresentation(); + } + + public static List createRepresentations(Session session, List contexts, List representationDescriptionIds, IProgressMonitor monitor) { + CompoundCommand compoundCommand = new CompoundCommand(); + + Iterator contextIterator = contexts.iterator(); + Iterator representationDescriptionIdIterator = representationDescriptionIds.iterator(); + while(contextIterator.hasNext() && representationDescriptionIdIterator.hasNext()) { + compoundCommand.append(createRepresentationCommand(session, contextIterator.next(), representationDescriptionIdIterator.next(), monitor)); + } + + executeCreateRepresentationCommand(compoundCommand, session); + + return compoundCommand.getCommandList().stream() + .map(CreateRepresentationCommand.class::cast) + .map(CreateRepresentationCommand::getCreatedRepresentation) + .collect(toList()); + } + + private static CreateRepresentationCommand createRepresentationCommand(Session session, EObject context, String representationDescriptionId, IProgressMonitor monitor) { RepresentationDescription representationDescription = SessionUtils.getRepresentationDescription(session, context, representationDescriptionId); String title = null; @@ -119,7 +174,7 @@ public static DRepresentation createRepresentation(Session session, EObject cont title = representationDescription.getLabel(); } - return createRepresentation(session, representationDescription, title, context, monitor); + return new CreateRepresentationCommand(session, representationDescription, context, title, monitor); } /** diff --git a/designs/environment/plugins/org.obeonetwork.dsl.environment.design/src/org/obeonetwork/dsl/environment/design/ui/menu/PartialViewCreationAction.java b/designs/environment/plugins/org.obeonetwork.dsl.environment.design/src/org/obeonetwork/dsl/environment/design/ui/menu/PartialViewCreationAction.java index 7ed541255..081d30e1f 100644 --- a/designs/environment/plugins/org.obeonetwork.dsl.environment.design/src/org/obeonetwork/dsl/environment/design/ui/menu/PartialViewCreationAction.java +++ b/designs/environment/plugins/org.obeonetwork.dsl.environment.design/src/org/obeonetwork/dsl/environment/design/ui/menu/PartialViewCreationAction.java @@ -106,7 +106,7 @@ public void run() { } String representationName = promptName.getValue(); - DDiagram diagram = (DDiagram) SiriusUIUtils.createRepresentation(session, representationDescription, representationName, context, new NullProgressMonitor()); + DDiagram diagram = (DDiagram) SiriusUIUtils.createRepresentation(session, context, representationDescription, representationName, new NullProgressMonitor()); try { PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(false, false, motitor -> @@ -117,8 +117,6 @@ public void run() { e.printStackTrace(); } - DialectUIManager.INSTANCE.openEditor(session, diagram, new NullProgressMonitor()); - // Restore the "Synchronize diagram on creation" preference diagramCorePreferences.putBoolean(SiriusDiagramInternalPreferencesKeys.PREF_SYNCHRONIZE_DIAGRAM_ON_CREATION.name(), syncOnCreation);