KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > dispatch > ProcessorInfo


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 BEA Systems, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.internal.compiler.apt.dispatch;
14
15 import java.util.Iterator JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.regex.Matcher JavaDoc;
18 import java.util.regex.Pattern JavaDoc;
19
20 import javax.annotation.processing.Processor;
21 import javax.lang.model.SourceVersion;
22 import javax.lang.model.element.TypeElement;
23
24 /**
25  * Cached information associated with a {@link Processor} in the context
26  * of annotation processor dispatch.
27  * <p>
28  * This class supports inclusion in a collection by implementing
29  * equals() and hashCode(). Its concept of identity is based on
30  * the class object of the Processor that it wraps; so, for instance,
31  * it is not possible to have a Set that contains more than one
32  * instance of a particular Processor class. In fact, it is possible
33  * to have more than one instance of a Processor if there are multiple
34  * build threads, but within the context of a particular dispatch
35  * manager, there will only be one of any given Processor class.
36  */

37 public class ProcessorInfo {
38     final Processor _processor;
39     final Set JavaDoc<String JavaDoc> _supportedOptions;
40     final SourceVersion _supportedSourceVersion;
41
42     private final Pattern JavaDoc _supportedAnnotationTypesPattern;
43     private final boolean _supportsStar;
44     private boolean _hasBeenCalled;
45
46     /**
47      * Create a ProcessorInfo wrapping a particular Processor. The Processor must already have been
48      * initialized (that is,
49      * {@link Processor#init(javax.annotation.processing.ProcessingEnvironment)} must already have
50      * been called). Its getSupportedXXX() methods will be called and the results will be cached.
51      */

52     public ProcessorInfo(Processor p)
53     {
54         _processor = p;
55         _hasBeenCalled = false;
56         _supportedSourceVersion = p.getSupportedSourceVersion();
57         _supportedOptions = p.getSupportedOptions();
58         Set JavaDoc<String JavaDoc> supportedAnnotationTypes = p.getSupportedAnnotationTypes();
59         
60         boolean supportsStar = false;
61         if (null != supportedAnnotationTypes && !supportedAnnotationTypes.isEmpty()) {
62             StringBuilder JavaDoc regex = new StringBuilder JavaDoc();
63             Iterator JavaDoc<String JavaDoc> iName = supportedAnnotationTypes.iterator();
64             while (true) {
65                 String JavaDoc name = iName.next();
66                 supportsStar |= "*".equals(name); //$NON-NLS-1$
67
String JavaDoc escapedName1 = name.replace(".", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
68
String JavaDoc escapedName2 = escapedName1.replace("*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
69
regex.append(escapedName2);
70                 if (!iName.hasNext()) {
71                     break;
72                 }
73                 regex.append('|');
74             }
75             _supportedAnnotationTypesPattern = Pattern.compile(regex.toString());
76         }
77         else {
78             _supportedAnnotationTypesPattern = null;
79         }
80         _supportsStar = supportsStar;
81     }
82     
83     /**
84      * Compute the subset of <code>annotations</code> that are described by <code>annotationTypes</code>,
85      * and determine whether the processor should be called. A processor will be called if it has
86      * any annotations to process, or if it supports "*", or if it was called in a previous round.
87      * If the return value of this method is true once for a given processor, then it will always be true on
88      * subsequent calls.
89      *
90      * @param annotations a set of annotation types
91      * @param annotationTypes a set of names, which may use the wildcard "*", as described in
92      * {@link Processor#getSupportedAnnotationTypes()}.
93      * @param result an empty modifiable set, which upon return will contain a subset of <code>annotations</code>, which may be empty but will not be null.
94      * @return true if the processor should be called on this round.
95      */

96     public boolean computeSupportedAnnotations(Set JavaDoc<TypeElement> annotations, Set JavaDoc<TypeElement> result)
97     {
98         if (null != annotations && !annotations.isEmpty() && null != _supportedAnnotationTypesPattern) {
99             for (TypeElement annotation : annotations) {
100                 Matcher JavaDoc matcher = _supportedAnnotationTypesPattern.matcher(annotation.getQualifiedName().toString());
101                 if (matcher.matches()) {
102                     result.add(annotation);
103                 }
104             }
105         }
106         boolean call = _hasBeenCalled || _supportsStar || !result.isEmpty();
107         _hasBeenCalled |= call;
108         return call;
109     }
110
111     /**
112      * @return true if the processor included "*" among its list of supported annotations.
113      */

114     public boolean supportsStar()
115     {
116         return _supportsStar;
117     }
118     
119     /**
120      * Must be called at the beginning of a build to ensure that no information is
121      * carried over from the previous build. In particular, processors are
122      * required to be called on every round after the round in which they are
123      * first called; this method resets the "has been called" flag.
124      */

125     public void reset()
126     {
127         _hasBeenCalled = false;
128     }
129
130     @Override JavaDoc
131     public int hashCode() {
132         return _processor.getClass().hashCode();
133     }
134
135     @Override JavaDoc
136     public boolean equals(Object JavaDoc obj) {
137         if (this == obj)
138             return true;
139         if (obj == null)
140             return false;
141         if (getClass() != obj.getClass())
142             return false;
143         final ProcessorInfo other = (ProcessorInfo) obj;
144         if (!_processor.getClass().equals(other._processor.getClass()))
145             return false;
146         return true;
147     }
148
149     @Override JavaDoc
150     public String JavaDoc toString()
151     {
152         return _processor.getClass().getName();
153     }
154     
155     /**
156      * @return a string representing the set of supported annotation types, in a format
157      * suitable for debugging. The format is unspecified and subject to change.
158      */

159     public String JavaDoc getSupportedAnnotationTypesAsString()
160     {
161         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
162         sb.append('[');
163         Iterator JavaDoc<String JavaDoc> iAnnots = _processor.getSupportedAnnotationTypes().iterator();
164         boolean hasNext = iAnnots.hasNext();
165         while (hasNext) {
166             sb.append(iAnnots.next());
167             hasNext = iAnnots.hasNext();
168             if (hasNext) {
169                 sb.append(',');
170             }
171         }
172         sb.append(']');
173         return sb.toString();
174     }
175 }
176
177
Popular Tags