Index: plugin-src/src/org/eclipse/emf/validation/model/CategoryManager.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/model/CategoryManager.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/model/CategoryManager.java (working copy) @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.common.EMFPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationDebugOptions; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; import org.eclipse.emf.validation.internal.l10n.ValidationMessages; @@ -230,19 +231,38 @@ * point. */ private void loadCategories() { - IConfigurationElement[] elements = Platform.getExtensionRegistry().getExtensionPoint( + IConfigurationElement[] elements = new IConfigurationElement[0]; + if (EMFPlugin.IS_ECLIPSE_RUNNING) { + elements = Platform.getExtensionRegistry().getExtensionPoint( EMFModelValidationPlugin.getPluginId(), EMFModelValidationPlugin.CONSTRAINT_PROVIDERS_EXT_P_NAME) .getConfigurationElements(); - - for (IConfigurationElement next : elements) { - if (next.getName().equals(XmlConfig.E_CATEGORY)) { - loadCategories(globalCategory, next); - } } + configureCategories(elements); } /** + *
+ * Configures my categories from the Eclipse configuration
+ * elements
+ *
+ * NOTE that this method should only be called by the EMF Model + * Validation Plug-in, not by any client code! + *
+ * + * @param elements + */ + public void configureCategories(IConfigurationElement[] elements) { + for (int i = 0; i < elements.length; i++) { + IConfigurationElement next = elements[i]; + if (next.getName().equals(XmlConfig.E_CATEGORY)) { + loadCategories(globalCategory, next); + } + } + } + + /** * Loads subcategories of the specifiedparent
category.
* @param parent
* @param element
Index: plugin-src/src/org/eclipse/emf/validation/preferences/EMFModelValidationPreferences.java
===================================================================
--- plugin-src/src/org/eclipse/emf/validation/preferences/EMFModelValidationPreferences.java (revision 1513)
+++ plugin-src/src/org/eclipse/emf/validation/preferences/EMFModelValidationPreferences.java (working copy)
@@ -14,6 +14,7 @@
import org.eclipse.core.runtime.Preferences;
+import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.validation.internal.EMFModelValidationPlugin;
import org.eclipse.emf.validation.service.ConstraintRegistry;
import org.eclipse.emf.validation.service.IConstraintDescriptor;
@@ -27,7 +28,7 @@
static final String CONSTRAINT_DISABLED_PREFIX = "con.disabled/"; //$NON-NLS-1$
private static final Preferences prefs =
- EMFModelValidationPlugin.getPlugin().getPluginPreferences();
+ (!EMFPlugin.IS_ECLIPSE_RUNNING)?new Preferences():EMFModelValidationPlugin.getPlugin().getPluginPreferences();
/**
* Not instantiable, as all features are static.
Index: plugin-src/src/org/eclipse/emf/validation/internal/service/TraversalStrategyManager.java
===================================================================
--- plugin-src/src/org/eclipse/emf/validation/internal/service/TraversalStrategyManager.java (revision 1513)
+++ plugin-src/src/org/eclipse/emf/validation/internal/service/TraversalStrategyManager.java (working copy)
@@ -18,6 +18,7 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
@@ -95,11 +96,12 @@
* required by a validation operation.
*/
private void initStrategies() {
- IConfigurationElement[] strats =
- Platform.getExtensionRegistry().getConfigurationElementsFor(
+ IConfigurationElement[] strats = new IConfigurationElement[0];
+ if (EMFPlugin.IS_ECLIPSE_RUNNING) {
+ strats = Platform.getExtensionRegistry().getConfigurationElementsFor(
EMFModelValidationPlugin.getPluginId(),
TRAVERSAL_EXT_P_NAME);
-
+ }
for (int i = 0; i < strats.length; i++) {
IConfigurationElement config = strats[i];
Index: plugin-src/src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java
===================================================================
--- plugin-src/src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java (revision 1513)
+++ plugin-src/src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java (working copy)
@@ -12,16 +12,25 @@
package org.eclipse.emf.validation.internal;
+import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.validation.internal.l10n.ValidationMessages;
+import org.eclipse.emf.validation.internal.service.ClientContextManager;
+import org.eclipse.emf.validation.internal.util.XmlConstraintFactory;
+import org.eclipse.emf.validation.model.CategoryManager;
+import org.eclipse.emf.validation.service.ConstraintFactory;
+import org.eclipse.emf.validation.service.ModelValidationService;
+import org.eclipse.emf.validation.util.XmlConfig;
import org.eclipse.osgi.util.NLS;
/**
@@ -166,6 +175,13 @@
new EMFModelValidationPlugin();
private static Implementation plugin;
+
+ /**
+ * Flag to track standalone configuration, that should happen once
+ * to prevent multiple registration of constraint providers, parsers,
+ * etc.
+ */
+ private boolean alreadyConfigured = false;
/**
* Initializes me.
@@ -174,6 +190,49 @@
super(new ResourceLocator[]{});
}
+ /**
+ * Configures parsers, constraint providers, categories and constraint bindings
+ * from the given XML document urls
in standalone mode (no Eclipse).
+ *
+ * At a minimum one URL should refer to the org.eclipse.emf.validation
plugin descriptor. For example:
+ *
jar:file:///c:/mydir/lib/org.eclipse.emf.validation_1.1.0.v200705301635.jar!/plugin.xml+ * and another URL should refer to the user contributed constraint providers. For example: + *
file:///c:/mydir/plugin.xml+ * To enable support for OCL constraints, add a URL to the
org.eclipse.emf.validation.ocl
plugin descriptor. For example:
+ * jar:file:///c:/mydir/lib/org.eclipse.emf.validation.ocl_1.1.0.v200705301635.jar!/plugin.xml+ * + * @param urls the locations of the XML documents to use for standalone initialization. + * @throws CoreException on any problem parsing an XML file + */ + public void configureStandalone(URL[] urls) throws CoreException { + assert urls != null; + if (!EMFPlugin.IS_ECLIPSE_RUNNING && !alreadyConfigured) { + alreadyConfigured = true; + for (int i=0; i < urls.length; i++) { + IConfigurationElement element = XmlConfig.load(urls[i]); + // Configure any defined parsers + IConfigurationElement[] parsers = + XmlConfig.findExtensionPoint(getPluginId() + "." + XmlConstraintFactory.CONSTRAINT_PARSERS_EXT_P_NAME, element); + if (parsers != null) { + ((XmlConstraintFactory)ConstraintFactory.getInstance()).configureParsers(parsers); + } + // Configure any defined constraint providers and categories + IConfigurationElement[] providers = + XmlConfig.findExtensionPoint(getPluginId() + "." + CONSTRAINT_PROVIDERS_EXT_P_NAME, element); + if (providers != null) { + ModelValidationService.getInstance().configureProviders(providers); + CategoryManager.getInstance().configureCategories(providers); + } + // Configure any defined constraint bindings + IConfigurationElement[] bindings = + XmlConfig.findExtensionPoint(getPluginId() + "." + CONSTRAINT_BINDINGS_EXT_P_NAME, element); + if (bindings != null) { + ClientContextManager.getInstance().configureConstraintBindings(bindings); + } + } + } + } + // implements the inherited method @Override public ResourceLocator getPluginResourceLocator() { @@ -195,7 +254,12 @@ * @return my plug-in unique ID */ public static String getPluginId() { - return getPlugin().getBundle().getSymbolicName(); + if (!EMFPlugin.IS_ECLIPSE_RUNNING) { + return "org.eclipse.emf.validation"; + } + else { + return getPlugin().getBundle().getSymbolicName(); + } } /** @@ -229,7 +293,7 @@ * */ protected static boolean shouldTrace() { - return plugin.isDebugging(); + return (!EMFPlugin.IS_ECLIPSE_RUNNING)?false:plugin.isDebugging(); } /** Index: plugin-src/src/org/eclipse/emf/validation/internal/util/ConstraintsContentHandler.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/internal/util/ConstraintsContentHandler.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/internal/util/ConstraintsContentHandler.java (working copy) @@ -31,6 +31,7 @@ import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; +import org.eclipse.emf.common.EMFPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationStatusCodes; @@ -529,6 +530,10 @@ if ((s == null) || !s.startsWith("%")) { //$NON-NLS-1$ return s; } else if (resourceBundle == null) { + // FIXME Localize in standalone mode + if (!EMFPlugin.IS_ECLIPSE_RUNNING) { + return s; + } return Platform.getResourceString( Platform.getBundle(extension.getNamespaceIdentifier()), s); Index: plugin-src/src/org/eclipse/emf/validation/internal/util/Log.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/internal/util/Log.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/internal/util/Log.java (working copy) @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.emf.common.EMFPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; /** @@ -141,8 +142,17 @@ Status s = new Status(severity, EMFModelValidationPlugin.getPluginId(), code, message, throwable); - - EMFModelValidationPlugin.getPlugin().log(s); + if (!EMFPlugin.IS_ECLIPSE_RUNNING) { + if (s.isOK()) { + System.out.println(s); + } + else { + System.err.println(s); + } + } + else { + EMFModelValidationPlugin.getPlugin().log(s); + } } /** @@ -154,7 +164,17 @@ * @param status The status object on which to base the log. */ public static void log(IStatus status) { - EMFModelValidationPlugin.getPlugin().log(status); + if (!EMFPlugin.IS_ECLIPSE_RUNNING) { + if (status.isOK()) { + System.out.println(status); + } + else { + System.err.println(status); + } + } + else { + EMFModelValidationPlugin.getPlugin().log(status); + } } /** Index: plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java (working copy) @@ -91,12 +91,18 @@ */ public Object createExecutableExtension(String propertyName) throws CoreException { - - String message = EMFModelValidationPlugin.getMessage( + Object result = null; + String className = getAttribute(propertyName); + try { + Class> clazz = this.getClass().getClassLoader().loadClass(className); + result = clazz.newInstance(); + } + catch (Exception ex) { + String message = EMFModelValidationPlugin.getMessage( EMFModelValidationStatusCodes.XML_CREATE_EXTENSION_MSG, new Object[] {getName()}); - CoreException ce = new CoreException( + CoreException ce = new CoreException( new Status( IStatus.ERROR, EMFModelValidationPlugin.getPluginId(), @@ -104,8 +110,10 @@ message, null)); - Trace.throwing(getClass(), "createExecutableExtension", ce); //$NON-NLS-1$ - throw ce; + Trace.throwing(getClass(), "createExecutableExtension", ce); //$NON-NLS-1$ + throw ce; + } + return result; } // implements the interface method Index: plugin-src/src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java (working copy) @@ -157,8 +157,13 @@ Bundle bundle = Platform.getBundle(bundleName); try { - Class> resultType = bundle.loadClass(className); - + Class> resultType = null; + if (bundle == null) { + resultType = this.getClass().getClassLoader().loadClass(className); + } + else { + resultType = bundle.loadClass(className); + } if (AbstractModelConstraint.class.isAssignableFrom(resultType)) { // instantiate the class extending AbstractModelConstraint result = new ConstraintAdapter( Index: plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java (working copy) @@ -43,7 +43,7 @@ /** * Extension point name for the model providers extension point. */ - private static final String CONSTRAINT_PARSERS_EXT_P_NAME = + public static final String CONSTRAINT_PARSERS_EXT_P_NAME = "constraintParsers"; //$NON-NLS-1$ /** Mapping of language names to parser implementations. */ @@ -115,6 +115,12 @@ } } + public void configureParsers(IConfigurationElement[] elements) { + for (int i = 0; i < elements.length; i++) { + registerParser(elements[i]); + } + } + @SuppressWarnings("deprecation") protected IModelConstraint createConstraint(IParameterizedConstraintDescriptor descriptor) { final String lang = descriptor.getLanguage(); @@ -210,11 +216,13 @@ * extension point. */ private void initializeParsers() { - IConfigurationElement[] configs = - Platform.getExtensionRegistry().getConfigurationElementsFor( + IConfigurationElement[] configs = new IConfigurationElement[0]; + if (Platform.getExtensionRegistry() != null) { + configs = + Platform.getExtensionRegistry().getConfigurationElementsFor( EMFModelValidationPlugin.getPluginId(), CONSTRAINT_PARSERS_EXT_P_NAME); - + } for (IConfigurationElement config : configs) { registerParser(config); } Index: plugin-src/src/org/eclipse/emf/validation/util/XmlConfig.java =================================================================== --- plugin-src/src/org/eclipse/emf/validation/util/XmlConfig.java (revision 1513) +++ plugin-src/src/org/eclipse/emf/validation/util/XmlConfig.java (working copy) @@ -20,7 +20,11 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IContributor; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IPluginDescriptor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.emf.validation.internal.EMFModelValidationDebugOptions; @@ -351,6 +355,19 @@ element.getDeclaringExtension().getNamespaceIdentifier()).getEntry("/"); //$NON-NLS-1$ } } + + /** + * Loads a configuration element from the specified
url
+ *
+ * @param url the location of the XML document
+ * @return the configuration element representing the XML document
+ * @throws CoreException on any problem parsing an XML file
+ * @see #load(IConfigurationElement, URL)
+ */
+ public static IConfigurationElement load(URL url)
+ throws CoreException {
+ return load(new DummyConfigurationElement(), url);
+ }
/**
* Loads a <constraints> element from the specified
@@ -410,6 +427,33 @@
}
}
+ /**
+ * Returns the children of the configuration element that matches the given
+ * extensionPoint
, searches recursively the given parent element.
+ *
+ * @param extensionPoint The name of the extension point to match
+ * @param parent The top level configuration element to search
+ * @return the matching configuration element children or null if not found
+ */
+ public static IConfigurationElement[] findExtensionPoint(String extensionPoint, IConfigurationElement parent) {
+ if (parent.getAttribute("point") != null && parent.getAttribute("point").equals(extensionPoint)) {
+ return parent.getChildren();
+ }
+ else {
+ // Recurse
+ IConfigurationElement[] children = parent.getChildren();
+ if (children != null) {
+ for (int i = 0; i < children.length; i++) {
+ IConfigurationElement[] result = findExtensionPoint(extensionPoint, children[i]);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Flushes the resource bundles that were loaded for localization of strings
* in an XML constraint provider's XML constraint declarations.
@@ -440,4 +484,139 @@
return result;
}
+
+ // Inner classes
+
+ /**
+ * A mock configuration element used to supply a valid extension namespace identifier
+ * + * This class is not intended to be used outside of the validation framework. + *
+ * @see XmlConfig#load(URL) + */ + private static class DummyConfigurationElement implements IConfigurationElement { + + IExtension dummyExtension = new DummyExtension("org.eclipse.emf.validation.internal"); + + public IExtension getDeclaringExtension() throws InvalidRegistryObjectException { + return dummyExtension; + } + + // Unused Methods + + public Object createExecutableExtension(String propertyName) throws CoreException { + return null; + } + + public String getAttribute(String name) throws InvalidRegistryObjectException { + return null; + } + + public String getAttributeAsIs(String name) throws InvalidRegistryObjectException { + return null; + } + + public String[] getAttributeNames() throws InvalidRegistryObjectException { + return null; + } + + public IConfigurationElement[] getChildren() throws InvalidRegistryObjectException { + return null; + } + + public IConfigurationElement[] getChildren(String name) throws InvalidRegistryObjectException { + return null; + } + + public IContributor getContributor() throws InvalidRegistryObjectException { + return null; + } + + public String getName() throws InvalidRegistryObjectException { + return null; + } + + public String getNamespace() throws InvalidRegistryObjectException { + return null; + } + + public String getNamespaceIdentifier() throws InvalidRegistryObjectException { + return null; + } + + public Object getParent() throws InvalidRegistryObjectException { + return null; + } + + public String getValue() throws InvalidRegistryObjectException { + return null; + } + + public String getValueAsIs() throws InvalidRegistryObjectException { + return null; + } + + public boolean isValid() { + return false; + } + + } + + /** + * A mock extension used to supply a valid namespace identifier + *+ * This class is not intended to be used outside of the validation framework. + *
+ * @see XmlConfig#load(URL) + */ + private static class DummyExtension implements IExtension { + + String namespaceIndentifier = null; + + public DummyExtension(String namespaceIdentifier) { + this.namespaceIndentifier = namespaceIdentifier; + } + + public String getNamespaceIdentifier() throws InvalidRegistryObjectException { + return namespaceIndentifier; + } + + // Unused Methods + + public IConfigurationElement[] getConfigurationElements() throws InvalidRegistryObjectException { + return null; + } + + public IContributor getContributor() throws InvalidRegistryObjectException { + return null; + } + + public IPluginDescriptor getDeclaringPluginDescriptor() throws InvalidRegistryObjectException { + return null; + } + + public String getExtensionPointUniqueIdentifier() throws InvalidRegistryObjectException { + return null; + } + + public String getLabel() throws InvalidRegistryObjectException { + return null; + } + + public String getNamespace() throws InvalidRegistryObjectException { + return null; + } + + public String getSimpleIdentifier() throws InvalidRegistryObjectException { + return null; + } + + public String getUniqueIdentifier() throws InvalidRegistryObjectException { + return null; + } + + public boolean isValid() { + return false; + } + } }