diff options
| author | cbrun | 2015-03-03 10:00:17 +0000 |
|---|---|---|
| committer | Maxime Porhel | 2015-03-31 13:42:40 +0000 |
| commit | 35f6066de6d2e92047387f5ed0b65d7dd6209596 (patch) | |
| tree | f2f6b5f37bc0308afb45fdc8a1b6f0b226f13ab1 | |
| parent | cd9877b378fb7b96d9f6a13ca88fa2c7083c16ed (diff) | |
| download | org.eclipse.sirius-35f6066de6d2e92047387f5ed0b65d7dd6209596.tar.gz org.eclipse.sirius-35f6066de6d2e92047387f5ed0b65d7dd6209596.tar.xz org.eclipse.sirius-35f6066de6d2e92047387f5ed0b65d7dd6209596.zip | |
[460947] Make ServiceInterpreter use JavaExtensionsManager
This brings support for Java services loaded from the workspace in the
'service:' interpreter.
Code completion is working.
I had to add logic to support de-registering of previously registered
services as in the context of the workspace a service might be updated.
The Interpreter only register a callback to the JavaExtensionsManager
instance even if it is owned by the Interpreter right now, but this is
done this way so that later on we can easily keep only one
JavaExtensionsManager which would be shared by several interpreters.
Bug: 460947
Change-Id: I8dd83fed107630a4db4afb298c0900fe044ede5a
Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
2 files changed, 54 insertions, 71 deletions
diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/ServiceProposalProvider.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/ServiceProposalProvider.java index 10b57f6155..dff2f287ca 100644 --- a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/ServiceProposalProvider.java +++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/ServiceProposalProvider.java @@ -76,15 +76,6 @@ public class ServiceProposalProvider implements IProposalProvider { - ServiceInterpreter.PREFIX.length() + VariableInterpreter.PREFIX.length(), context.getInterpreterContext()); proposals.addAll(getVariableProposals(context.getContents(), varContext)); - // Reset the available services (in case of call for other VSM) - serviceInterpreter.setProperty(IInterpreter.FILES, null); - - // for (String dependency : - // context.getInterpreterContext().getDependencies()) { - // serviceInterpreter.addImport(dependency); - // } - // TODO : when the ServiceInterpreter will support service use from - // workspace we could propose service completion } return proposals; } diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java index 36d31fd01c..9e7467b6da 100644 --- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java +++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/internal/interpreter/ServiceInterpreter.java @@ -15,28 +15,23 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; -import org.eclipse.core.runtime.Platform; import org.eclipse.emf.ecore.EObject; +import org.eclipse.sirius.common.tools.DslCommonPlugin; +import org.eclipse.sirius.common.tools.api.interpreter.ClassLoadingCallback; import org.eclipse.sirius.common.tools.api.interpreter.EvaluationException; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterProvider; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus; +import org.eclipse.sirius.common.tools.api.interpreter.JavaExtensionsManager; import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.base.Options; -import org.osgi.framework.Bundle; -import com.google.common.base.Function; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; +import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import com.google.common.collect.Multimap; /** * A specialized interpreter which can only directly invoke Java service @@ -58,24 +53,45 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip private final Map<Object, Object> properties = Maps.newHashMap(); - private final Set<Bundle> bundles = Sets.newLinkedHashSet(); + private final Map<String, PolymorphicService> services = Maps.newHashMap(); - private final Set<String> imports = Sets.newLinkedHashSet(); + /** + * Used to retrieve the services instances we create so that we can + * un-register those. + */ + private final Multimap<String, PolymorphicService> qualifiedNameToServices = HashMultimap.create(); - private final Map<String, PolymorphicService> services = Maps.newHashMap(); + private final JavaExtensionsManager javaExtensions = JavaExtensionsManager.createManagerWithOverride(); + + private final ClassLoadingCallback callback = new ClassLoadingCallback() { - private Function<String, String> file2bundleName = new Function<String, String>() { @Override - public String apply(String file) { - String[] segments = file.split(Pattern.quote("/")); - if (segments != null && segments.length > 1) { - return segments[1]; + public void unloaded(String qualifiedName, Class<?> clazz) { + for (PolymorphicService service : qualifiedNameToServices.get(qualifiedName)) { + services.remove(service.getName()); } - return null; + qualifiedNameToServices.removeAll(qualifiedName); + } + + @Override + public void notFound(String qualifiedName) { + DslCommonPlugin.getDefault().warning("Could not find Java extension class " + qualifiedName, new RuntimeException()); + } + + @Override + public void loaded(String qualifiedName, Class<?> clazz) { + registerServiceClass(qualifiedName, clazz); } }; /** + * Create an instance of {@link ServiceInterpreter}. + */ + public ServiceInterpreter() { + this.javaExtensions.addClassLoadingCallBack(callback); + } + + /** * Get the receiver variable name if any, none {@link Option} otherwise. * * @param expression @@ -91,7 +107,6 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip return Options.newNone(); } - @Override public IInterpreter createInterpreter() { return new ServiceInterpreter(); @@ -148,13 +163,10 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip @Override public void addImport(String dependency) { - Class<?> klass = loadClassFromBundlePath(dependency); - if (klass != null) { - registerServiceClass(klass); - } + javaExtensions.addImport(dependency); } - private void registerServiceClass(Class<?> klass) { + private void registerServiceClass(String qualifiedName, Class<?> klass) { Object serviceInstance = null; try { serviceInstance = klass.newInstance(); @@ -170,16 +182,17 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip for (Method m : klass.getMethods()) { if (isValidServiceMethod(m)) { - registerService(new MonomorphicService(serviceInstance, m)); + registerService(qualifiedName, new MonomorphicService(serviceInstance, m)); } } - imports.add(klass.getCanonicalName()); } - private void registerService(MonomorphicService service) { + private void registerService(String qualifiedName, MonomorphicService service) { String name = service.getName(); if (!services.containsKey(name)) { - services.put(name, new PolymorphicService(name)); + PolymorphicService newService = new PolymorphicService(name); + services.put(name, newService); + qualifiedNameToServices.put(qualifiedName, newService); } services.get(name).addImplementer(service); } @@ -214,53 +227,26 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip @Override public Collection<String> getImports() { - return Sets.newHashSet(imports); + return javaExtensions.getImports(); } @Override public void removeImport(String dependency) { - if (imports.remove(dependency)) { - // TODO - } + javaExtensions.removeImport(dependency); } @Override public void clearImports() { - imports.clear(); + javaExtensions.clearImports(); services.clear(); - } - - private Class<?> loadClassFromBundlePath(String className) { - for (Bundle bundle : bundles) { - try { - return bundle.loadClass(className); - } catch (ClassNotFoundException e) { - // Ignore, try next bundle in the path. - } - } - return null; + qualifiedNameToServices.clear(); } @Override public void setProperty(Object key, Object value) { properties.put(key, value); - if (IInterpreter.FILES.equals(key) && (value instanceof List<?>)) { - // Reload all the imported services using the new bundle path - updateBundlePath(Iterables.filter((List<?>) value, String.class)); - services.clear(); - for (String imp : Lists.newArrayList(imports)) { - addImport(imp); - } - } - } - - private void updateBundlePath(Iterable<String> files) { - bundles.clear(); - for (String name : Iterables.filter(Iterables.transform(files, file2bundleName), Predicates.notNull())) { - Bundle bundle = Platform.getBundle(name); - if (bundle != null) { - bundles.add(bundle); - } + if (IInterpreter.FILES.equals(key)) { + javaExtensions.updateScope((Collection<String>) value); } } @@ -278,4 +264,10 @@ public class ServiceInterpreter extends VariableInterpreter implements org.eclip Collection<IInterpreterStatus> interpreterStatus = new ArrayList<IInterpreterStatus>(); return interpreterStatus; } + + @Override + public void dispose() { + super.dispose(); + this.javaExtensions.removeClassLoadingCallBack(callback); + } } |
