diff options
| author | Laurent Fasani | 2017-05-15 08:23:08 +0000 |
|---|---|---|
| committer | Laurent Fasani | 2017-07-07 15:54:59 +0000 |
| commit | 96e11b09c677a39b4d68feff1a558784b39e0686 (patch) | |
| tree | 9f8d424b04bc58cdeae938140e5363c2b28ade23 | |
| parent | c52738d518392b43b20efcddda89cd269d4715e5 (diff) | |
| download | org.eclipse.sirius-96e11b09c677a39b4d68feff1a558784b39e0686.tar.gz org.eclipse.sirius-96e11b09c677a39b4d68feff1a558784b39e0686.tar.xz org.eclipse.sirius-96e11b09c677a39b4d68feff1a558784b39e0686.zip | |
[516669] Allow delegating representation resource strategy
* use the dRepresentationLocationRule extension point to delegate the
management of the resource URI that is used to store the representation.
As a default extension is provided by Sirius, a priority attribute has
been added on the extension point so that clients may provide their own
extension.
* createRepresentationInSeparateResource system property is renamed to
createLocalRepresentationInSeparateResource and is used only
for resources of type platform.
Bug: 516669
Change-Id: Icbd5f68f90d7f9299cce6ac7e19d3343bf221d53
Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
12 files changed, 519 insertions, 145 deletions
diff --git a/plugins/org.eclipse.sirius/plugin.xml b/plugins/org.eclipse.sirius/plugin.xml index 747ecd19af..97af602fe1 100644 --- a/plugins/org.eclipse.sirius/plugin.xml +++ b/plugins/org.eclipse.sirius/plugin.xml @@ -454,5 +454,12 @@ class="org.eclipse.sirius.business.internal.dialect.ViewpointMetamodelsProvider"> </descriptorprovider> </extension> + <extension + point="org.eclipse.sirius.dRepresentationLocationRule"> + <rule + class="org.eclipse.sirius.business.internal.representation.DRepLocationRuleForLocalResource" + priority="core"> + </rule> + </extension> </plugin> diff --git a/plugins/org.eclipse.sirius/schema/dRepresentationLocationRule.exsd b/plugins/org.eclipse.sirius/schema/dRepresentationLocationRule.exsd index f1193a22ba..781bfc5cbf 100644 --- a/plugins/org.eclipse.sirius/schema/dRepresentationLocationRule.exsd +++ b/plugins/org.eclipse.sirius/schema/dRepresentationLocationRule.exsd @@ -59,6 +59,25 @@ </appinfo> </annotation> </attribute> + <attribute name="priority" use="default" value="normal"> + <annotation> + <documentation> + the provider priority. + * core is the lowest priority and is reserved for Sirius and Sirius based applications. Clients should not use that priority. + * normal and high are intented to be used by clients. + </documentation> + </annotation> + <simpleType> + <restriction base="string"> + <enumeration value="core"> + </enumeration> + <enumeration value="normal"> + </enumeration> + <enumeration value="high"> + </enumeration> + </restriction> + </simpleType> + </attribute> </complexType> </element> diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/helper/SiriusUtil.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/helper/SiriusUtil.java index d86baeb079..370b03f4c4 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/helper/SiriusUtil.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/helper/SiriusUtil.java @@ -53,6 +53,9 @@ public final class SiriusUtil { /** The file extension for representation files. */ public static final String REPRESENTATION_FILE_EXTENSION = "srm"; //$NON-NLS-1$ + /** The name of the folder containing srm files. */ + public static final String REPRESENTATIONS_FOLDER_NAME = ".representations"; //$NON-NLS-1$ + /** The "environment:/" uri scheme. */ public static final String ENVIRONMENT_URI_SCHEME = "environment"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/FileQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/FileQuery.java index 61c5a092d5..6896140371 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/FileQuery.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/FileQuery.java @@ -10,13 +10,10 @@ *******************************************************************************/ package org.eclipse.sirius.business.api.query; -import java.util.List; - import org.eclipse.core.resources.IFile; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.sirius.business.api.helper.SiriusUtil; -import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; -import org.eclipse.sirius.common.tools.api.util.EclipseUtil; +import org.eclipse.sirius.business.internal.representation.DRepresentationLocationRuleRegistry; /** * Query allowing to determine the type of a file (i.e. if it contains a VSM, a DAnalysis...). It is leaner than the @@ -87,10 +84,7 @@ public class FileQuery { * @return true if the file is dedicated to representations, false otherwise */ public boolean isSrmFile() { - List<DRepresentationLocationRule> extensionPointRules = EclipseUtil.getExtensionPlugins(DRepresentationLocationRule.class, DRepresentationLocationRule.ID, - DRepresentationLocationRule.CLASS_ATTRIBUTE); - - boolean isSrmFile = extensionPointRules.stream().filter(rule -> rule.isARepresentationResource(fileExtension)).findFirst().isPresent(); + boolean isSrmFile = DRepresentationLocationRuleRegistry.getInstance().getRepLocationRules().stream().filter(rule -> rule.isARepresentationFileExtension(fileExtension)).findFirst().isPresent(); if (!isSrmFile) { if (repResourceFactory == null) { repResourceFactory = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().get(SiriusUtil.REPRESENTATION_FILE_EXTENSION); diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/session/danalysis/DRepresentationLocationRule.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/session/danalysis/DRepresentationLocationRule.java index 7cd4904cb0..5646320e9c 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/session/danalysis/DRepresentationLocationRule.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/session/danalysis/DRepresentationLocationRule.java @@ -24,16 +24,6 @@ import org.eclipse.sirius.viewpoint.DRepresentation; public interface DRepresentationLocationRule { /** - * The extension point id. - */ - String ID = "org.eclipse.sirius.dRepresentationLocationRule"; //$NON-NLS-1$ - - /** - * The class attribute. - */ - String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ - - /** * Indicates if this {@link DRepresentationLocationRule} provides a custom URI. If not and if there is no other * {@link DRepresentationLocationRule} that provides, Sirius fall back to the default implementation. * @@ -43,7 +33,7 @@ public interface DRepresentationLocationRule { * the DView resource * @return the value */ - boolean provides(DRepresentation representation, Resource dViewResource); + boolean providesURI(DRepresentation representation, Resource dViewResource); /** * Provides the new URI for the given representation. @@ -64,5 +54,5 @@ public interface DRepresentationLocationRule { * * @return true if the fileExtension is known as a representation file */ - Boolean isARepresentationResource(String fileExtension); + Boolean isARepresentationFileExtension(String fileExtension); } diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepLocationRuleForLocalResource.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepLocationRuleForLocalResource.java new file mode 100644 index 0000000000..8ca5654c15 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepLocationRuleForLocalResource.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2017 THALES GLOBAL SERVICES + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.business.internal.representation; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.util.TreeIterator; +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.sirius.business.api.helper.SiriusUtil; +import org.eclipse.sirius.business.api.query.URIQuery; +import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; +import org.eclipse.sirius.viewpoint.DRepresentation; + +/** + * This implementation to {@link DRepresentationLocationRule} give a behavior for representation resources in local + * workspace. + * + * @author <a href="mailto:laurent.fasani@obeo.fr">Laurent Fasani</a> + */ +public class DRepLocationRuleForLocalResource implements DRepresentationLocationRule { + + @Override + public boolean providesURI(DRepresentation representation, Resource dViewResource) { + return !new URIQuery(dViewResource.getURI()).isCDOURI(); + } + + @Override + public URI getResourceURI(DRepresentation representation, Resource airdResource) { + URI repResourceURI = null; + if (Boolean.getBoolean("createLocalRepresentationInSeparateResource")) { //$NON-NLS-1$ + repResourceURI = getDedicatedRepResourceURI(representation, airdResource); + } else { + repResourceURI = airdResource.getURI(); + } + return repResourceURI; + } + + /** + * Create the representation resource URI so that the representation can be stored in a specific resource.<br/> + * The URI is based on the aird resource URI. Only the last part of the segment is changed. + * + * @param airdResource + * the aird resource + * @param representation + * the representation + * @return the representation URI + */ + protected URI getDedicatedRepResourceURI(DRepresentation representation, Resource airdResource) { + int count = 0; + ResourceSet resourceSet = airdResource.getResourceSet(); + URI repUri = createRepURI(airdResource, representation, count++); + while (!isUsableURI(repUri, resourceSet, representation)) { + repUri = createRepURI(airdResource, representation, count++); + } + return repUri; + } + + private boolean isUsableURI(URI repUri, ResourceSet resourceSet, DRepresentation representation) { + boolean usableURI = true; + Resource resource = resourceSet.getResource(repUri, false); + // A usable URI is when the resource is not already in the resourceSet or does not exist, that is, is not + // loadable + usableURI = resource == null && !existsResource(repUri, resourceSet); + + // We consider the URI usable if the representation is already in the resource + if (resource != null) { + TreeIterator<EObject> allContents = resource.getAllContents(); + while (allContents.hasNext()) { + EObject object = allContents.next(); + if (object instanceof DRepresentation) { + if (representation.equals(object)) { + usableURI = true; + break; + } else { + allContents.prune(); + } + } + } + } + return usableURI; + } + + /** + * Indicates if the given uri corresponds to a resource that then could be loaded and added to the resourceSet. + * + * @param repUri + * the resource URI + * @param resourceSet + * the resourceSet + * @return true if the resource exists. + */ + protected boolean existsResource(URI repUri, ResourceSet resourceSet) { + return resourceSet.getURIConverter().exists(repUri, null); + } + + /** + * Create the representation URI based on the aird resource URI. Only the last part of the segment is changed. + * + * @param airdResource + * the aird resource + * @param representation + * the representation + * @param count + * @return the representation URI + */ + private URI createRepURI(Resource airdResource, DRepresentation representation, int count) { + // get the representation URI fragment + String repName = representation.getName().replace(' ', '_'); + if (count > 0) { + repName += String.valueOf(count); + } + URI airdURI = airdResource.getURI(); + + List<String> srmFileSegments = new ArrayList<>(airdURI.segmentsList()); + srmFileSegments.remove(srmFileSegments.size() - 1); + srmFileSegments.add(SiriusUtil.REPRESENTATIONS_FOLDER_NAME); + srmFileSegments.add(repName + "." + SiriusUtil.REPRESENTATION_FILE_EXTENSION); //$NON-NLS-1$ + + // return the URI + return URI.createHierarchicalURI(airdURI.scheme(), airdURI.authority(), airdURI.device(), srmFileSegments.toArray(new String[srmFileSegments.size()]), airdURI.query(), airdURI.fragment()); + } + + @Override + public Boolean isARepresentationFileExtension(String fileExtension) { + return SiriusUtil.REPRESENTATION_FILE_EXTENSION.equals(fileExtension); + } + +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationManager.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationManager.java new file mode 100644 index 0000000000..f89cfbe503 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationManager.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2017 THALES GLOBAL SERVICES and others, + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.business.internal.representation; + +import java.util.Optional; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; +import org.eclipse.sirius.viewpoint.DRepresentation; + +/** + * This manager is responsible to retrieve or create the {@link Resource} of a {@link DRepresentation}. + * + * @author fbarbin + * + */ +public class DRepresentationLocationManager { + + /** + * Get or creates (if it does not exist) the corresponding {@link Resource} for the given representation. + * + * @param representation + * the current representation. + * @param airdResource + * the aird resource from which the representation will be referenced. + * @return the representation resource. + */ + public Resource getOrCreateRepresentationResource(DRepresentation representation, Resource airdResource) { + Resource resource = null; + ResourceSet resourceSet = airdResource != null ? airdResource.getResourceSet() : null; + if (resourceSet != null) { + // Get the fragment of the URI + resource = getURIFromExtensionPoint(representation, airdResource).map(repResourceURI -> { + // get or create resource + Resource res = resourceSet.getResource(repResourceURI, false); + if (res == null) { + if (resourceSet.getURIConverter().exists(repResourceURI, null)) { + // load the resource in case the representation have to be added in a non loaded resource + res = resourceSet.getResource(repResourceURI, true); + } else { + res = resourceSet.createResource(repResourceURI); + } + } + return res; + }).orElse(null); + } + return resource; + } + + private Optional<URI> getURIFromExtensionPoint(DRepresentation representation, Resource airdResource) { + Optional<DRepresentationLocationRule> representationLocationRule = DRepresentationLocationRuleRegistry.getInstance().getRepresentationLocationRule(representation, airdResource); + + return representationLocationRule.map(r -> r.getResourceURI(representation, airdResource)); + } +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistry.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistry.java new file mode 100644 index 0000000000..92ee05f833 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistry.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2017 THALES GLOBAL SERVICES. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.business.internal.representation; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.sirius.business.api.resource.strategy.ResourceStrategy; +import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; +import org.eclipse.sirius.viewpoint.DRepresentation; + +/** + * Manage the available {@link ResourceStrategy}. + * + * @author <a href="mailto:laurent.fasani@obeo.fr">Laurent Fasani</a> + */ +public final class DRepresentationLocationRuleRegistry { + + /** + * The singleton instance of the ResourceStrategyRegistry. + */ + private static final DRepresentationLocationRuleRegistry INSTANCE = new DRepresentationLocationRuleRegistry(); + + private Map<DRepresentationLocationRule, Priority> repLocationRules = new HashMap<>(); + + private DRepresentationLocationRuleRegistry() { + } + + public static DRepresentationLocationRuleRegistry getInstance() { + return INSTANCE; + } + + /** + * Priority used to choose the right extension. + * + * @author lfasani + * + */ + public enum Priority { + /** + * Core priority. Clients should not use that priority. + */ + CORE(0), + /** + * Normal priority. + */ + NORMAL(1), + /** + * High priority. + */ + HIGH(2); + + private int priority; + + Priority(int priority) { + this.priority = priority; + } + + public int getPriority() { + return priority; + } + } + + /** + * Add a DRepresentationLocationRule to the registry. + * + * @param repLocationRule + * the DRepresentationLocationRule + * @param priority + * the priority + */ + public void addRepLocationRule(DRepresentationLocationRule repLocationRule, Priority priority) { + repLocationRules.put(repLocationRule, priority); + } + + /** + * Remove a DRepresentationLocationRule to the registry. + * + * @param repLocationRule + * the repLocationRule + */ + public void removeRepLocationRule(DRepresentationLocationRule repLocationRule) { + repLocationRules.remove(repLocationRule); + } + + public Set<DRepresentationLocationRule> getRepLocationRules() { + return repLocationRules.keySet(); + } + + /** + * Removes all extensions from the registry. This will be called at plugin stopping. + */ + public void dispose() { + repLocationRules.clear(); + } + + /** + * Get the compatible {@link DRepresentationLocationRule} that is one which provides and with highest priority. + * </br> + * If several are found, the first is returned. + * + * @param representation + * the current representation. + * @param airdResource + * the aird resource from which the representation will be referenced. + * @return the corresponding {@link ResourceStrategy} + */ + public Optional<DRepresentationLocationRule> getRepresentationLocationRule(DRepresentation representation, Resource airdResource) { + Optional<DRepresentationLocationRule> repLocRule = repLocationRules.keySet().stream().filter(locRule -> locRule.providesURI(representation, airdResource)).sorted((locRule1, locRule2) -> { + return repLocationRules.get(locRule2).getPriority() - repLocationRules.get(locRule1).getPriority(); + }).findFirst(); + return repLocRule; + } +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistryListener.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistryListener.java new file mode 100644 index 0000000000..d2c6f4e5dc --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/representation/DRepresentationLocationRuleRegistryListener.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2017 THALES GLOBAL SERVICES. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.business.internal.representation; + +import java.util.Collection; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IRegistryEventListener; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; +import org.eclipse.sirius.business.internal.representation.DRepresentationLocationRuleRegistry.Priority; +import org.eclipse.sirius.viewpoint.Messages; +import org.eclipse.sirius.viewpoint.SiriusPlugin; + +/** + * This listener will allow to be aware of contribution changes against the dRepresentationLocationRule extension point. + * + * @author <a href="mailto:laurent.fasani@obeo.fr">Laurent Fasani</a> + */ +public class DRepresentationLocationRuleRegistryListener implements IRegistryEventListener { + + /** Name of the extension point to parse for extensions. */ + public static final String REP_LOCATION_RULE_EXTENSION_POINT = SiriusPlugin.ID + ".dRepresentationLocationRule"; //$NON-NLS-1$ + + /** Name of the extension point's "dRepresentationLocationRule" tag. */ + private static final String REP_LOCATION_RULE_TAG_EXTENSION = "dRepresentationLocationRule"; //$NON-NLS-1$ + + /** Name of the dRepresentationLocationRule extension point's tag "class" attribute. */ + private static final String REP_LOCATION_RULE_CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ + + /** Name of the dRepresentationLocationRule extension point's tag "priority" attribute. */ + private static final String REP_LOCATION_RULE_CLASS_PRIORITY = "priority"; //$NON-NLS-1$ + + /** + * Register this listener and parse initial contributions. + */ + public void init() { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + registry.addListener(this, REP_LOCATION_RULE_EXTENSION_POINT); + parseInitialContributions(); + } + + @Override + public void added(IExtension[] extensions) { + for (IExtension extension : extensions) { + parseExtension(extension); + } + } + + @Override + public void added(IExtensionPoint[] extensionPoints) { + // no need to listen to this event + } + + @Override + public void removed(IExtension[] extensions) { + for (IExtension extension : extensions) { + final IConfigurationElement[] configElements = extension.getConfigurationElements(); + for (IConfigurationElement elem : configElements) { + if (REP_LOCATION_RULE_TAG_EXTENSION.equals(elem.getName())) { + final String extensionClassName = elem.getAttribute(REP_LOCATION_RULE_CLASS_ATTRIBUTE); + Collection<DRepresentationLocationRule> repLocationRules = DRepresentationLocationRuleRegistry.getInstance().getRepLocationRules(); + for (DRepresentationLocationRule repLocationRule : repLocationRules) { + if (extensionClassName.equals(repLocationRule.getClass())) { + DRepresentationLocationRuleRegistry.getInstance().removeRepLocationRule(repLocationRule); + } + } + } + } + } + } + + @Override + public void removed(IExtensionPoint[] extensionPoints) { + // no need to listen to this event + } + + /** + * Though this listener reacts to the extension point changes, there could have been contributions before it's been + * registered. This will parse these initial contributions. + */ + public void parseInitialContributions() { + final IExtensionRegistry registry = Platform.getExtensionRegistry(); + + for (IExtension extension : registry.getExtensionPoint(REP_LOCATION_RULE_EXTENSION_POINT).getExtensions()) { + parseExtension(extension); + } + } + + /** + * Parses a single extension contribution. + * + * @param extension + * Parses the given extension and adds its contribution to the registry. + */ + private void parseExtension(IExtension extension) { + final IConfigurationElement[] configElements = extension.getConfigurationElements(); + for (IConfigurationElement elem : configElements) { + try { + Object contribution = elem.createExecutableExtension(REP_LOCATION_RULE_CLASS_ATTRIBUTE); // $NON-NLS-1$ + if (contribution instanceof DRepresentationLocationRule) { + String priorityStr = elem.getAttribute(REP_LOCATION_RULE_CLASS_PRIORITY); + Priority priority = DRepresentationLocationRuleRegistry.Priority.valueOf(priorityStr.toUpperCase()); + DRepresentationLocationRuleRegistry.getInstance().addRepLocationRule((DRepresentationLocationRule) contribution, priority); + } + } catch (CoreException | IllegalArgumentException | NullPointerException e) { + SiriusPlugin.getDefault().getLog().log(new Status(Status.WARNING, SiriusPlugin.ID, Messages.AbstractSiriusMigrationService_contributionInstantiationErrorMsg, e)); + } + } + } + + /** + * Remove this listener and flush the associated registry. + */ + public void dispose() { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + registry.removeListener(this); + DRepresentationLocationRuleRegistry.getInstance().dispose(); + } + +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java index e1ba3e9678..d1cab7b3b4 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java @@ -34,6 +34,7 @@ import org.eclipse.sirius.business.api.session.danalysis.DAnalysisSelector; import org.eclipse.sirius.business.api.session.danalysis.DAnalysisSessionHelper; import org.eclipse.sirius.business.api.session.danalysis.DAnalysisSessionService; import org.eclipse.sirius.business.internal.query.DRepresentationDescriptorInternalHelper; +import org.eclipse.sirius.business.internal.representation.DRepresentationLocationManager; import org.eclipse.sirius.common.tools.api.util.EqualityHelper; import org.eclipse.sirius.viewpoint.DAnalysis; import org.eclipse.sirius.viewpoint.DAnalysisCustomData; @@ -359,13 +360,7 @@ public class DAnalysisSessionServicesImpl implements SessionService, DAnalysisSe analysis.getOwnedViews().add(dView); } - Resource resourceforRepresentation = null; - if (Boolean.getBoolean("createRepresentationInSeparateResource")) { //$NON-NLS-1$ - resourceforRepresentation = representationLocationManager.getOrCreateRepresentationResource(representation, dView.eResource()); - } - if (resourceforRepresentation == null) { - resourceforRepresentation = dView.eResource(); - } + Resource resourceforRepresentation = representationLocationManager.getOrCreateRepresentationResource(representation, dView.eResource()); if (resourceforRepresentation != null) { session.registerResourceInCrossReferencer(resourceforRepresentation); resourceforRepresentation.getContents().add(representation); diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DRepresentationLocationManager.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DRepresentationLocationManager.java deleted file mode 100644 index 8924ae1928..0000000000 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DRepresentationLocationManager.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 THALES GLOBAL SERVICES and others, - * 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: - * Obeo - initial API and implementation - *******************************************************************************/ -package org.eclipse.sirius.business.internal.session.danalysis; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.sirius.business.api.helper.SiriusUtil; -import org.eclipse.sirius.business.api.session.danalysis.DRepresentationLocationRule; -import org.eclipse.sirius.common.tools.api.util.EclipseUtil; -import org.eclipse.sirius.viewpoint.DRepresentation; - -import com.google.common.collect.Lists; - -/** - * This manager is responsible to retrieve or create the {@link Resource} of a {@link DRepresentation}. - * - * @author fbarbin - * - */ -public class DRepresentationLocationManager { - - /** - * Get or creates (if it does not exist) the corresponding {@link Resource} for the given representation. - * - * @param representation - * the current representation. - * @param aird - * the aird resource from which the representation will be referenced. - * @return the representation resource. - */ - public Resource getOrCreateRepresentationResource(DRepresentation representation, Resource aird) { - Resource resource = null; - ResourceSet resourceSet = aird != null ? aird.getResourceSet() : null; - if (resourceSet != null) { - // Get the fragment of the URI - URI repResourceURI = getURIFromExtensionPoint(representation, aird); - if (repResourceURI == null) { - repResourceURI = getRepURI(representation, aird, resourceSet); - } - - // get or create resource - resource = resourceSet.getResource(repResourceURI, false); - if (resource == null) { - resource = resourceSet.createResource(repResourceURI); - } - } - return resource; - } - - private URI getRepURI(DRepresentation representation, Resource aird, ResourceSet resourceSet) { - int count = 0; - URI repUri = createRepURI(aird, representation, count++); - while (resourceSet.getResource(repUri, false) != null) { - repUri = createRepURI(aird, representation, count++); - } - return repUri; - - } - - private URI getURIFromExtensionPoint(DRepresentation representation, Resource dViewResource) { - List<DRepresentationLocationRule> extensionPointRules = Lists.newArrayList(); - extensionPointRules.addAll(EclipseUtil.getExtensionPlugins(DRepresentationLocationRule.class, DRepresentationLocationRule.ID, DRepresentationLocationRule.CLASS_ATTRIBUTE)); - - Optional<DRepresentationLocationRule> locationRule = extensionPointRules.stream().filter(rule -> rule.provides(representation, dViewResource)).findFirst(); - return locationRule.isPresent() ? locationRule.get().getResourceURI(representation, dViewResource) : null; - } - - /** - * Create the representation URI based on the aird resource URI. Only the last part of the segment is changed. - * - * @param aird - * @param representation - * @param count - * @return - */ - private URI createRepURI(Resource aird, DRepresentation representation, int count) { - // get the representation URI fragment - String repName = representation.getName().replace(' ', '_'); - if (count > 0) { - repName += String.valueOf(count); - } - URI airdURI = aird.getURI(); - - List<String> srmFileSegments = new ArrayList<>(airdURI.segmentsList()); - srmFileSegments.remove(srmFileSegments.size() - 1); - srmFileSegments.add(airdURI.lastSegment().replace("." + SiriusUtil.SESSION_RESOURCE_EXTENSION, "_aird")); //$NON-NLS-1$ //$NON-NLS-2$ - srmFileSegments.add(repName + "." + SiriusUtil.REPRESENTATION_FILE_EXTENSION); //$NON-NLS-1$ - - // return the URI - return URI.createHierarchicalURI(airdURI.scheme(), airdURI.authority(), airdURI.device(), srmFileSegments.toArray(new String[srmFileSegments.size()]), airdURI.query(), airdURI.fragment()); - } -} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java index dbeb521e3f..7fa3e6499c 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/SiriusPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2016 THALES GLOBAL SERVICES and others. + * Copyright (c) 2007, 2017 THALES GLOBAL SERVICES and others. * 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 @@ -26,6 +26,7 @@ import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidat import org.eclipse.sirius.business.internal.dialect.description.InterpretedExpressionQueryProviderRegistry; import org.eclipse.sirius.business.internal.helper.delete.DeleteHookDescriptorRegistryListener; import org.eclipse.sirius.business.internal.helper.task.ModelOperationManagerRegistryListener; +import org.eclipse.sirius.business.internal.representation.DRepresentationLocationRuleRegistryListener; import org.eclipse.sirius.business.internal.resource.strategy.ResourceStrategyRegistryListener; import org.eclipse.sirius.business.internal.session.factory.SessionFactoryRegistryListener; import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessorsRegistry; @@ -69,8 +70,7 @@ public final class SiriusPlugin extends EMFPlugin { private static Implementation plugin; /** - * create at the initialization to avoid synchronization cost in - * ExtendedPackageRegistry + * create at the initialization to avoid synchronization cost in ExtendedPackageRegistry */ private static final ModelAccessorsRegistry REGISTRY = new ModelAccessorsRegistry(); @@ -110,32 +110,35 @@ public final class SiriusPlugin extends EMFPlugin { private InterpreterRegistry interRegistry; /** - * The registry listener that will be used to listen to sessionFactory - * extension changes. + * The registry listener that will be used to listen to sessionFactory extension changes. */ private SessionFactoryRegistryListener sessionFactoryRegistryListener; /** - * The registry listener that will be used to listen to extension - * changes. + * The registry listener that will be used to listen to extension changes. */ private DeleteHookDescriptorRegistryListener deleteHookDescriptorRegistryListener; /** - * The registry listener that will be used to listen to contribution - * changes against the external java action extension point. + * The registry listener that will be used to listen to contribution changes against the external java action + * extension point. */ private ExternalJavaActionRegistryListener javaActionRegistryListener; /** - * The registry listener that will be used to listen to contribution - * changes against the external resource strategy extension point. + * The registry listener that will be used to listen to contribution changes against the external resource + * strategy extension point. */ private ResourceStrategyRegistryListener resourceStrategyRegistryListener; /** - * The registry listener that will be used to listen to contribution - * changes. + * The registry listener that will be used to listen to contribution changes against the external + * dRepresentationLocationRule extension point. + */ + private DRepresentationLocationRuleRegistryListener repLocationRuleRegistryListener; + + /** + * The registry listener that will be used to listen to contribution changes. */ private ModelOperationManagerRegistryListener modelOperationManagerRegistryListener; @@ -175,6 +178,8 @@ public final class SiriusPlugin extends EMFPlugin { javaActionRegistryListener.init(); resourceStrategyRegistryListener = new ResourceStrategyRegistryListener(); resourceStrategyRegistryListener.init(); + repLocationRuleRegistryListener = new DRepresentationLocationRuleRegistryListener(); + repLocationRuleRegistryListener.init(); modelOperationManagerRegistryListener = new ModelOperationManagerRegistryListener(); modelOperationManagerRegistryListener.init(); expressionQueryProviderRegistry = new InterpretedExpressionQueryProviderRegistry(Platform.getExtensionRegistry(), this); @@ -202,6 +207,8 @@ public final class SiriusPlugin extends EMFPlugin { javaActionRegistryListener = null; resourceStrategyRegistryListener.dispose(); resourceStrategyRegistryListener = null; + repLocationRuleRegistryListener.dispose(); + repLocationRuleRegistryListener = null; modelOperationManagerRegistryListener.dispose(); modelOperationManagerRegistryListener = null; expressionQueryProviderRegistry.dispose(); |
