diff options
| author | Pierre-Charles David | 2016-07-08 12:49:13 +0000 |
|---|---|---|
| committer | Pierre-Charles David | 2016-08-22 15:00:07 +0000 |
| commit | 04cc6c431dcf1943ecd6ae8382c5cd591dc2fe19 (patch) | |
| tree | 9e4a8752c7d1effbbe14e230b20c2e5077e905e1 | |
| parent | 7144e40d03806a547fa7b02fd8dc545779f5121a (diff) | |
| download | org.eclipse.sirius-04cc6c431dcf1943ecd6ae8382c5cd591dc2fe19.tar.gz org.eclipse.sirius-04cc6c431dcf1943ecd6ae8382c5cd591dc2fe19.tar.xz org.eclipse.sirius-04cc6c431dcf1943ecd6ae8382c5cd591dc2fe19.zip | |
[496014] Add extension point to contribute IInterpretedExpressionQueryProviders
Bug: 496014
Change-Id: I3d0177448e014716c2997303f084afb7f0e27afd
Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
10 files changed, 365 insertions, 127 deletions
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html index a88b4393e4..288415824b 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html @@ -160,6 +160,12 @@ <code>org.eclipse.sirius</code> </h4> <ul> + <li><span class="label label-success">Added</span> A new extension point named + <code>org.eclipse.sirius.interpretedExpressionQueryProvider</code> (with the associated new interface + <code>org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider</code>) allows external contribution of + <code>IInterpretedExpressionQuery</code> specific to some particular expression occurrences in the VSM. This is used in particular for VSM extensions which do not fit well into the hard-coded assumptions about + <code>IInterpretedExpressionQuery</code>. In Sirius 4.1, this is used to add completion and validation support for expressions used in properties views descriptions. + </li> <li><span class="label label-success">Added</span> <code>org.eclipse.sirius.business.api.migration.AirdResourceVersionMismatchException</code> exception has been added to cancel Sirius session opening due to an .aird version mismatch, i.e. when one the of the loaded Representation resources is coming from a newer Sirius release. </li> diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile index df7e127be0..1229cf944a 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile @@ -32,6 +32,7 @@ h4. Changes in @org.eclipse.sirius.common@ h4. Changes in @org.eclipse.sirius@ +* <span class="label label-success">Added</span> A new extension point named @org.eclipse.sirius.interpretedExpressionQueryProvider@ (with the associated new interface @org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider@) allows external contribution of @IInterpretedExpressionQuery@ specific to some particular expression occurrences in the VSM. This is used in particular for VSM extensions which do not fit well into the hard-coded assumptions about @IInterpretedExpressionQuery@. In Sirius 4.1, this is used to add completion and validation support for expressions used in properties views descriptions. * <span class="label label-success">Added</span> @org.eclipse.sirius.business.api.migration.AirdResourceVersionMismatchException@ exception has been added to cancel Sirius session opening due to an .aird version mismatch, i.e. when one the of the loaded Representation resources is coming from a newer Sirius release. * <span class="label label-success">Added</span> @org.eclipse.sirius.viewpoint.DView.getOwnedRepresentationDescriptors()@ has been added as the first step to save the DRepresentation in its own resource. In this step, the DRepresentationDescriptor life cycle is the same as the associated DRepresentation. ** @org.eclipse.sirius.business.api.dialect.command.RenameRepresentationCommand@ diff --git a/plugins/org.eclipse.sirius/plugin.properties b/plugins/org.eclipse.sirius/plugin.properties index ba8bb04fa4..da6defd960 100644 --- a/plugins/org.eclipse.sirius/plugin.properties +++ b/plugins/org.eclipse.sirius/plugin.properties @@ -57,6 +57,7 @@ extension-point.deleteHook.name = org.eclipse.sirius.deleteHook extension-point.dialect.name = org.eclipse.sirius.dialect extension-point.externalJavaAction = External Java Actions extension-point.featureExtensions.name = org.eclipse.sirius.featureExtensions +extension-point.interpretedExpressionQueryProvider.name = org.eclipse.sirius.interpretedExpressionQueryProvider extension-point.migration.name = org.eclipse.sirius.migration extension-point.mmdescriptor.name = org.eclipse.sirius.mmdescriptor extension-point.refreshExtensionProvider.name = viewpoint.semantic.refresh.refreshExtensionProvider @@ -173,6 +174,7 @@ InitializeModelingProjectJob_invalidModelingProjectErrorMsg = One modeling proje InitializeModelingProjectJob_label = Initializing Modeling Projects InitializeModelingProjectJob_labelEmptyProject = Initializing Empty Modeling Projects InterpretedExpressionVariableTask_label = set or unset an acceleo variable task +InterpretedExpressionQueryProviderRegistry_instanciationError = An error occurred while trying to instanciate {0} as an IInterpretedExpressionQueryProvider. InterpreterRegistry_sessionNotFoundErrorMsg = Could not find a session for model element : {0} InterpreterRegistry_nullModelElementErrorMsg = Model element is null InterpreterRegistry_ImpossibleToFindInterpreterErrorMsg = Impossible to find an interpreter diff --git a/plugins/org.eclipse.sirius/plugin.xml b/plugins/org.eclipse.sirius/plugin.xml index b400593791..5dbff596f0 100644 --- a/plugins/org.eclipse.sirius/plugin.xml +++ b/plugins/org.eclipse.sirius/plugin.xml @@ -28,6 +28,7 @@ <extension-point id="migrationParticipant" name="%extension-point.migration.name" schema="schema/migrationParticipant.exsd"/> <extension-point id="repairParticipant" name="%extension-point.repairParticipant.name" schema="schema/repairParticipant.exsd"/> <extension-point id="resourceStrategy" name="%extension-point.resourceStrategy.name" schema="schema/resourceStrategy.exsd"/> + <extension-point id="interpretedExpressionQueryProvider" name="%extension-point.interpretedExpressionQueryProvider.name" schema="schema/interpretedExpressionQueryProvider.exsd"/> <extension point="org.eclipse.emf.ecore.generated_package"> <!-- @generated viewpoint --> diff --git a/plugins/org.eclipse.sirius/schema/interpretedExpressionQueryProvider.exsd b/plugins/org.eclipse.sirius/schema/interpretedExpressionQueryProvider.exsd new file mode 100644 index 0000000000..56a93a218e --- /dev/null +++ b/plugins/org.eclipse.sirius/schema/interpretedExpressionQueryProvider.exsd @@ -0,0 +1,114 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.eclipse.sirius" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="org.eclipse.sirius" id="interpretedExpressionQueryProvider" name="org.eclipse.sirius.interpretedExpressionQueryProvider"/> + </appInfo> + <documentation> + This extension points allows external contribution of <code>IInterpretedExpressionQuery</code> specific to some particular expression occurrence in the VSM. This is used in particular for VSM extensions which do not fit well into the hard-coded assumptions about <code>IInterpretedExpressionQuery</code>, which normally assumes interpreted expressions only occur inside the context of a dialect / representation description. + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="interpretedExpressionProvider" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="interpretedExpressionProvider"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + Sirius 4.1.0. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + See <code>org.eclipse.sirius.ui.properties.internal.expressions.PropertiesInterpretedExpressionQuery</code> which uses this mechanism to plug completion and validation support for expressions used in property views descriptions. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + See <code>org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider</code> and <code>org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery</code>. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + None. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + Copyright (c) 2016 Obeo. +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 + </documentation> + </annotation> + +</schema> diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQueryProvider.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQueryProvider.java new file mode 100644 index 0000000000..83f9495c63 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/IInterpretedExpressionQueryProvider.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2016 Obeo. + * 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.api.dialect.description; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.sirius.ext.base.Option; + +/** + * Instances can provide <code>IInterpretedExpressionQuery</code> specific to + * some particular expression occurrence in the VSM. + * + * @author pcdavid + */ +public interface IInterpretedExpressionQueryProvider { + /** + * Optionally provides an {@link IInterpretedExpressionQuery} for a specific + * interpreted expression occurrence. + * + * @param context + * the VSM element in which the expression to query occurs. + * @param expressionAttribute + * the attribute of the context element which designates the + * expression to consider (for example + * {@link org.eclipse.sirius.viewpoint.description.DescriptionPackage.Literals#REPRESENTATION_DESCRIPTION__TITLE_EXPRESSION} + * ) . + * @return an optional {@link IInterpretedExpressionQuery} that will query + * representation descriptions to determine useful informations + * (like the type to consider for Interpreted expressions). + * @return + */ + Option<IInterpretedExpressionQuery> getExpressionQueryFor(EObject context, EStructuralFeature expressionAttribute); +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/DialectManagerImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/DialectManagerImpl.java index f559c90e48..4d0ceeeddc 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/DialectManagerImpl.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/DialectManagerImpl.java @@ -21,7 +21,6 @@ import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; @@ -32,8 +31,10 @@ import org.eclipse.sirius.business.api.dialect.DialectManager; import org.eclipse.sirius.business.api.dialect.RepresentationNotification; import org.eclipse.sirius.business.api.dialect.description.DefaultInterpretedExpressionQuery; import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery; +import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider; import org.eclipse.sirius.business.api.dialect.identifier.RepresentationElementIdentifier; import org.eclipse.sirius.business.api.helper.task.AbstractCommandTask; +import org.eclipse.sirius.business.api.query.EObjectQuery; import org.eclipse.sirius.business.api.session.Session; import org.eclipse.sirius.business.internal.movida.Movida; import org.eclipse.sirius.common.tools.api.util.EclipseUtil; @@ -47,6 +48,7 @@ import org.eclipse.sirius.viewpoint.DRepresentationDescriptor; import org.eclipse.sirius.viewpoint.Messages; import org.eclipse.sirius.viewpoint.SiriusPlugin; import org.eclipse.sirius.viewpoint.ViewpointPackage; +import org.eclipse.sirius.viewpoint.description.DescriptionPackage; import org.eclipse.sirius.viewpoint.description.RepresentationDescription; import org.eclipse.sirius.viewpoint.description.RepresentationExtensionDescription; import org.eclipse.sirius.viewpoint.description.Viewpoint; @@ -81,10 +83,6 @@ public class DialectManagerImpl implements DialectManager { return manager; } - /** - * - * {@inheritDoc} - */ @Override public Collection<RepresentationDescription> getAvailableRepresentationDescriptions(final Collection<Viewpoint> vp, final EObject semantic) { final Collection<RepresentationDescription> descs = new ArrayList<RepresentationDescription>(); @@ -94,9 +92,6 @@ public class DialectManagerImpl implements DialectManager { return descs; } - /** - * {@inheritDoc} - */ @Override public void refreshEffectiveRepresentationDescription(DRepresentation representation, IProgressMonitor monitor) { if (Movida.isEnabled()) { @@ -106,17 +101,11 @@ public class DialectManagerImpl implements DialectManager { } } - /** - * {@inheritDoc} - */ @Override public void refresh(final DRepresentation representation, final IProgressMonitor monitor) { refresh(representation, false, monitor); } - /** - * {@inheritDoc} - */ @Override public void refresh(DRepresentation representation, boolean doFullRefresh, IProgressMonitor monitor) { try { @@ -145,17 +134,6 @@ public class DialectManagerImpl implements DialectManager { } } - /** - * {@inheritDoc} - */ - public DRepresentation createRepresentation(final String name, final EObject semantic, final RepresentationDescription description, final IProgressMonitor monitor) { - return createRepresentation(name, semantic, description, null, monitor); - } - - /** - * - * {@inheritDoc} - */ @Override public DRepresentation createRepresentation(final String name, final EObject semantic, final RepresentationDescription description, final Session session, final IProgressMonitor monitor) { DRepresentation created = null; @@ -190,13 +168,6 @@ public class DialectManagerImpl implements DialectManager { return created; } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#copyRepresentation(org.eclipse.sirius.viewpoint.DRepresentation, - * java.lang.String, org.eclipse.sirius.business.api.session.Session, - * org.eclipse.core.runtime.IProgressMonitor) - */ @Override public DRepresentation copyRepresentation(final DRepresentation representation, final String name, final Session session, final IProgressMonitor monitor) { Dialect invokedDialect = null; @@ -222,10 +193,6 @@ public class DialectManagerImpl implements DialectManager { return copy; } - /** - * - * {@inheritDoc} - */ @Override public boolean canRefresh(final DRepresentation representation) { for (final Dialect dialect : dialects.values()) { @@ -236,10 +203,6 @@ public class DialectManagerImpl implements DialectManager { return false; } - /** - * - * {@inheritDoc} - */ @Override public boolean canCreate(final EObject semantic, final RepresentationDescription desc) { boolean canCreate = false; @@ -256,31 +219,16 @@ public class DialectManagerImpl implements DialectManager { return canCreate; } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectManager#disableDialect(org.eclipse.sirius.business.api.dialect.Dialect) - */ @Override public void disableDialect(final Dialect dialect) { dialects.remove(dialect.getName()); } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectManager#enableDialect(org.eclipse.sirius.business.api.dialect.Dialect) - */ @Override public void enableDialect(final Dialect dialect) { dialects.put(dialect.getName(), dialect); } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#notify(org.eclipse.sirius.business.api.dialect.RepresentationNotification) - */ @Override public void notify(final RepresentationNotification representation) { for (final Dialect dialect : dialects.values()) { @@ -396,11 +344,6 @@ public class DialectManagerImpl implements DialectManager { } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#getDescription(org.eclipse.sirius.viewpoint.DRepresentation) - */ @Override public RepresentationDescription getDescription(final DRepresentation representation) { RepresentationDescription result = null; @@ -411,16 +354,6 @@ public class DialectManagerImpl implements DialectManager { return result; } - /** - * {@inheritDoc} - */ - public void initRepresentations(Viewpoint vp, EObject semantic) { - initRepresentations(vp, semantic, new NullProgressMonitor()); - } - - /** - * {@inheritDoc} - */ @Override public void initRepresentations(final Viewpoint vp, final EObject semantic, IProgressMonitor monitor) { for (final Dialect dialect : dialects.values()) { @@ -428,11 +361,6 @@ public class DialectManagerImpl implements DialectManager { } } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#canCreateIdentifier(org.eclipse.emf.ecore.EObject) - */ @Override public boolean canCreateIdentifier(final EObject representationElement) { for (final Dialect dialect : dialects.values()) { @@ -443,12 +371,6 @@ public class DialectManagerImpl implements DialectManager { return false; } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#createIdentifier(org.eclipse.emf.ecore.EObject, - * java.util.Map) - */ @Override public RepresentationElementIdentifier createIdentifier(final EObject representationElement, final Map<EObject, RepresentationElementIdentifier> elementToIdentifier) { for (final Dialect dialect : dialects.values()) { @@ -460,12 +382,6 @@ public class DialectManagerImpl implements DialectManager { return null; } - /** - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#updateRepresentationsExtendedBy(Session, - * Viewpoint, boolean) - */ @Override public void updateRepresentationsExtendedBy(final Session session, final Viewpoint viewpoint, final boolean activated) { for (final Dialect dialect : dialects.values()) { @@ -473,24 +389,28 @@ public class DialectManagerImpl implements DialectManager { } } - /** - * - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#createInterpretedExpressionQuery(org.eclipse.emf.ecore.EObject, - * org.eclipse.emf.ecore.EStructuralFeature) - */ @Override public IInterpretedExpressionQuery createInterpretedExpressionQuery(EObject target, EStructuralFeature feature) { IInterpretedExpressionQuery returnedQuery = null; - - // Step 1 : we search for a Dialect compatible with - // the given target - Dialect dialect = getDialectFromEObjectAccordingToRepresentationDescription(target); - if (dialect != null) { - // Step 2 : we delegate the query creation to the found - // DialectDescription - returnedQuery = dialect.getServices().createInterpretedExpressionQuery(target, feature); + // Ask registered providers first + for (IInterpretedExpressionQueryProvider provider : SiriusPlugin.getDefault().getInterpretedExpressionQueryProviders()) { + Option<IInterpretedExpressionQuery> answer = provider.getExpressionQueryFor(target, feature); + if (answer.some()) { + returnedQuery = answer.get(); + break; + } + } + if (returnedQuery == null) { + // Step 1 : we search for a Dialect compatible with + // the given target + Dialect dialect = getDialectFromEObjectAccordingToRepresentationDescription(target); + if (dialect != null) { + // Step 2 : we delegate the query creation to the found + // DialectDescription + returnedQuery = dialect.getServices().createInterpretedExpressionQuery(target, feature); + } else if (new EObjectQuery(target).getFirstAncestorOfType(DescriptionPackage.Literals.EXTENSION).some()) { + // We are not inside a dialect, but inside an extension + } } if (returnedQuery != null) { return returnedQuery; @@ -500,12 +420,6 @@ public class DialectManagerImpl implements DialectManager { return new DefaultInterpretedExpressionQuery(target, feature); } - /** - * - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#handles(org.eclipse.sirius.viewpoint.description.RepresentationDescription) - */ @Override public boolean handles(RepresentationDescription representationDescription) { for (Dialect dialect : dialects.values()) { @@ -560,12 +474,6 @@ public class DialectManagerImpl implements DialectManager { return foundDialect; } - /** - * - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#handles(org.eclipse.sirius.viewpoint.description.RepresentationExtensionDescription) - */ @Override public boolean handles(RepresentationExtensionDescription representationExtensionDescription) { for (Dialect dialect : dialects.values()) { @@ -576,12 +484,6 @@ public class DialectManagerImpl implements DialectManager { return false; } - /** - * - * {@inheritDoc} - * - * @see org.eclipse.sirius.business.api.dialect.DialectServices#invalidateMappingCache() - */ @Override public void invalidateMappingCache() { for (Dialect dialect : dialects.values()) { @@ -589,9 +491,6 @@ public class DialectManagerImpl implements DialectManager { } } - /** - * {@inheritDoc} - */ @Override public Option<? extends AbstractCommandTask> createTask(CommandContext context, ModelAccessor extPackage, ModelOperation op, Session session, UICallBack uiCallback) { Option<? extends AbstractCommandTask> task = Options.newNone(); @@ -603,9 +502,6 @@ public class DialectManagerImpl implements DialectManager { return task; } - /** - * {@inheritDoc} - */ @Override public boolean allowsEStructuralFeatureCustomization(EObject element) { boolean customizationAllowed = false; diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/InterpretedExpressionQueryProviderRegistry.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/InterpretedExpressionQueryProviderRegistry.java new file mode 100644 index 0000000000..46bb8e943a --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/InterpretedExpressionQueryProviderRegistry.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2016 Obeo + * 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.dialect.description; + +import java.text.MessageFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +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.IStatus; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider; +import org.eclipse.sirius.tools.internal.ui.ExternalJavaActionDescriptor; +import org.eclipse.sirius.viewpoint.Messages; + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +/** + * Maintains the set of {@link IInterpretedExpressionQueryProvider} currently + * registered. + * + * @author pcdavid + */ +public class InterpretedExpressionQueryProviderRegistry { + /** Name of the extension point to parse. */ + public static final String EXTENSION_POINT = "org.eclipse.sirius.interpretedExpressionQueryProvider"; //$NON-NLS-1$ + + /** The attributed used to designate the provider implementation class. */ + public static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ + + private final IExtensionRegistry registry; + + private final Plugin context; + + private final Collection<IInterpretedExpressionQueryProvider> entries; + + private final IRegistryEventListener listener = new IRegistryEventListener() { + + @Override + public void added(IExtension[] extensions) { + for (IExtension extension : extensions) { + for (IConfigurationElement elem : extension.getConfigurationElements()) { + register(elem); + } + } + } + + @Override + public void removed(IExtension[] extensions) { + for (IExtension extension : extensions) { + for (IConfigurationElement elem : extension.getConfigurationElements()) { + unregister(elem); + } + } + } + + @Override + public void added(IExtensionPoint[] extensionPoints) { + // no need to listen to this event + } + + @Override + public void removed(IExtensionPoint[] extensionPoints) { + // no need to listen to this event + } + }; + + /** + * Constructor. + * + * @param registry + * the registry to look for registered providers. + * @param context + * the plug-in in the context of which we're running; used for + * logging. + */ + public InterpretedExpressionQueryProviderRegistry(IExtensionRegistry registry, Plugin context) { + this.registry = Preconditions.checkNotNull(registry); + this.context = context; + this.entries = Sets.newConcurrentHashSet(); + } + + /** + * Register this listener and parse initial contributions. + */ + public void init() { + registry.addListener(listener, InterpretedExpressionQueryProviderRegistry.EXTENSION_POINT); + IExtension[] initialExtensions = registry.getExtensionPoint(InterpretedExpressionQueryProviderRegistry.EXTENSION_POINT).getExtensions(); + listener.added(initialExtensions); + } + + /** + * Stop listening for further registry changes and forget about all + * currently known entries. + */ + public void dispose() { + registry.removeListener(listener); + entries.clear(); + } + + /** + * Returns all the currently registered + * {@link IInterpretedExpressionQueryProvider}. + * + * @return the currently registered + * {@link IInterpretedExpressionQueryProvider}. + */ + public Collection<IInterpretedExpressionQueryProvider> getEntries() { + return Collections.unmodifiableList(Lists.newArrayList(entries)); + } + + private void register(IConfigurationElement elem) { + Object executableExtension; + try { + executableExtension = elem.createExecutableExtension(CLASS_ATTRIBUTE); + if (executableExtension instanceof IInterpretedExpressionQueryProvider) { + entries.add((IInterpretedExpressionQueryProvider) executableExtension); + } + } catch (CoreException e) { + String message = MessageFormat.format(Messages.InterpretedExpressionQueryProviderRegistry_instanciationError, elem.getAttribute(CLASS_ATTRIBUTE)); + context.getLog().log(new Status(IStatus.ERROR, context.getBundle().getSymbolicName(), message, e)); + } + } + + private void unregister(IConfigurationElement elem) { + String className = elem.getAttribute(ExternalJavaActionDescriptor.CLASS_ATTRIBUTE); + Iterator<IInterpretedExpressionQueryProvider> iter = entries.iterator(); + while (iter.hasNext()) { + IInterpretedExpressionQueryProvider provider = iter.next(); + if (Objects.equal(className, provider.getClass().getName())) { + iter.remove(); + } + } + } +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java index 1308d23c60..35f5322d2a 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java @@ -331,6 +331,9 @@ public final class Messages { @TranslatableMessage public static String InterpreterRegistry_sessionNotFoundErrorMsg; + + @TranslatableMessage + public static String InterpretedExpressionQueryProviderRegistry_instanciationError; @TranslatableMessage public static String InterpreterRegistry_nullModelElementErrorMsg; 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 d516c8d901..ec02b97f64 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 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.sirius.viewpoint; +import java.util.Collection; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; @@ -19,8 +21,10 @@ import org.eclipse.emf.common.util.ResourceLocator; import org.eclipse.emf.ecore.EValidator; import org.eclipse.emf.ecore.plugin.EcorePlugin; import org.eclipse.sirius.business.api.componentization.ViewpointRegistry; +import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQueryProvider; import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator; import org.eclipse.sirius.business.api.helper.SiriusUtil; +import org.eclipse.sirius.business.internal.dialect.description.InterpretedExpressionQueryProviderRegistry; import org.eclipse.sirius.business.internal.helper.delete.DeleteHookDescriptorRegistryListener; import org.eclipse.sirius.business.internal.resource.strategy.ResourceStrategyRegistryListener; import org.eclipse.sirius.business.internal.session.factory.SessionFactoryRegistryListener; @@ -69,7 +73,6 @@ public final class SiriusPlugin extends EMFPlugin { */ private static final ModelAccessorsRegistry REGISTRY = new ModelAccessorsRegistry(SiriusUtil.DESCRIPTION_MODEL_EXTENSION); - /** * Creates the instance. */ @@ -130,6 +133,11 @@ public final class SiriusPlugin extends EMFPlugin { private ResourceStrategyRegistryListener resourceStrategyRegistryListener; /** + * The registry for {@link IInterpretedExpressionQueryProvider}. + */ + private InterpretedExpressionQueryProviderRegistry expressionQueryProviderRegistry; + + /** * Creates an instance. */ public Implementation() { @@ -155,6 +163,17 @@ public final class SiriusPlugin extends EMFPlugin { javaActionRegistryListener.init(); resourceStrategyRegistryListener = new ResourceStrategyRegistryListener(); resourceStrategyRegistryListener.init(); + expressionQueryProviderRegistry = new InterpretedExpressionQueryProviderRegistry(Platform.getExtensionRegistry(), this); + expressionQueryProviderRegistry.init(); + } + + /** + * Returns all the registered IInterpretedExpressionQueryProvider. + * + * @return the registered IInterpretedExpressionQueryProvider. + */ + public Collection<IInterpretedExpressionQueryProvider> getInterpretedExpressionQueryProviders() { + return expressionQueryProviderRegistry.getEntries(); } @Override @@ -169,6 +188,8 @@ public final class SiriusPlugin extends EMFPlugin { javaActionRegistryListener = null; resourceStrategyRegistryListener.dispose(); resourceStrategyRegistryListener = null; + expressionQueryProviderRegistry.dispose(); + expressionQueryProviderRegistry = null; ViewpointRegistry.getInstance().dispose(); |
