### Eclipse Workspace Patch 1.0 #P org.eclipse.emf.validation Index: src/org/eclipse/emf/validation/internal/service/ProviderDescriptor.java =================================================================== RCS file: /cvsroot/technology/org.eclipse.emft/validation/plugins/org.eclipse.emf.validation/src/org/eclipse/emf/validation/internal/service/ProviderDescriptor.java,v retrieving revision 1.2 diff -u -r1.2 ProviderDescriptor.java --- src/org/eclipse/emf/validation/internal/service/ProviderDescriptor.java 9 Feb 2006 20:42:04 -0000 1.2 +++ src/org/eclipse/emf/validation/internal/service/ProviderDescriptor.java 22 Nov 2006 15:33:46 -0000 @@ -12,6 +12,7 @@ package org.eclipse.emf.validation.internal.service; +import java.util.Collection; import java.util.Map; import java.util.Set; @@ -19,10 +20,10 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; - import org.eclipse.emf.validation.EMFEventType; import org.eclipse.emf.validation.internal.EMFModelValidationDebugOptions; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; @@ -64,6 +65,22 @@ NullProvider() { super(); } + + @Override + public Collection getBatchConstraints(EObject eObject, Collection constraints) { + return noOp(constraints); + } + + @Override + public Collection getLiveConstraints(Notification notification, Collection constraints) { + return noOp(constraints); + } + + private Collection noOp(Collection constraints) { + return (constraints == null) + ? new java.util.ArrayList() + : constraints; + } } /** Index: src/org/eclipse/emf/validation/service/AbstractConstraintProvider.java =================================================================== RCS file: /cvsroot/technology/org.eclipse.emft/validation/plugins/org.eclipse.emf.validation/src/org/eclipse/emf/validation/service/AbstractConstraintProvider.java,v retrieving revision 1.1 diff -u -r1.1 AbstractConstraintProvider.java --- src/org/eclipse/emf/validation/service/AbstractConstraintProvider.java 27 Oct 2005 17:21:00 -0000 1.1 +++ src/org/eclipse/emf/validation/service/AbstractConstraintProvider.java 22 Nov 2006 15:33:46 -0000 @@ -13,6 +13,9 @@ package org.eclipse.emf.validation.service; import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; import java.util.Set; import org.eclipse.core.runtime.CoreException; @@ -22,10 +25,13 @@ import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; - +import org.eclipse.emf.validation.IValidationContext; +import org.eclipse.emf.validation.internal.EMFModelValidationDebugOptions; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationStatusCodes; +import org.eclipse.emf.validation.internal.util.DisabledConstraint; import org.eclipse.emf.validation.internal.util.Trace; +import org.eclipse.emf.validation.model.IModelConstraint; import org.eclipse.emf.validation.util.XmlConfig; /** @@ -54,6 +60,97 @@ IExecutableExtension { private String[] namespaceUris; + private List myConstraints = java.util.Collections.EMPTY_LIST; + + /** + * A proxy for a lazily instantiated implementation of the + * {@link IModelConstraint} interface. + * + * @author Christian W. Damus (cdamus) + */ + private class ConstraintProxy implements IModelConstraint { + private final IConstraintDescriptor descriptor; + private IModelConstraint delegate = null; + + /** + * Initializes me with the descriptor that I can provide with little + * performance cost. + * + * @param descriptor my descriptor + */ + ConstraintProxy(IConstraintDescriptor descriptor) { + this.descriptor = descriptor; + } + + /* (non-Javadoc) + * Implements the interface method. + */ + public IConstraintDescriptor getDescriptor() { + return descriptor; + } + + /** + * Lazily initializes my delegate constraint before invoking it, + * if necessary. + */ + public IStatus validate(IValidationContext ctx) { + IStatus result; + + if (delegate == null) { + if (Trace.shouldTrace(EMFModelValidationDebugOptions.CONSTRAINTS)) { + Trace.trace( + EMFModelValidationDebugOptions.CONSTRAINTS, + "Initializing constraint delegate: " + descriptor); //$NON-NLS-1$ + } + + // this will throw if the delegate could not be created + delegate = createModelConstraint(descriptor); + } + + try { + if (Trace.shouldTrace(EMFModelValidationDebugOptions.CONSTRAINTS_EVALUATION)) { + Trace.trace( + EMFModelValidationDebugOptions.CONSTRAINTS_EVALUATION, + "Delegating validate() method to: " + delegate //$NON-NLS-1$ + + " for: " + descriptor); //$NON-NLS-1$ + } + + result = delegate.validate(ctx); + } catch (RuntimeException e) { + Trace.catching(getClass(), "validate()", e); //$NON-NLS-1$ + + Trace.trace(EMFModelValidationDebugOptions.CONSTRAINTS_DISABLED, + "Constraint is disabled: " + descriptor); //$NON-NLS-1$ + + // the disabled constraint is a placeholder for the missing + // functionality. It will log a disablement message and + // thereafter be silent + delegate = new DisabledConstraint(descriptor, e); + + // won't throw an exception, this time! + // (the disabled constraint never does; it returns an INFO + // status to report the problem to the user) + result = delegate.validate(ctx); + } + + // replace me with my delegate in the list of constraints, to avoid + // the delegation in future invocations and to free some memory + for (ListIterator iter = getConstraints().listIterator(); + iter.hasNext();) { + + if (iter.next() == this) { + iter.set(delegate); + break; + } + } + + // in case this provider is cached, also replace me in the + // validation service's cache + ModelValidationService.getInstance().replaceInCache(this, delegate); + + return result; + } + } /** Initializes me. */ protected AbstractConstraintProvider() { @@ -61,6 +158,48 @@ } /** + * Creates the model constraint implementation from the descriptor. + *

+ * A meaningful implementation of this method is to be provided by the concrete provider and is + * to be used to initialize its constraints list if it's the intention to initialize actual constraints directly. + * + * @param descriptor the descriptor of the constraint to be created + * @return actual constraint implementation + */ + protected IModelConstraint createModelConstraint(IConstraintDescriptor descriptor) { + // Remark: + // Perhaps, this method should not be provider specific, but currently the only available factory + // ConstraintFactory.getInstance().newConstraint(..) takes only IXmlConstraintDescriptor + // + // It is not made abstract not to break existing unittest mock providers + throw new UnsupportedOperationException(); + } + + /** + * Creates a contraint proxy which lazily initializes the actual + * constraint implementation represented by the given descriptor. + *

+ * This method is to be used by the concrete provider to initialize its constraints list if + * it's the intention to initialize the actual constraints lazily. + * + * @param descriptor the descriptor of the constraint for which a proxy is to be created + * @return a proxy for the actual constraint implementation + */ + protected final IModelConstraint createModelConstraintProxy(IConstraintDescriptor descriptor) { + return new ConstraintProxy(descriptor); + } + + /** + * Obtains my constraints. + * + * @return a list of constraints + */ + protected List getConstraints() { + return myConstraints; + } + + + /** * Obtains the namespace URIs of the EMF packages that I provide constraints * for. * @@ -117,40 +256,76 @@ } namespaceUris = (String[]) uris.toArray(new String[uris.size()]); + this.myConstraints = new java.util.ArrayList(); } - /** - * This is a no-op implementation. Subclasses that need to implement it - * should redefine this method. There is no need to call - * super. - */ - public Collection getBatchConstraints( - EObject eObject, - Collection constraints) { - return noOp(constraints); - } - - /** - * This is a no-op implementation. Subclasses that need to implement it - * should redefine this method. There is no need to call - * super. - */ + // implements the provider interface public Collection getLiveConstraints( Notification notification, Collection constraints) { - return noOp(constraints); + + assert notification != null; + + if (Trace.shouldTraceEntering(EMFModelValidationDebugOptions.PROVIDERS)) { + Trace.entering(getClass(), "getLiveConstraints"); //$NON-NLS-1$ + } + + Collection result = constraints; + + if (result == null) { + result = new java.util.ArrayList(); + } + + if (notification.getNotifier() instanceof EObject) { + EObject eObject = (EObject)notification.getNotifier(); + + for (Iterator iter = getConstraints().iterator(); iter.hasNext(); ) { + IModelConstraint next = (IModelConstraint)iter.next(); + IConstraintDescriptor desc = next.getDescriptor(); + + if (desc.isLive() && desc.targetsTypeOf(eObject) + && desc.targetsEvent(notification)) { + result.add(next); + } + } + } + + if (Trace.shouldTraceExiting(EMFModelValidationDebugOptions.PROVIDERS)) { + Trace.exiting(getClass(), "getLiveConstraints"); //$NON-NLS-1$ + } + + return result; } + - /** - * Helper to implement the no-op methods. - * - * @param constraints the constraints passed to the provider method - * @return constraints if it is not null; - * a new modifiable collection, otherwise - */ - private Collection noOp(Collection constraints) { - return (constraints == null) - ? new java.util.ArrayList() - : constraints; + // implements the provider interface + public Collection getBatchConstraints( + EObject eObject, + Collection constraints) { + + if (Trace.shouldTraceEntering(EMFModelValidationDebugOptions.PROVIDERS)) { + Trace.entering(getClass(), "getBatchConstraints"); //$NON-NLS-1$ + } + + Collection result = constraints; + + if (result == null) { + result = new java.util.ArrayList(); + } + + for (Iterator iter = getConstraints().iterator(); iter.hasNext(); ) { + IModelConstraint next = (IModelConstraint)iter.next(); + IConstraintDescriptor desc = next.getDescriptor(); + + if (desc.isBatch() && desc.targetsTypeOf(eObject)) { + result.add(next); + } + } + + if (Trace.shouldTraceExiting(EMFModelValidationDebugOptions.PROVIDERS)) { + Trace.exiting(getClass(), "getBatchConstraints"); //$NON-NLS-1$ + } + + return result; } } Index: src/org/eclipse/emf/validation/xml/XmlConstraintProvider.java =================================================================== RCS file: /cvsroot/technology/org.eclipse.emft/validation/plugins/org.eclipse.emf.validation/src/org/eclipse/emf/validation/xml/XmlConstraintProvider.java,v retrieving revision 1.2 diff -u -r1.2 XmlConstraintProvider.java --- src/org/eclipse/emf/validation/xml/XmlConstraintProvider.java 22 Feb 2006 21:52:45 -0000 1.2 +++ src/org/eclipse/emf/validation/xml/XmlConstraintProvider.java 22 Nov 2006 15:33:46 -0000 @@ -12,23 +12,13 @@ package org.eclipse.emf.validation.xml; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.validation.IValidationContext; import org.eclipse.emf.validation.internal.EMFModelValidationDebugOptions; import org.eclipse.emf.validation.internal.EMFModelValidationPlugin; import org.eclipse.emf.validation.internal.EMFModelValidationStatusCodes; import org.eclipse.emf.validation.internal.l10n.ValidationMessages; -import org.eclipse.emf.validation.internal.util.DisabledConstraint; import org.eclipse.emf.validation.internal.util.Log; import org.eclipse.emf.validation.internal.util.Trace; import org.eclipse.emf.validation.internal.util.XmlConfigurationElement; @@ -39,7 +29,6 @@ import org.eclipse.emf.validation.service.ConstraintFactory; import org.eclipse.emf.validation.service.ConstraintRegistry; import org.eclipse.emf.validation.service.IConstraintDescriptor; -import org.eclipse.emf.validation.service.ModelValidationService; import org.eclipse.emf.validation.util.XmlConfig; /** @@ -89,99 +78,6 @@ */ static final String UNKNOWN_FILE = ValidationMessages.xml_unknown_file; - private List myConstraints = java.util.Collections.EMPTY_LIST; - - /** - * A proxy for a lazily instantiated implementation of the - * {@link IModelConstraint} interface. - * - * @author Christian W. Damus (cdamus) - */ - private class ConstraintProxy implements IModelConstraint { - private final IXmlConstraintDescriptor descriptor; - private IModelConstraint delegate = null; - - /** - * Initializes me with the descriptor that I can provide with little - * performance cost. - * - * @param descriptor my descriptor - */ - ConstraintProxy(IXmlConstraintDescriptor descriptor) { - this.descriptor = descriptor; - } - - /* (non-Javadoc) - * Implements the interface method. - */ - public IConstraintDescriptor getDescriptor() { - return descriptor; - } - - /** - * Lazily initializes my delegate constraint before invoking it, - * if necessary. - */ - public IStatus validate(IValidationContext ctx) { - IStatus result; - - if (delegate == null) { - if (Trace.shouldTrace(EMFModelValidationDebugOptions.CONSTRAINTS)) { - Trace.trace( - EMFModelValidationDebugOptions.CONSTRAINTS, - "Initializing constraint delegate: " + descriptor); //$NON-NLS-1$ - } - - // this will throw if the delegate could not be created - delegate = ConstraintFactory.getInstance() - .newConstraint(descriptor); - } - - try { - if (Trace.shouldTrace(EMFModelValidationDebugOptions.CONSTRAINTS_EVALUATION)) { - Trace.trace( - EMFModelValidationDebugOptions.CONSTRAINTS_EVALUATION, - "Delegating validate() method to: " + delegate //$NON-NLS-1$ - + " for: " + descriptor); //$NON-NLS-1$ - } - - result = delegate.validate(ctx); - } catch (RuntimeException e) { - Trace.catching(getClass(), "validate()", e); //$NON-NLS-1$ - - Trace.trace(EMFModelValidationDebugOptions.CONSTRAINTS_DISABLED, - "Constraint is disabled: " + descriptor); //$NON-NLS-1$ - - // the disabled constraint is a placeholder for the missing - // functionality. It will log a disablement message and - // thereafter be silent - delegate = new DisabledConstraint(descriptor, e); - - // won't throw an exception, this time! - // (the disabled constraint never does; it returns an INFO - // status to report the problem to the user) - result = delegate.validate(ctx); - } - - // replace me with my delegate in the list of constraints, to avoid - // the delegation in future invocations and to free some memory - for (ListIterator iter = getConstraints().listIterator(); - iter.hasNext();) { - - if (iter.next() == this) { - iter.set(delegate); - break; - } - } - - // in case this provider is cached, also replace me in the - // validation service's cache - ModelValidationService.getInstance().replaceInCache(this, delegate); - - return result; - } - } - /** * Extends the inherited method to configure myself with my meta-data of * one or more constraints. @@ -198,8 +94,6 @@ IConfigurationElement[] constraintses = config.getChildren( XmlConfig.E_CONSTRAINTS); - - this.myConstraints = new java.util.ArrayList(); for (int i = 0; i < constraintses.length; i++) { IConfigurationElement next = @@ -215,85 +109,12 @@ XmlConfig.flushResourceBundles(); } - // implements the provider interface - public Collection getLiveConstraints( - Notification notification, - Collection constraints) { - - assert notification != null; - - if (Trace.shouldTraceEntering(EMFModelValidationDebugOptions.PROVIDERS)) { - Trace.entering(getClass(), "getLiveConstraints"); //$NON-NLS-1$ - } - - Collection result = constraints; - - if (result == null) { - result = new java.util.ArrayList(); - } - - if (notification.getNotifier() instanceof EObject) { - EObject eObject = (EObject)notification.getNotifier(); - - for (Iterator iter = getConstraints().iterator(); iter.hasNext(); ) { - IModelConstraint next = (IModelConstraint)iter.next(); - IConstraintDescriptor desc = next.getDescriptor(); - - if (desc.isLive() && desc.targetsTypeOf(eObject) - && desc.targetsEvent(notification)) { - result.add(next); - } - } - } - - if (Trace.shouldTraceExiting(EMFModelValidationDebugOptions.PROVIDERS)) { - Trace.exiting(getClass(), "getLiveConstraints"); //$NON-NLS-1$ - } - - return result; + @Override + protected IModelConstraint createModelConstraint(IConstraintDescriptor descriptor) { + assert descriptor instanceof IXmlConstraintDescriptor; + return ConstraintFactory.getInstance().newConstraint((IXmlConstraintDescriptor)descriptor); } - - // implements the provider interface - public Collection getBatchConstraints( - EObject eObject, - Collection constraints) { - - if (Trace.shouldTraceEntering(EMFModelValidationDebugOptions.PROVIDERS)) { - Trace.entering(getClass(), "getBatchConstraints"); //$NON-NLS-1$ - } - - Collection result = constraints; - - if (result == null) { - result = new java.util.ArrayList(); - } - - for (Iterator iter = getConstraints().iterator(); iter.hasNext(); ) { - IModelConstraint next = (IModelConstraint)iter.next(); - IConstraintDescriptor desc = next.getDescriptor(); - - if (desc.isBatch() && desc.targetsTypeOf(eObject)) { - result.add(next); - } - } - - if (Trace.shouldTraceExiting(EMFModelValidationDebugOptions.PROVIDERS)) { - Trace.exiting(getClass(), "getBatchConstraints"); //$NON-NLS-1$ - } - - return result; - } - - /** - * Obtains my constraint proxies which lazily initialize the actual - * constraint implementations. - * - * @return a list of constraint proxies - */ - protected List getConstraints() { - return myConstraints; - } - + /** * Adds a constraint to my collection, constructed from the specified XML * content. @@ -351,7 +172,7 @@ xmlConstraint.resolveTargetTypes(getNamespaceUris()); - IModelConstraint proxy = new ConstraintProxy(xmlConstraint); + IModelConstraint proxy = createModelConstraintProxy(xmlConstraint); getConstraints().add(proxy);