We
need to make that decision on which validation method to move forward
with.
EMF Validation or JDT-APT.
WTP
3.2.0 M6 is API and UI freeze.
So
I'd like to get this done as soon as possible to enable any changes
to extension points, dependencies, unit tests, adding more rules
etc..
In
an effort to move the discussion along lets take a look at the
validation options from an end-users perspective.
Let's say
for arguments sake that an end-user wants to add a validation rule
that reports an error when the 'portName' attribute of the
javax.jws.WebService annotation is a certain value e.g.
'eclipse'.
What do they have to do to 'plug-in' to each of the
validation mechanisms that we currently have. In the least number of
steps.
Danail
if i've stated anything that's wrong below about the WST/EMF
Validation mechanism please correct me.
For
JDT-APT.
Create
a plug-in project. Add the org.eclipse.jst.ws.annotations.core,
org.eclipse.jdt.apt.core
and org.eclipse.jdt.core
dependencies.
Add
an extension to the
org.eclipse.jst.ws.annotations.core.annotationProcessor
extension point.
<extension
point="org.eclipse.jst.ws.annotations.core.annotationProcessor">
<processor
annotation="javax.jws.WebService"
class="com.example.ValidatePortName">
<description>
Validate
a WebService portName attribute
</description>
</processor>
<extension>
2.
Provide
a class that extends
org.eclipse.jst.ws.annotations.core.processor.AbstractAnnotationProcessor
and implement the process() method.
import
org.eclipse.jst.ws.annotations.core.processor.AbstractAnnotationProcessor;
import
org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import
com.sun.mirror.declaration.AnnotationMirror;
import
com.sun.mirror.declaration.AnnotationTypeDeclaration;
import
com.sun.mirror.declaration.AnnotationValue;
import
com.sun.mirror.declaration.Declaration;
public
class
ValidatePortName extends
AbstractAnnotationProcessor {
@Override
public
void
process() {
AnnotationTypeDeclaration
annotationDeclaration = (AnnotationTypeDeclaration) environment
.getTypeDeclaration(javax.jws.WebService.class.getName());
Collection<Declaration>
annotatedTypes = environment.getDeclarationsAnnotatedWith(annotationDeclaration);
for
(Declaration declaration : annotatedTypes) {
AnnotationMirror
webService = AnnotationUtils.getAnnotation(declaration,
javax.jws.WebService.class);
AnnotationValue
name = AnnotationUtils.getAnnotationValue(webService,
"portName");
if
(name.getValue().equals("eclipse"))
{
printError(name.getPosition(),
"An
informative error message");
}
}
}
}
For
WST/EMF-Validation:
We
can use the JAX-WS DOM model and the existing
org.eclipse.jst.ws.jaxws.dom.runtime.validation.JaxWsDomValidator.
Create
a plug-in project. Add the org.eclipse.jst.ws.jaxws.dom.runtime,
org.eclipse.emf.validation
and org.eclipse.jdt.core
dependencies.
Provide
an extension to the org.eclipse.emf.validation.constraintProviders
extension point.
<extension
point="org.eclipse.emf.validation.constraintProviders">
<constraintProvider
cache="true"
class="org.example.ValidationConstraintProvider">
<package
namespaceUri="http:///org/eclipse/jst/ws/jaxws/dom/runtime/dom.ecore"/>
</constraintProvider>
</extension>
3.
Provide a class that implements the
org.eclipse.emf.validation.service.IModelConstraintProvider interface that returns the constraint.
import
org.eclipse.emf.common.notify.Notification;
import
org.eclipse.emf.ecore.EObject;
import
org.eclipse.emf.validation.model.IModelConstraint;
import
org.eclipse.emf.validation.service.IModelConstraintProvider;
import
org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebService;
import
org.eclipse.jst.ws.jaxws.dom.runtime.util.DomSwitch;
public
class
ValidationConstraintProvider implements
IModelConstraintProvider {
private
final
DomSwitch<Collection<IModelConstraint>> domSwitch;
public
ValidationConstraintProvider() {
domSwitch
= createDomSwitch();
}
@SuppressWarnings("unchecked")
public
Collection getBatchConstraints(EObject eObject, Collection
constraints) {
Collection<IModelConstraint> modelConstraints =
domSwitch.doSwitch(eObject);
if
(modelConstraints != null)
{
constraints.addAll(modelConstraints);
}
return
constraints;
}
@SuppressWarnings("unchecked")
public
Collection getLiveConstraints(Notification arg0, Collection
constraints) {
return
constraints;
}
private
DomSwitch<Collection<IModelConstraint>> createDomSwitch()
{
return
new
DomSwitch<Collection<IModelConstraint>>() {
@Override
public
Collection<IModelConstraint> caseIWebService(IWebService
object) {
Set<IModelConstraint>
constraints = new
HashSet<IModelConstraint>();
constraints.add(new
ValidationConstraint());
return
constraints;
}
};
}
}
4.
Code the constraint that contains the validation logic:
import
org.eclipse.core.runtime.CoreException;
import
org.eclipse.core.runtime.IStatus;
import
org.eclipse.emf.validation.IValidationContext;
import
org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebService;
import
org.eclipse.jst.ws.jaxws.dom.runtime.validation.AbstractValidationConstraint;
public
class
ValidationConstraint extends
AbstractValidationConstraint {
public
ValidationConstraint() {
super(new
ValidationConstraintDescriptor());
}
@Override
protected
IStatus doValidate(IValidationContext ctx) throws
CoreException {
IWebService webService =
(IWebService) ctx.getTarget();
if
(webService.getPortName().equals("eclipse"))
{
return
createStatus(webService, "another
informative message",
"javax.jws.WebService",
"portName");
}
return
createOkStatus(webService);
}
}
5.
We'll also need a descriptor to describe the problem.
import
org.eclipse.emf.validation.model.ConstraintSeverity;
import
org.eclipse.jst.ws.jaxws.dom.runtime.validation.DomValidationConstraintDescriptor;
public
class
ValidationConstraintDescriptor extends
DomValidationConstraintDescriptor {
public
String getId() {
return
"validation.constraint";
}
public
String getPluginId() {
return
Activator.PLUGIN_ID;
}
public
ConstraintSeverity getSeverity() {
return
ConstraintSeverity.ERROR;
}
public
int
getStatusCode() {
return
-99;
}
}
That's
a lot of overhead to add one constraint . Granted the above
ValidationConstraintProvider
and
ValidationConstraintDescriptor
can be resued, added to when adding more constraints to your plug-in.
Questions:
Using
WST/EMF Validation If we want to provide rules for non-modeled
objects e.g. javax.xml.ws.WebServiceProvider
what's the best way to do that?
Using
the exisitng org.eclipse.jst.ws.jaxws.dom.runtime.domruntimes
extension the WST/EMF Validation and the JAX-WS Web Services nodes
in the Project Explorer are currently tied to jst.web 2.5 projects.
What would we have to do to make both available for jst.web 2.4
projects? Provide another extension point for 2.4 projects?
Thanks,
Shane
Hotmail: Powerful Free email with security by Microsoft. Get it now.
|