Index: src/org/eclipse/emf/validation/model/CategoryManager.java =================================================================== --- src/org/eclipse/emf/validation/model/CategoryManager.java (revision 1053) +++ src/org/eclipse/emf/validation/model/CategoryManager.java (working copy) @@ -18,6 +18,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; @@ -229,20 +230,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 (int i = 0; i < elements.length; i++) { - IConfigurationElement next = elements[i]; - - 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 specified parent category. * @param parent Index: src/org/eclipse/emf/validation/preferences/EMFModelValidationPreferences.java =================================================================== --- src/org/eclipse/emf/validation/preferences/EMFModelValidationPreferences.java (revision 1053) +++ 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: src/org/eclipse/emf/validation/internal/service/TraversalStrategyManager.java =================================================================== --- src/org/eclipse/emf/validation/internal/service/TraversalStrategyManager.java (revision 1053) +++ 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: src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java =================================================================== --- src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java (revision 1053) +++ src/org/eclipse/emf/validation/internal/EMFModelValidationPlugin.java (working copy) @@ -12,11 +12,13 @@ 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.Platform; @@ -25,7 +27,11 @@ 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; import org.osgi.framework.BundleContext; @@ -164,7 +170,14 @@ 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. */ @@ -177,6 +190,49 @@ return plugin; } + /** + * 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.0.1.v200609250852.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.0.1.v200609250852.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); + } + } + } + } + /** * Obtains the Eclipse plug-in that I implement. * @@ -192,9 +248,14 @@ * @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(); + } } - + /** * The definition of the Eclipse plug-in flavour of this EMF plug-in. * @@ -274,7 +335,7 @@ * */ protected static boolean shouldTrace() { - return plugin.isDebugging(); + return (!EMFPlugin.IS_ECLIPSE_RUNNING)?false:plugin.isDebugging(); } /** Index: src/org/eclipse/emf/validation/internal/util/ConstraintsContentHandler.java =================================================================== --- src/org/eclipse/emf/validation/internal/util/ConstraintsContentHandler.java (revision 1053) +++ 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; @@ -524,6 +525,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: src/org/eclipse/emf/validation/internal/util/Log.java =================================================================== --- src/org/eclipse/emf/validation/internal/util/Log.java (revision 1053) +++ src/org/eclipse/emf/validation/internal/util/Log.java (working copy) @@ -17,6 +17,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; /** @@ -142,8 +143,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); + } } /** @@ -155,7 +165,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: src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java =================================================================== --- src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java (revision 1053) +++ src/org/eclipse/emf/validation/internal/util/XmlConfigurationElement.java (working copy) @@ -92,23 +92,30 @@ */ 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(), - EMFModelValidationStatusCodes.ERROR_PARSING_XML, - message, - null)); - - Trace.throwing(getClass(), "createExecutableExtension", ce); //$NON-NLS-1$ - throw ce; + IStatus.ERROR, + EMFModelValidationPlugin.getPluginId(), + EMFModelValidationStatusCodes.ERROR_PARSING_XML, + message, + ex)); + Trace.throwing(getClass(), "createExecutableExtension", ce); //$NON-NLS-1$ + throw ce; + } + return result; } - + // implements the interface method public String getAttribute(String name) { return (String)attributes.get(name); Index: src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java =================================================================== --- src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java (revision 1053) +++ src/org/eclipse/emf/validation/internal/util/JavaConstraintParser.java (working copy) @@ -133,8 +133,13 @@ .getNamespaceIdentifier()); 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: src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java =================================================================== --- src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java (revision 1053) +++ src/org/eclipse/emf/validation/internal/util/XmlConstraintFactory.java (working copy) @@ -39,7 +39,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. */ @@ -85,6 +85,12 @@ return new DisabledConstraint(desc, e); } } + + public void configureParsers(IConfigurationElement[] elements) { + for (int i = 0; i < elements.length; i++) { + registerParser(elements[i]); + } + } /** * Registers a parser implementation against the language that it provides. @@ -141,11 +147,12 @@ * 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 (int i = 0; i < configs.length; i++) { IConfigurationElement config = configs[i]; Index: src/org/eclipse/emf/validation/util/XmlConfig.java =================================================================== --- src/org/eclipse/emf/validation/util/XmlConfig.java (revision 1053) +++ 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; @@ -348,6 +352,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 @@ -414,4 +431,168 @@ public static void flushResourceBundles() { ConstraintsContentHandler.flushResourceBundleCache(); } + + /** + * 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(IConfigurationElement child: children) { + IConfigurationElement[] result = findExtensionPoint(extensionPoint, child); + if (result != null) { + return result; + } + } + } + } + return null; + } + + // 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; + } + + } + } Index: META-INF/MANIFEST.MF =================================================================== --- META-INF/MANIFEST.MF (revision 1053) +++ META-INF/MANIFEST.MF (working copy) @@ -22,6 +22,6 @@ g.eclipse.emf.validation.marker,org.eclipse.emf.validation.model,org. eclipse.emf.validation.preferences,org.eclipse.emf.validation.service ,org.eclipse.emf.validation.util,org.eclipse.emf.validation.xml -Bundle-Version: 1.0.1.v200609250852 +Bundle-Version: 1.0.1.v200609250852a Eclipse-LazyStart: true