Source Code Cross Referenced for ClassEnhancer.java in  » JMX » je » com » sleepycat » persist » model » 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 » JMX » je » com.sleepycat.persist.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*-
002:         * See the file LICENSE for redistribution information.
003:         *
004:         * Copyright (c) 2002,2008 Oracle.  All rights reserved.
005:         *
006:         * $Id: ClassEnhancer.java,v 1.14.2.3 2008/01/07 15:14:20 cwl Exp $
007:         */
008:
009:        package com.sleepycat.persist.model;
010:
011:        import java.io.File;
012:        import java.io.FileInputStream;
013:        import java.io.FileOutputStream;
014:        import java.io.IOException;
015:        import java.lang.instrument.ClassFileTransformer;
016:        import java.lang.instrument.Instrumentation;
017:        import java.security.ProtectionDomain;
018:        import java.util.ArrayList;
019:        import java.util.HashSet;
020:        import java.util.List;
021:        import java.util.Set;
022:        import java.util.StringTokenizer;
023:
024:        import com.sleepycat.asm.ClassReader;
025:        import com.sleepycat.asm.ClassVisitor;
026:        import com.sleepycat.asm.ClassWriter;
027:
028:        /**
029:         * Enhances the bytecode of persistent classes to provide efficient access to
030:         * fields and constructors, and to avoid special security policy settings for
031:         * accessing non-public members.  Classes are enhanced if they are annotated
032:         * with {@link Entity} or {@link Persistent}.
033:         *
034:         * <p>{@code ClassEnhancer} objects are thread-safe.  Multiple threads may
035:         * safely call the methods of a shared {@code ClassEnhancer} object.</p>
036:         *
037:         * <p>As described in the {@link <a
038:         * href="../package-summary.html#bytecode">package summary</a>}, bytecode
039:         * enhancement may be used either at runtime or offline (at build time).</p>
040:         *
041:         * <p>To use enhancement offline, this class may be used as a {@link #main main
042:         * program} or via an {@link ClassEnhancerTask ant task}.</p>
043:         *
044:         * <p>For enhancement at runtime, this class provides the low level support
045:         * needed to transform class bytes during class loading.  To configure runtime
046:         * enhancement you may use one of the following approaches:</p>
047:         * <ol>
048:         * <li>For Java 1.5, the {@code je-<version>.jar} file may be used as an instrumentation
049:         * agent as follows:
050:         * <pre class="code">{@literal java -javaagent:lib/je-<version>.jar=enhance:packageNames ...}</pre>
051:         * {@code packageNames} is a comma separated list of packages containing
052:         * persistent classes.  Sub-packages of these packages are also searched.  If
053:         * {@code packageNames} is omitted then all packages known to the current
054:         * classloader are searched.
055:         * <p>The "-v" option may be included in the comma separated list to print the
056:         * name of each class that is enhanced.</p></li>
057:         * <br>
058:         * <li>The {@link #enhance} method may be called to implement a class loader
059:         * that performs enhancement.  Using this approach, it is the developer's
060:         * responsibility to implement and configure the class loader.</li>
061:         * </ol>
062:         *
063:         * @author Mark Hayes
064:         */
065:        public class ClassEnhancer implements  ClassFileTransformer {
066:
067:            private static final String AGENT_PREFIX = "enhance:";
068:
069:            private Set<String> packagePrefixes;
070:            private boolean verbose;
071:
072:            /**
073:             * Enhances classes in the directories specified.  The class files are
074:             * replaced when they are enhanced, without changing the file modification
075:             * date.  For example:
076:             *
077:             * <pre class="code">java -cp je-&lt;version&gt;.jar com.sleepycat.persist.model.ClassEnhancer ./classes</pre>
078:             *
079:             * <p>The "-v" argument may be specified to print the name of each class
080:             * file that is enhanced.  The total number of class files enhanced will
081:             * always be printed.</p>
082:             *
083:             * @param args one or more directories containing classes to be enhanced.
084:             * Subdirectories of these directories will also be searched.  Optionally,
085:             * -v may be included to print the name of every class file enhanced.
086:             */
087:            public static void main(String[] args) throws Exception {
088:                try {
089:                    boolean verbose = false;
090:                    List<File> fileList = new ArrayList<File>();
091:                    for (int i = 0; i < args.length; i += 1) {
092:                        String arg = args[i];
093:                        if (arg.startsWith("-")) {
094:                            if ("-v".equals(args[i])) {
095:                                verbose = true;
096:                            } else {
097:                                throw new IllegalArgumentException(
098:                                        "Unknown arg: " + arg);
099:                            }
100:                        } else {
101:                            fileList.add(new File(arg));
102:                        }
103:                    }
104:                    ClassEnhancer enhancer = new ClassEnhancer();
105:                    enhancer.setVerbose(verbose);
106:                    int nFiles = 0;
107:                    for (File file : fileList) {
108:                        nFiles += enhancer.enhanceFile(file);
109:                    }
110:                    if (nFiles > 0) {
111:                        System.out.println("Enhanced: " + nFiles + " files");
112:                    }
113:                } catch (Exception e) {
114:                    e.printStackTrace();
115:                    throw e;
116:                }
117:            }
118:
119:            /**
120:             * Enhances classes as specified by a JVM -javaagent argument.
121:             *
122:             * @see java.lang.instrument
123:             */
124:            public static void premain(String args, Instrumentation inst) {
125:                if (!args.startsWith(AGENT_PREFIX)) {
126:                    throw new IllegalArgumentException(
127:                            "Unknown javaagent args: " + args
128:                                    + " Args must start with: \""
129:                                    + AGENT_PREFIX + '"');
130:                }
131:                args = args.substring(AGENT_PREFIX.length());
132:                Set<String> packageNames = null;
133:                boolean verbose = false;
134:                if (args.length() > 0) {
135:                    packageNames = new HashSet<String>();
136:                    StringTokenizer tokens = new StringTokenizer(args, ",");
137:                    while (tokens.hasMoreTokens()) {
138:                        String token = tokens.nextToken();
139:                        if (token.startsWith("-")) {
140:                            if (token.equals("-v")) {
141:                                verbose = true;
142:                            } else {
143:                                throw new IllegalArgumentException(
144:                                        "Unknown javaagent arg: " + token);
145:                            }
146:                        } else {
147:                            packageNames.add(token);
148:                        }
149:                    }
150:                }
151:                ClassEnhancer enhancer = new ClassEnhancer(packageNames);
152:                enhancer.setVerbose(verbose);
153:                inst.addTransformer(enhancer);
154:            }
155:
156:            /**
157:             * Creates a class enhancer that searches all packages.
158:             */
159:            public ClassEnhancer() {
160:            }
161:
162:            /**
163:             * Sets verbose mode.
164:             *
165:             * <p>True may be specified to print the name of each class file that is
166:             * enhanced.  This property is false by default.</p>
167:             */
168:            public void setVerbose(boolean verbose) {
169:                this .verbose = verbose;
170:            }
171:
172:            /**
173:             * Gets verbose mode.
174:             *
175:             * @see #setVerbose
176:             */
177:            public boolean getVerbose() {
178:                return verbose;
179:            }
180:
181:            /**
182:             * Creates a class enhancer that searches a given set of packages.
183:             *
184:             * @param packageNames a set of packages to search for persistent
185:             * classes.  Sub-packages of these packages are also searched.  If empty or
186:             * null, all packages known to the current classloader are searched.
187:             */
188:            public ClassEnhancer(Set<String> packageNames) {
189:                if (packageNames != null) {
190:                    packagePrefixes = new HashSet<String>();
191:                    for (String name : packageNames) {
192:                        packagePrefixes.add(name + '.');
193:                    }
194:                }
195:            }
196:
197:            public byte[] transform(ClassLoader loader, String className,
198:                    Class<?> classBeingRedefined,
199:                    ProtectionDomain protectionDomain, byte[] classfileBuffer) {
200:                className = className.replace('/', '.');
201:                byte[] bytes = enhance(className, classfileBuffer);
202:                if (verbose && bytes != null) {
203:                    System.out.println("Enhanced: " + className);
204:                }
205:                return bytes;
206:            }
207:
208:            /**
209:             * Enhances the given class bytes if the class is annotated with {@link
210:             * Entity} or {@link Persistent}.
211:             *
212:             * @param className the class name in binary format; for example,
213:             * "my.package.MyClass$Name", or null if no filtering by class name
214:             * should be performed.
215:             *
216:             * @param classBytes are the class file bytes to be enhanced.
217:             *
218:             * @return the enhanced bytes, or null if no enhancement was performed.
219:             */
220:            public byte[] enhance(String className, byte[] classBytes) {
221:                if (className != null && packagePrefixes != null) {
222:                    for (String prefix : packagePrefixes) {
223:                        if (className.startsWith(prefix)) {
224:                            return enhanceBytes(classBytes);
225:                        }
226:                    }
227:                    return null;
228:                } else {
229:                    return enhanceBytes(classBytes);
230:                }
231:            }
232:
233:            int enhanceFile(File file) throws IOException {
234:
235:                int nFiles = 0;
236:                if (file.isDirectory()) {
237:                    String[] names = file.list();
238:                    if (names != null) {
239:                        for (int i = 0; i < names.length; i += 1) {
240:                            nFiles += enhanceFile(new File(file, names[i]));
241:                        }
242:                    }
243:                } else if (file.getName().endsWith(".class")) {
244:                    byte[] newBytes = enhanceBytes(readFile(file));
245:                    if (newBytes != null) {
246:                        long modified = file.lastModified();
247:                        writeFile(file, newBytes);
248:                        file.setLastModified(modified);
249:                        nFiles += 1;
250:                        if (verbose) {
251:                            System.out.println("Enhanced: " + file);
252:                        }
253:                    }
254:                }
255:                return nFiles;
256:            }
257:
258:            private byte[] readFile(File file) throws IOException {
259:
260:                byte[] bytes = new byte[(int) file.length()];
261:                FileInputStream in = new FileInputStream(file);
262:                try {
263:                    in.read(bytes);
264:                } finally {
265:                    in.close();
266:                }
267:                return bytes;
268:            }
269:
270:            private void writeFile(File file, byte[] bytes) throws IOException {
271:
272:                FileOutputStream out = new FileOutputStream(file);
273:                try {
274:                    out.write(bytes);
275:                } finally {
276:                    out.close();
277:                }
278:            }
279:
280:            private byte[] enhanceBytes(byte[] bytes) {
281:
282:                /*
283:                 * The writer is at the end of the visitor chain.  Pass true to
284:                 * calculate stack size, for safety.
285:                 */
286:                ClassWriter writer = new ClassWriter(true);
287:                ClassVisitor visitor = writer;
288:
289:                /* The enhancer is at the beginning of the visitor chain. */
290:                visitor = new BytecodeEnhancer(visitor);
291:
292:                /* The reader processes the class and invokes the visitors. */
293:                ClassReader reader = new ClassReader(bytes);
294:                try {
295:
296:                    /*
297:                     * Pass false for skipDebug since we are rewriting the class and
298:                     * should include all information.
299:                     */
300:                    reader.accept(visitor, false);
301:                    return writer.toByteArray();
302:                } catch (BytecodeEnhancer.NotPersistentException e) {
303:                    /* The class is not persistent and should not be enhanced. */
304:                    return null;
305:                }
306:            }
307:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.