KickJava   Java API By Example, From Geeks To Geeks.

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


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.List JavaDoc;
25 import java.util.ArrayList JavaDoc;
26
27 import javax.persistence.FetchType;
28 import javax.persistence.CascadeType;
29 import javax.persistence.JoinColumn;
30 import javax.persistence.JoinColumns;
31 import javax.persistence.PrimaryKeyJoinColumn;
32 import javax.persistence.PrimaryKeyJoinColumns;
33
34 import oracle.toplink.essentials.internal.helper.DatabaseField;
35
36 import oracle.toplink.essentials.mappings.DatabaseMapping;
37 import oracle.toplink.essentials.mappings.ForeignReferenceMapping;
38
39 import oracle.toplink.essentials.indirection.ValueHolderInterface;
40
41 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataConstants;
42 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor;
43 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDescriptor;
44
45 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.columns.MetadataJoinColumn;
46 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.columns.MetadataJoinColumns;
47
48 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.ClassAccessor;
49 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataAccessibleObject;
50
51 /**
52  * An relational accessor.
53  *
54  * @author Guy Pelletier
55  * @since TopLink EJB 3.0 Reference Implementation
56  */

57 public abstract class RelationshipAccessor extends MetadataAccessor {
58     protected String JavaDoc m_mappedBy;
59     protected Class JavaDoc m_targetEntity;
60     protected ArrayList JavaDoc<String JavaDoc> m_cascadeTypes;
61     
62     /**
63      * INTERNAL:
64      */

65     protected RelationshipAccessor(MetadataAccessibleObject accessibleObject, ClassAccessor classAccessor) {
66         super(accessibleObject, classAccessor);
67         
68         // These are the defaults. Any subclass should override these settings
69
// where necessary.
70
m_mappedBy = "";
71         setIsOptional(false);
72         m_targetEntity = void.class;
73         setFetchType(MetadataConstants.LAZY);
74         m_cascadeTypes = new ArrayList JavaDoc<String JavaDoc>();
75     }
76     
77     /**
78      * INTERNAL:
79      */

80     public void addCascadeType(String JavaDoc cascadeType) {
81         m_cascadeTypes.add(cascadeType);
82     }
83     
84     /**
85      * INTERNAL:
86      * Return the cascade types for this accessor. This method is supported by
87      * all relational accessors.
88      */

89     public ArrayList JavaDoc<String JavaDoc> getCascadeTypes() {
90         return m_cascadeTypes;
91     }
92     
93     /**
94      * INTERNAL: (Overridden in XMLOneToOneAccessor, XMLManyToManyAccessor and XMLOneToManyAccessor)
95      * Process the @JoinColumns and @JoinColumn.
96      */

97     protected MetadataJoinColumns getJoinColumns() {
98         JoinColumn joinColumn = getAnnotation(JoinColumn.class);
99         JoinColumns joinColumns = getAnnotation(JoinColumns.class);
100         
101         return new MetadataJoinColumns(joinColumns, joinColumn);
102     }
103     
104     /**
105      * INTERNAL:
106      * Return the mapped by attribute for this accessor. This method is
107      * supported by all relational accessors except for many-to-one.
108      */

109     public String JavaDoc getMappedBy() {
110         return m_mappedBy;
111     }
112     
113     /**
114      * INTERNAL:
115      * Method to return an owner mapping. It will tell the owner class to
116      * process itself if it hasn't already done so.
117      */

118     protected DatabaseMapping getOwningMapping() {
119         String JavaDoc ownerAttributeName = m_mappedBy;
120         MetadataDescriptor ownerDescriptor = getReferenceDescriptor();
121         DatabaseMapping mapping = ownerDescriptor.getMappingForAttributeName(ownerAttributeName);
122         
123         // If no mapping was found, there is an error in the mappedBy field,
124
// therefore, throw an exception.
125
if (mapping == null) {
126             m_validator.throwNoMappedByAttributeFound(ownerDescriptor.getJavaClass(), ownerAttributeName, getJavaClass(), getAttributeName());
127         }
128         
129         return mapping;
130     }
131     
132     /**
133      * INTERNAL:
134      * Return the target entity for this accessor. This method is supported by
135      * all relational accessors.
136      */

137     public Class JavaDoc getTargetEntity() {
138         return m_targetEntity;
139     }
140     
141     /**
142      * INTERNAL:
143      * Method to check if an annotated element has a @JoinColumn.
144      */

145     public boolean hasJoinColumn() {
146         return isAnnotationPresent(JoinColumn.class);
147     }
148     
149     /**
150      * INTERNAL:
151      * Method to check if an annotated element has a @JoinColumns.
152      */

153     public boolean hasJoinColumns() {
154         return isAnnotationPresent(JoinColumns.class);
155     }
156     
157     /**
158      * INTERNAL: (Overridden in XMLOneToOneAccessor)
159      * Method to check if an annotated element has a @PrimaryKeyJoinColumns or
160      * at the very least a @PrimaryKeyJoinColumn.
161      */

162     public boolean hasPrimaryKeyJoinColumns() {
163         return isAnnotationPresent(PrimaryKeyJoinColumns.class) || isAnnotationPresent(PrimaryKeyJoinColumn.class);
164     }
165     
166     /**
167      * INTERNAL:
168      * Return true if this accessor represents a 1-1 primary key relationship.
169      */

170     public boolean isOneToOnePrimaryKeyRelationship() {
171         return isOneToOne() && hasPrimaryKeyJoinColumns();
172     }
173     
174     /**
175      * INTERNAL:
176      */

177     protected void processCascadeTypes(ForeignReferenceMapping mapping) {
178         for (String JavaDoc cascadeType : getCascadeTypes()) {
179             setCascadeType(cascadeType, mapping);
180         }
181         
182         // Apply the persistence unit default cascade-persist if necessary.
183
if (m_descriptor.isCascadePersist() && ! mapping.isCascadePersist()) {
184             setCascadeType(CascadeType.PERSIST.name(), mapping);
185         }
186     }
187     
188     /**
189      * INTERNAL:
190      * Process a @JoinColumns or @JoinColumn. Will look for association
191      * overrides.
192      */

193     protected List JavaDoc<MetadataJoinColumn> processJoinColumns() {
194         if (m_descriptor.hasAssociationOverrideFor(getAttributeName())) {
195             return processJoinColumns(m_descriptor.getAssociationOverrideFor(getAttributeName()), getReferenceDescriptor());
196         } else {
197             return processJoinColumns(getJoinColumns(), getReferenceDescriptor());
198         }
199     }
200     
201     /**
202      * INTERNAL:
203      * Process MetadataJoinColumns.
204      */

205     protected List JavaDoc<MetadataJoinColumn> processJoinColumns(MetadataJoinColumns joinColumns, MetadataDescriptor descriptor) {
206         if (descriptor.hasCompositePrimaryKey()) {
207             // The number of join columns should equal the number of primary key fields.
208
if (joinColumns.size() != descriptor.getPrimaryKeyFields().size()) {
209                 m_validator.throwIncompleteJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
210             }
211             
212             // All the primary and foreign key field names should be specified.
213
for (MetadataJoinColumn joinColumn : joinColumns.values()) {
214                 if (joinColumn.isPrimaryKeyFieldNotSpecified() || joinColumn.isForeignKeyFieldNotSpecified()) {
215                     m_validator.throwIncompleteJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
216                 }
217             }
218         } else {
219             if (joinColumns.size() > 1) {
220                 m_validator.throwExcessiveJoinColumnsSpecified(getJavaClass(), getAnnotatedElement());
221             }
222         }
223         
224         return joinColumns.values();
225     }
226     
227     /**
228      * INTERNAL:
229      * Front end validation before actually processing the relationship
230      * accessor. The process() method should not be called directly.
231      */

232     public void processRelationship() {
233         // The processing of this accessor may have been fast tracked through a
234
// non-owning relationship. If so, no processing is required.
235
if (! isProcessed()) {
236             if (m_descriptor.hasMappingForAttributeName(getAttributeName())) {
237                 // Only true if there is one that came from Project.xml
238
m_logger.logWarningMessage(m_logger.IGNORE_MAPPING, this);
239             } else {
240                 // If a @Column is specified then throw an exception.
241
if (hasColumn()) {
242                     m_validator.throwRelationshipHasColumnSpecified(getJavaClass(), getAttributeName());
243                 }
244                 
245                 // Process the relationship accessor only if the target entity
246
// is not a ValueHolderInterface.
247
if (getTargetEntity() == ValueHolderInterface.class || (getTargetEntity() == void.class && getReferenceClass() == ValueHolderInterface.class)) {
248                     // do nothing ... I'm too lazy (or too stupid) to do the negation of this expression :-)
249
} else {
250                     process();
251                 }
252             }
253             
254             // Set its processing completed flag to avoid double processing.
255
setIsProcessed();
256         }
257     }
258
259     /**
260      * INTERNAL:
261      * Set the cascade type on a mapping.
262      */

263     protected void setCascadeType(String JavaDoc type, ForeignReferenceMapping mapping) {
264         if (type.equals(MetadataConstants.CASCADE_ALL) || type.equals(CascadeType.ALL.name())) {
265             mapping.setCascadeAll(true);
266         } else if (type.equals(MetadataConstants.CASCADE_MERGE) || type.equals(CascadeType.MERGE.name())) {
267             mapping.setCascadeMerge(true);
268         } else if (type.equals(MetadataConstants.CASCADE_PERSIST) || type.equals(CascadeType.PERSIST.name())) {
269             mapping.setCascadePersist(true);
270         } else if (type.equals(MetadataConstants.CASCADE_REFRESH) || type.equals(CascadeType.REFRESH.name())) {
271             mapping.setCascadeRefresh(true);
272         } else if (type.equals(MetadataConstants.CASCADE_REMOVE) || type.equals(CascadeType.REMOVE.name())) {
273             mapping.setCascadeRemove(true);
274         }
275     }
276     
277     /**
278      * INTERNAL:
279      */

280     public void setCascadeTypes(CascadeType[] cascadeTypes) {
281         for (CascadeType cascadeType : cascadeTypes) {
282             addCascadeType(cascadeType.name());
283         }
284     }
285
286     /**
287      * INTERNAL:
288      */

289     public void setMappedBy(String JavaDoc mappedBy) {
290         m_mappedBy = mappedBy;
291     }
292     
293     /**
294      * INTERNAL:
295      * Set the reference class for this accessor.
296      */

297     public void setReferenceClass(Class JavaDoc potentialReferenceClass, String JavaDoc context) {
298         if (potentialReferenceClass == void.class) {
299             // Log the defaulting column name based on the given context.
300
getLogger().logConfigMessage(context, getAnnotatedElement(), getReferenceClass());
301         } else {
302             m_accessibleObject.setReferenceClass(potentialReferenceClass);
303         }
304     }
305     
306     /**
307      * INTERNAL:
308      */

309     public void setTargetEntity(Class JavaDoc targetEntity) {
310         m_targetEntity = targetEntity;
311     }
312 }
313
Popular Tags