Source Code Cross Referenced for PhysicalStateClassLoader.java in  » Net » Terracotta » com » tc » objectserver » managedobject » bytecode » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » Terracotta » com.tc.objectserver.managedobject.bytecode 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003:         * notice. All rights reserved.
004:         */
005:        package com.tc.objectserver.managedobject.bytecode;
006:
007:        import com.tc.asm.ClassWriter;
008:        import com.tc.asm.FieldVisitor;
009:        import com.tc.asm.Label;
010:        import com.tc.asm.MethodVisitor;
011:        import com.tc.asm.Opcodes;
012:        import com.tc.exception.TCRuntimeException;
013:        import com.tc.object.LiteralValues;
014:        import com.tc.object.ObjectID;
015:        import com.tc.util.AdaptedClassDumper;
016:        import com.tc.util.Assert;
017:
018:        import java.util.ArrayList;
019:        import java.util.Collections;
020:        import java.util.HashMap;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.Map;
024:
025:        public class PhysicalStateClassLoader extends ClassLoader implements 
026:                Opcodes {
027:
028:            public static class MethodDetail {
029:
030:                private final String methodName;
031:                private final String methodDesc;
032:
033:                public MethodDetail(String methodName, String methodDesc) {
034:                    this .methodName = methodName;
035:                    this .methodDesc = methodDesc;
036:                }
037:
038:                public String getMethodDescriptor() {
039:                    return methodDesc;
040:                }
041:
042:                public String getMethodName() {
043:                    return methodName;
044:                }
045:
046:            }
047:
048:            private static final String PARENT_ID_FIELD = "parentId";
049:
050:            private static final Map OBJECT_OUTPUT_METHODS = Collections
051:                    .synchronizedMap(new HashMap());
052:            private static final Map OBJECT_INPUT_METHODS = Collections
053:                    .synchronizedMap(new HashMap());
054:
055:            static {
056:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.INTEGER,
057:                        "writeInt", "(I)V");
058:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.LONG,
059:                        "writeLong", "(J)V");
060:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.CHARACTER,
061:                        "writeChar", "(I)V");
062:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.BYTE,
063:                        "writeByte", "(I)V");
064:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.SHORT,
065:                        "writeShort", "(I)V");
066:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.FLOAT,
067:                        "writeFloat", "(F)V");
068:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.DOUBLE,
069:                        "writeDouble", "(D)V");
070:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.BOOLEAN,
071:                        "writeBoolean", "(Z)V");
072:                // rest are written as Objects - Since we use TCObjectOutputStream, we optimize it there.
073:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.OBJECT,
074:                        "writeObject", "(Ljava/lang/Object;)V");
075:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.OBJECT_ID,
076:                        "writeObject", "(Ljava/lang/Object;)V");
077:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.ARRAY,
078:                        "writeObject", "(Ljava/lang/Object;)V");
079:                addMapping(OBJECT_OUTPUT_METHODS,
080:                        LiteralValues.JAVA_LANG_CLASS, "writeObject",
081:                        "(Ljava/lang/Object;)V");
082:                addMapping(OBJECT_OUTPUT_METHODS,
083:                        LiteralValues.JAVA_LANG_CLASS_HOLDER, "writeObject",
084:                        "(Ljava/lang/Object;)V");
085:                addMapping(OBJECT_OUTPUT_METHODS,
086:                        LiteralValues.STACK_TRACE_ELEMENT, "writeObject",
087:                        "(Ljava/lang/Object;)V");
088:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.STRING,
089:                        "writeObject", "(Ljava/lang/Object;)V");
090:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.STRING_BYTES,
091:                        "writeObject", "(Ljava/lang/Object;)V");
092:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.BIG_INTEGER,
093:                        "writeObject", "(Ljava/lang/Object;)V");
094:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.BIG_DECIMAL,
095:                        "writeObject", "(Ljava/lang/Object;)V");
096:
097:                addMapping(OBJECT_OUTPUT_METHODS,
098:                        LiteralValues.JAVA_LANG_CLASSLOADER, "writeObject",
099:                        "(Ljava/lang/Object;)V");
100:                addMapping(OBJECT_OUTPUT_METHODS,
101:                        LiteralValues.JAVA_LANG_CLASSLOADER_HOLDER,
102:                        "writeObject", "(Ljava/lang/Object;)V");
103:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.ENUM,
104:                        "writeObject", "(Ljava/lang/Object;)V");
105:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.ENUM_HOLDER,
106:                        "writeObject", "(Ljava/lang/Object;)V");
107:                addMapping(OBJECT_OUTPUT_METHODS, LiteralValues.CURRENCY,
108:                        "writeObject", "(Ljava/lang/Object;)V");
109:
110:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.INTEGER,
111:                        "readInt", "()I");
112:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.LONG,
113:                        "readLong", "()J");
114:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.CHARACTER,
115:                        "readChar", "()C");
116:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.BYTE,
117:                        "readByte", "()B");
118:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.SHORT,
119:                        "readShort", "()S");
120:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.FLOAT,
121:                        "readFloat", "()F");
122:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.DOUBLE,
123:                        "readDouble", "()D");
124:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.BOOLEAN,
125:                        "readBoolean", "()Z");
126:                // rest are read as Objects - Since we use TCObjectInputStream, we optimize it there.
127:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.OBJECT,
128:                        "readObject", "()Ljava/lang/Object;");
129:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.OBJECT_ID,
130:                        "readObject", "()Ljava/lang/Object;");
131:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.ARRAY,
132:                        "readObject", "()Ljava/lang/Object;");
133:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.JAVA_LANG_CLASS,
134:                        "readObject", "()Ljava/lang/Object;");
135:                addMapping(OBJECT_INPUT_METHODS,
136:                        LiteralValues.JAVA_LANG_CLASS_HOLDER, "readObject",
137:                        "()Ljava/lang/Object;");
138:                addMapping(OBJECT_INPUT_METHODS,
139:                        LiteralValues.STACK_TRACE_ELEMENT, "readObject",
140:                        "()Ljava/lang/Object;");
141:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.STRING,
142:                        "readObject", "()Ljava/lang/Object;");
143:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.STRING_BYTES,
144:                        "readObject", "()Ljava/lang/Object;");
145:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.BIG_INTEGER,
146:                        "readObject", "()Ljava/lang/Object;");
147:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.BIG_DECIMAL,
148:                        "readObject", "()Ljava/lang/Object;");
149:
150:                addMapping(OBJECT_INPUT_METHODS,
151:                        LiteralValues.JAVA_LANG_CLASSLOADER, "readObject",
152:                        "()Ljava/lang/Object;");
153:                addMapping(OBJECT_INPUT_METHODS,
154:                        LiteralValues.JAVA_LANG_CLASSLOADER_HOLDER,
155:                        "readObject", "()Ljava/lang/Object;");
156:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.ENUM,
157:                        "readObject", "()Ljava/lang/Object;");
158:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.ENUM_HOLDER,
159:                        "readObject", "()Ljava/lang/Object;");
160:                addMapping(OBJECT_INPUT_METHODS, LiteralValues.CURRENCY,
161:                        "readObject", "()Ljava/lang/Object;");
162:            }
163:
164:            public PhysicalStateClassLoader(ClassLoader parent) {
165:                super (parent);
166:            }
167:
168:            private static void addMapping(Map map, int type,
169:                    String methodName, String methodDesc) {
170:                map.put(new Integer(type), new MethodDetail(methodName,
171:                        methodDesc));
172:            }
173:
174:            private static MethodDetail get(Map map, int type) {
175:                MethodDetail md = (MethodDetail) map.get(new Integer(type));
176:                if (md == null) {
177:                    throw new TCRuntimeException("Unknown Type : " + type
178:                            + " Map = " + map);
179:                }
180:                return md;
181:            }
182:
183:            // Helper Method for tests
184:            public static void verifyTypePresent(int type) {
185:                MethodDetail md = get(OBJECT_INPUT_METHODS, type);
186:                Assert.assertNotNull(md);
187:                md = get(OBJECT_OUTPUT_METHODS, type);
188:                Assert.assertNotNull(md);
189:            }
190:
191:            public PhysicalStateClassLoader() {
192:                super ();
193:            }
194:
195:            public byte[] createClassBytes(ClassSpec cs, ObjectID parentID,
196:                    List fields) {
197:                byte data[] = basicCreateClassBytes(cs, parentID, fields);
198:                AdaptedClassDumper.INSTANCE.write(cs.getGeneratedClassName(),
199:                        data);
200:                return data;
201:            }
202:
203:            public Class defineClassFromBytes(String className, int classId,
204:                    byte[] clazzBytes, int offset, int length) {
205:                Class clazz = defineClass(className, clazzBytes, offset, length);
206:                return clazz;
207:            }
208:
209:            private byte[] basicCreateClassBytes(ClassSpec cs,
210:                    ObjectID parentID, List fields) {
211:                String classNameSlash = cs.getGeneratedClassName().replace('.',
212:                        '/');
213:                String super ClassNameSlash = cs.getSuperClassName().replace(
214:                        '.', '/');
215:                ClassWriter cw = new ClassWriter(0); // don't compute maxs
216:
217:                cw.visit(V1_2, ACC_PUBLIC | ACC_SUPER, classNameSlash, null,
218:                        super ClassNameSlash, null);
219:
220:                createConstructor(cw, super ClassNameSlash);
221:                if (!parentID.isNull()) {
222:                    createParentIDField(cw);
223:                    createGetParentIDMethod(cw, classNameSlash);
224:                    createSetParentIDMethod(cw, classNameSlash);
225:                }
226:
227:                createFields(cw, fields);
228:                createGetClassNameMethod(cw, classNameSlash, cs);
229:                createGetLoaderDescriptionMethod(cw, classNameSlash, cs);
230:                createGetObjectReferencesMethod(cw, classNameSlash, parentID,
231:                        cs, super ClassNameSlash, fields);
232:                createBasicSetMethod(cw, classNameSlash, cs,
233:                        super ClassNameSlash, fields);
234:                createBasicDehydrateMethod(cw, classNameSlash, cs,
235:                        super ClassNameSlash, fields);
236:                createAddValuesMethod(cw, classNameSlash, cs,
237:                        super ClassNameSlash, fields);
238:                createWriteObjectMethod(cw, classNameSlash, cs,
239:                        super ClassNameSlash, fields);
240:                createReadObjectMethod(cw, classNameSlash, cs,
241:                        super ClassNameSlash, fields);
242:
243:                createGetClassIdMethod(cw, classNameSlash, cs);
244:
245:                cw.visitEnd();
246:                return cw.toByteArray();
247:            }
248:
249:            // *************************************************************************************
250:            // The Code generated by this method looks (kind of) this.
251:            //
252:            // public String getLoaderDescription() {
253:            // return "System.ext";
254:            // }
255:            // *************************************************************************************
256:            private void createGetLoaderDescriptionMethod(ClassWriter cw,
257:                    String classNameSlash, ClassSpec cs) {
258:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
259:                    // We dont have to regenerate this method as the super class would have it.
260:                    return;
261:                }
262:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,
263:                        "getLoaderDescription", "()Ljava/lang/String;", null,
264:                        null);
265:                mv.visitCode();
266:                mv.visitLdcInsn(cs.getLoaderDesc());
267:                mv.visitInsn(ARETURN);
268:                mv.visitMaxs(1, 1);
269:                mv.visitEnd();
270:            }
271:
272:            // *************************************************************************************
273:            // The Code generated by this method looks (kind of) this.
274:            //
275:            // public String getClassName() {
276:            // return "com.tc.className";
277:            // }
278:            // *************************************************************************************
279:            private void createGetClassNameMethod(ClassWriter cw,
280:                    String classNameSlash, ClassSpec cs) {
281:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
282:                    // We dont have to regenerate this method as the super class would have it.
283:                    return;
284:                }
285:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getClassName",
286:                        "()Ljava/lang/String;", null, null);
287:                mv.visitCode();
288:                mv.visitLdcInsn(cs.getClassName());
289:                mv.visitInsn(ARETURN);
290:                mv.visitMaxs(1, 1);
291:                mv.visitEnd();
292:            }
293:
294:            // *************************************************************************************
295:            // The Code generated by this method looks (kind of) this.
296:            //
297:            // protected int getClassId() {
298:            // return 8;
299:            // }
300:            // *************************************************************************************
301:            private void createGetClassIdMethod(ClassWriter cw,
302:                    String classNameSlash, ClassSpec cs) {
303:                MethodVisitor mv = cw.visitMethod(ACC_PROTECTED, "getClassId",
304:                        "()I", null, null);
305:                mv.visitLdcInsn(new Integer(cs.getClassID()));
306:                mv.visitInsn(IRETURN);
307:                mv.visitMaxs(1, 1);
308:                mv.visitEnd();
309:            }
310:
311:            // *************************************************************************************
312:            // The Code generated by this method looks (kind of) this.
313:            //
314:            // long x;
315:            // Object o;
316:            // char c;
317:            // public void writeObject(ObjectOutput out) throws IOException {
318:            // out.writeLong(x);
319:            // out.writeObject(o);
320:            // out.writeChar(c);
321:            // }
322:            // *************************************************************************************
323:            private void createWriteObjectMethod(ClassWriter cw,
324:                    String classNameSlash, ClassSpec cs,
325:                    String super ClassNameSlash, List fields) {
326:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "writeObject",
327:                        "(Ljava/io/ObjectOutput;)V", null,
328:                        new String[] { "java/io/IOException" });
329:                mv.visitCode();
330:
331:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
332:                    mv.visitVarInsn(ALOAD, 0);
333:                    mv.visitVarInsn(ALOAD, 1);
334:                    mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
335:                            "writeObject", "(Ljava/io/ObjectOutput;)V");
336:                }
337:
338:                for (Iterator i = fields.iterator(); i.hasNext();) {
339:                    FieldType f = (FieldType) i.next();
340:                    mv.visitVarInsn(ALOAD, 1);
341:                    mv.visitVarInsn(ALOAD, 0);
342:                    mv
343:                            .visitFieldInsn(GETFIELD, classNameSlash, f
344:                                    .getLocalFieldName(), getFieldTypeDesc(f
345:                                    .getType()));
346:                    MethodDetail md = get(OBJECT_OUTPUT_METHODS, f.getType());
347:                    mv.visitMethodInsn(INVOKEINTERFACE, "java/io/ObjectOutput",
348:                            md.getMethodName(), md.getMethodDescriptor());
349:                }
350:                mv.visitInsn(RETURN);
351:                mv.visitMaxs(3, 2);
352:                mv.visitEnd();
353:            }
354:
355:            // *************************************************************************************
356:            // The Code generated by this method looks (kind of) this.
357:            //
358:            // long x;
359:            // Object o;
360:            // char c;
361:            //
362:            // public void readObject(ObjectInput in) throws IOException, ClassNotFoundException {
363:            // x = in.readLong();
364:            // o = in.readObject();
365:            // c = in.readChar();
366:            // }
367:            // *************************************************************************************
368:            private void createReadObjectMethod(ClassWriter cw,
369:                    String classNameSlash, ClassSpec cs,
370:                    String super ClassNameSlash, List fields) {
371:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "readObject",
372:                        "(Ljava/io/ObjectInput;)V", null, new String[] {
373:                                "java/io/IOException",
374:                                "java/lang/ClassNotFoundException" });
375:                mv.visitCode();
376:
377:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
378:                    mv.visitVarInsn(ALOAD, 0);
379:                    mv.visitVarInsn(ALOAD, 1);
380:                    mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
381:                            "readObject", "(Ljava/io/ObjectInput;)V");
382:                }
383:
384:                for (Iterator i = fields.iterator(); i.hasNext();) {
385:                    FieldType f = (FieldType) i.next();
386:                    mv.visitVarInsn(ALOAD, 0);
387:                    mv.visitVarInsn(ALOAD, 1);
388:                    MethodDetail md = get(OBJECT_INPUT_METHODS, f.getType());
389:                    mv.visitMethodInsn(INVOKEINTERFACE, "java/io/ObjectInput",
390:                            md.getMethodName(), md.getMethodDescriptor());
391:                    mv
392:                            .visitFieldInsn(PUTFIELD, classNameSlash, f
393:                                    .getLocalFieldName(), getFieldTypeDesc(f
394:                                    .getType()));
395:                }
396:                mv.visitInsn(RETURN);
397:                mv.visitMaxs(3, 2);
398:                mv.visitEnd();
399:            }
400:
401:            // *************************************************************************************
402:            // The Code generated by this method looks (kind of) this.
403:            //
404:            // long x;
405:            // Object o;
406:            // public Map addValues(Map map) {
407:            // map.put("x", new Long(x));
408:            // map.put("o", o);
409:            // return map;
410:            // }
411:            // *************************************************************************************
412:            private void createAddValuesMethod(ClassWriter cw,
413:                    String classNameSlash, ClassSpec cs,
414:                    String super ClassNameSlash, List fields) {
415:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "addValues",
416:                        "(Ljava/util/Map;)Ljava/util/Map;", null, null);
417:                mv.visitCode();
418:
419:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
420:                    mv.visitVarInsn(ALOAD, 0);
421:                    mv.visitVarInsn(ALOAD, 1);
422:                    mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
423:                            "addValues", "(Ljava/util/Map;)Ljava/util/Map;");
424:                    mv.visitInsn(POP);
425:                }
426:
427:                for (Iterator i = fields.iterator(); i.hasNext();) {
428:                    FieldType f = (FieldType) i.next();
429:                    mv.visitVarInsn(ALOAD, 1);
430:                    mv.visitLdcInsn(f.getQualifiedName());
431:                    getObjectFor(mv, classNameSlash, f);
432:                    mv
433:                            .visitMethodInsn(INVOKEINTERFACE, "java/util/Map",
434:                                    "put",
435:                                    "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
436:                    mv.visitInsn(POP);
437:                }
438:                mv.visitVarInsn(ALOAD, 1);
439:                mv.visitInsn(ARETURN);
440:
441:                mv.visitMaxs(6, 2);
442:                mv.visitEnd();
443:
444:            }
445:
446:            // *************************************************************************************
447:            // The Code generated by this method looks (kind of) this.
448:            //
449:            // long x;
450:            // Object o;
451:            // protected void basicDehydrate(DNAWriter writer) {
452:            // writer.addPhysicalAction("x", new Long(x), false);
453:            // writer.addPhysicalAction("o", o, true);
454:            // }
455:            // *************************************************************************************
456:            private void createBasicDehydrateMethod(ClassWriter cw,
457:                    String classNameSlash, ClassSpec cs,
458:                    String super ClassNameSlash, List fields) {
459:                MethodVisitor mv = cw.visitMethod(ACC_PROTECTED,
460:                        "basicDehydrate",
461:                        "(Lcom/tc/object/dna/api/DNAWriter;)V", null, null);
462:                mv.visitCode();
463:
464:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
465:                    mv.visitVarInsn(ALOAD, 0);
466:                    mv.visitVarInsn(ALOAD, 1);
467:                    mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
468:                            "basicDehydrate",
469:                            "(Lcom/tc/object/dna/api/DNAWriter;)V");
470:                }
471:
472:                for (Iterator i = fields.iterator(); i.hasNext();) {
473:                    FieldType f = (FieldType) i.next();
474:                    mv.visitVarInsn(ALOAD, 1);
475:                    mv.visitLdcInsn(f.getQualifiedName());
476:                    getObjectFor(mv, classNameSlash, f);
477:                    if (f.canBeReferenced()) {
478:                        mv.visitInsn(ICONST_1); // true
479:                    } else {
480:                        mv.visitInsn(ICONST_0); // false
481:                    }
482:                    // XXX:: We are calling DNAWriter methods from instrumented code !
483:                    mv.visitMethodInsn(INVOKEINTERFACE,
484:                            "com/tc/object/dna/api/DNAWriter",
485:                            "addPhysicalAction",
486:                            "(Ljava/lang/String;Ljava/lang/Object;Z)V");
487:                }
488:                mv.visitInsn(RETURN);
489:
490:                mv.visitMaxs(6, 2);
491:                mv.visitEnd();
492:            }
493:
494:            // *************************************************************************************
495:            // The Code generated by this method looks (kind of) this.
496:            //
497:            // long x;
498:            // Object o;
499:            // protected Object basicSet(String f, Object value) {
500:            // if ("x".equals(f)) {
501:            // Object old = new Long(x);
502:            // x = ((Long) value).longValue();
503:            // return old;
504:            // }
505:            // if("o".equals(f)) {
506:            // Object old = o;
507:            // o = value;
508:            // return old;
509:            // }
510:            // throw new ClassNotCompatableException("Not found ! field = " + f + " value = " + value);
511:            // }
512:            // *************************************************************************************
513:            private void createBasicSetMethod(ClassWriter cw,
514:                    String classNameSlash, ClassSpec cs,
515:                    String super ClassNameSlash, List fields) {
516:                MethodVisitor mv = cw
517:                        .visitMethod(
518:                                ACC_PROTECTED,
519:                                "basicSet",
520:                                "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;",
521:                                null, null);
522:                mv.visitCode();
523:
524:                for (Iterator i = fields.iterator(); i.hasNext();) {
525:                    FieldType f = (FieldType) i.next();
526:                    mv.visitLdcInsn(f.getQualifiedName());
527:                    mv.visitVarInsn(ALOAD, 1);
528:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
529:                            "equals", "(Ljava/lang/Object;)Z");
530:                    Label l1 = new Label();
531:                    mv.visitJumpInsn(IFEQ, l1);
532:                    getObjectFor(mv, classNameSlash, f);
533:                    mv.visitVarInsn(ASTORE, 3);
534:                    mv.visitVarInsn(ALOAD, 0);
535:                    mv.visitVarInsn(ALOAD, 2);
536:                    getValueFrom(mv, classNameSlash, f);
537:                    mv
538:                            .visitFieldInsn(PUTFIELD, classNameSlash, f
539:                                    .getLocalFieldName(), getFieldTypeDesc(f
540:                                    .getType()));
541:                    mv.visitVarInsn(ALOAD, 3);
542:                    mv.visitInsn(ARETURN);
543:                    mv.visitLabel(l1);
544:                }
545:
546:                if (cs.isDirectSubClassOfPhysicalMOState()) {
547:                    // throw Assertion Error
548:                    mv
549:                            .visitTypeInsn(NEW,
550:                                    "com/tc/objectserver/managedobject/bytecode/ClassNotCompatableException");
551:                    mv.visitInsn(DUP);
552:                    mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
553:                    mv.visitInsn(DUP);
554:                    mv.visitLdcInsn("Not found ! field = ");
555:                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer",
556:                            "<init>", "(Ljava/lang/String;)V");
557:                    mv.visitVarInsn(ALOAD, 1);
558:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
559:                            "append",
560:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
561:                    mv.visitLdcInsn(" value = ");
562:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
563:                            "append",
564:                            "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
565:                    mv.visitVarInsn(ALOAD, 2);
566:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
567:                            "append",
568:                            "(Ljava/lang/Object;)Ljava/lang/StringBuffer;");
569:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer",
570:                            "toString", "()Ljava/lang/String;");
571:                    mv
572:                            .visitMethodInsn(
573:                                    INVOKESPECIAL,
574:                                    "com/tc/objectserver/managedobject/bytecode/ClassNotCompatableException",
575:                                    "<init>", "(Ljava/lang/String;)V");
576:                    mv.visitInsn(ATHROW);
577:                } else {
578:                    // Call super class's implementation
579:                    mv.visitVarInsn(ALOAD, 0);
580:                    mv.visitVarInsn(ALOAD, 1);
581:                    mv.visitVarInsn(ALOAD, 2);
582:                    mv
583:                            .visitMethodInsn(INVOKESPECIAL,
584:                                    super ClassNameSlash, "basicSet",
585:                                    "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
586:                    mv.visitInsn(ARETURN);
587:                }
588:
589:                mv.visitMaxs(5, 4);
590:                mv.visitEnd();
591:            }
592:
593:            /**
594:             * This method generates code to the object reference from the top of the stack and convert it into a primitive type
595:             * (if needed) and leave that value in the top of the stack.
596:             */
597:            private void getValueFrom(MethodVisitor mv, String classNameSlash,
598:                    FieldType f) {
599:                String classOnStack = getClassNameFor(f.getType());
600:                if ("java/lang/Object".equals(classOnStack)) {
601:                    return;
602:                }
603:                mv.visitTypeInsn(CHECKCAST, classOnStack);
604:                mv.visitMethodInsn(INVOKEVIRTUAL, classOnStack,
605:                        getMethodNameForPrimitives(f.getType()), "()"
606:                                + getFieldTypeDesc((f.getType())));
607:
608:            }
609:
610:            /**
611:             * This method generates code so that the object equivalent of the field is left on the stack.
612:             */
613:            private void getObjectFor(MethodVisitor mv, String classNameSlash,
614:                    FieldType f) {
615:                String classToReturn = getClassNameFor(f.getType());
616:                if ("java/lang/Object".equals(classToReturn)) {
617:                    mv.visitVarInsn(ALOAD, 0);
618:                    mv
619:                            .visitFieldInsn(GETFIELD, classNameSlash, f
620:                                    .getLocalFieldName(), getFieldTypeDesc(f
621:                                    .getType()));
622:                    return;
623:                }
624:                String fieldTypeDesc = getFieldTypeDesc(f.getType());
625:                String constructorDesc = "(" + fieldTypeDesc + ")V";
626:                mv.visitTypeInsn(NEW, classToReturn);
627:                mv.visitInsn(DUP);
628:                mv.visitVarInsn(ALOAD, 0);
629:                mv.visitFieldInsn(GETFIELD, classNameSlash, f
630:                        .getLocalFieldName(), fieldTypeDesc);
631:                mv.visitMethodInsn(INVOKESPECIAL, classToReturn, "<init>",
632:                        constructorDesc);
633:
634:            }
635:
636:            // *************************************************************************************
637:            // The Code generated by this method looks (kind of) this.
638:            //
639:            // private Object oid1;
640:            // public Set getObjectReferences() {
641:            // Set result = new THashSet(25);
642:            // if (oid1 instanceof ObjectID && !((ObjectID)oid1).isNull() ) {
643:            // result.add(oid1);
644:            // }
645:            // return result;
646:            // }
647:            // *************************************************************************************
648:            private void createGetObjectReferencesMethod(ClassWriter cw,
649:                    String classNameSlash, ObjectID parentID, ClassSpec cs,
650:                    String super ClassNameSlash, List fields) {
651:                List referenceFields = new ArrayList(fields.size());
652:                for (Iterator i = fields.iterator(); i.hasNext();) {
653:                    FieldType f = (FieldType) i.next();
654:                    if (f.getType() == LiteralValues.OBJECT_ID) {
655:                        referenceFields.add(f);
656:                    }
657:                }
658:
659:                // There is no references in this object and it is not a direct subclass of Physical Managed Object State
660:                if (referenceFields.size() == 0 && parentID.isNull()
661:                        && !cs.isDirectSubClassOfPhysicalMOState()) {
662:                    // The parent object has the necessary implementations
663:                    return;
664:                }
665:
666:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC,
667:                        "getObjectReferences", "()Ljava/util/Set;", null, null);
668:                mv.visitCode();
669:
670:                // There is no references in this object
671:                if (referenceFields.size() == 0 && parentID.isNull()) {
672:                    mv.visitFieldInsn(GETSTATIC, "java/util/Collections",
673:                            "EMPTY_SET", "Ljava/util/Set;");
674:                    mv.visitInsn(ARETURN);
675:                    mv.visitMaxs(1, 1);
676:                    mv.visitEnd();
677:                    return;
678:                }
679:
680:                int size = referenceFields.size();
681:                if (!parentID.isNull()
682:                        && cs.isDirectSubClassOfPhysicalMOState()) {
683:                    size++;
684:                }
685:
686:                mv.visitTypeInsn(NEW, "gnu/trove/THashSet");
687:                mv.visitInsn(DUP);
688:                mv.visitIntInsn(BIPUSH, size);
689:                mv.visitMethodInsn(INVOKESPECIAL, "gnu/trove/THashSet",
690:                        "<init>", "(I)V");
691:                mv.visitVarInsn(ASTORE, 1);
692:
693:                if (!cs.isDirectSubClassOfPhysicalMOState()) {
694:                    mv.visitVarInsn(ALOAD, 0);
695:                    mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
696:                            "getObjectReferences", "()Ljava/util/Set;");
697:                    mv.visitVarInsn(ASTORE, 2);
698:                    mv.visitVarInsn(ALOAD, 1);
699:                    mv.visitVarInsn(ALOAD, 2);
700:                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set",
701:                            "addAll", "(Ljava/util/Collection;)Z");
702:                    mv.visitInsn(POP);
703:                }
704:
705:                for (Iterator i = referenceFields.iterator(); i.hasNext();) {
706:                    FieldType f = (FieldType) i.next();
707:                    mv.visitVarInsn(ALOAD, 0);
708:                    mv
709:                            .visitFieldInsn(GETFIELD, classNameSlash, f
710:                                    .getLocalFieldName(), getFieldTypeDesc(f
711:                                    .getType()));
712:                    mv.visitTypeInsn(INSTANCEOF, "com/tc/object/ObjectID");
713:                    Label l2 = new Label();
714:                    mv.visitJumpInsn(IFEQ, l2);
715:                    mv.visitVarInsn(ALOAD, 0);
716:                    mv
717:                            .visitFieldInsn(GETFIELD, classNameSlash, f
718:                                    .getLocalFieldName(), getFieldTypeDesc(f
719:                                    .getType()));
720:                    mv.visitTypeInsn(CHECKCAST, "com/tc/object/ObjectID");
721:                    mv.visitMethodInsn(INVOKEVIRTUAL, "com/tc/object/ObjectID",
722:                            "isNull", "()Z");
723:                    mv.visitJumpInsn(IFNE, l2);
724:                    mv.visitVarInsn(ALOAD, 1);
725:                    mv.visitVarInsn(ALOAD, 0);
726:                    mv
727:                            .visitFieldInsn(GETFIELD, classNameSlash, f
728:                                    .getLocalFieldName(), getFieldTypeDesc(f
729:                                    .getType()));
730:                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "add",
731:                            "(Ljava/lang/Object;)Z");
732:                    mv.visitInsn(POP);
733:                    mv.visitLabel(l2);
734:                }
735:                if (!parentID.isNull()
736:                        && cs.isDirectSubClassOfPhysicalMOState()) {
737:                    // add parentID too
738:                    mv.visitVarInsn(ALOAD, 1);
739:                    mv.visitVarInsn(ALOAD, 0);
740:                    mv.visitFieldInsn(GETFIELD, classNameSlash,
741:                            PARENT_ID_FIELD, "Lcom/tc/object/ObjectID;");
742:                    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "add",
743:                            "(Ljava/lang/Object;)Z");
744:                    mv.visitInsn(POP);
745:                }
746:                mv.visitVarInsn(ALOAD, 1);
747:                mv.visitInsn(ARETURN);
748:                mv.visitMaxs(3, 3);
749:                mv.visitEnd();
750:            }
751:
752:            private void createFields(ClassWriter cw, List fields) {
753:                for (Iterator i = fields.iterator(); i.hasNext();) {
754:                    FieldType f = (FieldType) i.next();
755:                    FieldVisitor fv = cw.visitField(ACC_PRIVATE, f
756:                            .getLocalFieldName(),
757:                            getFieldTypeDesc(f.getType()), null, null);
758:                    fv.visitEnd();
759:                }
760:            }
761:
762:            private String getFieldTypeDesc(int type) {
763:                switch (type) {
764:                case LiteralValues.INTEGER:
765:                    return "I";
766:                case LiteralValues.LONG:
767:                    return "J";
768:                case LiteralValues.CHARACTER:
769:                    return "C";
770:                case LiteralValues.FLOAT:
771:                    return "F";
772:                case LiteralValues.DOUBLE:
773:                    return "D";
774:                case LiteralValues.BYTE:
775:                    return "B";
776:                case LiteralValues.SHORT:
777:                    return "S";
778:                case LiteralValues.BOOLEAN:
779:                    return "Z";
780:                case LiteralValues.OBJECT_ID:
781:                    return "Ljava/lang/Object;"; // ObjectIDs are NOT stored as longs anymore :(
782:                default:
783:                    return "Ljava/lang/Object;"; // Everything else is stored as Object reference
784:                }
785:            }
786:
787:            // TODO:: Clean up to use MethodDetail class
788:            private String getMethodNameForPrimitives(int type) {
789:                switch (type) {
790:                case LiteralValues.INTEGER:
791:                    return "intValue";
792:                case LiteralValues.LONG:
793:                    return "longValue";
794:                case LiteralValues.CHARACTER:
795:                    return "charValue";
796:                case LiteralValues.FLOAT:
797:                    return "floatValue";
798:                case LiteralValues.DOUBLE:
799:                    return "doubleValue";
800:                case LiteralValues.BYTE:
801:                    return "byteValue";
802:                case LiteralValues.SHORT:
803:                    return "shortValue";
804:                case LiteralValues.BOOLEAN:
805:                    return "booleanValue";
806:                    // ObjectIDs are NOT stored as longs anymore :(
807:                    // case LiteralValues.OBJECT_ID:
808:                    // return "toLong";
809:                default:
810:                    throw new AssertionError("This type is invalid : " + type);
811:                }
812:            }
813:
814:            private String getClassNameFor(int type) {
815:                switch (type) {
816:                case LiteralValues.INTEGER:
817:                    return "java/lang/Integer";
818:                case LiteralValues.LONG:
819:                    return "java/lang/Long";
820:                case LiteralValues.CHARACTER:
821:                    return "java/lang/Character";
822:                case LiteralValues.FLOAT:
823:                    return "java/lang/Float";
824:                case LiteralValues.DOUBLE:
825:                    return "java/lang/Double";
826:                case LiteralValues.BYTE:
827:                    return "java/lang/Byte";
828:                case LiteralValues.SHORT:
829:                    return "java/lang/Short";
830:                case LiteralValues.BOOLEAN:
831:                    return "java/lang/Boolean";
832:                case LiteralValues.OBJECT_ID:
833:                    return "java/lang/Object"; // ObjectIDs are NOT stored as longs anymore :(
834:                default:
835:                    return "java/lang/Object"; // Everything else is stored as Object reference
836:                }
837:            }
838:
839:            private void createParentIDField(ClassWriter cw) {
840:                FieldVisitor fv = cw.visitField(ACC_PRIVATE, PARENT_ID_FIELD,
841:                        "Lcom/tc/object/ObjectID;", null, null);
842:                fv.visitEnd();
843:            }
844:
845:            // *************************************************************************************
846:            // The Code generated by this method looks (kind of) this.
847:            //
848:            // ObjectID parentId;
849:            // public ObjectID getParentID() {
850:            // return parentId;
851:            // }
852:            // *************************************************************************************
853:            private void createGetParentIDMethod(ClassWriter cw,
854:                    String classNameSlash) {
855:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getParentID",
856:                        "()Lcom/tc/object/ObjectID;", null, null);
857:                mv.visitCode();
858:                mv.visitVarInsn(ALOAD, 0);
859:                mv.visitFieldInsn(GETFIELD, classNameSlash, PARENT_ID_FIELD,
860:                        "Lcom/tc/object/ObjectID;");
861:                mv.visitInsn(ARETURN);
862:                mv.visitMaxs(2, 1);
863:                mv.visitEnd();
864:            }
865:
866:            // *************************************************************************************
867:            // The Code generated by this method looks (kind of) this.
868:            //
869:            // ObjectID parentId;
870:            // public void setParentID(ObjectID id) {
871:            // parentId = id;
872:            // }
873:            // *************************************************************************************
874:            private void createSetParentIDMethod(ClassWriter cw,
875:                    String classNameSlash) {
876:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "setParentID",
877:                        "(Lcom/tc/object/ObjectID;)V", null, null);
878:                mv.visitCode();
879:                mv.visitVarInsn(ALOAD, 0);
880:                mv.visitVarInsn(ALOAD, 1);
881:                mv.visitFieldInsn(PUTFIELD, classNameSlash, PARENT_ID_FIELD,
882:                        "Lcom/tc/object/ObjectID;");
883:                mv.visitInsn(RETURN);
884:                mv.visitMaxs(3, 2);
885:                mv.visitEnd();
886:            }
887:
888:            private void createConstructor(ClassWriter cw,
889:                    String super ClassNameSlash) {
890:                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V",
891:                        null, null);
892:                mv.visitCode();
893:                mv.visitVarInsn(ALOAD, 0);
894:                mv.visitMethodInsn(INVOKESPECIAL, super ClassNameSlash,
895:                        "<init>", "()V");
896:                mv.visitInsn(RETURN);
897:                mv.visitMaxs(2, 2);
898:                mv.visitEnd();
899:            }
900:
901:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.