KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > proactive > core > component > asmgen > MetaObjectInterfaceClassGenerator


1 /*
2  * ################################################################
3  *
4  * ProActive: The Java(TM) library for Parallel, Distributed,
5  * Concurrent computing with Security and Mobility
6  *
7  * Copyright (C) 1997-2004 INRIA/University of Nice-Sophia Antipolis
8  * Contact: proactive-support@inria.fr
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  * USA
24  *
25  * Initial developer(s): The ProActive Team
26  * http://www.inria.fr/oasis/ProActive/contacts.html
27  * Contributor(s):
28  *
29  * ################################################################
30  */

31 package org.objectweb.proactive.core.component.asmgen;
32
33 import org.apache.log4j.Logger;
34
35 import org.objectweb.asm.CodeVisitor;
36 import org.objectweb.asm.Type;
37
38 import org.objectweb.fractal.api.Component;
39 import org.objectweb.fractal.api.type.InterfaceType;
40
41 import org.objectweb.proactive.core.component.ProActiveInterface;
42 import org.objectweb.proactive.core.component.exceptions.InterfaceGenerationFailedException;
43
44 import java.io.Serializable JavaDoc;
45
46 import java.lang.reflect.Method JavaDoc;
47
48 import java.util.Hashtable JavaDoc;
49 import java.util.Vector JavaDoc;
50
51
52 /**
53  * Creates Interface implementations for the functional interfaces of the
54  * component metaobject.
55  *<br>
56  * The functional calls are delegated to the "impl" field, whose value is set during
57  * binding operations.
58  *<br>
59  * - In case of a primitive component, the impl field will be the reified object to
60  * which the body is attached.<br>
61  * - In case of a composite component, the impl field will be a component
62  * representative.<br>
63  * - For a parallel component, the impl field will be a group of component representatives.<br>
64  *
65  * @author Matthieu Morel
66  *
67  */

68 public class MetaObjectInterfaceClassGenerator
69     extends AbstractInterfaceClassGenerator {
70     protected static Logger logger = Logger.getLogger(MetaObjectInterfaceClassGenerator.class.getName());
71     protected static final String JavaDoc IMPL_FIELD_NAME = "impl"; //delegatee
72
private static MetaObjectInterfaceClassGenerator instance;
73
74     // generatedClassesCache that contains all the generated classes according to their name
75
private static Hashtable JavaDoc generatedClassesCache = new Hashtable JavaDoc();
76
77     // Those fields contain information about the class
78
// for which we are building a wrapper
79
protected Class JavaDoc cl;
80     protected String JavaDoc className;
81     protected String JavaDoc packageName;
82
83     // this boolean for deciding of a possible indirection for the functionnal calls
84
protected boolean isPrimitive = false;
85
86     public MetaObjectInterfaceClassGenerator() {
87         // Obtains the object that represents the type we want to create
88
// a wrapper class for. This call may fail with a ClassNotFoundException
89
// if the class corresponding to this type cannot be found.
90
this.cl = ProActiveInterface.class;
91
92         // Keep this info at hand for performance purpose
93
this.className = cl.getName();
94
95         //generatedClassesCache = new Hashtable();
96
}
97
98     public static MetaObjectInterfaceClassGenerator instance() {
99         if (instance == null) {
100             return new MetaObjectInterfaceClassGenerator();
101         } else {
102             return instance;
103         }
104     }
105
106     /**
107      * retreives the bytecode associated to the generated class of the given name
108      */

109     public static byte[] getClassData(String JavaDoc classname) {
110         return (byte[]) getGeneratedClassesCache().get(classname);
111     }
112
113     /**
114              * Returns the generatedClassesCache.
115              * @return Hashtable
116              */

117     public static Hashtable JavaDoc getGeneratedClassesCache() {
118         return generatedClassesCache;
119     }
120
121     public ProActiveInterface generateInterface(final String JavaDoc fcInterfaceName,
122         Component owner, InterfaceType interfaceType, boolean isInternal,
123         boolean isPrimitive) throws InterfaceGenerationFailedException {
124         try {
125             if (logger.isDebugEnabled()) {
126                 logger.debug("generating metaobject interface reference");
127             }
128
129             //isPrimitive = ((ProActiveComponent) owner).getHierarchicalType().equals(ComponentParameters.PRIMITIVE);
130
interfacesToImplement = new Vector JavaDoc();
131
132             // add functional interface
133
interfacesToImplement.add(Class.forName(
134                     interfaceType.getFcItfSignature()));
135
136             // add Serializable interface
137
interfacesToImplement.addElement(Serializable JavaDoc.class);
138
139             this.stubClassFullName = org.objectweb.proactive.core.component.asmgen.Utils.getMetaObjectClassName(fcInterfaceName,
140                     interfaceType.getFcItfSignature());
141
142             Class JavaDoc generated_class;
143
144             // check whether class has already been generated
145
try {
146                 generated_class = loadClass(stubClassFullName);
147             } catch (ClassNotFoundException JavaDoc cnfe) {
148                 byte[] bytes;
149                 setInfos();
150                 bytes = create();
151                 getGeneratedClassesCache().put(stubClassFullName, bytes);
152                 if (logger.isDebugEnabled()) {
153                     logger.debug("added " + stubClassFullName + " to cache");
154                     logger.debug("generated classes cache is : " +
155                         getGeneratedClassesCache().toString());
156                 }
157
158                 // // Next few lines for debugging only
159
// try {
160
// //java.io.File file = new java.io.File(System.getProperty("user.home") + "/ProActive/generated/" + stubClassFullName + ".class");
161
// java.io.File file = new java.io.File("generated/" + stubClassFullName + ".class");
162
//
163
// java.io.FileOutputStream fos = new java.io.FileOutputStream(file);
164
// fos.write(bytes);
165
// fos.close();
166
// } catch (Exception e) {
167
// // e.printStackTrace();
168
// logger.info("if you want a dump of the generated classes, you need to create a /generated folder at the root of you command");
169
// }
170
// convert the bytes into a Class
171
generated_class = defineClass(stubClassFullName, bytes);
172             }
173
174             ProActiveInterface reference = (ProActiveInterface) generated_class.newInstance();
175             reference.setName(fcInterfaceName);
176             reference.setOwner(owner);
177             reference.setType(interfaceType);
178             reference.setIsInternal(isInternal);
179
180             return reference;
181         } catch (ClassNotFoundException JavaDoc e) {
182             throw new InterfaceGenerationFailedException("cannot find interface signature class",
183                 e);
184         } catch (IllegalAccessException JavaDoc e) {
185             throw new InterfaceGenerationFailedException("constructor not accessible",
186                 e);
187         } catch (InstantiationException JavaDoc e) {
188             throw new InterfaceGenerationFailedException("constructor belongs to an abstract class?",
189                 e);
190         }
191     }
192
193     protected void createGetAndSetFcItfImplMethods() {
194         // Do the getFcItfImpl method first
195
CodeVisitor cv = this.classGenerator.visitMethod(ACC_PUBLIC,
196                 "getFcItfImpl", "()" + OBJECT_TYPE, null, null);
197
198         // Now, fills in the instruction list
199
cv.visitVarInsn(ALOAD, 0);
200         cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'),
201             IMPL_FIELD_NAME, OBJECT_TYPE);
202         cv.visitInsn(ARETURN);
203
204         // Needed stack size
205
// Needed locals
206
cv.visitMaxs(0, 0);
207
208         // Now, do the setProxy method
209
cv = this.classGenerator.visitMethod(ACC_PUBLIC, "setFcItfImpl",
210                 "(" + OBJECT_TYPE + ")V", null, null);
211
212         // Now, fills in the instruction list
213
cv.visitVarInsn(ALOAD, 0);
214         cv.visitVarInsn(ALOAD, 1);
215
216         // add a cast if there is only one interface?
217
cv.visitFieldInsn(PUTFIELD, this.stubClassFullName.replace('.', '/'),
218             IMPL_FIELD_NAME, OBJECT_TYPE);
219         cv.visitInsn(RETURN);
220
221         // Needed stack size
222
// Needed locals
223
cv.visitMaxs(0, 0);
224
225         return;
226     }
227
228     protected CodeVisitor createMethod(int methodIndex, Method JavaDoc m) {
229         String JavaDoc itf = Type.getInternalName(m.getDeclaringClass());
230         String JavaDoc method_name = m.getName();
231         String JavaDoc method_descriptor = Type.getMethodDescriptor(m);
232         CodeVisitor cv = createMethodGenerator(m);
233
234         // step 1.
235
// Pushes on the stack the reference to the impl object
236
cv.visitVarInsn(ALOAD, 0);
237         cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'),
238             IMPL_FIELD_NAME, OBJECT_TYPE);
239
240         // add a cast if there is more than 1 interface implemented
241
if (interfacesToImplement.size() > 1) {
242             cv.visitTypeInsn(CHECKCAST, itf);
243         }
244
245         // Step 2.
246
Class JavaDoc[] paramTypes = m.getParameterTypes();
247         int offset = 1;
248         for (int i = 0; i < paramTypes.length; ++i) {
249             cv.visitVarInsn(ILOAD + getOpcodeOffset(paramTypes[i]), offset);
250             offset += getSize(paramTypes[i]);
251         }
252
253         // Step 3. invoke method m
254
cv.visitMethodInsn(INVOKEINTERFACE, itf, method_name, method_descriptor);
255
256         // Step 4. return the result
257
createReturnCode(cv, m.getReturnType());
258
259         cv.visitMaxs(0, 0); // max stack and max locals automatically computed
260

261         return cv;
262     }
263
264     protected void createFields() {
265         // Creates the field that points to the delegatee
266
this.classGenerator.visitField(ACC_PROTECTED, IMPL_FIELD_NAME,
267             OBJECT_TYPE, null, null);
268     }
269
270     protected void createStaticVariables() {
271         // no static variables
272
}
273
274     protected void createStaticInitializer() throws ClassNotFoundException JavaDoc {
275     }
276
277     /**
278      *implementation of abstract method from superclass
279      */

280     protected void createDefaultMethods() {
281         createGetAndSetFcItfImplMethods();
282     }
283 }
284
Popular Tags