KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > descriptors > MethodClassExtractor


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.descriptors;
23
24 import java.lang.reflect.*;
25 import java.security.AccessController JavaDoc;
26 import java.security.PrivilegedActionException JavaDoc;
27
28 import oracle.toplink.essentials.internal.helper.*;
29 import oracle.toplink.essentials.exceptions.*;
30 import oracle.toplink.essentials.descriptors.ClassDescriptor;
31 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
32 import oracle.toplink.essentials.sessions.Session;
33 import oracle.toplink.essentials.sessions.Record;
34 import oracle.toplink.essentials.internal.security.*;
35
36 /**
37  * <p><b>Purpose</b>:
38  * Used to allow complex inheritance support. Typically class indicators are used to define inheritance in the database,
39  * however in complex cases the class type may be determined through another mechanism.
40  * The method calls a static method on the descriptor class to determine the class to use for the database row.
41  *
42  * @see oracle.toplink.essentials.descriptors.InheritancePolicy#setClassExtractor(ClassExtrator)
43  */

44 public class MethodClassExtractor extends ClassExtractor {
45     protected transient ClassDescriptor descriptor;
46     protected String JavaDoc classExtractionMethodName;
47     protected transient Method classExtractionMethod;
48
49     /**
50      * INTERNAL:
51      * Return all the classExtractionMethod
52      */

53     public Method getClassExtractionMethod() {
54         return classExtractionMethod;
55     }
56
57     /**
58      * PUBLIC:
59      * A class extraction method can be registered with the descriptor to override the default inheritance mechanism.
60      * This allows for the class indicator field to not be used, and a user defined one instead.
61      * The method registered must be a static method on the class that the descriptor is for,
62      * the method must take DatabaseRow as argument, and must return the class to use for that row.
63      * This method will be used to decide which class to instantiate when reading from the database.
64      * It is the application's responsiblity to populate any typing information in the database required
65      * to determine the class from the row.
66      * If this method is used then the class indicator field and mapping cannot be used,
67      * also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.
68      */

69     public String JavaDoc getClassExtractionMethodName() {
70         return classExtractionMethodName;
71     }
72
73     /**
74      * INTERNAL:
75      */

76     protected void setClassExtractionMethod(Method classExtractionMethod) {
77         this.classExtractionMethod = classExtractionMethod;
78     }
79
80     /**
81      * PUBLIC:
82      * A class extraction method can be registered with the descriptor to override the default inheritance mechanism.
83      * This allows for the class indicator field to not be used, and a user defined one instead.
84      * The method registered must be a static method on the class that the descriptor is for,
85      * the method must take DatabaseRow as argument, and must return the class to use for that row.
86      * This method will be used to decide which class to instantiate when reading from the database.
87      * It is the application's responsiblity to populate any typing information in the database required
88      * to determine the class from the row.
89      * If this method is used then the class indicator field and mapping cannot be used,
90      * also the descriptor's withAllSubclasses and onlyInstances expressions must also be setup correctly.
91      */

92     public void setClassExtractionMethodName(String JavaDoc staticClassClassExtractionMethod) {
93         this.classExtractionMethodName = staticClassClassExtractionMethod;
94     }
95
96     /**
97      * INTERNAL:
98      * Setup the default classExtractionMethod, or if one was specified by the user make sure it is valid.
99      */

100     public void initialize(ClassDescriptor descriptor, Session session) throws DescriptorException {
101         setDescriptor(descriptor);
102         Class JavaDoc[] declarationParameters = new Class JavaDoc[1];
103         declarationParameters[0] = ClassConstants.DatabaseRow_Class;
104
105         try {
106             setClassExtractionMethod(Helper.getDeclaredMethod(descriptor.getJavaClass(), getClassExtractionMethodName(), declarationParameters));
107         } catch (NoSuchMethodException JavaDoc ignore) {
108             declarationParameters[0] = ClassConstants.Record_Class;
109             try {
110                 setClassExtractionMethod(Helper.getDeclaredMethod(descriptor.getJavaClass(), getClassExtractionMethodName(), declarationParameters));
111             } catch (NoSuchMethodException JavaDoc exception) {
112                 throw DescriptorException.noSuchMethodWhileInitializingClassExtractionMethod(getClassExtractionMethodName(), descriptor, exception);
113             }
114         } catch (SecurityException JavaDoc exception) {
115             throw DescriptorException.securityWhileInitializingClassExtractionMethod(getClassExtractionMethodName(), descriptor, exception);
116         }
117
118         // CR#2818667 Ensure the method is static.
119
if (!Modifier.isStatic(getClassExtractionMethod().getModifiers())) {
120             throw DescriptorException.classExtractionMethodMustBeStatic(getClassExtractionMethodName(), descriptor);
121         }
122     }
123
124     /**
125      * INTERNAL
126      * Extract/compute the class from the database row and return the class.
127      * Map is used as the public interface to database row, the key is the field name,
128      * the value is the database value.
129      */

130     public Class JavaDoc extractClassFromRow(Record row, oracle.toplink.essentials.sessions.Session session) {
131         Class JavaDoc classForRow;
132
133         try {
134             Object JavaDoc[] arguments = new Object JavaDoc[1];
135             arguments[0] = row;
136             if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
137                 try {
138                     classForRow = (Class JavaDoc)AccessController.doPrivileged(new PrivilegedMethodInvoker(getClassExtractionMethod(), null, arguments));
139                 } catch (PrivilegedActionException JavaDoc exception) {
140                     Exception JavaDoc throwableException = exception.getException();
141                     if (throwableException instanceof IllegalAccessException JavaDoc) {
142                         throw DescriptorException.illegalAccessWhileInvokingRowExtractionMethod((AbstractRecord)row, getClassExtractionMethod(), getDescriptor(), throwableException);
143                     } else {
144                         throw DescriptorException.targetInvocationWhileInvokingRowExtractionMethod((AbstractRecord)row, getClassExtractionMethod(), getDescriptor(), throwableException);
145                     }
146                 }
147             } else {
148                 classForRow = (Class JavaDoc)PrivilegedAccessHelper.invokeMethod(getClassExtractionMethod(), null, arguments);
149             }
150         } catch (IllegalAccessException JavaDoc exception) {
151             throw DescriptorException.illegalAccessWhileInvokingRowExtractionMethod((AbstractRecord)row, getClassExtractionMethod(), getDescriptor(), exception);
152         } catch (InvocationTargetException exception) {
153             throw DescriptorException.targetInvocationWhileInvokingRowExtractionMethod((AbstractRecord)row, getClassExtractionMethod(), getDescriptor(), exception);
154         }
155
156         return classForRow;
157     }
158
159     /**
160      * INTERNAL:
161      * Return the descriptor.
162      */

163     protected ClassDescriptor getDescriptor() {
164         return descriptor;
165     }
166
167     /**
168      * INTERNAL:
169      * Set the descriptor.
170      */

171     protected void setDescriptor(ClassDescriptor descriptor) {
172         this.descriptor = descriptor;
173     }
174 }
175
Popular Tags