Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/infra/org.eclipse.papyrus.infra.extendedtypes/src/org/eclipse/papyrus/infra/extendedtypes/invariantsemantictypeconfiguration/RuleConfigurationFactoryRegistry.java')
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.extendedtypes/src/org/eclipse/papyrus/infra/extendedtypes/invariantsemantictypeconfiguration/RuleConfigurationFactoryRegistry.java456
1 files changed, 456 insertions, 0 deletions
diff --git a/plugins/infra/org.eclipse.papyrus.infra.extendedtypes/src/org/eclipse/papyrus/infra/extendedtypes/invariantsemantictypeconfiguration/RuleConfigurationFactoryRegistry.java b/plugins/infra/org.eclipse.papyrus.infra.extendedtypes/src/org/eclipse/papyrus/infra/extendedtypes/invariantsemantictypeconfiguration/RuleConfigurationFactoryRegistry.java
new file mode 100644
index 00000000000..3d5dfda2c9d
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.extendedtypes/src/org/eclipse/papyrus/infra/extendedtypes/invariantsemantictypeconfiguration/RuleConfigurationFactoryRegistry.java
@@ -0,0 +1,456 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Remi Schnekenburger (CEA LIST) - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.extendedtypes.invariantsemantictypeconfiguration;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gmf.runtime.emf.type.core.IElementMatcher;
+import org.eclipse.papyrus.infra.extendedtypes.Activator;
+import org.osgi.framework.Bundle;
+
+/**
+ * Registry for all matcher factories.
+ */
+public class RuleConfigurationFactoryRegistry {
+
+ /** private singleton instance */
+ private static RuleConfigurationFactoryRegistry registry;
+
+ /** map configuration type to matcher descriptor */
+ protected Map<String, ConfigurableClassDescriptor> configurationTypeToClassDescriptor = null;
+
+ /**
+ * returns the singleton instance of this registry
+ *
+ * @return the singleton instance of this registry
+ */
+ public static synchronized RuleConfigurationFactoryRegistry getInstance() {
+ if(registry == null) {
+ registry = new RuleConfigurationFactoryRegistry();
+ registry.init();
+ }
+ return registry;
+ }
+
+ /**
+ * Inits the registry.
+ */
+ protected void init() {
+ configurationTypeToClassDescriptor = new HashMap<String, RuleConfigurationFactoryRegistry.ConfigurableClassDescriptor>();
+ //read invariant rule configuration etension point
+ IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(IInvariantRuleExtensionPoint.EXTENSION_POINT_ID);
+ // for each element, parses and retrieve the model file. then loads it and returns the root element
+ for(IConfigurationElement configurationElement : elements) {
+ // contributor will always be the same, but implementation could be different.
+ String contributorName = configurationElement.getContributor().getName();
+
+ String configurationClass = configurationElement.getAttribute(IInvariantRuleExtensionPoint.RULE_CONFIGURATION_CLASS);
+
+ String matcherClassName = configurationElement.getAttribute(IInvariantRuleExtensionPoint.ELEMENT_MATCHER_CLASS);
+ String editHelperAdviceClassName = configurationElement.getAttribute(IInvariantRuleExtensionPoint.EDIT_HELPER_ADVICE_CLASS);
+ String containerDescriptorClassName = configurationElement.getAttribute(IInvariantRuleExtensionPoint.CONTAINER_DESCRIPTOR_CLASS);
+ String creationElementValidatorClassName = configurationElement.getAttribute(IInvariantRuleExtensionPoint.CREATION_ELEMENT_VALIDATOR_CLASS);
+
+ ConfigurableClassDescriptor configurableClassDescriptor = new ConfigurableClassDescriptor(contributorName, matcherClassName, contributorName, editHelperAdviceClassName, contributorName, containerDescriptorClassName, contributorName, creationElementValidatorClassName);
+ configurationTypeToClassDescriptor.put(configurationClass, configurableClassDescriptor);
+ }
+
+ }
+
+ /**
+ * Creates the {@link IElementMatcher} specific to the given rule configuration
+ *
+ * @param ruleConfiguration
+ * the rule configuration that will configure the created matcher
+ * @return the {@link IElementMatcher} created or <code>null</code> if none could be created
+ */
+ public IInvariantElementMatcher<InvariantRuleConfiguration> createMatcher(InvariantRuleConfiguration ruleConfiguration) {
+ // creates the matcher from the extension points
+ Class<IInvariantElementMatcher<InvariantRuleConfiguration>> elementMatcherClass = getMatcherClass(ruleConfiguration);
+ if(elementMatcherClass == null) {
+ return null;
+ }
+ try {
+ IInvariantElementMatcher<InvariantRuleConfiguration> matcher = elementMatcherClass.newInstance();
+ if(matcher != null) {
+ matcher.init(ruleConfiguration);
+ }
+ return matcher;
+ } catch (InstantiationException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * @param ruleConfiguration
+ * @return
+ */
+ public IInvariantContainerDescriptor<InvariantRuleConfiguration> createContainerDescriptor(InvariantRuleConfiguration ruleConfiguration) {
+ Class<IInvariantContainerDescriptor<InvariantRuleConfiguration>> containerDescriptorClass = getContainerDescriptorClass(ruleConfiguration);
+ if(containerDescriptorClass == null) {
+ return null;
+ }
+ try {
+ IInvariantContainerDescriptor<InvariantRuleConfiguration> containerDescriptor = containerDescriptorClass.newInstance();
+ if(containerDescriptor != null) {
+ containerDescriptor.init(ruleConfiguration);
+ }
+ return containerDescriptor;
+ } catch (InstantiationException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * @param ruleConfiguration
+ * @return
+ */
+ public IInvariantEditHelperAdvice<InvariantRuleConfiguration> createEditHelperAdvice(InvariantRuleConfiguration ruleConfiguration) {
+ Class<IInvariantEditHelperAdvice<InvariantRuleConfiguration>> editHelperAdviceClass = getEditHelperAdviceClass(ruleConfiguration);
+ if(editHelperAdviceClass == null) {
+ Activator.log.error("impossible to find the edit helper advice implementation for configuration type : " + ((ruleConfiguration!=null) ? ruleConfiguration.eClass().getName() : "null"), null);
+ return null;
+ }
+ try {
+ IInvariantEditHelperAdvice<InvariantRuleConfiguration> editHelperAdvice = editHelperAdviceClass.newInstance();
+ if(editHelperAdvice != null) {
+ editHelperAdvice.init(ruleConfiguration);
+ }
+ return editHelperAdvice;
+ } catch (InstantiationException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * @param ruleConfiguration
+ * @return
+ */
+ public IInvariantCreationElementValidator<InvariantRuleConfiguration> createCreationElementValidator(InvariantRuleConfiguration ruleConfiguration) {
+ Class<IInvariantCreationElementValidator<InvariantRuleConfiguration>> creationElementValidatorClass = getCreationElementValidatorClass(ruleConfiguration);
+ if(creationElementValidatorClass == null) {
+ // Activator.log.error("impossible to find the Creation Element Validator for configuration type : " + ((ruleConfiguration!=null) ? ruleConfiguration.eClass().getName() : "null"), null);
+ return null;
+ }
+ try {
+ IInvariantCreationElementValidator<InvariantRuleConfiguration> creationElementValidator = creationElementValidatorClass.newInstance();
+ if(creationElementValidator != null) {
+ creationElementValidator.init(ruleConfiguration);
+ }
+ return creationElementValidator;
+ } catch (InstantiationException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+
+ /**
+ * @param ruleConfiguration
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ protected Class<IInvariantCreationElementValidator<InvariantRuleConfiguration>> getCreationElementValidatorClass(InvariantRuleConfiguration configuration) {
+ String configurationType = configuration.eClass().getInstanceClassName();
+ String className = configurationTypeToClassDescriptor.get(configurationType).getCreationElementValidatorClassName();
+ String contributorName = configurationTypeToClassDescriptor.get(configurationType).getCreationElementValidatorContributorName();
+
+ // look in the list of registered matcher for the right one
+ if(className ==null) {
+ //Activator.log.error("There should be an implementation class for the configuration "+configurationType+ " from contributor "+contributorName, null);
+ } else if(contributorName !=null) {
+ return (Class<IInvariantCreationElementValidator<InvariantRuleConfiguration>>)loadClass(className, contributorName);
+ }
+ return null;
+ }
+
+ /**
+ * @param configurationType
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ protected Class<IInvariantElementMatcher<InvariantRuleConfiguration>> getMatcherClass(InvariantRuleConfiguration configuration) {
+
+ String configurationType = configuration.eClass().getInstanceClassName();
+ String className = configurationTypeToClassDescriptor.get(configurationType).getElementMatcherClassName();
+ String contributorName = configurationTypeToClassDescriptor.get(configurationType).getElementMatcherContributorName();
+
+ // look in the list of registered matcher for the right one
+ if(className !=null && contributorName !=null) {
+ return (Class<IInvariantElementMatcher<InvariantRuleConfiguration>>)loadClass(className, contributorName);
+ }
+ return null;
+ }
+
+ /**
+ * @param configurationType
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ protected Class<IInvariantEditHelperAdvice<InvariantRuleConfiguration>> getEditHelperAdviceClass(InvariantRuleConfiguration configuration) {
+ String configurationType = configuration.eClass().getInstanceClassName();
+ String className = configurationTypeToClassDescriptor.get(configurationType).getEditHelperAdviceClassName();
+ String contributorName = configurationTypeToClassDescriptor.get(configurationType).getEditHelperAdviceContributorName();
+
+ // look in the list of registered edit helper advices for the right one
+ return (Class<IInvariantEditHelperAdvice<InvariantRuleConfiguration>>)loadClass(className, contributorName);
+ }
+
+ /**
+ * @param configurationType
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ protected Class<IInvariantContainerDescriptor<InvariantRuleConfiguration>> getContainerDescriptorClass(InvariantRuleConfiguration configuration) {
+ String configurationType = configuration.eClass().getInstanceClassName();
+ String className = configurationTypeToClassDescriptor.get(configurationType).getContainerDescriptorClassName();
+ String contributorName = configurationTypeToClassDescriptor.get(configurationType).getContainerDescriptorContributorName();
+
+
+ // look in the list of registered edit helper advices for the right one
+ if(className !=null && contributorName !=null) {
+ return (Class<IInvariantContainerDescriptor<InvariantRuleConfiguration>>)loadClass(className, contributorName);
+ }
+ return null;
+ }
+
+ protected static class ConfigurableClassDescriptor {
+
+ /**
+ * @param elementMatcherContributorName
+ * @param elementMatcherClassName
+ * @param editHelperAdviceContributorName
+ * @param editHelperAdviceClassName
+ * @param containerDescriptorContributorName
+ * @param containerDescriptorClassName
+ */
+ public ConfigurableClassDescriptor(String elementMatcherContributorName, String elementMatcherClassName, String editHelperAdviceContributorName, String editHelperAdviceClassName, String containerDescriptorContributorName, String containerDescriptorClassName, String creationElementValidatorContributorName, String creationElementValidatorClassName) {
+ this.elementMatcherContributorName = elementMatcherContributorName;
+ this.elementMatcherClassName = elementMatcherClassName;
+ this.editHelperAdviceContributorName = editHelperAdviceContributorName;
+ this.editHelperAdviceClassName = editHelperAdviceClassName;
+ this.containerDescriptorContributorName = containerDescriptorContributorName;
+ this.containerDescriptorClassName = containerDescriptorClassName;
+ this.creationElementValidatorContributorName = creationElementValidatorContributorName;
+ this.creationElementValidatorClassName = creationElementValidatorClassName;
+ }
+
+ private final String elementMatcherContributorName;
+
+ private final String elementMatcherClassName;
+
+ private final String editHelperAdviceContributorName;
+
+ private final String editHelperAdviceClassName;
+
+ private final String containerDescriptorContributorName;
+
+ private final String containerDescriptorClassName;
+
+ private final String creationElementValidatorContributorName;
+
+ private final String creationElementValidatorClassName;
+
+ /**
+ * @return
+ */
+ public String getCreationElementValidatorContributorName() {
+ return creationElementValidatorContributorName;
+ }
+
+ /**
+ * @return
+ */
+ public String getCreationElementValidatorClassName() {
+ return creationElementValidatorClassName;
+ }
+
+ /**
+ * @return the elementMatcherContributorName
+ */
+ public String getElementMatcherContributorName() {
+ return elementMatcherContributorName;
+ }
+
+
+ /**
+ * @return the elementMatcherClassName
+ */
+ public String getElementMatcherClassName() {
+ return elementMatcherClassName;
+ }
+
+
+ /**
+ * @return the editHelperAdviceContributorName
+ */
+ public String getEditHelperAdviceContributorName() {
+ return editHelperAdviceContributorName;
+ }
+
+
+ /**
+ * @return the editHelperAdviceClassName
+ */
+ public String getEditHelperAdviceClassName() {
+ return editHelperAdviceClassName;
+ }
+
+
+ /**
+ * @return the containerDescriptorContributorName
+ */
+ public String getContainerDescriptorContributorName() {
+ return containerDescriptorContributorName;
+ }
+
+
+ /**
+ * @return the containerDescriptorClassName
+ */
+ public String getContainerDescriptorClassName() {
+ return containerDescriptorClassName;
+ }
+
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // loading resource
+ ///////////////////////////////////////////////////////////////////////////
+ /** A map of classes that have been successfully loaded, keyed on the class name optionally prepended by the plugin ID, if specified. */
+ private static Map<String, WeakReference<Class<?>>> successLookupTable = new HashMap<String, WeakReference<Class<?>>>();
+
+ /** A map of classes that could not be loaded, keyed on the class name, optionally prepended by the plugin ID if specified. */
+ private static Set<String> failureLookupTable = new HashSet<String>();
+
+ /** A map to hold the bundle to exception list */
+ private static Map<Bundle, Set<String>> bundleToExceptionsSetMap = new HashMap<Bundle, Set<String>>();
+
+ /**
+ * A utility method to load a class using its name and a given class loader.
+ *
+ * @param className
+ * The class name
+ * @param bundle
+ * The class loader
+ * @return The loaded class or <code>null</code> if could not be loaded
+ */
+ protected static Class<?> loadClass(String className, String pluginId) {
+ StringBuffer keyStringBuf = new StringBuffer(className.length() + pluginId.length() + 2); // 2 is for . and extra.
+ keyStringBuf.append(pluginId);
+ keyStringBuf.append('.');
+ keyStringBuf.append(className);
+ String keyString = keyStringBuf.toString();
+ WeakReference<Class<?>> ref = successLookupTable.get(keyString);
+ Class<?> found = (ref != null) ? ref.get() : null;
+ if(found == null) {
+ if(ref != null)
+ successLookupTable.remove(keyString);
+ if(!failureLookupTable.contains(keyString)) {
+ try {
+ Bundle bundle = basicGetPluginBundle(pluginId);
+ if(bundle != null) {
+ // never load the class if the bundle is not active other wise
+ // we will cause the plugin to load
+ // unless the class is in the exception list
+ int state = bundle.getState();
+ if(state == org.osgi.framework.Bundle.ACTIVE || isInExceptionList(bundle, className)) {
+ found = bundle.loadClass(className);
+ successLookupTable.put(keyString, new WeakReference<Class<?>>(found));
+ if(state == org.osgi.framework.Bundle.ACTIVE) {
+ bundleToExceptionsSetMap.remove(bundle);
+ }
+ }
+ } else {
+ failureLookupTable.add(keyString);
+ }
+ } catch (ClassNotFoundException e) {
+ failureLookupTable.add(keyString);
+ }
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Given a bundle id, it checks if the bundle is found and activated. If it
+ * is, the method returns the bundle, otherwise it returns <code>null</code>.
+ *
+ * @param pluginId
+ * the bundle ID
+ * @return the bundle, if found
+ */
+ protected static Bundle getPluginBundle(String pluginId) {
+ Bundle bundle = basicGetPluginBundle(pluginId);
+ if(null != bundle && bundle.getState() == org.osgi.framework.Bundle.ACTIVE)
+ return bundle;
+ return null;
+ }
+
+ private static Bundle basicGetPluginBundle(String pluginId) {
+ return Platform.getBundle(pluginId);
+ }
+
+ private static boolean isInExceptionList(Bundle bundle, String className) {
+ String packageName = className.substring(0, className.lastIndexOf('.'));
+ Set<String> exceptionSet = bundleToExceptionsSetMap.get(bundle);
+ if(exceptionSet == null) {
+ Dictionary<String, String> dict = bundle.getHeaders();
+ String value = dict.get("Eclipse-LazyStart"); //$NON-NLS-1$
+ if(value != null) {
+ int index = value.indexOf("exceptions"); //$NON-NLS-1$
+ if(index != -1) {
+ try {
+ int start = value.indexOf('"', index + 1);
+ int end = value.indexOf('"', start + 1);
+ String exceptions = value.substring(start + 1, end);
+ exceptionSet = new HashSet<String>(2);
+ StringTokenizer tokenizer = new StringTokenizer(exceptions, ","); //$NON-NLS-1$
+ while(tokenizer.hasMoreTokens()) {
+ exceptionSet.add(tokenizer.nextToken().trim());
+ }
+ } catch (IndexOutOfBoundsException exception) {
+ // this means the MF did not follow the documented format for the exceptions list so i'll consider it empty
+ exceptionSet = Collections.emptySet();
+ }
+ } else {
+ exceptionSet = Collections.emptySet();
+ }
+ } else {
+ exceptionSet = Collections.emptySet();
+ }
+ bundleToExceptionsSetMap.put(bundle, exceptionSet);
+ }
+ return exceptionSet.contains(packageName);
+ }
+}

Back to the top