Source Code Cross Referenced for CodeConverter.java in  » Byte-Code » Javassist » javassist » 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 » Byte Code » Javassist » javassist 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Javassist, a Java-bytecode translator toolkit.
003:         * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004:         *
005:         * The contents of this file are subject to the Mozilla Public License Version
006:         * 1.1 (the "License"); you may not use this file except in compliance with
007:         * the License.  Alternatively, the contents of this file may be used under
008:         * the terms of the GNU Lesser General Public License Version 2.1 or later.
009:         *
010:         * Software distributed under the License is distributed on an "AS IS" basis,
011:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012:         * for the specific language governing rights and limitations under the
013:         * License.
014:         */
015:
016:        package javassist;
017:
018:        import javassist.bytecode.*;
019:        import javassist.convert.*;
020:
021:        /**
022:         * Simple translator of method bodies
023:         * (also see the <code>javassist.expr</code> package).
024:         *
025:         * <p>Instances of this class specifies how to instrument of the
026:         * bytecodes representing a method body.  They are passed to
027:         * <code>CtClass.instrument()</code> or
028:         * <code>CtMethod.instrument()</code> as a parameter.
029:         *
030:         * <p>Example:
031:         * <ul><pre>
032:         * ClassPool cp = ClassPool.getDefault();
033:         * CtClass point = cp.get("Point");
034:         * CtClass singleton = cp.get("Singleton");
035:         * CtClass client = cp.get("Client");
036:         * CodeConverter conv = new CodeConverter();
037:         * conv.replaceNew(point, singleton, "makePoint");
038:         * client.instrument(conv);
039:         * </pre></ul>
040:         *
041:         * <p>This program substitutes "<code>Singleton.makePoint()</code>"
042:         * for all occurrences of "<code>new Point()</code>"
043:         * appearing in methods declared in a <code>Client</code> class.
044:         *
045:         * @see javassist.CtClass#instrument(CodeConverter)
046:         * @see javassist.CtMethod#instrument(CodeConverter)
047:         * @see javassist.expr.ExprEditor
048:         */
049:        public class CodeConverter {
050:            Transformer transformers = null;
051:
052:            /**
053:             * Modify a method body so that instantiation of the specified class
054:             * is replaced with a call to the specified static method.  For example,
055:             * <code>replaceNew(ctPoint, ctSingleton, "createPoint")</code>
056:             * (where <code>ctPoint</code> and <code>ctSingleton</code> are
057:             * compile-time classes for class <code>Point</code> and class
058:             * <code>Singleton</code>, respectively)
059:             * replaces all occurrences of:
060:             *
061:             * <ul><code>new Point(x, y)</code></ul>
062:             *
063:             * in the method body with:
064:             *
065:             * <ul><code>Singleton.createPoint(x, y)</code></ul>
066:             * 
067:             * <p>This enables to intercept instantiation of <code>Point</code>
068:             * and change the samentics.  For example, the following
069:             * <code>createPoint()</code> implements the singleton pattern:
070:             *
071:             * <ul><pre>public static Point createPoint(int x, int y) {
072:             *     if (aPoint == null)
073:             *         aPoint = new Point(x, y);
074:             *     return aPoint;
075:             * }
076:             * </pre></ul>
077:             *
078:             * <p>The static method call substituted for the original <code>new</code>
079:             * expression must be
080:             * able to receive the same set of parameters as the original
081:             * constructor.  If there are multiple constructors with different
082:             * parameter types, then there must be multiple static methods
083:             * with the same name but different parameter types.
084:             *
085:             * <p>The return type of the substituted static method must be
086:             * the exactly same as the type of the instantiated class specified by
087:             * <code>newClass</code>.
088:             *
089:             * @param newClass          the instantiated class.
090:             * @param calledClass       the class in which the static method is
091:             *                          declared.
092:             * @param calledMethod      the name of the static method.
093:             */
094:            public void replaceNew(CtClass newClass, CtClass calledClass,
095:                    String calledMethod) {
096:                transformers = new TransformNew(transformers, newClass
097:                        .getName(), calledClass.getName(), calledMethod);
098:            }
099:
100:            /**
101:             * Modify a method body so that field read/write expressions access
102:             * a different field from the original one.
103:             *
104:             * <p>Note that this method changes only the filed name and the class
105:             * declaring the field; the type of the target object does not change.
106:             * Therefore, the substituted field must be declared in the same class
107:             * or a superclass of the original class.
108:             *
109:             * <p>Also, <code>clazz</code> and <code>newClass</code> must specify
110:             * the class directly declaring the field.  They must not specify
111:             * a subclass of that class.
112:             *
113:             * @param field             the originally accessed field.
114:             * @param newClass  the class declaring the substituted field.
115:             * @param newFieldname      the name of the substituted field.
116:             */
117:            public void redirectFieldAccess(CtField field, CtClass newClass,
118:                    String newFieldname) {
119:                transformers = new TransformFieldAccess(transformers, field,
120:                        newClass.getName(), newFieldname);
121:            }
122:
123:            /**
124:             * Modify a method body so that an expression reading the specified
125:             * field is replaced with a call to the specified <i>static</i> method.
126:             * This static method receives the target object of the original
127:             * read expression as a parameter.  It must return a value of
128:             * the same type as the field.
129:             *
130:             * <p>For example, the program below
131:             *
132:             * <ul><pre>Point p = new Point();
133:             * int newX = p.x + 3;</pre></ul>
134:             *
135:             * <p>can be translated into:
136:             *
137:             * <ul><pre>Point p = new Point();
138:             * int newX = Accessor.readX(p) + 3;</pre></ul>
139:             *
140:             * <p>where
141:             *
142:             * <ul><pre>public class Accessor {
143:             *     public static int readX(Object target) { ... }
144:             * }</pre></ul>
145:             *
146:             * <p>The type of the parameter of <code>readX()</code> must
147:             * be <code>java.lang.Object</code> independently of the actual
148:             * type of <code>target</code>.  The return type must be the same
149:             * as the field type.
150:             *
151:             * @param field             the field.
152:             * @param calledClass       the class in which the static method is
153:             *                          declared.
154:             * @param calledMethod      the name of the static method.
155:             */
156:            public void replaceFieldRead(CtField field, CtClass calledClass,
157:                    String calledMethod) {
158:                transformers = new TransformReadField(transformers, field,
159:                        calledClass.getName(), calledMethod);
160:            }
161:
162:            /**
163:             * Modify a method body so that an expression writing the specified
164:             * field is replaced with a call to the specified static method.
165:             * This static method receives two parameters: the target object of
166:             * the original
167:             * write expression and the assigned value.  The return type of the
168:             * static method is <code>void</code>.
169:             * 
170:             * <p>For example, the program below
171:             *
172:             * <ul><pre>Point p = new Point();
173:             * p.x = 3;</pre></ul>
174:             *
175:             * <p>can be translated into:
176:             *
177:             * <ul><pre>Point p = new Point();
178:             * Accessor.writeX(3);</pre></ul>
179:             *
180:             * <p>where
181:             *
182:             * <ul><pre>public class Accessor {
183:             *     public static void writeX(Object target, int value) { ... }
184:             * }</pre></ul>
185:             *
186:             * <p>The type of the first parameter of <code>writeX()</code> must
187:             * be <code>java.lang.Object</code> independently of the actual
188:             * type of <code>target</code>.  The type of the second parameter
189:             * is the same as the field type.
190:             *
191:             * @param field             the field.
192:             * @param calledClass       the class in which the static method is
193:             *                          declared.
194:             * @param calledMethod      the name of the static method.
195:             */
196:            public void replaceFieldWrite(CtField field, CtClass calledClass,
197:                    String calledMethod) {
198:                transformers = new TransformWriteField(transformers, field,
199:                        calledClass.getName(), calledMethod);
200:            }
201:
202:            /**
203:             * Modify method invocations in a method body so that a different
204:             * method will be invoked.
205:             *
206:             * <p>Note that the target object, the parameters, or 
207:             * the type of invocation
208:             * (static method call, interface call, or private method call)
209:             * are not modified.  Only the method name is changed.  The substituted
210:             * method must have the same signature that the original one has.
211:             * If the original method is a static method, the substituted method
212:             * must be static.
213:             *
214:             * @param origMethod        original method
215:             * @param substMethod       substituted method
216:             */
217:            public void redirectMethodCall(CtMethod origMethod,
218:                    CtMethod substMethod) throws CannotCompileException {
219:                String d1 = origMethod.getMethodInfo2().getDescriptor();
220:                String d2 = substMethod.getMethodInfo2().getDescriptor();
221:                if (!d1.equals(d2))
222:                    throw new CannotCompileException("signature mismatch");
223:
224:                int mod1 = origMethod.getModifiers();
225:                int mod2 = substMethod.getModifiers();
226:                if (Modifier.isStatic(mod1) != Modifier.isStatic(mod2)
227:                        || (Modifier.isPrivate(mod1) && !Modifier
228:                                .isPrivate(mod2))
229:                        || origMethod.getDeclaringClass().isInterface() != substMethod
230:                                .getDeclaringClass().isInterface())
231:                    throw new CannotCompileException("invoke-type mismatch");
232:
233:                transformers = new TransformCall(transformers, origMethod,
234:                        substMethod);
235:            }
236:
237:            /**
238:             * Correct invocations to a method that has been renamed.
239:             * If a method is renamed, calls to that method must be also
240:             * modified so that the method with the new name will be called.
241:             *
242:             * <p>The method must be declared in the same class before and
243:             * after it is renamed.
244:             *
245:             * <p>Note that the target object, the parameters, or 
246:             * the type of invocation
247:             * (static method call, interface call, or private method call)
248:             * are not modified.  Only the method name is changed.
249:             *
250:             * @param oldMethodName        the old name of the method.
251:             * @param newMethod            the method with the new name.
252:             * @see javassist.CtMethod#setName(String)
253:             */
254:            public void redirectMethodCall(String oldMethodName,
255:                    CtMethod newMethod) throws CannotCompileException {
256:                transformers = new TransformCall(transformers, oldMethodName,
257:                        newMethod);
258:            }
259:
260:            /**
261:             * Insert a call to another method before an existing method call.
262:             * That "before" method must be static.  The return type must be
263:             * <code>void</code>.  As parameters, the before method receives
264:             * the target object and all the parameters to the originally invoked
265:             * method.  For example, if the originally invoked method is
266:             * <code>move()</code>:
267:             *
268:             * <ul><pre>class Point {
269:             *     Point move(int x, int y) { ... }
270:             * }</pre></ul>
271:             *
272:             * <p>Then the before method must be something like this:
273:             *
274:             * <ul><pre>class Verbose {
275:             *     static void print(Point target, int x, int y) { ... }
276:             * }</pre></ul>
277:             *
278:             * <p>The <code>CodeConverter</code> would translate bytecode
279:             * equivalent to:
280:             *
281:             * <ul><pre>Point p2 = p.move(x + y, 0);</pre></ul>
282:             *
283:             * <p>into the bytecode equivalent to:
284:             *
285:             * <ul><pre>int tmp1 = x + y;
286:             * int tmp2 = 0;
287:             * Verbose.print(p, tmp1, tmp2);
288:             * Point p2 = p.move(tmp1, tmp2);</pre></ul>
289:             *
290:             * @param origMethod        the method originally invoked.
291:             * @param beforeMethod      the method invoked before
292:             *                          <code>origMethod</code>.
293:             */
294:            public void insertBeforeMethod(CtMethod origMethod,
295:                    CtMethod beforeMethod) throws CannotCompileException {
296:                try {
297:                    transformers = new TransformBefore(transformers,
298:                            origMethod, beforeMethod);
299:                } catch (NotFoundException e) {
300:                    throw new CannotCompileException(e);
301:                }
302:            }
303:
304:            /**
305:             * Inserts a call to another method after an existing method call.
306:             * That "after" method must be static.  The return type must be
307:             * <code>void</code>.  As parameters, the after method receives
308:             * the target object and all the parameters to the originally invoked
309:             * method.  For example, if the originally invoked method is
310:             * <code>move()</code>:
311:             *
312:             * <ul><pre>class Point {
313:             *     Point move(int x, int y) { ... }
314:             * }</pre></ul>
315:             *
316:             * <p>Then the after method must be something like this:
317:             *
318:             * <ul><pre>class Verbose {
319:             *     static void print(Point target, int x, int y) { ... }
320:             * }</pre></ul>
321:             *
322:             * <p>The <code>CodeConverter</code> would translate bytecode
323:             * equivalent to:
324:             *
325:             * <ul><pre>Point p2 = p.move(x + y, 0);</pre></ul>
326:             *
327:             * <p>into the bytecode equivalent to:
328:             *
329:             * <ul><pre>int tmp1 = x + y;
330:             * int tmp2 = 0;
331:             * Point p2 = p.move(tmp1, tmp2);
332:             * Verbose.print(p, tmp1, tmp2);</pre></ul>
333:             *
334:             * @param origMethod        the method originally invoked.
335:             * @param afterMethod       the method invoked after
336:             *                          <code>origMethod</code>.
337:             */
338:            public void insertAfterMethod(CtMethod origMethod,
339:                    CtMethod afterMethod) throws CannotCompileException {
340:                try {
341:                    transformers = new TransformAfter(transformers, origMethod,
342:                            afterMethod);
343:                } catch (NotFoundException e) {
344:                    throw new CannotCompileException(e);
345:                }
346:            }
347:
348:            /**
349:             * Performs code conversion.
350:             */
351:            void doit(CtClass clazz, MethodInfo minfo, ConstPool cp)
352:                    throws CannotCompileException {
353:                Transformer t;
354:
355:                CodeAttribute codeAttr = minfo.getCodeAttribute();
356:                if (codeAttr == null || transformers == null)
357:                    return;
358:
359:                for (t = transformers; t != null; t = t.getNext())
360:                    t.initialize(cp, codeAttr);
361:
362:                CodeIterator iterator = codeAttr.iterator();
363:                while (iterator.hasNext()) {
364:                    try {
365:                        int pos = iterator.next();
366:                        for (t = transformers; t != null; t = t.getNext())
367:                            pos = t.transform(clazz, pos, iterator, cp);
368:                    } catch (BadBytecode e) {
369:                        throw new CannotCompileException(e);
370:                    }
371:                }
372:
373:                int locals = 0;
374:                for (t = transformers; t != null; t = t.getNext()) {
375:                    int s = t.extraLocals();
376:                    if (s > locals)
377:                        locals = s;
378:                }
379:
380:                for (t = transformers; t != null; t = t.getNext())
381:                    t.clean();
382:
383:                codeAttr.setMaxLocals(codeAttr.getMaxLocals() + locals);
384:            }
385:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.