KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > support > ejb > model > DeploymentDescriptorModel


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 in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
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 Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * DeploymentDescriptorModel.java
26  *
27  * Created on December 3, 2001, 3:43 PM
28  */

29
30 package com.sun.jdo.spi.persistence.support.ejb.model;
31
32 import java.io.*;
33 import java.util.*;
34 import java.lang.reflect.*;
35
36 import com.sun.enterprise.deployment.*;
37 import com.sun.jdo.api.persistence.model.RuntimeModel;
38 import com.sun.jdo.spi.persistence.support.ejb.model.util.NameMapper;
39 import com.sun.jdo.api.persistence.model.jdo.RelationshipElement;
40 import com.sun.jdo.api.persistence.model.jdo.PersistenceFieldElement;
41 import com.sun.jdo.spi.persistence.utility.JavaTypeHelper;
42
43 /** This is a subclass of RuntimeModel which uses the deployment descriptor
44  * to augment the java metadata for a non-existent persistence-capable
45  * java/class file. It is primarily used at ejbc time, though it could be
46  * used at any time as long as sufficient mapping and deployment descriptor
47  * information is available. See the javadoc for individual methods below
48  * for differences and translations between persistence-capable and ejb
49  * names and behavior. There are different answers to methods depending
50  * on whether they are called on the persistence-capable or the ejb. These
51  * are primarily for the handling of serializable, non-primitive, non-wrapper
52  * type fields: isByteArray, getFieldType (returning byte array),
53  * isPersistentTypeAllowed and isPersistentAllowed (returning true) which
54  * return answers about the byte array when called on the persistence-capable
55  * and return answers about the serializable type when called on the ejb.
56  *
57  * @author Rochelle Raccah
58  */

59 public class DeploymentDescriptorModel extends RuntimeModel
60 {
61     private ClassLoader JavaDoc _classLoader;
62     private NameMapper _nameMapper;
63         
64     /**
65      * Signature with CVS keyword substitution for identifying the generated code
66      */

67     public static final String JavaDoc SIGNATURE = "$RCSfile: DeploymentDescriptorModel.java,v $ $Revision: 1.2 $"; //NOI18N
68

69     /** Creates a new instance of DeploymentDescriptorModel
70      * @param nameMapper the name mapper to be used as a helper for
71      * translation between persistence class and ejb names.
72      * @param classLoader the class loader object which is used for the
73      * application.
74      */

75     public DeploymentDescriptorModel (NameMapper nameMapper,
76         ClassLoader JavaDoc classLoader)
77     {
78         super();
79         _classLoader = classLoader;
80         _nameMapper = nameMapper;
81     }
82
83     private ClassLoader JavaDoc getClassLoader () { return _classLoader; }
84     private NameMapper getNameMapper () { return _nameMapper; }
85
86     /** Returns the input stream with the supplied resource name found with
87      * the supplied class name. This method overrides the one in
88      * RuntimeModel to enforce using the class loader provided at construction
89      * time instead of the one specified in this method.
90      * @param className the fully qualified name of the class which will be
91      * used as a base to find the resource
92      * @param classLoader the class loader used to find mapping information
93      * This parameter is ignored in this implementation - instead the
94      * class loader supplied at construction time is used.
95      * @param resourceName the name of the resource to be found
96      * @return the input stream for the specified resource, <code>null</code>
97      * if an error occurs or none exists
98      */

99     protected BufferedInputStream getInputStreamForResource (String JavaDoc className,
100         ClassLoader JavaDoc classLoader, String JavaDoc resourceName)
101     {
102         return super.getInputStreamForResource(
103             className, getClassLoader(), resourceName);
104     }
105
106     /** Returns the name of the second to top (top excluding java.lang.Object)
107      * superclass for the given class name. This method overrides the one in
108      * RuntimeModel in order to return the supplied className if it
109      * represents a persistence-capable class. This is because the
110      * persistence-capable classes don't mirror the inheritance
111      * hierarchy of the ejbs.
112      * @param className the fully qualified name of the class to be checked
113      * @return the top non-Object superclass for className,
114      * <code>className</code> if an error occurs or none exists
115      */

116     protected String JavaDoc findPenultimateSuperclass (String JavaDoc className)
117     {
118         return (isPCClassName(className) ? className :
119             super.findPenultimateSuperclass(className));
120     }
121
122     /** Returns the name of the superclass for the given class name. This
123      * method overrides the one in RuntimeModel in order to return
124      * java.lang.Object if the supplied className represents a
125      * persistence-capable class. This is because the persistence-capable
126      * classes don't mirror the inheritance hierarchy of the ejbs.
127      * @param className the fully qualified name of the class to be checked
128      * @return the superclass for className, <code>null</code> if an error
129      * occurs or none exists
130      */

131     protected String JavaDoc getSuperclass (String JavaDoc className)
132     {
133         return (isPCClassName(className) ? "java.lang.Object" : // NOI18N
134
super.getSuperclass(className));
135     }
136
137     /** Creates a file with the given base file name and extension
138      * parallel to the supplied class (if it does not yet exist). This
139      * method overrides the one in RuntimeModel and throws
140      * UnsupportedOperationException in the case where the file
141      * doesn't yet exist. If the file exists (even if it has
142      * just been "touched"), this method will return that output stream,
143      * but it is not capable of using the supplied class as a sibling location.
144      * @param className the fully qualified name of the class
145      * @param baseFileName the name of the base file
146      * @param extension the file extension
147      * @return the output stream for the specified resource, <code>null</code>
148      * if an error occurs or none exists
149      * @exception IOException if there is some error creating the file
150      */

151     protected BufferedOutputStream createFile (String JavaDoc className, String JavaDoc baseFileName,
152         String JavaDoc extension) throws IOException
153     {
154         BufferedOutputStream outputStream =
155             super.createFile(className, baseFileName, extension);
156
157         if (outputStream != null)
158             return outputStream;
159
160         throw new UnsupportedOperationException JavaDoc();
161     }
162
163     /** Deletes the file with the given file name which is parallel
164      * to the supplied class. This method overrides the one in RuntimeModel
165      * and throws UnsupportedOperationException.
166      * @param className the fully qualified name of the class
167      * @param fileName the name of the file
168      * @exception IOException if there is some error deleting the file
169      */

170     protected void deleteFile (String JavaDoc className, String JavaDoc fileName)
171         throws IOException
172     {
173         throw new UnsupportedOperationException JavaDoc();
174     }
175
176     /** Returns the class element with the specified className. If the
177      * specified className represents a persistence-capable class, the
178      * abstract bean class for the corresponding ejb is always returned
179      * (even if there is a Class object available for the
180      * persistence-capable). If there is an ejb name and an abstract bean
181      * class with the same name, the abstract bean class which is associated
182      * with the ejb will be returned, not the abstract bean class which
183      * corresponds to the supplied name (directly). If the specified
184      * className represents a persistence-capable key class name, the
185      * corresponding bean's key class is returned.
186      * @param className the fully qualified name of the class to be checked
187      * @param classLoader the class loader used to find mapping information
188      * @return the class element for the specified className
189      */

190     public Object JavaDoc getClass (final String JavaDoc className,
191         final ClassLoader JavaDoc classLoader)
192     {
193         String JavaDoc testClass = className;
194
195         // translate the class name to corresponding ejb name's abstract
196
// bean or key class if necessary
197
if (className != null)
198         {
199             NameMapper nameMapper = getNameMapper();
200             String JavaDoc ejbName =
201                 (isPCClassName(className) ? getEjbName(className) : className);
202
203             if (nameMapper.isEjbName(ejbName))
204                 testClass = nameMapper.getAbstractBeanClassForEjbName(ejbName);
205             else
206             {
207                 String JavaDoc keyClass =
208                     nameMapper.getKeyClassForPersistenceKeyClass(className);
209
210                 if (keyClass != null)
211                 {
212                     // if it's a pk field of type primitive, byte[],
213
// or other array, return the primitive class or a
214
// dummy class
215
if (NameMapper.PRIMARY_KEY_FIELD ==
216                         getPersistenceKeyClassType(className))
217                     {
218                         if (isPrimitive(keyClass))
219                             return JavaTypeHelper.getPrimitiveClass(keyClass);
220                         if (isByteArray(keyClass) || keyClass.endsWith("[]"))
221                             return byte[].class;
222                     }
223
224                     testClass = keyClass;
225                 }
226             }
227         }
228
229         return super.getClass(testClass, getClassLoader());
230     }
231
232     /** Returns a wrapped constructor element for the specified argument types
233      * in the class with the specified name. If the specified class name is
234      * a persistence-capable key class name which corresponds to a bean
235      * with an unknown primary key class a dummy constructor will also be
236      * returned. Types are specified as type names for primitive type
237      * such as int, float or as fully qualified class names.
238      * @param className the name of the class which contains the constructor
239      * to be checked
240      * @param argTypeNames the fully qualified names of the argument types
241      * @return the constructor element
242      * @see #getClass
243      */

244     public Object JavaDoc getConstructor (final String JavaDoc className, String JavaDoc[] argTypeNames)
245     {
246         Object JavaDoc returnObject = null;
247
248         if ((NameMapper.PRIMARY_KEY_FIELD ==
249             getPersistenceKeyClassType(className)) &&
250             argTypeNames.equals(NO_ARGS))
251         {
252             returnObject = new MemberWrapper(className, null, Modifier.PUBLIC,
253                 (Class JavaDoc)getClass(className));
254         }
255
256         if (returnObject == null)
257         {
258             returnObject = super.getConstructor(className, argTypeNames);
259
260             if (returnObject instanceof Constructor) // wrap it
261
returnObject = new MemberWrapper((Constructor)returnObject);
262         }
263
264         return returnObject;
265     }
266
267     /** Returns a wrapped method element for the specified method name and
268      * argument types in the class with the specified name. If the
269      * specified className represents a persistence-capable class and
270      * the requested methodName is readObject or writeObject, a dummy
271      * method will be returned. Similarly, if the specified class name is
272      * a persistence-capable key class name which corresponds to a bean
273      * with an unknown primary key class or a primary key field (in both
274      * cases there is no user defined primary key class) and the requested
275      * method is equals or hashCode, a dummy method will also be returned.
276      * Types are specified as type names for primitive type such as int,
277      * float or as fully qualified class names. Note, the method does not
278      * return inherited methods.
279      * @param className the name of the class which contains the method
280      * to be checked
281      * @param methodName the name of the method to be checked
282      * @param argTypeNames the fully qualified names of the argument types
283      * @return the method element
284      * @see #getClass
285      */

286     public Object JavaDoc getMethod (final String JavaDoc className, final String JavaDoc methodName,
287         String JavaDoc[] argTypeNames)
288     {
289         int keyClassType = getPersistenceKeyClassType(className);
290         Object JavaDoc returnObject = null;
291
292         if (isPCClassName(className))
293         {
294             if ((methodName.equals("readObject") && // NOI18N
295
argTypeNames.equals(READ_OBJECT_ARGS)) ||
296                 (methodName.equals("writeObject") && // NOI18N
297
argTypeNames.equals(WRITE_OBJECT_ARGS)))
298             {
299                 returnObject = new MemberWrapper(methodName,
300                     Void.TYPE, Modifier.PRIVATE, (Class JavaDoc)getClass(className));
301             }
302         }
303         if ((NameMapper.UNKNOWN_KEY_CLASS == keyClassType) ||
304             (NameMapper.PRIMARY_KEY_FIELD == keyClassType))
305         {
306             if (methodName.equals("equals") && // NOI18N
307
argTypeNames.equals(EQUALS_ARGS))
308             {
309                 returnObject = new MemberWrapper(methodName,
310                     Boolean.TYPE, Modifier.PUBLIC, (Class JavaDoc)getClass(className));
311             }
312             else if (methodName.equals("hashCode") && // NOI18N
313
argTypeNames.equals(NO_ARGS))
314             {
315                 returnObject = new MemberWrapper(methodName,
316                     Integer.TYPE, Modifier.PUBLIC, (Class JavaDoc)getClass(className));
317             }
318         }
319
320         if (returnObject == null)
321         {
322             returnObject = super.getMethod(className, methodName, argTypeNames);
323
324             if (returnObject instanceof Method) // wrap it
325
returnObject = new MemberWrapper((Method)returnObject);
326         }
327
328         return returnObject;
329     }
330
331     /** Returns the inherited method element for the specified method
332      * name and argument types in the class with the specified name.
333      * Types are specified as type names for primitive type such as
334      * int, float or as fully qualified class names. Note that the class
335      * with the specified className is not checked for this method, only
336      * superclasses are checked. This method overrides the one in
337      * Model in order to do special handling for a persistence-capable key
338      * class name which corresponds to a bean with a primary key
339      * field. In that case, we don't want to climb the inheritance
340      * of the primary key field type.
341      * @param className the name of the class which contains the method
342      * to be checked
343      * @param methodName the name of the method to be checked
344      * @param argTypeNames the fully qualified names of the argument types
345      * @return the method element
346      * @see #getClass
347      */

348     public Object JavaDoc getInheritedMethod (String JavaDoc className, String JavaDoc methodName,
349         String JavaDoc[] argTypeNames)
350     {
351         // If the class name corresponds to a pk field (which means that
352
// there is no user defined primary key class, we don't want to
353
// climb the inheritance hierarchy, we only process this class.
354
return ((NameMapper.PRIMARY_KEY_FIELD ==
355             getPersistenceKeyClassType(className)) ?
356             getMethod(className, methodName, argTypeNames) :
357             super.getInheritedMethod(className, methodName, argTypeNames));
358     }
359
360     /** Returns a list of names of all the declared field elements in the
361      * class with the specified name. If the specified className represents
362      * a persistence-capable class, the list of field names from the
363      * corresponding ejb is returned (even if there is a Class object
364      * available for the persistence-capable).
365      * @param className the fully qualified name of the class to be checked
366      * @return the names of the field elements for the specified class
367      */

368     public List getFields (final String JavaDoc className)
369     {
370         final EjbCMPEntityDescriptor descriptor = getCMPDescriptor(className);
371         String JavaDoc testClass = className;
372
373         if (descriptor != null) // need to get names of ejb fields
374
{
375             Iterator iterator = descriptor.getFieldDescriptors().iterator();
376             List returnList = new ArrayList();
377
378             while (iterator.hasNext())
379                 returnList.add(((FieldDescriptor)iterator.next()).getName());
380
381             return returnList;
382         }
383         else
384         {
385             NameMapper nameMapper = getNameMapper();
386             String JavaDoc ejbName =
387                 nameMapper.getEjbNameForPersistenceKeyClass(className);
388
389             switch (getPersistenceKeyClassType(className))
390             {
391                 // find the field names we need in the corresponding
392
// ejb key class
393
case NameMapper.USER_DEFINED_KEY_CLASS:
394                     testClass = nameMapper.getKeyClassForEjbName(ejbName);
395                     break;
396                 // find the field name we need in the abstract bean
397
case NameMapper.PRIMARY_KEY_FIELD:
398                     return Arrays.asList(new String JavaDoc[]{
399                         getCMPDescriptor(ejbName).
400                         getPrimaryKeyFieldDesc().getName()});
401                 // find the field name we need in the persistence capable
402
case NameMapper.UNKNOWN_KEY_CLASS:
403                     String JavaDoc pcClassName =
404                         nameMapper.getPersistenceClassForEjbName(ejbName);
405                     PersistenceFieldElement[] fields =
406                         getPersistenceClass(pcClassName).getFields();
407                     int i, count = ((fields != null) ? fields.length : 0);
408
409                     for (i = 0; i < count; i++)
410                     {
411                         PersistenceFieldElement pfe = fields[i];
412
413                         if (pfe.isKey())
414                             return Arrays.asList(new String JavaDoc[]{pfe.getName()});
415                     }
416                     break;
417             }
418         }
419
420         return super.getFields(testClass);
421     }
422
423     /** Returns a list of names of all the field elements in the
424      * class with the specified name. This list includes the inherited
425      * fields. If the specified className represents a
426      * persistence-capable class, the list of field names from the
427      * corresponding ejb is returned (even if there is a Class object
428      * available for the persistence-capable). This method overrides
429      * the one in Model in order to do special handling for a
430      * persistence-capable key class name which corresponds to a bean
431      * with a primary key field. In that case, we don't want to
432      * climb the inheritance hierarchy of the primary key field type.
433      * @param className the fully qualified name of the class to be checked
434      * @return the names of the field elements for the specified class
435      */

436     public List getAllFields (String JavaDoc className)
437     {
438         // If the class name corresponds to a pk field (which means that
439
// there is no user defined primary key class, we don't want to
440
// climb the inheritance hierarchy, we only process this class.
441
return ((NameMapper.PRIMARY_KEY_FIELD ==
442             getPersistenceKeyClassType(className)) ? getFields(className) :
443             super.getAllFields(className));
444     }
445
446     /** Returns a wrapped field element for the specified fieldName in the
447      * class with the specified className. If the specified className
448      * represents a persistence-capable class, a field representing the
449      * field in the abstract bean class for the corresponding ejb is always
450      * returned (even if there is a Field object available for the
451      * persistence-capable). If there is an ejb name and an abstract bean
452      * class with the same name, the abstract bean class which is associated
453      * with the ejb will be used, not the abstract bean class which
454      * corresponds to the supplied name (directly).
455      * @param className the fully qualified name of the class which contains
456      * the field to be checked
457      * @param fieldName the name of the field to be checked
458      * @return the wrapped field element for the specified fieldName
459      */

460     public Object JavaDoc getField (final String JavaDoc className, String JavaDoc fieldName)
461     {
462         String JavaDoc testClass = className;
463         Object JavaDoc returnObject = null;
464
465         if (className != null)
466         {
467             NameMapper nameMapper = getNameMapper();
468             boolean isPCClass = isPCClassName(className);
469             boolean isPKClassName = false;
470             String JavaDoc searchClassName = className;
471             String JavaDoc searchFieldName = fieldName;
472
473             // translate the class name & field names to corresponding
474
// ejb name's abstract bean equivalents if necessary
475
if (isPCClass)
476             {
477                 searchFieldName = nameMapper.
478                     getEjbFieldForPersistenceField(className, fieldName);
479                 searchClassName = getEjbName(className);
480             }
481             else // check if it's a pk class without a user defined key class
482
{
483                 String JavaDoc ejbName =
484                     nameMapper.getEjbNameForPersistenceKeyClass(className);
485
486                 switch (getPersistenceKeyClassType(className))
487                 {
488                     // find the field we need in the corresponding
489
// abstract bean (translated below from ejbName)
490
case NameMapper.PRIMARY_KEY_FIELD:
491                         testClass = ejbName;
492                         searchClassName = ejbName;
493                         isPKClassName = true;
494                         break;
495                     // find the field we need by called updateFieldWrapper
496
// below which handles the generated field for the
497
// unknown key class - need to use the
498
// persistence-capable class name and flag to call that
499
// code, so we configure it here
500
case NameMapper.UNKNOWN_KEY_CLASS:
501                         testClass = nameMapper.
502                             getPersistenceClassForEjbName(ejbName);
503                         isPCClass = true;
504                         isPKClassName = true;
505                         break;
506                 }
507             }
508
509             if (nameMapper.isEjbName(searchClassName))
510             {
511                 searchClassName = nameMapper.
512                     getAbstractBeanClassForEjbName(searchClassName);
513             }
514
515             returnObject = super.getField(searchClassName, searchFieldName);
516
517             if (returnObject == null) // try getting it from the descriptor
518
returnObject = getFieldWrapper(testClass, searchFieldName);
519             else if (returnObject instanceof Field) // wrap it
520
returnObject = new MemberWrapper((Field)returnObject);
521
522             if (isPCClass)
523             {
524                 returnObject = updateFieldWrapper(
525                     (MemberWrapper)returnObject, testClass, fieldName);
526             }
527             // when asking for these fields as part of the
528
// persistence-capable's key class, we need to represent the
529
// public modifier which will be generated in the inner class
530
if (isPKClassName && (returnObject instanceof MemberWrapper))
531                 ((MemberWrapper)returnObject)._modifiers = Modifier.PUBLIC;
532             
533         }
534
535         return returnObject;
536     }
537
538     /** Returns the field type for the specified fieldName in the class
539      * with the specified className. This method is overrides the one in
540      * Model in order to do special handling for non-collection relationship
541      * fields. If it's a generated relationship that case, the returned
542      * MemberWrapper from getField contains a type of the abstract bean and
543      * it's impossible to convert that into the persistence capable class name, so here
544      * that case is detected, and if found, the ejb name is extracted and
545      * used to find the corresponding persistence capable class. For a
546      * relationship which is of type of the local interface, we do the
547      * conversion from local interface to persistence-capable class. In the
548      * case of a collection relationship (generated or not), the superclass'
549      * implementation which provides the java type is sufficient.
550      * @param className the fully qualified name of the class which contains
551      * the field to be checked
552      * @param fieldName the name of the field to be checked
553      * @return the field type for the specified fieldName
554      */

555     public String JavaDoc getFieldType (String JavaDoc className, String JavaDoc fieldName)
556     {
557         String JavaDoc returnType = super.getFieldType(className, fieldName);
558
559         if (!isCollection(returnType) && isPCClassName(className))
560         {
561             NameMapper nameMapper = getNameMapper();
562             String JavaDoc ejbName =
563                 nameMapper.getEjbNameForPersistenceClass(className);
564             String JavaDoc ejbField =
565                 nameMapper.getEjbFieldForPersistenceField(className, fieldName);
566
567             if (nameMapper.isGeneratedEjbRelationship(ejbName, ejbField))
568             {
569                 String JavaDoc[] inverse =
570                     nameMapper.getEjbFieldForGeneratedField(ejbName, ejbField);
571             
572                 returnType = nameMapper.
573                     getPersistenceClassForEjbName(inverse[0]);
574             }
575
576             if (nameMapper.isLocalInterface(returnType))
577             {
578                 returnType = nameMapper.getPersistenceClassForLocalInterface(
579                     className, fieldName, returnType);
580             }
581         }
582
583         return returnType;
584     }
585
586     /** Returns the string representation of declaring class of
587      * the specified member element. Note, the member element is
588      * either a class element as returned by getClass, a field element
589      * as returned by getField, a constructor element as returned by
590      * getConstructor, or a method element as returned by getMethod
591      * executed on the same model instance. This implementation expects
592      * the member element to be a reflection instance or a wrapped member
593      * instance.
594      * @param memberElement the member element to be checked
595      * @return the string representation of the declaring class of
596      * the specified memberElement
597      * @see #getClass
598      * @see #getField
599      * @see #getConstructor
600      * @see #getMethod
601      */

602     public String JavaDoc getDeclaringClass (Object JavaDoc memberElement)
603     {
604         if ((memberElement != null) && (memberElement instanceof MemberWrapper))
605         {
606             Class JavaDoc classElement =
607                 ((MemberWrapper)memberElement).getDeclaringClass();
608
609             return ((classElement != null) ? classElement.getName() : null);
610         }
611
612         return super.getDeclaringClass(memberElement);
613     }
614
615     /** Returns the modifier mask for the specified member element.
616      * Note, the member element is either a class element as returned by
617      * getClass, a member wrapper element as returned by getField or
618      * getMethod, a constructor element as returned by getConstructor
619      * executed on the same model instance.
620      * This implementation expects the member element being a reflection
621      * instance or a wrapped member instance.
622      * @param memberElement the member element to be checked
623      * @return the modifier mask for the specified memberElement
624      * @see java.lang.reflect.Modifier
625      * @see #getClass
626      * @see #getField
627      * @see #getConstructor
628      * @see #getMethod
629      */

630     public int getModifiers (Object JavaDoc memberElement)
631     {
632         if ((memberElement != null) && (memberElement instanceof MemberWrapper))
633             return ((MemberWrapper)memberElement).getModifiers();
634
635         return super.getModifiers(memberElement);
636     }
637
638     /** Returns the modifier mask for the specified className. This method
639      * overrides the one in Model to strip out the abstract modifier when
640      * the persistence capable class is represented by the abstract bean.
641      * It also adds the static modifier when the specified class represents
642      * the persistence capable key class which will be generated.
643      * @param className the fully qualified name of the class to be checked
644      * @return the modifier mask for the specified class
645      * @see java.lang.reflect.Modifier
646      */

647     public int getModifiersForClass (String JavaDoc className)
648     {
649         int modifiers = super.getModifiersForClass(className);
650
651         if (isPCClassName(className))
652             modifiers &= ~Modifier.ABSTRACT;
653         else if (getNameMapper().
654             getKeyClassForPersistenceKeyClass(className) != null)
655         {
656             modifiers |= Modifier.STATIC;
657         }
658
659         return modifiers;
660     }
661
662     /** Determines if the specified className and fieldName pair represent a
663      * field which has a type which is valid for key fields. Valid key
664      * field types include non-collection SCOs (wrappers, Date, Time, etc.)
665      * and primitives for user defined key classes. This method overrides
666      * the one in Model in order to do special handling for a
667      * persistence-capable key class name which corresponds to a bean
668      * with a primary key field. In that case, we want to restrict the
669      * list of allowable types not to include primitives.
670      * @param className the fully qualified name of the class which contains
671      * the field to be checked
672      * @param fieldName the name of the field to be checked
673      * @return <code>true</code> if this field name represents a field
674      * with a valid type for a key field; <code>false</code> otherwise.
675      */

676     public boolean isValidKeyType (String JavaDoc className, String JavaDoc fieldName)
677     {
678         return (((NameMapper.PRIMARY_KEY_FIELD ==
679             getPersistenceKeyClassType(className)) &&
680             isPrimitive(className, fieldName)) ? false :
681             super.isValidKeyType(className, fieldName));
682     }
683
684     /** Returns the Class type of the specified element.
685      * If element denotes a field, it returns the type of the field.
686      * If element denotes a method, it returns the return type of the method.
687      * Note, element is either a field element as returned by getField, or a
688      * method element as returned by getMethod executed on the same model
689      * instance.
690      * @param element the element to be checked
691      * @return the Class type of the element
692      * @see #getField
693      * @see RuntimeModel#getMethod
694      */

695     protected Class JavaDoc getTypeObject (Object JavaDoc element)
696     {
697         Class JavaDoc type = super.getTypeObject(element);
698
699         if ((element != null) && (element instanceof MemberWrapper))
700             type = ((MemberWrapper)element).getType();
701
702         return type;
703     }
704
705     /**
706      * This method returns the class loader used to find mapping information
707      * for the specified className. This implementation overrides the one in
708      * RuntimeModel so that it always returns the ClassLoader provided at
709      * construction time.
710      * @param className the fully qualified name of the class to be checked
711      * @param classLoader the class loader used to find mapping information
712      * @return the class loader used to find mapping information for the
713      * specified className
714      */

715     protected ClassLoader JavaDoc findClassLoader (String JavaDoc className,
716         ClassLoader JavaDoc classLoader)
717     {
718         return getClassLoader();
719     }
720
721     // return true if a conversion to a ejb class is needed for
722
// java.lang.reflect metadata
723
private boolean isPCClassName (String JavaDoc className)
724     {
725         return (getEjbName(className) != null);
726     }
727
728     private String JavaDoc getEjbName (String JavaDoc className)
729     {
730         return getNameMapper().getEjbNameForPersistenceClass(className);
731     }
732
733     private EjbCMPEntityDescriptor getCMPDescriptor (String JavaDoc className)
734     {
735         String JavaDoc descriptorName = (isPCClassName(className) ?
736             getEjbName(className) : className);
737
738         return getNameMapper().getDescriptorForEjbName(descriptorName);
739     }
740
741     private int getPersistenceKeyClassType (String JavaDoc className)
742     {
743         int returnValue = -1;
744
745         if (getCMPDescriptor(className) == null)
746         {
747             NameMapper nameMapper = getNameMapper();
748             String JavaDoc ejbName =
749                 nameMapper.getEjbNameForPersistenceKeyClass(className);
750
751             if (ejbName != null)
752                 returnValue = nameMapper.getKeyClassTypeForEjbName(ejbName);
753         }
754
755         return returnValue;
756     }
757
758     private MemberWrapper getFieldWrapper (String JavaDoc className, String JavaDoc fieldName)
759     {
760         EjbCMPEntityDescriptor descriptor = getCMPDescriptor(className);
761         MemberWrapper returnObject = null;
762
763         if (descriptor != null)
764         {
765             PersistenceDescriptor persistenceDescriptor =
766                 descriptor.getPersistenceDescriptor();
767
768             if (persistenceDescriptor != null)
769             {
770                 Class JavaDoc fieldType = null;
771
772                 try
773                 {
774                     fieldType = persistenceDescriptor.getTypeFor(fieldName);
775                 }
776                 catch (RuntimeException JavaDoc e)
777                 {
778                     // fieldType will be null - there is no such field
779
}
780
781                 returnObject = ((fieldType == null) ? null :
782                     new MemberWrapper(fieldName, fieldType,
783                     Modifier.PRIVATE, (Class JavaDoc)getClass(className)));
784             }
785         }
786
787         return returnObject;
788     }
789
790     private MemberWrapper updateFieldWrapper (MemberWrapper returnObject,
791         String JavaDoc className, String JavaDoc fieldName)
792     {
793         NameMapper nameMapper = getNameMapper();
794
795         if (returnObject == null)
796         {
797             // can't call isPersistent or isKey because that calls
798
// hasField which calls getField and that would end up
799
// in an endless loop
800
PersistenceFieldElement field =
801                 getPersistenceFieldInternal(className, fieldName);
802
803             if (field != null)
804             {
805                 String JavaDoc ejbName = getEjbName(className);
806                 String JavaDoc ejbFieldName = nameMapper.
807                     getEjbFieldForPersistenceField(className, fieldName);
808
809                 // Check if this is the auto-added field for unknown pk
810
// support. If so, return a private field of type Long.
811
if (field.isKey() && (ejbName != null) &&
812                     (nameMapper.getKeyClassTypeForEjbName(ejbName) ==
813                     NameMapper.UNKNOWN_KEY_CLASS))
814                 {
815                     returnObject = new MemberWrapper(ejbFieldName,
816                         Long JavaDoc.class, Modifier.PRIVATE,
817                         (Class JavaDoc)getClass(className));
818                 }
819
820                 // Check if this is the auto-added field for 2 way managed rels
821
// support. If so, return a private field of type according to
822
// cardinality of the relationship.
823
else if ((field instanceof RelationshipElement) &&
824                     nameMapper.isGeneratedEjbRelationship(ejbName,
825                     ejbFieldName))
826                 {
827                     RelationshipElement rel = (RelationshipElement)field;
828                     Class JavaDoc classType = null;
829
830                     // figure out the type
831
if (rel.getUpperBound() > 1)
832                         classType = java.util.HashSet JavaDoc.class;
833                     else
834                     {
835                         String JavaDoc[] inverse = nameMapper.
836                             getEjbFieldForGeneratedField(ejbName, ejbFieldName);
837
838                         classType = (Class JavaDoc)getClass(inverse[0]);
839                     }
840
841                     if (classType != null)
842                     {
843                         returnObject = new MemberWrapper(ejbFieldName,
844                             classType, Modifier.PRIVATE,
845                             (Class JavaDoc)getClass(className));
846                     }
847                 }
848                 // Check if this is the auto-added version field.
849
// If so, return a private field of type long.
850
else if (ejbFieldName.startsWith(
851                     NameMapper.GENERATED_VERSION_FIELD_PREFIX) &&
852                     nameMapper.isGeneratedField(ejbName, ejbFieldName))
853                 {
854                     returnObject = new MemberWrapper(ejbFieldName,
855                         Long.TYPE, Modifier.PRIVATE,
856                         (Class JavaDoc)getClass(className));
857                 }
858             }
859         }
860
861         // if the field in the corresponding ejb is a serializable,
862
// non-primitive, non-wrapper type, convert it to byte[] here
863
if (!isPersistentTypeAllowed(getType(returnObject),
864             getClassLoader()) && isSerializable(returnObject))
865         {
866             returnObject.setType(byte[].class);
867         }
868
869         return returnObject;
870     }
871
872     private class MemberWrapper
873     {
874         private String JavaDoc _name;
875         private Class JavaDoc _type;
876         private int _modifiers;
877         private Class JavaDoc _declaringClass;
878
879         private MemberWrapper (Member member)
880         {
881             this(member.getName(), ((member instanceof Field) ?
882                 ((Field)member).getType() : ((member instanceof Method) ?
883                 ((Method)member).getReturnType() : null)),
884                 member.getModifiers(), member.getDeclaringClass());
885         }
886
887         private MemberWrapper (String JavaDoc name, Class JavaDoc type, int modifiers,
888             Class JavaDoc declaringClass)
889         {
890             _name = name;
891             _type = type;
892             _modifiers = modifiers;
893             _declaringClass = declaringClass;
894         }
895
896         private Class JavaDoc getType () { return _type; }
897         private void setType (Class JavaDoc type) { _type = type; }
898         private String JavaDoc getName () { return _name; }
899         private int getModifiers () { return _modifiers; }
900         private Class JavaDoc getDeclaringClass () { return _declaringClass; }
901
902         /** Returns a string representation of this object.
903          * @return a string reprentation of the member wrapper object.
904          */

905         public String JavaDoc toString () { return getName(); }
906     }
907 }
908
Popular Tags