KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > jpa > conf > AnnotationProcessorFactory


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20
21 package org.apache.cayenne.jpa.conf;
22
23 import java.lang.annotation.Annotation JavaDoc;
24 import java.lang.reflect.AnnotatedElement JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Map JavaDoc;
27
28 /**
29  * A factory for annotation processors. Concrete subclasses can simply define inner
30  * classes for the each type of annotation processors they support.
31  * {@link #createProcessor(String)} method will use naming conventions to determine the
32  * type of the processor.
33  *
34  * @author Andrus Adamchik
35  */

36 abstract class AnnotationProcessorFactory {
37
38     static final String JavaDoc ANNOTATIONS_PACKAGE = "javax.persistence.";
39     static final String JavaDoc PROCESSOR_NAME_SUFFIX = "Processor";
40     static final AnnotationProcessor NOOP_PROCESSOR = new AnnotationProcessor() {
41
42         public void onFinishElement(
43                 AnnotatedElement JavaDoc element,
44                 AnnotationProcessorStack context) {
45         }
46
47         public void onStartElement(
48                 AnnotatedElement JavaDoc element,
49                 AnnotationProcessorStack context) {
50         }
51     };
52
53     /**
54      * Dervies processor inner class name, applying naming conventions.
55      */

56     static Class JavaDoc processorClass(Class JavaDoc factoryClass, String JavaDoc annotationFQN) {
57         if (annotationFQN.startsWith(ANNOTATIONS_PACKAGE)) {
58
59             // derive the processor name from the annotation unqualified name, so that we
60
// do not have to configure the processors manually
61

62             // assume that the processor class is an inner class of a concrete factory...
63

64             String JavaDoc processorName = factoryClass.getName()
65                     + "$"
66                     + annotationFQN.substring(ANNOTATIONS_PACKAGE.length())
67                     + PROCESSOR_NAME_SUFFIX;
68
69             try {
70                 return Class.forName(processorName, true, Thread
71                         .currentThread()
72                         .getContextClassLoader());
73
74             }
75             catch (Exception JavaDoc e) {
76                 // there are a few unsupported annotations in the JPA package related
77
// to Java EE conatiners
78
return null;
79             }
80         }
81         else {
82             return null;
83         }
84
85     }
86
87     /**
88      * Returns an annotation class handled by the processor, applying naming conventions.
89      */

90     static Class JavaDoc annotationClass(Class JavaDoc processorClass) {
91         String JavaDoc name = processorClass.getName();
92         if (!name.endsWith(PROCESSOR_NAME_SUFFIX)) {
93             return null;
94         }
95
96         int split = name.lastIndexOf('$');
97         if (split <= 0) {
98             return null;
99         }
100
101         String JavaDoc className = name.substring(split + 1);
102         String JavaDoc annotationFQN = ANNOTATIONS_PACKAGE
103                 + className.substring(0, className.length()
104                         - PROCESSOR_NAME_SUFFIX.length());
105
106         try {
107             return Class.forName(annotationFQN, true, Thread
108                     .currentThread()
109                     .getContextClassLoader());
110
111         }
112         catch (Exception JavaDoc e) {
113             // there are a few unsupported annotations in the JPA package related
114
// to Java EE conatiners
115
return null;
116         }
117     }
118
119     final Map JavaDoc<String JavaDoc, AnnotationProcessor> processors;
120
121     AnnotationProcessorFactory() {
122         this.processors = new HashMap JavaDoc<String JavaDoc, AnnotationProcessor>();
123     }
124
125     /**
126      * Returns processor for a given annotation, caching it ofr future use. Returns null
127      * if an annotation is not a JPA annotation.
128      */

129     AnnotationProcessor getProcessor(Annotation JavaDoc annotation) {
130
131         String JavaDoc annotationName = annotation.annotationType().getName();
132         AnnotationProcessor processor = processors.get(annotationName);
133
134         if (processor == null) {
135             processor = createProcessor(annotationName);
136             processors.put(annotationName, processor);
137         }
138
139         return processor == NOOP_PROCESSOR ? null : processor;
140     }
141
142     /**
143      * Creates a new processor for the annotation full class name.
144      */

145     AnnotationProcessor createProcessor(String JavaDoc annotationFQN) {
146
147         Class JavaDoc processorClass = processorClass(getClass(), annotationFQN);
148
149         if (processorClass != null) {
150
151             try {
152                 return (AnnotationProcessor) processorClass.newInstance();
153             }
154             catch (Exception JavaDoc e) {
155                 return NOOP_PROCESSOR;
156             }
157         }
158
159         // not a JPA annotation...
160
return NOOP_PROCESSOR;
161     }
162 }
163
Popular Tags