001: package com.bm.introspectors;
002:
003: import java.lang.annotation.Annotation;
004: import java.lang.reflect.Field;
005: import java.lang.reflect.Modifier;
006: import java.util.Collection;
007: import java.util.HashMap;
008: import java.util.HashSet;
009: import java.util.Map;
010: import java.util.Set;
011:
012: import javax.annotation.Resource;
013: import javax.ejb.EJB;
014: import javax.persistence.PersistenceContext;
015:
016: import org.apache.log4j.Logger;
017:
018: import com.bm.ejb3metadata.annotations.metadata.ClassAnnotationMetadata;
019: import com.bm.ejb3metadata.annotations.metadata.MetaDataCache;
020: import com.bm.ejb3metadata.annotations.metadata.MethodAnnotationMetadata;
021: import com.bm.utils.Ejb3Utils;
022:
023: /**
024: * Abstract instrospector fur Session, MDBs und JBoss services.
025: *
026: * @author Daniel Wiese
027: * @since 24.03.2007
028: * @param <T>
029: * the type
030: *
031: * TODO: why is it not implementing the interface interospector?
032: */
033: public abstract class AbstractIntrospector<T> {
034: private static final Logger log = Logger
035: .getLogger(SessionBeanIntrospector.class);
036:
037: /** the class represented by this introspector (e.g. the entity bean)* */
038: protected final Class<? extends T> representingClass;
039:
040: /** the fields to inject * */
041: private Set<Property> fieldsToInject = new HashSet<Property>();
042:
043: /** we assume thet a injected field has only one annotation * */
044: private Map<Property, Annotation> annotationForField = new HashMap<Property, Annotation>();
045:
046: /** because the entity manager is often used so, we store it extra * */
047: private Property entityManagerField = null;
048:
049: protected ClassAnnotationMetadata classMetaData = null;
050:
051: /**
052: * Constructor.
053: *
054: * @param toInspect -
055: * the class to inspect.
056: */
057: public AbstractIntrospector(Class<? extends T> toInspect) {
058: this .representingClass = toInspect;
059: classMetaData = MetaDataCache.getMetaData(toInspect);
060: }
061:
062: /**
063: * If the access type is field, we will extract all the neccessary meta
064: * informations from the fields.
065: *
066: * @param toInspect -
067: * the class to inspect
068: */
069: protected void processAccessTypeField(Class<? extends T> toInspect) {
070:
071: // extract meta information
072: Field[] fields = Ejb3Utils.getAllFields(toInspect);
073: for (Field aktField : fields) {
074: // dontīs introspect fields generated by hibernate
075: if (!this .isStatic(aktField)
076: && !aktField.getName().startsWith("$")) {
077: Annotation[] fieldAnnotations = aktField
078: .getAnnotations();
079: this .processAnnotations(new Property(aktField),
080: fieldAnnotations);
081: }
082: }
083: }
084:
085: /**
086: * Anylse the annotation of a (field or getterMethod)
087: *
088: * @param aktProperty -
089: * the property
090: * @param propertyAnnotations -
091: * the corresponding annotations
092: */
093: private void processAnnotations(Property aktProperty,
094: Annotation[] propertyAnnotations) {
095:
096: // look into the annotations
097: for (Annotation a : propertyAnnotations) {
098: // skip transient fields
099: if (a instanceof PersistenceContext) {
100: this .entityManagerField = aktProperty;
101: addAnotatedField(aktProperty, a);
102: } else if (a instanceof Resource) {
103: addAnotatedField(aktProperty, a);
104: } else if (a instanceof EJB) {
105: addAnotatedField(aktProperty, a);
106: } else {
107: log.warn("The Annotation (" + a + ") for field ("
108: + aktProperty
109: + ") will not be injected (is unknown)");
110: }
111: }
112: }
113:
114: /**
115: * Register a new field with annotation
116: *
117: * @author Daniel Wiese
118: * @since 08.11.2005
119: * @param aktProperty -
120: * akt property
121: * @param a -
122: * akt annotation
123: */
124: private void addAnotatedField(Property aktProperty, Annotation a) {
125: this .fieldsToInject.add(aktProperty);
126: this .annotationForField.put(aktProperty, a);
127: }
128:
129: /**
130: * Returns the representingClass.
131: *
132: * @return Returns the representingClass.
133: */
134: public Class<? extends T> getRepresentingClass() {
135: return this .representingClass;
136: }
137:
138: /**
139: * Returns the annotationForField.
140: *
141: * @param field -
142: * for field
143: * @return Returns the annotationForField.
144: */
145: public Annotation getAnnotationForField(Property field) {
146: return this .annotationForField.get(field);
147: }
148:
149: /**
150: * Returns the fieldsToInject.
151: *
152: * @return Returns the fieldsToInject.
153: */
154: public Set<Property> getFieldsToInject() {
155: return this .fieldsToInject;
156: }
157:
158: /**
159: * Returns the lifecycle methods.
160: *
161: * @return Returns the lofe cycle methods.
162: */
163: public Set<MethodAnnotationMetadata> getLifecycleMethods() {
164: final Set<MethodAnnotationMetadata> back = new HashSet<MethodAnnotationMetadata>();
165: final Collection<MethodAnnotationMetadata> methods = this
166: .getClassMetaData()
167: .getMethodAnnotationMetadataCollection();
168: for (MethodAnnotationMetadata current : methods) {
169: if (current.isLifeCycleMethod()) {
170: back.add(current);
171: }
172: }
173:
174: return back;
175: }
176:
177: /**
178: * True is the session bean has an entity manager.
179: *
180: * @author Daniel Wiese
181: * @since 08.11.2005
182: * @return - true if yes
183: */
184: public boolean hasEntityManager() {
185: return this .entityManagerField != null;
186: }
187:
188: /**
189: * Returns the field, which holds the reference to the entity manager.
190: *
191: * @author Daniel Wiese
192: * @since 08.11.2005
193: * @return - the em field
194: */
195: public Property getEntityManagerField() {
196: return this .entityManagerField;
197: }
198:
199: /**
200: * Returns the classMetaData.
201: *
202: * @return Returns the classMetaData.
203: */
204: public ClassAnnotationMetadata getClassMetaData() {
205: return this .classMetaData;
206: }
207:
208: /**
209: * Check if the field is static
210: *
211: * @param toCheck
212: * -the field to check
213: * @return - true if static
214: */
215: private boolean isStatic(Field toCheck) {
216: return Modifier.isStatic(toCheck.getModifiers());
217:
218: }
219:
220: /**
221: * Get the implemenation name for the interface.
222: *
223: *
224: * @param toInspect
225: * interface to whoes implementation to look for
226: * @return the implementation of the parameter interface
227: */
228: public Class<?> getImplementationForInterface(Class<?> toInspect) {
229:
230: // try to get the implemenation name for the interface
231: String implementationName = MetaDataCache
232: .getBeanImplementationForInterface(toInspect);
233:
234: log.debug("Using: Local/Remote Interface (" + toInspect
235: + ") --> Implemetation (" + implementationName + ")");
236:
237: Class<?> implementation = null;
238: try {
239: implementation = Thread.currentThread()
240: .getContextClassLoader().loadClass(
241: implementationName.replace('/', '.'));
242: } catch (ClassNotFoundException e) {
243: throw new RuntimeException(
244: "Class ("
245: + implementationName
246: + ") was not found as an implementation for interface ("
247: + toInspect.getName() + ")");
248: }
249:
250: return implementation;
251: }
252:
253: }
|