01: /**
02: * Spoon - http://spoon.gforge.inria.fr/
03: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
04: *
05: * This software is governed by the CeCILL-C License under French law and
06: * abiding by the rules of distribution of free software. You can use,
07: * modify and/or redistribute the software under the terms of the
08: * CeCILL-C
09: * license as circulated by CEA, CNRS and INRIA at the following URL:
10: * http://www.cecill.info.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C
15: * License for more details.
16: *
17: * The fact that you are presently reading this means that you have had
18: * knowledge of the CeCILL-C license and that you accept its terms.
19: */package spoon.aval.support.validator;
20:
21: import java.util.HashMap;
22: import java.util.Map;
23:
24: import spoon.aval.Validator;
25: import spoon.aval.annotation.value.Unique;
26: import spoon.aval.processing.AValProcessor;
27: import spoon.aval.processing.ValidationPoint;
28: import spoon.reflect.declaration.CtAnnotation;
29: import spoon.reflect.declaration.CtElement;
30: import spoon.reflect.reference.CtFieldReference;
31:
32: /**
33: * Implements the {@link Unique} validator.
34: *
35: *<p>
36: * This class implements the {@link Unique} validator. It
37: * traverses the complete metamodel checking for CtElements that are
38: * annotated with the same annotation as the one in the current validation point.
39: * If the @Unique attribute has the same value in at least two annotations, an ERROR
40: * is reported.
41: * <p>
42: * To avoid unnecesary (and maybe costly) traversals of the model, a cache is kept with
43: * the annotations and values found during the first traversal of the model.
44: */
45: public class UniqueValueValidator implements Validator<Unique> {
46:
47: static private Map<Object, CtAnnotation> cache = new HashMap<Object, CtAnnotation>();
48: static private CtElement scope = null;
49:
50: /**
51: * Implementation of the Validator interface. Called by {@link AValProcessor}
52: */
53: public void check(ValidationPoint<Unique> vp) {
54: String attribName = ((CtFieldReference) vp.getDslElement())
55: .getSimpleName();
56: Object value = vp.getDslAnnotation()
57: .getElementValue(attribName);
58:
59: Class<? extends CtElement> dScope = vp.getValAnnotation()
60: .scope();
61: if (!dScope.equals(CtElement.class)) {
62: CtElement _scope = vp.getProgramElement().getParent(dScope);
63: if (!_scope.equals(scope)) {
64: scope = _scope;
65: cache.clear();
66: }
67: }
68:
69: if ((cache.get(value)) != null) {
70: CtAnnotation dslAnnotation = vp.getDslAnnotation();
71:
72: String message = vp.getValAnnotation().message().replace(
73: "?val", value.toString());
74: ValidationPoint.report(vp.getValAnnotation().severity(),
75: dslAnnotation, message, vp.fixerFactory(vp
76: .getValAnnotation().fixers()));
77: }
78: cache.put(value, vp.getDslAnnotation());
79: }
80:
81: }
|