KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > metadata > accessors > MetadataAccessor


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.List JavaDoc;
26
27 import java.lang.annotation.Annotation JavaDoc;
28 import java.lang.Boolean JavaDoc;
29
30 import java.lang.reflect.AnnotatedElement JavaDoc;
31 import java.lang.reflect.Type JavaDoc;
32
33 import javax.persistence.Column;
34 import javax.persistence.FetchType;
35 import javax.persistence.PrimaryKeyJoinColumn;
36 import javax.persistence.PrimaryKeyJoinColumns;
37 import javax.persistence.UniqueConstraint;
38
39 import oracle.toplink.essentials.mappings.DatabaseMapping;
40
41 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.ClassAccessor;
42
43 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataAccessibleObject;
44 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataClass;
45 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataMethod;
46
47 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.columns.MetadataPrimaryKeyJoinColumn;
48 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.columns.MetadataPrimaryKeyJoinColumns;
49
50 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataHelper;
51 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataLogger;
52 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProject;
53 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataValidator;
54 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataConstants;
55 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor;
56 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDescriptor;
57
58 import oracle.toplink.essentials.internal.ejb.cmp3.xml.XMLHelper;
59
60 import oracle.toplink.essentials.internal.helper.DatabaseField;
61 import oracle.toplink.essentials.internal.helper.DatabaseTable;
62
63 /**
64  * Top level metatata accessor.
65  *
66  * @author Guy Pelletier
67  * @since TopLink EJB 3.0 Reference Implementation
68  */

69 public abstract class MetadataAccessor {
70     // Making the member variables private to force subclasss to make API calls.
71
private String JavaDoc m_fetchType;
72     private boolean m_isOptional;
73     
74     private boolean m_isProcessed;
75     private Boolean JavaDoc m_isRelationship;
76     
77     protected MetadataLogger m_logger;
78     protected MetadataProject m_project;
79     protected MetadataProcessor m_processor;
80     protected MetadataValidator m_validator;
81     protected MetadataDescriptor m_descriptor;
82     protected MetadataAccessibleObject m_accessibleObject;
83     
84     /**
85      * INTERNAL:
86      */

87     public MetadataAccessor(MetadataAccessibleObject accessibleObject, ClassAccessor classAccessor) {
88         this(accessibleObject, classAccessor.getProcessor(), classAccessor.getDescriptor());
89     }
90     
91     /**
92      * INTERNAL:
93      */

94     public MetadataAccessor(MetadataAccessibleObject accessibleObject, MetadataProcessor processor, MetadataDescriptor descriptor) {
95         m_isOptional = true;
96         m_isProcessed = false;
97         
98         m_processor = processor;
99         m_descriptor = descriptor;
100         m_logger = processor.getLogger();
101         m_project = processor.getProject();
102         m_validator = processor.getValidator();
103         
104         m_fetchType = MetadataConstants.EAGER;
105         m_accessibleObject = accessibleObject;
106     }
107     
108     /**
109      * INTERNAL:
110      * Return the annotated element for this accessor.
111      */

112     public AnnotatedElement JavaDoc getAnnotatedElement() {
113         return m_accessibleObject.getAnnotatedElement();
114     }
115     
116     /**
117      * INTERNAL:
118      * Return the annotated element for this accessor.
119      */

120     protected <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc annotation) {
121         return (T) getAnnotation(annotation, getAnnotatedElement());
122     }
123     
124     /**
125      * INTERNAL:
126      * Return the annotated element for this accessor.
127      */

128     protected <T extends Annotation JavaDoc> T getAnnotation(Class JavaDoc annotation, AnnotatedElement JavaDoc annotatedElement) {
129         return (T) MetadataHelper.getAnnotation(annotation, annotatedElement, m_descriptor);
130     }
131     
132     /**
133      * INTERNAL:
134      * Return the attribute name for this accessor.
135      */

136     public String JavaDoc getAttributeName() {
137         return m_accessibleObject.getAttributeName();
138     }
139     
140     /**
141      * INTERNAL:
142      * Return the MetadataDescriptor for this accessor.
143      */

144     public MetadataDescriptor getDescriptor() {
145         return m_descriptor;
146     }
147     
148     /**
149      * INTERNAL:
150      *
151      */

152     public String JavaDoc getFetchType() {
153         return m_fetchType;
154     }
155         
156     /**
157      * INTERNAL: (Overridden in ClassAccessor)
158      * Return the java class associated with this accessor's descriptor.
159      */

160     public Class JavaDoc getJavaClass() {
161         return m_descriptor.getJavaClass();
162     }
163     
164     /**
165      * INTERNAL:
166      * Return the java class that defines this accessor.
167      */

168     protected String JavaDoc getJavaClassName() {
169         return getJavaClass().getName();
170     }
171
172     /**
173      * INTERNAL:
174      * Return the metadata validator.
175      */

176     public MetadataLogger getLogger() {
177         return m_logger;
178     }
179     
180     /**
181      * INTERNAL:
182      * Returns the name of this accessor. If it is a field, it will return
183      * the field name. For a method it will return the method name.
184      */

185     public String JavaDoc getName() {
186         return m_accessibleObject.getName();
187     }
188     
189     /**
190      * INTERNAL:
191      * Helper method to return a field name from a candidate field name and a
192      * default field name.
193      *
194      * Requires the context from where this method is called to output the
195      * correct logging message when defaulting the field name.
196      */

197     protected String JavaDoc getName(DatabaseField field, String JavaDoc defaultName, String JavaDoc context) {
198         return getName(field.getName(), defaultName, context);
199     }
200     
201     /**
202      * INTERNAL:
203      * Helper method to return a field name from a candidate field name and a
204      * default field name.
205      *
206      * Requires the context from where this method is called to output the
207      * correct logging message when defaulting the field name.
208      *
209      * In some cases, both the name and defaultName could be "" or null,
210      * therefore, don't log any message and return name.
211      */

212     protected String JavaDoc getName(String JavaDoc name, String JavaDoc defaultName, String JavaDoc context) {
213         // Check if a candidate was specified otherwise use the default.
214
if (name != null && !name.equals("")) {
215             return name;
216         } else if (defaultName == null || defaultName.equals("")) {
217             return "";
218         } else {
219             // Log the defaulting field name based on the given context.
220
m_logger.logConfigMessage(context, getAnnotatedElement(), defaultName);
221             return defaultName;
222         }
223     }
224     
225     /**
226      * INTERNAL: (Overridden in XMLClassAccessor and XMLOneToOneAccessor)
227      * Process the @PrimaryKeyJoinColumns and @PrimaryKeyJoinColumn.
228      */

229     protected MetadataPrimaryKeyJoinColumns getPrimaryKeyJoinColumns(String JavaDoc sourceTableName, String JavaDoc targetTableName) {
230         PrimaryKeyJoinColumn primaryKeyJoinColumn = getAnnotation(PrimaryKeyJoinColumn.class);
231         PrimaryKeyJoinColumns primaryKeyJoinColumns = getAnnotation(PrimaryKeyJoinColumns.class);
232         
233         return new MetadataPrimaryKeyJoinColumns(primaryKeyJoinColumns, primaryKeyJoinColumn, sourceTableName, targetTableName);
234     }
235     
236     /**
237      * INTERNAL:
238      * Return the MetadataProject.
239      */

240     public MetadataProject getProject() {
241         return m_project;
242     }
243     
244     /**
245      * INTERNAL:
246      * Return the MetadataProcessor.
247      */

248     public MetadataProcessor getProcessor() {
249         return m_processor;
250     }
251
252     /**
253      * INTERNAL:
254      * Return the raw class for this accessor.
255      * Eg. For an accessor with a type of java.util.Collection<Employee>, this
256      * method will return java.util.Collection
257      */

258     public Class JavaDoc getRawClass() {
259         return m_accessibleObject.getRawClass();
260     }
261     
262     /**
263      * INTERNAL:
264      * Return the reference class for this accessor.
265      */

266     protected Class JavaDoc getReferenceClass() {
267         return m_accessibleObject.getReferenceClass();
268     }
269
270     /**
271      * INTERNAL:
272      * Return the reference class name for this accessor.
273      */

274     public String JavaDoc getReferenceClassName() {
275         return getReferenceClass().getName();
276     }
277     
278     /**
279      * INTERNAL:
280      * Return the reference metadata descriptor for this accessor.
281      */

282     public MetadataDescriptor getReferenceDescriptor() {
283         return m_project.getDescriptor(getReferenceClass());
284     }
285     
286     /**
287      * INTERNAL:
288      * Return the relation type of this accessor.
289      */

290     protected Type JavaDoc getRelationType() {
291         return m_accessibleObject.getRelationType();
292     }
293     
294     /**
295      * INTERNAL:
296      * Returns the set method name of a method accessor. Note, this method
297      * should not be called when processing field access.
298      */

299     protected String JavaDoc getSetMethodName() {
300         return ((MetadataMethod) m_accessibleObject).getSetMethodName();
301     }
302     
303     /**
304      * INTERNAL:
305      * Return the upper cased attribute name for this accessor. Used when
306      * defaulting.
307      */

308     protected String JavaDoc getUpperCaseAttributeName() {
309         return getAttributeName().toUpperCase();
310     }
311     
312     /**
313      * INTERNAL:
314      * Return the metadata validator.
315      */

316     public MetadataValidator getValidator() {
317         return m_validator;
318     }
319     
320     /**
321      * INTERNAL:
322      * Method to check if an annotated element has @Column.
323      */

324     protected boolean hasColumn() {
325         return isAnnotationPresent(Column.class);
326     }
327     
328     /**
329      * INTERNAL:
330      * Method to check if the class has @PrimaryKeyJoinColumns.
331      */

332     protected boolean hasPrimaryKeyJoinColumns() {
333         return isAnnotationPresent(PrimaryKeyJoinColumns.class);
334     }
335     
336     /**
337      * INTERNAL:
338      * Indicates whether the specified annotation is present on the annotated
339      * element for this accessor. Method checks against the metadata complete
340      * flag.
341      */

342     protected boolean isAnnotationPresent(Class JavaDoc<? extends Annotation JavaDoc> annotation) {
343         return isAnnotationPresent(annotation, getAnnotatedElement());
344     }
345     
346     /**
347      * INTERNAL:
348      * Indicates whether the specified annotation is present on the annotated
349      * element for this accessor. Method checks against the metadata complete
350      * flag.
351      */

352     protected boolean isAnnotationPresent(Class JavaDoc<? extends Annotation JavaDoc> annotation, AnnotatedElement JavaDoc annotatedElement) {
353         return MetadataHelper.isAnnotationPresent(annotation, annotatedElement, m_descriptor);
354     }
355     
356     /**
357      * INTERNAL:
358      * Return true if this accessor represents a basic mapping.
359      */

360     public boolean isBasic() {
361         return false;
362     }
363     
364     /**
365      * INTERNAL:
366      * Return true if this accessor represents a class.
367      */

368     public boolean isClass() {
369         return false;
370     }
371     
372     /**
373      * INTERNAL:
374      * Return true if this accessor represents an aggregate mapping.
375      */

376     public boolean isEmbedded() {
377         return false;
378     }
379     
380     /**
381      * INTERNAL:
382      * Return true if this accessor represents an aggregate id mapping.
383      */

384     public boolean isEmbeddedId() {
385         return false;
386     }
387     
388     /**
389      * INTERNAL:
390      * Return true if this accessor represents a m-m relationship.
391      */

392     public boolean isManyToMany() {
393         return false;
394     }
395     
396     /**
397      * INTERNAL:
398      * Return true if this accessor represents a m-1 relationship.
399      */

400     public boolean isManyToOne() {
401         return false;
402     }
403     
404     /**
405      * INTERNAL:
406      * Return true if this accessor represents a 1-m relationship.
407      */

408     public boolean isOneToMany() {
409         return false;
410     }
411     
412     /**
413      * INTERNAL:
414      * Return true if this accessor represents a 1-1 relationship.
415      */

416     public boolean isOneToOne() {
417         return false;
418     }
419     
420     /**
421      * INTERNAL:
422      */

423     public boolean isOptional() {
424         return m_isOptional;
425     }
426     
427     /**
428      * INTERNAL:
429      * Return true if this accessor method represents a relationship. It will
430      * cache the boolean value to avoid multiple checks and validation.
431      */

432     public boolean isRelationship() {
433         if (m_isRelationship == null) {
434             m_isRelationship = new Boolean JavaDoc(isManyToOne() || isManyToMany() || isOneToMany() || isOneToOne());
435         }
436         
437         return m_isRelationship.booleanValue();
438     }
439     
440     /**
441      * INTERNAL:
442      * Return true if this is an XML processing accessor.
443      */

444     public boolean isXMLAccessor() {
445         return false;
446     }
447     
448     /**
449      * INTERNAL:
450      * Return true if this accessor has already been processed.
451      */

452     public boolean isProcessed() {
453         return m_isProcessed;
454     }
455     
456     /**
457      * INTERNAL:
458      * Every accessor knows how to process themselves since they have all the
459      * information they need.
460      */

461     public abstract void process();
462     
463     /**
464      * INTERNAL: (Overidden in XMLClassAccessor and XMLEmbeddedAccessor)
465      * Fast track processing a ClassAccessor for the given descriptor.
466      * Inheritance root classes and embeddables may be fast tracked.
467      */

468     protected ClassAccessor processAccessor(MetadataDescriptor descriptor) {
469         ClassAccessor accessor = new ClassAccessor(new MetadataClass(descriptor.getJavaClass()), getProcessor(), descriptor);
470         descriptor.setClassAccessor(accessor);
471         accessor.process();
472         return accessor;
473     }
474     
475     /**
476      * INTERNAL:
477      * Process the primary key join columms for this accessors annotated element.
478      */

479     protected List JavaDoc<MetadataPrimaryKeyJoinColumn> processPrimaryKeyJoinColumns(MetadataPrimaryKeyJoinColumns primaryKeyJoinColumns) {
480         if (m_descriptor.hasCompositePrimaryKey()) {
481             // Validate the number of primary key fields defined.
482
if (primaryKeyJoinColumns.size() != m_descriptor.getPrimaryKeyFields().size()) {
483                 m_validator.throwIncompletePrimaryKeyJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
484             }
485             
486             // All the primary and foreign key field names should be specified.
487
for (MetadataPrimaryKeyJoinColumn primaryKeyJoinColumn : primaryKeyJoinColumns.values()) {
488                 if (primaryKeyJoinColumn.isPrimaryKeyFieldNotSpecified() || primaryKeyJoinColumn.isForeignKeyFieldNotSpecified()) {
489                     m_validator.throwIncompletePrimaryKeyJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
490                 }
491             }
492         } else {
493             if (primaryKeyJoinColumns.size() > 1) {
494                 m_validator.throwExcessivePrimaryKeyJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
495             }
496         }
497         
498         return primaryKeyJoinColumns.values();
499     }
500     
501     /**
502      * INTERNAL:
503      * Set the getter and setter access methods for this accessor.
504      */

505     protected void setAccessorMethods(DatabaseMapping mapping) {
506         if (m_descriptor.usesPropertyAccess()) {
507             mapping.setGetMethodName(getName());
508             mapping.setSetMethodName(getSetMethodName());
509         }
510     }
511     
512     /**
513      * INTERNAL:
514      * Return the annotated element for this accessor.
515      */

516     public void setAnnotatedElement(AnnotatedElement JavaDoc annotatedElement) {
517         m_accessibleObject.setAnnotatedElement(annotatedElement);
518     }
519     
520     /**
521      * INTERNAL:
522      */

523     public void setFetchType(FetchType fetchType) {
524         m_fetchType = fetchType.name();
525     }
526     
527     /**
528      * INTERNAL:
529      */

530     public void setFetchType(String JavaDoc fetchType) {
531         m_fetchType = fetchType;
532     }
533     
534     /**
535      * INTERNAL:
536      */

537     public void setIsOptional(boolean isOptional) {
538         m_isOptional = isOptional;
539     }
540     
541     /**
542      * INTERNAL:
543      */

544     public void setIsProcessed() {
545         m_isProcessed = true;
546     }
547     
548     /**
549      * INTERNAL:
550      */

551     public boolean usesIndirection() {
552         return m_fetchType.equals(MetadataConstants.LAZY);
553     }
554 }
555
Popular Tags