001: /**
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use,
007: * modify and/or redistribute the software under the terms of the
008: * CeCILL-C
009: * license as circulated by CEA, CNRS and INRIA at the following URL:
010: * http://www.cecill.info.
011: *
012: * This program is distributed in the hope that it will be useful, but
013: * WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C
015: * License for more details.
016: *
017: * The fact that you are presently reading this means that you have had
018: * knowledge of the CeCILL-C license and that you accept its terms.
019: */package spoon.aval.processing;
020:
021: import java.lang.annotation.Annotation;
022: import java.util.Collection;
023:
024: import spoon.aval.Validator;
025: import spoon.aval.annotation.Implementation;
026: import spoon.processing.AbstractProcessor;
027: import spoon.processing.Property;
028: import spoon.reflect.declaration.CtAnnotation;
029: import spoon.reflect.declaration.CtElement;
030: import spoon.reflect.declaration.CtPackage;
031: import spoon.reflect.reference.CtFieldReference;
032: import spoon.reflect.reference.CtReference;
033: import spoon.reflect.reference.CtTypeReference;
034:
035: /**
036: * Spoon processor that analyses a program and executes the
037: *
038: * @Validators it finds. By default, if any validator reports an error, all
039: * further processing (like code generation) will be skiped.
040: *
041: * The processor passes though all CtElements in the model. For each element,
042: * it:
043: *
044: * <ol>
045: * <li> processes all the annotations of the CtElement.
046: * <li> processes all the meta-annotations (@Validators).
047: * <li> for each @Validator, it creates an instance of its implementation,
048: * and constructs the corresponding
049: * {@link spoon.aval.processing.ValidationPoint}
050: * <li> it invokes the check method on the @Validator's implementation.
051: * </ol>
052: *
053: * @see spoon.aval.Validator
054: * @see spoon.aval.processing.ValidationPoint
055: */
056: public class AValProcessor extends AbstractProcessor<CtElement> {
057:
058: @Property
059: static public boolean stopOnErrors = true;
060:
061: /**
062: * Main Validation processing method. Invoked by Spoon.
063: */
064: public void process(CtElement element) {
065:
066: if (element.getParent(CtPackage.class) == null) {
067: return;
068: }
069:
070: for (CtAnnotation dslAnn : element.getAnnotations()) {
071: processValidators(element, dslAnn);
072: }
073: }
074:
075: @SuppressWarnings("unchecked")
076: private void processValidators(CtElement element,
077: CtAnnotation dslAnn) {
078:
079: CtTypeReference annotationType = dslAnn.getAnnotationType();
080: Annotation[] annotations = annotationType.getAnnotations();
081:
082: for (Annotation annotation : annotations) {
083: CtTypeReference<?> ref = getFactory().Type()
084: .createReference(annotation.annotationType());
085: Implementation sv = ref.getAnnotation(Implementation.class);
086: if (sv == null || ref == null)
087: continue;
088: invokeValidator(sv.value(), element, annotation, dslAnn,
089: ref);
090:
091: }
092:
093: Collection<CtFieldReference> dslB = annotationType
094: .getDeclaredFields();
095: for (CtFieldReference reference : dslB) {
096: Annotation[] anns = reference.getAnnotations();
097: if (anns == null)
098: continue;
099: for (Annotation annotation : anns) {
100: CtTypeReference<?> ref = getFactory().Type()
101: .createReference(annotation.annotationType());
102: Implementation sv = ref
103: .getAnnotation(Implementation.class);
104: if (sv == null || ref == null)
105: continue;
106: invokeValidator(sv.value(), element, annotation,
107: dslAnn, reference);
108: }
109: }
110: }
111:
112: @SuppressWarnings("unchecked")
113: private void invokeValidator(Class<? extends Validator> validator,
114: CtElement element, Annotation annotation,
115: CtAnnotation dslAnn, CtReference reference) {
116:
117: try {
118: Validator validatorInstance = validator.newInstance();
119: ValidationPoint vp = new ValidationPoint(element, dslAnn,
120: reference, annotation);
121: validatorInstance.check(vp);
122:
123: } catch (InstantiationException e) {
124: e.printStackTrace();
125: } catch (IllegalAccessException e) {
126: e.printStackTrace();
127: }
128:
129: }
130:
131: @Override
132: public void processingDone() {
133: super .processingDone();
134: // if (stopOnErrors) {
135: // getFactory().getEnvironment().setProcessingStopped(
136: // ValidationPoint.shouldStopProcessing());
137: // }
138: }
139:
140: @Override
141: public void init() {
142: super.init();
143: ValidationPoint.resetShouldStopFlag();
144: }
145:
146: }
|