1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.services.reflect.ReflectGeneratedClass |
4 | |
5 | Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.impl.services.reflect; |
22 | |
23 | import org.apache.derby.iapi.services.loader.GeneratedMethod; |
24 | import org.apache.derby.iapi.services.loader.GeneratedByteCode; |
25 | import org.apache.derby.iapi.services.loader.ClassFactory; |
26 | |
27 | import org.apache.derby.iapi.error.StandardException; |
28 | import org.apache.derby.iapi.reference.SQLState; |
29 | |
30 | import org.apache.derby.iapi.services.context.Context; |
31 | |
32 | import java.lang.reflect.Method; |
33 | import java.util.Hashtable; |
34 | |
35 | public final class ReflectGeneratedClass extends LoadedGeneratedClass { |
36 | |
37 | private final Hashtable methodCache; |
38 | private static final GeneratedMethod[] directs; |
39 | |
40 | |
41 | private final Class factoryClass; |
42 | private GCInstanceFactory factory; |
43 | |
44 | static { |
45 | directs = new GeneratedMethod[10]; |
46 | for (int i = 0; i < directs.length; i++) { |
47 | directs[i] = new DirectCall(i); |
48 | } |
49 | } |
50 | |
51 | public ReflectGeneratedClass(ClassFactory cf, Class jvmClass, Class factoryClass) { |
52 | super(cf, jvmClass); |
53 | methodCache = new Hashtable(); |
54 | this.factoryClass = factoryClass; |
55 | } |
56 | |
57 | public Object newInstance(Context context) throws StandardException { |
58 | if (factoryClass == null) { |
59 | return super.newInstance(context); |
60 | } |
61 | |
62 | if (factory == null) { |
63 | |
64 | Throwable t; |
65 | try { |
66 | factory = (GCInstanceFactory) factoryClass.newInstance(); |
67 | t = null; |
68 | } catch (InstantiationException ie) { |
69 | t = ie; |
70 | } catch (IllegalAccessException iae) { |
71 | t = iae; |
72 | } catch (LinkageError le) { |
73 | t = le; |
74 | } |
75 | |
76 | if (t != null) |
77 | throw StandardException.newException(SQLState.GENERATED_CLASS_INSTANCE_ERROR, t, getName()); |
78 | } |
79 | |
80 | GeneratedByteCode ni = factory.getNewInstance(); |
81 | ni.initFromContext(context); |
82 | ni.setGC(this); |
83 | ni.postConstructor(); |
84 | return ni; |
85 | |
86 | } |
87 | |
88 | public GeneratedMethod getMethod(String simpleName) |
89 | throws StandardException { |
90 | |
91 | GeneratedMethod rm = (GeneratedMethod) methodCache.get(simpleName); |
92 | if (rm != null) |
93 | return rm; |
94 | |
95 | // Only look for methods that take no arguments |
96 | try { |
97 | if ((simpleName.length() == 2) && simpleName.startsWith("e")) { |
98 | |
99 | int id = ((int) simpleName.charAt(1)) - '0'; |
100 | |
101 | rm = directs[id]; |
102 | |
103 | |
104 | } |
105 | else |
106 | { |
107 | Method m = getJVMClass().getMethod(simpleName, (Class []) null); |
108 | |
109 | rm = new ReflectMethod(m); |
110 | } |
111 | methodCache.put(simpleName, rm); |
112 | return rm; |
113 | |
114 | } catch (NoSuchMethodException nsme) { |
115 | throw StandardException.newException(SQLState.GENERATED_CLASS_NO_SUCH_METHOD, |
116 | nsme, getName(), simpleName); |
117 | } |
118 | } |
119 | } |
120 | |
121 | class DirectCall implements GeneratedMethod { |
122 | |
123 | private final int which; |
124 | |
125 | DirectCall(int which) { |
126 | |
127 | this.which = which; |
128 | } |
129 | |
130 | public Object invoke(Object ref) |
131 | throws StandardException { |
132 | |
133 | try { |
134 | |
135 | GeneratedByteCode gref = (GeneratedByteCode) ref; |
136 | switch (which) { |
137 | case 0: |
138 | return gref.e0(); |
139 | case 1: |
140 | return gref.e1(); |
141 | case 2: |
142 | return gref.e2(); |
143 | case 3: |
144 | return gref.e3(); |
145 | case 4: |
146 | return gref.e4(); |
147 | case 5: |
148 | return gref.e5(); |
149 | case 6: |
150 | return gref.e6(); |
151 | case 7: |
152 | return gref.e7(); |
153 | case 8: |
154 | return gref.e8(); |
155 | case 9: |
156 | return gref.e9(); |
157 | } |
158 | return null; |
159 | } catch (StandardException se) { |
160 | throw se; |
161 | } |
162 | catch (Throwable t) { |
163 | throw StandardException.unexpectedUserException(t); |
164 | } |
165 | } |
166 | } |