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.List;
023:
024: import spoon.aval.annotation.ReplacesAnnotationInPackage;
025: import spoon.processing.AbstractManualProcessor;
026: import spoon.processing.Property;
027: import spoon.processing.Severity;
028: import spoon.reflect.Factory;
029: import spoon.reflect.declaration.CtAnnotation;
030: import spoon.reflect.declaration.CtAnnotationType;
031: import spoon.reflect.declaration.CtPackage;
032: import spoon.reflect.visitor.Filter;
033: import spoon.reflect.visitor.Query;
034: import spoon.reflect.visitor.filter.AnnotationFilter;
035:
036: /**
037: * Processes dummy implementations of external validated annotations.
038: * <p>
039: * Processes Annotation types that are annotated with
040: * {@link ReplacesAnnotationInPackage}. These annotations are used to
041: * @Validate annotations for which the source code is not available.
042: *
043: */
044: public class DummyPreProcessor extends AbstractManualProcessor {
045:
046: /**
047: * Property that contains the names of the packages in which the dummies are
048: * located.
049: */
050: @Property
051: String[] packs;
052:
053: @Override
054: public void init() {
055: super .init();
056: }
057:
058: /**
059: * Processes the dummy packages as defined by
060: * {@link DummyPreProcessor#packs}.
061: * <p>
062: * This method is upcalled by spoon.
063: */
064: public void process() {
065:
066: Factory fac = getFactory();
067: if (packs == null) {
068: List<CtAnnotationType<? extends Annotation>> types = Query
069: .getElements(
070: fac,
071: new Filter<CtAnnotationType<? extends Annotation>>() {
072:
073: @SuppressWarnings("unchecked")
074: public Class<CtAnnotationType<? extends Annotation>> getType() {
075: // TODO Auto-generated method stub
076: return (Class) CtAnnotationType.class;
077: }
078:
079: public boolean matches(
080: CtAnnotationType<? extends Annotation> element) {
081: return element
082: .getAnnotation(ReplacesAnnotationInPackage.class) != null;
083: }
084:
085: });
086:
087: for (CtAnnotationType<? extends Annotation> type : types) {
088: replaceAnnotationImpl(fac, type);
089: }
090: } else {
091: for (String packag : packs) {
092: processDummyPackage(fac, packag);
093: }
094: }
095: }
096:
097: private void processDummyPackage(Factory fac, String packag) {
098: List<CtAnnotationType<? extends Annotation>> dummys = getPackages(
099: fac, packag);
100:
101: for (CtAnnotationType<? extends Annotation> type : dummys) {
102: replaceAnnotationImpl(fac, type);
103: }
104: }
105:
106: private void replaceAnnotationImpl(Factory fac,
107: CtAnnotationType<? extends Annotation> type) {
108: CtAnnotation<ReplacesAnnotationInPackage> rep = type
109: .getAnnotation(fac.Type().createReference(
110: ReplacesAnnotationInPackage.class));
111: String repPackName = (String) rep.getElementValue("value");
112: CtPackage repPack = fac.Package().get(repPackName);
113: if (repPack == null) {
114: fac.getEnvironment().report(
115: this ,
116: Severity.MESSAGE,
117: rep,
118: "Replaces annotation refers to unknown package "
119: + repPackName);
120: repPack = fac.Package().getOrCreate(repPackName);
121: }
122: type.getParent(CtPackage.class).getTypes().remove(type);
123: repPack.getTypes().add(type);
124: type.setParent(repPack);
125: // fac.Package().registerPackage(pck)
126: }
127:
128: private List<CtAnnotationType<? extends Annotation>> getPackages(
129: Factory fac, String packag) {
130: CtPackage dummyP = fac.Package().get(packag);
131: List<CtAnnotationType<? extends Annotation>> dummys = Query
132: .getElements(
133: dummyP,
134: new AnnotationFilter<CtAnnotationType<? extends Annotation>>(
135: ReplacesAnnotationInPackage.class));
136: return dummys;
137: }
138: }
|