diff options
Diffstat (limited to 'plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus')
19 files changed, 2170 insertions, 0 deletions
diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/Activator.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/Activator.java new file mode 100644 index 00000000000..4b6d2d237f5 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/Activator.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture; + +import org.eclipse.core.runtime.Plugin; +import org.eclipse.papyrus.infra.core.log.LogHelper; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.papyrus.infra.architecture"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** Logging helper */ + public static LogHelper log; + + /** + * The constructor + */ + public Activator() { + } + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + log = new LogHelper(this); + } + + @Override + public void stop(BundleContext context) throws Exception { + log = null; + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDescriptionUtils.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDescriptionUtils.java new file mode 100644 index 00000000000..18c9e69463c --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDescriptionUtils.java @@ -0,0 +1,333 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.transaction.RecordingCommand; +import org.eclipse.papyrus.infra.architecture.commands.IModelConversionCommand; +import org.eclipse.papyrus.infra.architecture.commands.IModelCreationCommand; +import org.eclipse.papyrus.infra.architecture.commands.ModelCommandProviderRegistry; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescription; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionPreferences; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureFactory; +import org.eclipse.papyrus.infra.core.architecture.ArchitecturePackage; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureContext; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureViewpoint; +import org.eclipse.papyrus.infra.core.resource.IModel; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel; + +/** + * An API for manipulating architecture descriptions in a model set + * + * @since 1.0 + */ +public class ArchitectureDescriptionUtils { + + /** + * The model set in context + */ + private ModelSet modelSet; + + /** + * The architecture domain manager + */ + private ArchitectureDomainManager manager = ArchitectureDomainManager.getInstance(); + + /** + * Constructs an instance of this class given a model set + * + * @param modelSet The given model set + */ + public ArchitectureDescriptionUtils(ModelSet modelSet) { + this.modelSet = modelSet; + } + + /** + * Gets the model set in context + * + * @return a model set + */ + public ModelSet getModelSet() { + return modelSet; + } + + /** + * Gets the architecture context set in the model set + * + * @return architecture context + */ + public MergedArchitectureContext getArchitectureContext() { + String contextId = getArchitectureContextId(); + return manager.getArchitectureContextById(contextId); + } + + /** + * Gets the architecture context id set in the model set + * + * @return architecture context id + */ + public String getArchitectureContextId() { + ArchitectureDescription description = getArchitectureDescription(); + if (description != null) + return description.getContextId(); + return ArchitectureDomainManager.getInstance().getDefaultArchitectureContextId(); + } + + /** + * Gets the architecture viewpoints set in the model set + * + * @return a collection of architecture viewpoints + */ + public Collection<MergedArchitectureViewpoint> getArchitectureViewpoints() { + List<MergedArchitectureViewpoint> viewpoints = new ArrayList<MergedArchitectureViewpoint>(); + for (String viewpointId : getArchitectureViewpointIds()) { + MergedArchitectureViewpoint viewpoint = manager.getArchitectureViewpointById(viewpointId); + if (viewpoint != null) + viewpoints.add(viewpoint); + } + return viewpoints; + } + + /** + * Gets the architecture viewpoint ids set in the model set + * + * @return a collection of architecture viewpoin ids + */ + public Collection<String> getArchitectureViewpointIds() { + ArchitectureDescriptionPreferences preferences = getArchitectureDescriptionPreferences(); + if (preferences != null) + return preferences.getViewpointIds(); + MergedArchitectureContext context = ArchitectureDomainManager.getInstance().getDefaultArchitectureContext(); + List<String> viewpointIds = new ArrayList<String>(); + for (MergedArchitectureViewpoint viewpoint : context.getViewpoints()) { + viewpointIds.add(viewpoint.getId()); + } + return viewpointIds; + } + + /** + * Returns a command that applies the given contextId and viewpoint ids to the model set + * and creates a new model in the set based on them + * + * Model creation is based on the creation command configured with the architecture context + * and contribution commands registered in extensions + * + * @param contextId the context id to apply to the model set + * @param viewpointIds the viewpoint ids to apply to the model set + * @return a command to create a new model + */ + public Command createNewModel(final String contextId, final String[] viewpointIds) { + CompoundCommand cc = new CompoundCommand("Create New Model"); + // Add the main command to create the model + cc.append(getModelCreationCommand(contextId)); + // Add commands from registered providers to create the model + cc.append(ModelCommandProviderRegistry.getInstance().getModelCreationCommand(modelSet, contextId)); + // Add a command to set the new context id to the model set + cc.append(getSetContextCommand(contextId)); + // Add a command to set the new viewpoint ids to the model set + cc.append(getSetViewpointCommand(viewpointIds)); + return cc; + } + + /** + * Returns a command that switches the contextId of the model set to the given id and + * converts the semantic model as a result + * + * Model conversion is based on the conversion command configured with the architecture context + * and contribution commands registered in extensions + * + * @param contextId the context id to apply to the model set + * @return a command that switches the model set to the given context id + */ + public Command switchArchitectureContextId(final String contextId) { + CompoundCommand cc = new CompoundCommand("Switch Architecture Context"); + // Add the main command to convert the model + cc.append(getModelConversionCommand(contextId)); + // Add commands from registered providers to convert the model + cc.append(ModelCommandProviderRegistry.getInstance().getModelConversionCommand(modelSet, contextId)); + // Add a command to set the new context id + cc.append(getSetContextCommand(contextId)); + return cc; + } + + /** + * Returns a command that switches the viewpoints of the model set to the given id + * + * @param viewpointIds the new viewpoint ids to apply to the model set + * @return a command that switches the model set to the given viewpoint ids + */ + public Command switchArchitectureViewpointIds(final String[] viewpointIds) { + CompoundCommand cc = new CompoundCommand("Switch Architecture Viewpoints"); + // Add a command to convert the model + cc.append(getSetViewpointCommand(viewpointIds)); + return cc; + } + + /** + * Returns a command to set the context id in the model set + * + * @param contextId the new context id + * @return a command that sets the context id in the model set + */ + protected Command getSetContextCommand(String contextId) { + return new RecordingCommand(modelSet.getTransactionalEditingDomain()) { + @Override + protected void doExecute() { + ArchitectureDescription description = getArchitectureDescription(); + if (description == null) { + description = ArchitectureFactory.eINSTANCE.createArchitectureDescription(); + addArchitectureDescription(description); + } + description.setContextId(contextId); + } + }; + } + + /** + * Returns a command to create a new model in the model set based on the given context id + * + * @param contextId the context id + * @return a command that creates a new model + */ + protected Command getModelCreationCommand(String contextId) { + final MergedArchitectureContext context = manager.getArchitectureContextById(contextId); + if (context.getCreationCommandClass() == null) + return null; + return new RecordingCommand(modelSet.getTransactionalEditingDomain()) { + @Override + protected void doExecute() { + try { + IModelCreationCommand creationCommand = (IModelCreationCommand) context.getCreationCommandClass().newInstance(); + creationCommand.createModel(modelSet); + } catch (Exception e) { + Activator.log.error(e); + } + } + }; + } + + /** + * Returns a command to converts a new model in the model set based on the given new context id + * + * @param contextId the new context id + * @return a command that converts a model + */ + protected Command getModelConversionCommand(String contextId) { + MergedArchitectureContext context = manager.getArchitectureContextById(contextId); + if (context.getConversionCommandClass() == null) + return null; + return new RecordingCommand(modelSet.getTransactionalEditingDomain()) { + @Override + protected void doExecute() { + try { + IModelConversionCommand conversionCommand = (IModelConversionCommand) context.getConversionCommandClass().newInstance(); + conversionCommand.convertModel(modelSet); + } catch (Exception e) { + Activator.log.error(e); + } + } + }; + } + + /** + * Returns a command that sets the given viewpoint ids to the model set + * + * @param viewpointIds The new viewpoint ids + * @return a command to set the viewpoint ids + */ + protected Command getSetViewpointCommand(String[] viewpointIds) { + return new RecordingCommand(modelSet.getTransactionalEditingDomain()) { + @Override + protected void doExecute() { + ArchitectureDescriptionPreferences preferences = getArchitectureDescriptionPreferences(); + if (preferences == null) { + preferences = ArchitectureFactory.eINSTANCE.createArchitectureDescriptionPreferences(); + addArchitectureDescriptionPreferences(preferences); + } + Arrays.sort(viewpointIds); + preferences.eSet(ArchitecturePackage.eINSTANCE.getArchitectureDescriptionPreferences_ViewpointIds(), Arrays.asList(viewpointIds)); + } + }; + } + + /** + * Gets the architecture description element in the model set + * + * @return the architecture description element + */ + protected ArchitectureDescription getArchitectureDescription() { + ArchitectureDescription description = null; + for (EObject root : getDiResource().getContents()) { + if (root instanceof ArchitectureDescription) { + description = (ArchitectureDescription) root; + break; + } + } + return description; + } + + /** + * Adds the given architecture description element to the resource set + * + * @param description an architecture description element + */ + protected void addArchitectureDescription(ArchitectureDescription description) { + getDiResource().getContents().add(description); + } + + /** + * Gets the architecture description preferences element in the model set + * + * @return the architecture description preferences element + */ + protected ArchitectureDescriptionPreferences getArchitectureDescriptionPreferences() { + ArchitectureDescriptionPreferences preferences = null; + for (EObject root : getDiResource().getContents()) { + if (root instanceof ArchitectureDescriptionPreferences) { + preferences = (ArchitectureDescriptionPreferences) root; + break; + } + } + return preferences; + } + + /** + * Adds the given architecture description preferences element to the resource set + * + * @param description an architecture description preferences element + */ + protected void addArchitectureDescriptionPreferences(ArchitectureDescriptionPreferences preferences) { + getDiResource().getContents().add(preferences); + } + + /** + * Gets the DI resource from the model set + * + * @return the DI resource + */ + protected Resource getDiResource() { + IModel model = modelSet.getModel(DiModel.DI_MODEL_ID); + return ((DiModel)model).getResource(); + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainManager.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainManager.java new file mode 100644 index 00000000000..152e35b9baf --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainManager.java @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.eclipse.emf.common.util.URI; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureContext; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureDomain; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureViewpoint; + +/** + * The main API for reading architecture domains information + * + * It reads architecture domain models registered in extensions and preferences + * + * @since 1.0 + */ +public class ArchitectureDomainManager implements IPreferenceChangeListener { + + /** + * The extension point for architecture models + */ + private static final String EXTENSION_POINT = Activator.PLUGIN_ID + ".models"; + + /** + * The name pf the path attribute + */ + private static final String PATH = "path"; //$NON-NLS-1$ + + /** + * The singleton instance of this class + */ + private static ArchitectureDomainManager INSTANCE; + + /** + * Gets the singleton instance of this class + * + * @return the singleton instance of this class + */ + public static ArchitectureDomainManager getInstance() { + if (INSTANCE == null) + INSTANCE = new ArchitectureDomainManager(); + return INSTANCE; + } + + /** + * An interface for listening to changes to architectural domains + */ + public static interface Listener { + public void domainManagerChanged(); + } + + /** + * The architecture domain preferences + */ + private ArchitectureDomainPreferences preferences; + + /** + * The architecture domain merger + */ + private ArchitectureDomainMerger merger; + + /** + * A collection of listeners to architecture domain changes + */ + private Collection<Listener> listeners; + + /** + * Constructs a new instance of this class + */ + private ArchitectureDomainManager() { + listeners = new HashSet<Listener>(); + merger = new ArchitectureDomainMerger(); + preferences = new ArchitectureDomainPreferences(); + preferences.addListener(this); + initializeFromExtensions(); + initializeFromPreferences(); + merger.init(); // init as early as possible + } + + /** + * initialize the architecture domain merger from the registered extensions + */ + private void initializeFromExtensions() { + List<URI> models = new ArrayList<URI>(); + IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT); + for (IConfigurationElement element : elements) { + String path = element.getAttribute(PATH); + String bundleId = element.getContributor().getName(); + String modelPath = bundleId + IPath.SEPARATOR + path; + models.add(URI.createPlatformPluginURI(modelPath, true)); + } + merger.setExtensionModels(models); + } + + /** + * initialize the architecture domain merger from the preferences + */ + private void initializeFromPreferences() { + preferences.read(); + List<URI> models = new ArrayList<URI>(); + for (String value : preferences.getAddedModelURIs()) { + if (value.length()>0) { + models.add(URI.createURI(value, true)); + } + } + merger.setPreferenceModels(models); + } + + /** + * Add the given listener to the domain changes + * + * @param listener a given domain change listener + */ + public void addListener(Listener listener) { + listeners.add(listener); + } + + /** + * Remove the given listener to the domain changes + * + * @param listener a given domain change listener + */ + public void removeListener(Listener listener) { + listeners.remove(listener); + } + + /** + * React to the preferences changing by reinitializing from them; notify listeners + * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) + * + * @param event a preference change event + */ + @Override + public void preferenceChange(PreferenceChangeEvent event) { + initializeFromPreferences(); + for (Listener listener : listeners) + listener.domainManagerChanged(); + } + + /** + * Gets the architecture domain preferences + * + * @return the architecture domain preferences + */ + public ArchitectureDomainPreferences getPreferences() { + return preferences; + } + + /** + * Get the architecture domain merger + * + * @return the architecture domain merger + */ + public ArchitectureDomainMerger getMerger() { + return merger; + } + + /** + * Gets the collection of architecture contexts that are visible based on preferences + * + * @return a list of architecture contexts + */ + public Collection<MergedArchitectureContext> getVisibleArchitectureContexts() { + Collection<MergedArchitectureContext> contexts = new ArrayList<MergedArchitectureContext>(); + for (MergedArchitectureDomain domain : merger.getDomains()) { + for (MergedArchitectureContext context : domain.getContexts()) { + if (!preferences.getExcludedContextIds().contains(context.getId())) + contexts.add(context); + } + } + return contexts; + } + + /** + * Gets the id of the default architecture context + * + * @return the default architecture context id + */ + public String getDefaultArchitectureContextId() { + return preferences.getDefaultContextId(); + } + + /** + * Gets the default architecture context + * + * @return the default architecture context + */ + public MergedArchitectureContext getDefaultArchitectureContext() { + return getArchitectureContextById(getDefaultArchitectureContextId()); + } + + /** + * Gets an architecture context by the given id + * + * @param id a given id of an architecture context + * @return the architecture context with the given id + */ + public MergedArchitectureContext getArchitectureContextById(String id) { + return merger.getArchitectureContextById(id); + } + + /** + * Gets an architecture viewpoint by the given id + * + * @param id a given id of an architecture viewpoint + * @return the architecture viewpoint with the given id + */ + public MergedArchitectureViewpoint getArchitectureViewpointById(String id) { + return merger.getArchitectureViewpointById(id); + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainMerger.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainMerger.java new file mode 100644 index 00000000000..62d2c0f94cd --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainMerger.java @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDomain; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedADElement; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureContext; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureDomain; +import org.eclipse.papyrus.infra.core.architecture.merged.MergedArchitectureViewpoint; + +/** + * A merger for architecture domains read from extensions or preferences or contributed + * dynamically (programmatically) + * + * It produces a collection of {@link org.eclipse.papyrus.infra.core.architecture. + * merged.MergedDomain}s by merging a collection of {@link org.eclipse.papyrus.infra. + * core.architecture.ArchitectureDomain}s. + * + * @since 1.0 + */ +public class ArchitectureDomainMerger implements Cloneable { + + /** + * A resource set used to load architecture models + */ + private ResourceSet resourceSet; + + /** + * a collection of architecture models coming from extensions + */ + private Collection<URI> extensionModels; + + /** + * a collection of architecture models coming from preferences + */ + private Collection<URI> preferenceModels; + + /** + * a collection of architecture domains contributed dynamically (programmatically) + */ + private Collection<ArchitectureDomain> dynamicDomains; + + /** + * A collection of merged domains + */ + private Map<String, MergedArchitectureDomain> mergedDomains; + + /** + * a cached mapping from id to ADElement + */ + private Map<String, MergedADElement> idCache; + + /** + * Constructs a new instance of the class + */ + ArchitectureDomainMerger() { + } + + /** + * Sets the collection of architecture models URIs read from extensions + * + * @param models a collection of architecture model URIs + */ + public void setExtensionModels(Collection<URI> models) { + this.extensionModels = models; + reset(); + } + + /** + * Sets the collection of architecture model URIs read from preferences + * + * @param models a collection of architecture model URIS + */ + public void setPreferenceModels(Collection<URI> models) { + this.preferenceModels = models; + reset(); + } + + /** + * Sets the collection of architecture domains contributed dynamically + * + * @param domains a collection of architecture domains + */ + public void setDynamicDomains(Collection<ArchitectureDomain> domains) { + this.dynamicDomains = domains; + reset(); + } + + /** + * Gets the collection of merged architecture domains + * + * @return the collection of merged architecture domains + */ + public Collection<MergedArchitectureDomain> getDomains() { + if (mergedDomains == null) + init(); + return mergedDomains.values(); + } + + /** + * Gets an architecture context given its id + * + * @param id an id for an architecture context + * @return an architecture context + */ + public MergedArchitectureContext getArchitectureContextById(String id) { + if (mergedDomains == null) + init(); + MergedADElement found = idCache.get(id); + return (found instanceof MergedArchitectureContext)? (MergedArchitectureContext)found : null; + } + + /** + * Gets an architecture viewpoint given its id + * + * @param id an id for an architecture viewpoint + * @return an architecture viewpoint + */ + public MergedArchitectureViewpoint getArchitectureViewpointById(String id) { + if (mergedDomains == null) + init(); + MergedADElement found = idCache.get(id); + return (found instanceof MergedArchitectureViewpoint)? (MergedArchitectureViewpoint)found : null; + } + + @Override + public ArchitectureDomainMerger clone() { + ArchitectureDomainMerger clone = new ArchitectureDomainMerger(); + clone.setExtensionModels(extensionModels); + clone.setPreferenceModels(preferenceModels); + return clone; + } + + /* + * Resets the merger's state + */ + private void reset() { + resourceSet = null; + mergedDomains = null; + idCache = null; + } + + /** + * Initializes this instance of the merger + */ + void init() { + resourceSet = new ResourceSetImpl(); + mergedDomains = new HashMap<String, MergedArchitectureDomain>(); + if (extensionModels != null) { + for (URI model : extensionModels) { + ArchitectureDomain domain = loadDomain(resourceSet.createResource(model)); + if (domain != null) + merge(domain); + } + } + if (preferenceModels != null) { + for (URI model : preferenceModels) { + ArchitectureDomain domain = loadDomain(resourceSet.createResource(model)); + if (domain != null) + merge(domain); + } + } + if (dynamicDomains != null) { + for (ArchitectureDomain domain : dynamicDomains) { + if (domain != null) + merge(domain); + } + } + buildCache(); + } + + /* + * Read an architecture domain from the given architecture model resource + */ + private ArchitectureDomain loadDomain(Resource resource) { + try { + resource.load(null); + } catch (IOException e) { + // Don't log the error yet; we're trying several options + return null; + } + EObject content = resource.getContents().get(0); + if (content instanceof ArchitectureDomain) { + return (ArchitectureDomain) content; + } else + Activator.log.warn("file "+resource.getURI()+ " is not an architecture model"); + return null; + } + + /* + * Merges the given architecture domain with the others + */ + private void merge(ArchitectureDomain domain) { + MergedArchitectureDomain merged = mergedDomains.get(domain.getName()); + if (merged == null) { + mergedDomains.put(domain.getName(), merged = new MergedArchitectureDomain()); + } + merged.merge(domain); + } + + /* + * builds a id to element cache for faster lookup + */ + private void buildCache() { + idCache = new HashMap<String, MergedADElement>(); + for (MergedArchitectureDomain domain : mergedDomains.values()) { + for (MergedArchitectureContext context : domain.getContexts()) { + idCache.put(context.getId(), context); + for (MergedArchitectureViewpoint viewpoint : context.getViewpoints()) { + idCache.put(viewpoint.getId(), viewpoint); + } + } + } + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainPreferences.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainPreferences.java new file mode 100644 index 00000000000..e7954f363d6 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/ArchitectureDomainPreferences.java @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.papyrus.infra.services.edit.context.TypeContext; +import org.osgi.service.prefs.BackingStoreException; + +/** + * This class reads/writes the architecture domain preferences + * + * @since 1.0 + */ +public class ArchitectureDomainPreferences implements Cloneable { + + /** + * The addedModels preference property name + */ + public static final String ADDED_MODELS = "addedModels"; //$NON-NLS-1$ + + /** + * The excludedContexts preference property name + */ + public static final String EXCLUDED_CONTEXTS = "excludedContexts"; //$NON-NLS-1$ + + /** + * The defaultContext preference property name + */ + public static final String DEFAULT_CONTEXT = "defaultContext"; //$NON-NLS-1$ + + /** + * The list of added architecture models in the preferences + */ + private List<String> addedModels; + + /** + * The set of excluded architecture contexts in the preferences + */ + private Set<String> excludedContexts; + + /** + * The id of the default context in the preferences + */ + private String defaultContext; + + /** + * The default value of the default context when not set + */ + private String defaultDefaultContext = TypeContext.getDefaultContextId(); + + /* + * Gets the preferences node + */ + private static IEclipsePreferences getPreferences() { + return InstanceScope.INSTANCE.getNode(Activator.PLUGIN_ID); + } + + /** + * Reads the state of the preferences + */ + public void read() { + addedModels = Arrays.asList(getPreferences().get(ArchitectureDomainPreferences.ADDED_MODELS, "").split(" ")); + excludedContexts = new HashSet<String>(Arrays.asList(getPreferences().get(ArchitectureDomainPreferences.EXCLUDED_CONTEXTS, "").split(","))); + defaultContext = getPreferences().get(ArchitectureDomainPreferences.DEFAULT_CONTEXT, defaultDefaultContext); + } + + /** + * Writes the state of the preferences + */ + public void write() { + getPreferences().put(ArchitectureDomainPreferences.ADDED_MODELS, String.join(" ", addedModels)); + getPreferences().put(ArchitectureDomainPreferences.EXCLUDED_CONTEXTS, String.join(",", excludedContexts)); + if (defaultContext != null) + getPreferences().put(ArchitectureDomainPreferences.DEFAULT_CONTEXT, defaultContext); + else + getPreferences().remove(ArchitectureDomainPreferences.DEFAULT_CONTEXT); + try { + getPreferences().flush(); + } catch (BackingStoreException e) { + Activator.log.error(e); + } + } + + /** + * Resets the state of this class to default + */ + public void reset() { + addedModels.clear(); + excludedContexts.clear(); + defaultContext = defaultDefaultContext; + } + + /** + * Adds the given preference change listener + * + * @param listener + */ + public void addListener(IPreferenceChangeListener listener) { + getPreferences().addPreferenceChangeListener(listener); + } + + /** + * @return the added model URIs + */ + public List<String> getAddedModelURIs() { + return addedModels; + } + + /** + * @return the excluded context ids + */ + public Set<String> getExcludedContextIds() { + return excludedContexts; + } + + /** + * @return the default context id + */ + public String getDefaultContextId() { + return defaultContext; + } + + /** + * Sets the default context id + * + * @param defaultContext the default context id + */ + public void setDefaultContextId(String defaultContext) { + this.defaultContext = defaultContext; + } + + @Override + public ArchitectureDomainPreferences clone() { + ArchitectureDomainPreferences clone = new ArchitectureDomainPreferences(); + clone.addedModels = new ArrayList<String>(getAddedModelURIs()); + clone.excludedContexts = new HashSet<String>(getExcludedContextIds()); + clone.setDefaultContextId(getDefaultContextId()); + return clone; + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCommandProvider.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCommandProvider.java new file mode 100644 index 00000000000..0e27176bdaa --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCommandProvider.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.commands; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.papyrus.infra.core.resource.ModelSet; + +/** + * An interface to provide architecture model creation and conversion commands by an extension + * + * @since 1.0 + */ +public interface IModelCommandProvider { + + /** + * Gets a model creation command that represents the contributions of a command provider + * The model is created in the given model set based on the given context id + * + * @param modelSet the model set to create the model in + * @param contextId context id for which a model is created + * @return a command to create a model + */ + Command getModelCreationCommand(ModelSet modelSet, String contextId); + + /** + * Gets a model conversion command that represents the contributions of a command provider + * The model is converted in the given model set based on the given new context id + * + * @param modelSet the model set that contains the model to be converted + * @param contextId the context id for which a model is converted + * @return a command to convert a model to the given context id + */ + Command getModelConversionCommand(ModelSet modelSet, String contextId); + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelConversionCommand.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelConversionCommand.java new file mode 100644 index 00000000000..615b49af0e0 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelConversionCommand.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.commands; + +import org.eclipse.papyrus.infra.core.resource.ModelSet; + +/** + * An Interface to convert a model in a model set + * + * @since 1.0 + */ +public interface IModelConversionCommand { + + /** + * Converts the model in the given model set + * + * @param modelSet the model set + */ + void convertModel(final ModelSet modelSet); + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCreationCommand.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCreationCommand.java new file mode 100644 index 00000000000..b8b6dd9912f --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/IModelCreationCommand.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.commands; + +import org.eclipse.papyrus.infra.core.resource.ModelSet; + +/** + * An Interface to create a model in a model set + * + * @since 1.0 + */ +public interface IModelCreationCommand { + + /** + * Creates the model in the given model set + * + * @param modelSet the model set + */ + void createModel(final ModelSet modelSet); + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/ModelCommandProviderRegistry.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/ModelCommandProviderRegistry.java new file mode 100644 index 00000000000..c30b5251d2f --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/commands/ModelCommandProviderRegistry.java @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.commands; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.papyrus.infra.architecture.Activator; +import org.eclipse.papyrus.infra.core.resource.ModelSet; + +/** + * A registry for architecture model command providers registered in extensions + * + * @since 1.0 + */ +public class ModelCommandProviderRegistry implements IModelCommandProvider { + + /** + * The extension point id + */ + private final static String EXTENSION_POINT_ID = Activator.PLUGIN_ID + ".commandProviders"; + + /** + * The name of the class attribute + */ + private static final String PROVIDER_CLASS = "class"; + + /** + * The singleton instance of this class + */ + private static ModelCommandProviderRegistry registry; + + /** + * A collection of registerd command providers + */ + private Collection<IModelCommandProvider> providers; + + /** + * Gets the singleton instance of this class + * + * @return the singleton instance + */ + public static synchronized ModelCommandProviderRegistry getInstance() { + if (registry == null) { + registry = new ModelCommandProviderRegistry(); + registry.init(); + } + return registry; + } + + /** + * Gets a model creation command that aggregates the contributions of the command providers + * The model is created in the given model set based on the given context id + * + * @param modelSet the model set to create the model in + * @param contextId context id for which a model is created + * @return a command to create a model + */ + @Override + public Command getModelCreationCommand(ModelSet modelSet, String contextId) { + CompoundCommand cc = new CompoundCommand("Contributions to Model Creation"); + for (IModelCommandProvider provider : providers) { + cc.append(provider.getModelCreationCommand(modelSet, contextId)); + } + return cc.isEmpty() ? null : cc; + } + + /** + * Gets a model conversion command that aggregates the contributions of the command providers + * The model is converted in the given model set based on the given new context id + * + * @param modelSet the model set that contains the model to be converted + * @param contextId the context id for which a model is converted + * @return a command to convert a model to the given context id + */ + @Override + public Command getModelConversionCommand(ModelSet modelSet, String contextId) { + CompoundCommand cc = new CompoundCommand("Contributions to Model Conversion"); + for (IModelCommandProvider provider : providers) { + cc.append(provider.getModelConversionCommand(modelSet, contextId)); + } + return cc.isEmpty() ? null : cc; + } + + /* + * initializes the registry from extensions + */ + private void init() { + providers = new ArrayList<IModelCommandProvider>(); + IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID); + for (IConfigurationElement configurationElement : elements) { + try { + Object providerClass = configurationElement.createExecutableExtension(PROVIDER_CLASS); + if (providerClass instanceof IModelCommandProvider) { + providers.add((IModelCommandProvider) providerClass); + } + } catch (CoreException e) { + Activator.log.error(e); + } + } + } +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionAdapter.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionAdapter.java new file mode 100644 index 00000000000..6acaa9220a0 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionAdapter.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.listeners; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescription; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionPreferences; + +/** + * An adapter that is installed in DI models to listen to architecture description changes + * + * @since 1.0 + */ +public class ArchitectureDescriptionAdapter extends EContentAdapter { + + /** + * Listens to changes on ArchitectureDescription* objects + */ + @Override + public void notifyChanged(Notification notification) { + if (notification.getEventType() == Notification.REMOVING_ADAPTER) + return; + Object notifier = notification.getNotifier(); + if (notifier instanceof ArchitectureDescription) { + ArchitectureDescriptionNotifier.getInstance().fireArchitectureContextChanged(notification); + } else if (notifier instanceof ArchitectureDescriptionPreferences) { + ArchitectureDescriptionNotifier.getInstance().fireArchitectureViewpointsChanged(notification); + } + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionNotifier.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionNotifier.java new file mode 100644 index 00000000000..dc221a27b4e --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionNotifier.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.listeners; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrus.infra.architecture.Activator; + +/** + * A notifier for registered listeners on events affecting architecture descriptions in models + * + * @since 1.0 + */ +public class ArchitectureDescriptionNotifier { + + /** + * The name of the extension point + */ + private final static String EXTENSION_POINT_ID = Activator.PLUGIN_ID + ".listeners"; + + /** + * The class property name + */ + private static final String LISTENER_CLASS = "class"; + + /** + * The singleton instance of this class + */ + private static ArchitectureDescriptionNotifier notifier; + + /** + * The collection of registered listeners in extensions + */ + private static Collection<IArchitectureDescriptionListener> listeners; + + /** + * Gets the singleton instance of this class + * + * @return the singleton instance + */ + public static synchronized ArchitectureDescriptionNotifier getInstance() { + if (notifier == null) { + notifier = new ArchitectureDescriptionNotifier(); + listeners = new ArrayList<IArchitectureDescriptionListener>(); + notifier.init(); + } + return notifier; + } + + /** + * Fires architecture context change events for registered listeners + * + * @param notification the change event + */ + public void fireArchitectureContextChanged(Notification notification) { + for (IArchitectureDescriptionListener policyCheckerListener : listeners) { + policyCheckerListener.architectureContextChanged(notification); + } + } + + /** + * Fires architecture viewpoint change events for registered listeners + * + * @param notification the change event + */ + public void fireArchitectureViewpointsChanged(Notification notification) { + for (IArchitectureDescriptionListener policyCheckerListener : listeners) { + policyCheckerListener.architectureViewpointsChanged(notification); + } + } + + /* + * initializes the collection of listeners from the extensions + */ + private void init() { + IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID); + for (IConfigurationElement configurationElement : elements) { + try { + Object listenerClass = configurationElement.createExecutableExtension(LISTENER_CLASS); + if (listenerClass instanceof IArchitectureDescriptionListener) { + listeners.add((IArchitectureDescriptionListener) listenerClass); + } + } catch (CoreException e) { + Activator.log.error(e); + } + } + } +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionSnippet.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionSnippet.java new file mode 100644 index 00000000000..2739e936fa6 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/ArchitectureDescriptionSnippet.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.listeners; + +import org.eclipse.papyrus.infra.core.resource.IModelSetSnippet; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel; + +/** + * A model snippet to install the architecture description adapter in the DI model + * + * @since 1.0 + */ +public class ArchitectureDescriptionSnippet implements IModelSetSnippet { + + /** + * The installed adapter + */ + private ArchitectureDescriptionAdapter adapter; + + /** + * Installs the architecture adapter model snippet on the given model set + * + * @see org.eclipse.papyrus.infra.core.resource.IModelSetSnippet#start(org.eclipse.papyrus.infra.core.resource.ModelSet) + * + * @param modelSet the given model set + */ + @Override + public void start(ModelSet modelSet) { + DiModel diModel = (DiModel) modelSet.getModel(DiModel.DI_MODEL_ID); + diModel.getResource().eAdapters().add(adapter = new ArchitectureDescriptionAdapter()); + } + + /** + * Removes the architecture adapter model snippet from the given model set + * + * @see org.eclipse.papyrus.infra.core.resource.IModelSetSnippet#dispose(org.eclipse.papyrus.infra.core.resource.ModelSet) + * + * @param modelSet the given model set + */ + @Override + public void dispose(ModelSet modelSet) { + DiModel diModel = (DiModel) modelSet.getModel(DiModel.DI_MODEL_ID); + diModel.getResource().eAdapters().remove(adapter); + } +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/IArchitectureDescriptionListener.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/IArchitectureDescriptionListener.java new file mode 100644 index 00000000000..2814e2f73a6 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/architecture/listeners/IArchitectureDescriptionListener.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.architecture.listeners; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionPreferences; + +/** + * An interface for listening to architecture description change events in models + * Listeners are expected to update UI in response + * + * @since 1.0 + */ +public interface IArchitectureDescriptionListener { + + /** + * Responds to an architecture context id change event + * + * The event's notifier is of type {@link ArchitectureDescription} + * + * @param notification the change event + */ + void architectureContextChanged(Notification notification); + + /** + * Responds to an architecture viewpoint id change events + * + * The event's notifier is of type {@link ArchitectureDescriptionPreferences} + * + * @param notification the change event + */ + void architectureViewpointsChanged(Notification notification); + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedADElement.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedADElement.java new file mode 100644 index 00000000000..5c0500a5de4 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedADElement.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.papyrus.infra.core.architecture.ADElement; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ADElement}s that are instances of the same EClass. This allows the definition + * of architecture elements to be split across several architectural models (*.architecture). + * + * All merged elements is assumed to have the same name and qualified name values. However, only + * one of those elements (the main merge increment) has values for the single-valued properties. + * On the other hand, all multi-valued properties of the elements are merged. + * + * @see org.eclipse.papyrus.infra.core.architecture.ADElement + * @since 1.0 + */ +public class MergedADElement { + + /** + * The merged parent of this element + */ + protected MergedADElement parent; + + /** + * the architecture elements that represent merge increments of this element + */ + protected Collection<ADElement> elements; + + /** + * Create a new '<em><b>Merged AD Element</b></em>'. + * + * @param parent the merged parent of this element + */ + public MergedADElement(MergedADElement parent) { + this.parent = parent; + this.elements = new LinkedHashSet<ADElement>(); + } + + /** + * Get the element's parent + * + * @return the parent element + */ + public MergedADElement getParent() { + return parent; + } + + /** + * Get the element's name + * + * @return a name + */ + public String getName() { + for (ADElement element : elements) { + if (element.getName() != null) + return element.getName(); + } + return null; + } + + /** + * Get the element's qualified name + * + * @return a qualified name + */ + public String getQualifiedName() { + for (ADElement element : elements) { + if (element.getQualifiedName() != null) + return element.getQualifiedName(); + } + return null; + } + + /** + * Get the element's description + * + * @return a description + */ + public String getDesciption() { + for (ADElement element : elements) { + if (element.getDesciption() != null) + return element.getDesciption(); + } + return null; + } + + /** + * Get a merge increment whose image represents that of the merged element + * + * By default, any one of the merge increments will be returned. Subclasses may override. + * + * @return a merge increment + */ + public Object getImageObject() { + if (!elements.isEmpty()) + return elements.iterator().next(); + return null; + } + + @Override + public int hashCode() { + int hash = 0; + for (ADElement element : elements) { + hash += element.hashCode(); + } + return hash; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof MergedADElement)) + return false; + MergedADElement other = (MergedADElement) obj; + if (other.parent != this.parent) + return false; + Set<ADElement> copy = new HashSet<ADElement>(this.elements); + copy.retainAll(other.elements); + return copy.size() == this.elements.size(); + } + + @Override + public String toString() { + Iterator<ADElement> i = elements.iterator(); + if (i.hasNext()) + return i.next().toString(); + return super.toString(); + } + + /* + * Adds the given element to the collection of merged elements + */ + void merge(ADElement element) { + elements.add(element); + } + + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureContext.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureContext.java new file mode 100644 index 00000000000..85d487ac916 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureContext.java @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.papyrus.infra.core.architecture.ADElement; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureContext; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureViewpoint; +import org.eclipse.papyrus.infra.types.ElementTypeSetConfiguration; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ArchitectureContext}s. This allows the definition of architecture contexts + * to be split across several architectural models (*.architecture). + * + * This class is a subclass of {@link org.eclipse.papyrus.infra.core.architecture.merged. + * MergedADElement}s + * + * @see org.eclipse.papyrus.infra.core.architecture.ArchitectureContext + * @since 1.0 + */ +public abstract class MergedArchitectureContext extends MergedADElement { + + /** + * Create a new '<em><b>Merged Architecture Context</b></em>'. + * + * @param domain the merged parent domain of this context + */ + public MergedArchitectureContext(MergedArchitectureDomain domain) { + super(domain); + } + + /** + * Gets the context's id + * + * @return an id + */ + public String getId() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getId() != null) + return context.getId(); + } + return null; + } + + /** + * Gets the context's icon path + * + * @return an icon path + */ + public String getIcon() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getIcon() != null) + return context.getIcon(); + } + return null; + } + + /** + * Gets the context's extension prefix + * + * @return an extension prefix + */ + public String getExtensionPrefix() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getExtensionPrefix() != null) + return context.getExtensionPrefix(); + } + return null; + } + + /** + * Gets the context's creation command class + * + * @return a creation command class + */ + public Class<?> getCreationCommandClass() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getCreationCommandClass() != null) + return context.getCreationCommandClass(); + } + return null; + } + + /** + * Gets the context's conversion command class + * + * @return a conversion command class + */ + public Class<?> getConversionCommandClass() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getConversionCommandClass() != null) + return context.getConversionCommandClass(); + } + return null; + } + + /** + * Gets the context's parent domain + * + * @return the parent domain + */ + public MergedArchitectureDomain getDomain() { + return (MergedArchitectureDomain) getParent(); + } + + /** + * Gets the context's element type set configurations + * + * @return a merged collection of element type set configurations + */ + public Collection<ElementTypeSetConfiguration> getElementTypes() { + Set<ElementTypeSetConfiguration> configurations = new LinkedHashSet<ElementTypeSetConfiguration>(); + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + configurations.addAll(context.getElementTypes()); + } + return Collections.unmodifiableCollection(configurations); + } + + /** + * Gets the context's viewpoints + * + * @return a merged collection of viewpoints + */ + public Collection<MergedArchitectureViewpoint> getViewpoints() { + Map<String, MergedArchitectureViewpoint> viewpoints = new HashMap<String, MergedArchitectureViewpoint>(); + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + for (ArchitectureViewpoint viewpoint : context.getViewpoints()) { + MergedArchitectureViewpoint merged = viewpoints.get(viewpoint.getName()); + if (merged == null) { + viewpoints.put(viewpoint.getName(), merged = new MergedArchitectureViewpoint(this)); + } + merged.merge(viewpoint); + } + } + return Collections.unmodifiableCollection(viewpoints.values()); + } + + /* + * Gets the merge increment that has an icon value + */ + @Override + public Object getImageObject() { + for (ADElement element : elements) { + ArchitectureContext context = (ArchitectureContext) element; + if (context.getIcon() != null) + return context; + } + return super.getImageObject(); + } +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDescriptionLanguage.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDescriptionLanguage.java new file mode 100644 index 00000000000..5e0b7b191e5 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDescriptionLanguage.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.papyrus.infra.core.architecture.ADElement; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionLanguage; +import org.eclipse.papyrus.infra.core.architecture.RepresentationKind; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ArchitectureDescriptionLanguage}s. This allows the definition of architecture + * description languages to be split across several architectural models (*.architecture). + * + * This class is a subclass of {@link org.eclipse.papyrus.infra.core.architecture.merged. + * MergedArchitectureContext}s + * + * @see org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionLanguage + * @since 1.0 + */ +public class MergedArchitectureDescriptionLanguage extends MergedArchitectureContext { + + /** + * Create a new '<em><b>Merged Architecture Description Language</b></em>'. + * + * @param domain the merged parent domain of this language + */ + public MergedArchitectureDescriptionLanguage(MergedArchitectureDomain domain) { + super(domain); + } + + /** + * Get the language's metamodel EPackage + * + * @return an EPackage + */ + public EPackage getMetamodel() { + for (ADElement element : elements) { + ArchitectureDescriptionLanguage language = (ArchitectureDescriptionLanguage) element; + if (language.getMetamodel() != null) + return language.getMetamodel(); + } + return null; + } + + /** + * Get a merged collection of the language's profile EPackages + * + * @return a collection of EPackages + */ + public Collection<EPackage> getProfiles() { + Set<EPackage> profiles = new LinkedHashSet<EPackage>(); + for (ADElement element : elements) { + ArchitectureDescriptionLanguage language = (ArchitectureDescriptionLanguage) element; + profiles.addAll(language.getProfiles()); + } + return Collections.unmodifiableCollection(profiles); + } + + /** + * Get a merged collection of the language's representation kinds + * + * @return a collection of representation kinds + */ + public Collection<RepresentationKind> getRepresentationKinds() { + Set<RepresentationKind> kinds = new LinkedHashSet<RepresentationKind>(); + for (ADElement element : elements) { + ArchitectureDescriptionLanguage language = (ArchitectureDescriptionLanguage) element; + kinds.addAll(language.getRepresentationKinds()); + } + return Collections.unmodifiableCollection(kinds); + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDomain.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDomain.java new file mode 100644 index 00000000000..0eeea05adb0 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureDomain.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.papyrus.infra.core.architecture.ADElement; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureContext; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionLanguage; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureDomain; +import org.eclipse.papyrus.infra.core.architecture.Concern; +import org.eclipse.papyrus.infra.core.architecture.Stakeholder; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ArchitectureDomain}s. This allows the definition of architecture + * domains to be split across several architectural models (*.architecture). + * + * This class is a subclass of {@link org.eclipse.papyrus.infra.core.architecture.merged. + * MergedADElement}s + * + * @see org.eclipse.papyrus.infra.core.architecture.ArchitectureDomain + * @since 1.0 + */ +public class MergedArchitectureDomain extends MergedADElement { + + /** + * Create a new '<em><b>Merged Architecture Domain</b></em>'. + */ + public MergedArchitectureDomain() { + super(null); + } + + /** + * Get a merged collection of the domain's stakeholders + * + * @return a collection of stakeholders + */ + public Collection<Stakeholder> getStakeholders() { + Set<Stakeholder> stakeholders = new LinkedHashSet<Stakeholder>(); + for (ADElement element : elements) { + ArchitectureDomain domain = (ArchitectureDomain) element; + stakeholders.addAll(domain.getStakeholders()); + } + return Collections.unmodifiableCollection(stakeholders); + } + + /** + * Get a merged collection of the domain's concerns + * + * @return a collection of concerns + */ + public Collection<Concern> getConcerns() { + Set<Concern> concerns = new LinkedHashSet<Concern>(); + for (ADElement element : elements) { + ArchitectureDomain domain = (ArchitectureDomain) element; + concerns.addAll(domain.getConcerns()); + } + return Collections.unmodifiableCollection(concerns); + } + + /** + * Get a merged collection of the domain's contexts + * + * @return a collection of contexts + */ + public Collection<MergedArchitectureContext> getContexts() { + Map<String, MergedArchitectureContext> contexts = new HashMap<String, MergedArchitectureContext>(); + for (ADElement element : elements) { + ArchitectureDomain domain = (ArchitectureDomain) element; + for (ArchitectureContext context : domain.getContexts()) { + MergedArchitectureContext merged = contexts.get(context.getName()); + if (merged == null) { + if (context instanceof ArchitectureDescriptionLanguage) + contexts.put(context.getName(), merged = new MergedArchitectureDescriptionLanguage(this)); + else + contexts.put(context.getName(), merged = new MergedArchitectureFramework(this)); + } + merged.merge(context); + } + } + return Collections.unmodifiableCollection(contexts.values()); + } + + /** + * Merges the given domain element with the other merge increments + * + * @param domain a given domain to merge + */ + public void merge(ArchitectureDomain domain) { + elements.add(domain); + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureFramework.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureFramework.java new file mode 100644 index 00000000000..4bf826ae1a6 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureFramework.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ArchitectureFramework}s. This allows the definition of architecture + * framework to be split across several architectural models (*.architecture). + * + * This class is a subclass of {@link org.eclipse.papyrus.infra.core.architecture.merged. + * MergedArchitectureContext}s + * + * @see org.eclipse.papyrus.infra.core.architecture.ArchitectureFramework + * @since 1.0 + */ +public class MergedArchitectureFramework extends MergedArchitectureContext { + + /** + * Create a new '<em><b>Merged Architecture Framework</b></em>'. + * + * @param domain the merged parent domain of this framework + */ + public MergedArchitectureFramework(MergedArchitectureDomain domain) { + super(domain); + } + +} diff --git a/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureViewpoint.java b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureViewpoint.java new file mode 100644 index 00000000000..2930fc544e0 --- /dev/null +++ b/plugins/infra/architecture/org.eclipse.papyrus.infra.architecture/src/org/eclipse/papyrus/infra/core/architecture/merged/MergedArchitectureViewpoint.java @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2017 CEA LIST. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Maged Elaasar - Initial API and implementation + * + * + */ +package org.eclipse.papyrus.infra.core.architecture.merged; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.papyrus.infra.core.architecture.ADElement; +import org.eclipse.papyrus.infra.core.architecture.ArchitectureViewpoint; +import org.eclipse.papyrus.infra.core.architecture.Concern; +import org.eclipse.papyrus.infra.core.architecture.RepresentationKind; + +/** + * An element that represents a merged collection of {@link org.eclipse.papyrus.infra.core. + * architecture.ArchitectureViewpoint}s. This allows the definition of architecture + * viewpoints to be split across several architectural models (*.architecture). + * + * This class is a subclass of {@link org.eclipse.papyrus.infra.core.architecture.merged. + * MergedADElement}s + * + * @see org.eclipse.papyrus.infra.core.architecture.ArchitectureViewpoint + * @since 1.0 + */ +public class MergedArchitectureViewpoint extends MergedADElement { + + /** + * Create a new '<em><b>Merged Architecture Viewpoint</b></em>'. + * + * @param context the merged parent context of this viewpoint + */ + public MergedArchitectureViewpoint(MergedArchitectureContext context) { + super(context); + } + + /** + * Gets the viewpoint's parent context + * + * @return an architecture context + */ + public MergedArchitectureContext getContext() { + return (MergedArchitectureContext) getParent(); + } + + /** + * Get the viewpoints's id + * + * @return an id + */ + public String getId() { + for (ADElement element : elements) { + ArchitectureViewpoint viewpoint = (ArchitectureViewpoint) element; + if (viewpoint.getId() != null) + return viewpoint.getId(); + } + return null; + } + + /** + * Gets the viewpoint's merged concerns + * + * @return a merged collection of concerns + */ + public Collection<Concern> getConcerns() { + Set<Concern> concerns = new LinkedHashSet<Concern>(); + for (ADElement element : elements) { + ArchitectureViewpoint viewpoint = (ArchitectureViewpoint) element; + concerns.addAll(viewpoint.getConcerns()); + } + return Collections.unmodifiableCollection(concerns); + } + + /** + * Gets the viewpoint's merged representation kinds + * + * @return a merged collection of representation kinds + */ + public Collection<RepresentationKind> getRepresentationKinds() { + Set<RepresentationKind> kinds = new LinkedHashSet<RepresentationKind>(); + for (ADElement element : elements) { + ArchitectureViewpoint viewpoint = (ArchitectureViewpoint) element; + kinds.addAll(viewpoint.getRepresentationKinds()); + } + return Collections.unmodifiableCollection(kinds); + } + +} |