Source Code Cross Referenced for ClassFileLoader.java in  » Database-DBMS » db4o-6.4 » EDU » purdue » cs » bloat » file » 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 » Database DBMS » db4o 6.4 » EDU.purdue.cs.bloat.file 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com
002:
003:        This file is part of the db4o open source object database.
004:
005:        db4o is free software; you can redistribute it and/or modify it under
006:        the terms of version 2 of the GNU General Public License as published
007:        by the Free Software Foundation and as clarified by db4objects' GPL 
008:        interpretation policy, available at
009:        http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010:        Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011:        Suite 350, San Mateo, CA 94403, USA.
012:
013:        db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014:        WARRANTY; without even the implied warranty of MERCHANTABILITY or
015:        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
016:        for more details.
017:
018:        You should have received a copy of the GNU General Public License along
019:        with this program; if not, write to the Free Software Foundation, Inc.,
020:        59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */
021:        package EDU.purdue.cs.bloat.file;
022:
023:        import java.io.*;
024:        import java.util.*;
025:        import java.util.zip.*;
026:        import java.net.URL;
027:
028:        import EDU.purdue.cs.bloat.reflect.*;
029:
030:        /**
031:         * ClassFileLoder provides an interface for loading classes from files. The
032:         * actual loading is done by the ClassFile itself.
033:         * <p>
034:         * Classes may be specified by their full package name (<tt>java.lang.String</tt>),
035:         * or by the name of their class file (<tt>myclasses/Test.class</tt>). The
036:         * class path may contain directories or Zip or Jar files. Any classes that are
037:         * written back to disk ("committed") are placed in the output directory.
038:         * 
039:         * @author Nate Nystrom (<a
040:         *         href="mailto:nystrom@cs.purdue.edu">nystrom@cs.purdue.edu</a>)
041:         */
042:        public class ClassFileLoader implements  ClassInfoLoader {
043:            public static boolean DEBUG = false;
044:
045:            public static boolean USE_SYSTEM_CLASSES = true;
046:
047:            private File outputDir; // Directory in which to write committed class files
048:
049:            private String classpath; // Path to search for classes
050:
051:            private Map openZipFiles; // zip files to search for class files
052:
053:            private LinkedList cache; // We keep a cache of CACHE_LIMIT class files
054:
055:            private boolean verbose;
056:
057:            private static final int CACHE_LIMIT = 10;
058:
059:            private ClassSource _classSource;
060:
061:            public ClassFileLoader(ClassSource classSource) {
062:                outputDir = new File(".");
063:                classpath = System.getProperty("java.class.path");
064:                classpath += File.pathSeparator
065:                        + System.getProperty("sun.boot.class.path");
066:                if (ClassFileLoader.USE_SYSTEM_CLASSES) {
067:                    classpath += File.pathSeparator
068:                            + System.getProperty("java.sys.class.path");
069:                }
070:                openZipFiles = new HashMap();
071:                cache = new LinkedList();
072:                verbose = false;
073:                _classSource = classSource;
074:            }
075:
076:            /**
077:             * Constructor. The classpath initially consists of the contents of the
078:             * <tt>java.class.path</tt> and <tt>sun.boot.class.path</tt> system
079:             * properties.
080:             */
081:            public ClassFileLoader() {
082:                this (new DefaultClassSource());
083:            }
084:
085:            public void setVerbose(final boolean verbose) {
086:                this .verbose = verbose;
087:            }
088:
089:            /**
090:             * Sets the classpath.
091:             */
092:            public void setClassPath(final String classpath) {
093:                this .classpath = classpath;
094:            }
095:
096:            /**
097:             * Adds to the classpath (CLASSPATH = CLASSPATH + morePath).
098:             */
099:            public void appendClassPath(final String morePath) {
100:                this .classpath += File.pathSeparator + morePath;
101:            }
102:
103:            /**
104:             * Adds to the classpath (CLASSPATH = morePath + CLASSPATH).
105:             */
106:            public void prependClassPath(final String morePath) {
107:                this .classpath = morePath + File.pathSeparator + this .classpath;
108:            }
109:
110:            /**
111:             * Returns the path used to search for class files.
112:             */
113:            public String getClassPath() {
114:                return (this .classpath);
115:            }
116:
117:            /**
118:             * Load the class from a stream.
119:             * 
120:             * @param inputFile
121:             *            The file from which to load the class.
122:             * @param stream
123:             *            The stream from which to load the class.
124:             * @return A ClassInfo for the class.
125:             * @exception ClassNotFoundException
126:             *                The class cannot be found in the class path.
127:             */
128:            private ClassInfo loadClassFromStream(final File inputFile,
129:                    final InputStream stream) throws ClassNotFoundException {
130:
131:                final DataInputStream in = new DataInputStream(stream);
132:                final ClassFile file = new ClassFile(inputFile, this , in);
133:
134:                return file;
135:            }
136:
137:            /**
138:             * Load the class from the file.
139:             * 
140:             * @param file
141:             *            The File from which to load a class.
142:             * @return A ClassInfo for the class.
143:             * @exception ClassNotFoundException
144:             *                The class cannot be found in the class path.
145:             */
146:            private ClassInfo loadClassFromFile(final File file)
147:                    throws ClassNotFoundException {
148:                try {
149:                    final InputStream in = new FileInputStream(file);
150:
151:                    final ClassInfo info = loadClassFromStream(file, in);
152:
153:                    if (verbose) {
154:                        System.out.println("[Loaded " + info.name() + " from "
155:                                + file.getPath() + "]");
156:                    }
157:
158:                    try {
159:                        in.close();
160:                    } catch (final IOException ex) {
161:                    }
162:
163:                    return info;
164:                } catch (final FileNotFoundException e) {
165:                    throw new ClassNotFoundException(file.getPath());
166:                }
167:            }
168:
169:            /**
170:             * Loads all of the classes that are contained in a zip (or jar) file.
171:             * Returns an array of the <tt>ClassInfo</tt>s for the classes in the zip
172:             * file.
173:             */
174:            public ClassInfo[] loadClassesFromZipFile(final ZipFile zipFile)
175:                    throws ClassNotFoundException {
176:                final ClassInfo[] infos = new ClassInfo[zipFile.size()];
177:
178:                // Examine each entry in the zip file
179:                final Enumeration entries = zipFile.entries();
180:                for (int i = 0; entries.hasMoreElements(); i++) {
181:                    final ZipEntry entry = (ZipEntry) entries.nextElement();
182:                    if (entry.isDirectory()
183:                            || !entry.getName().endsWith(".class")) {
184:                        continue;
185:                    }
186:
187:                    try {
188:                        final InputStream stream = zipFile
189:                                .getInputStream(entry);
190:                        final File file = new File(entry.getName());
191:
192:                        infos[i] = loadClassFromStream(file, stream);
193:
194:                    } catch (final IOException ex) {
195:                        System.err.println("IOException: " + ex);
196:                    }
197:                }
198:
199:                return (infos);
200:            }
201:
202:            public ClassInfo newClass(final int modifiers,
203:                    final int classIndex, final int super ClassIndex,
204:                    final int[] interfaceIndexes, final List constants) {
205:                return new ClassFile(modifiers, classIndex, super ClassIndex,
206:                        interfaceIndexes, constants, this );
207:            }
208:
209:            /**
210:             * Thhis method tries to load a Class by its ressource.
211:             * @param name the Name of the Class
212:             * @return the ClassInfo
213:             */
214:            private ClassInfo loadClassFromRessource(String name) {
215:                name = name.replace('/', '.');
216:                try {
217:                    Class clazz = _classSource.loadClass(name);
218:                    int i = name.lastIndexOf('.');
219:                    if (i >= 0 && i < name.length()) {
220:                        name = name.substring(i + 1);
221:                    }
222:                    URL url = clazz.getResource(name + ".class");
223:                    if (url != null) {
224:                        return loadClassFromStream(new File(url.getFile()), url
225:                                .openStream());
226:                    }
227:                } catch (Exception e) {
228:                }
229:                return null;
230:            }
231:
232:            /**
233:             * Loads the class with the given name. Searches the class path, including
234:             * zip files, for the class and then returns a data stream for the class
235:             * file.
236:             * 
237:             * @param name
238:             *            The name of the class to load, including the package name.
239:             * @return A ClassInfo for the class.
240:             * @exception ClassNotFoundException
241:             *                The class cannot be found in the class path.
242:             */
243:            public ClassInfo loadClass(String name)
244:                    throws ClassNotFoundException {
245:                ClassInfo file = null;
246:
247:                // Check to see if name ends with ".class". If so, load the class from
248:                // that file. Note that this is okay because we can never have a class
249:                // named "class" (i.e. a class named "class" with a lower-case 'c' can
250:                // never be specified in a fully-specified java class name) because
251:                // "class" is a reserved word.
252:
253:                if (name.endsWith(".class")) {
254:                    final File nameFile = new File(name);
255:
256:                    if (!nameFile.exists()) {
257:                        throw new ClassNotFoundException(name);
258:
259:                    } else {
260:                        return (loadClassFromFile(nameFile));
261:                    }
262:                }
263:
264:                if ((file = loadClassFromRessource(name)) != null) {
265:                    addToCache(file);
266:                    return file;
267:                }
268:
269:                // Otherwise, we have a (possibly fully-specified) class name.
270:                name = name.replace('.', '/');
271:
272:                // Check the cache for the class file.
273:                if (ClassFileLoader.DEBUG) {
274:                    System.out.println("  Looking for " + name + " in cache = "
275:                            + cache);
276:                }
277:
278:                final Iterator iter = cache.iterator();
279:
280:                while (iter.hasNext()) {
281:                    file = (ClassFile) iter.next();
282:
283:                    if (name.equals(file.name())) {
284:                        if (ClassFileLoader.DEBUG) {
285:                            System.out.println("  Found " + file.name()
286:                                    + " in cache");
287:                        }
288:
289:                        // Move to the front of the cache.
290:                        iter.remove();
291:                        cache.addFirst(file);
292:
293:                        return file;
294:                    }
295:                }
296:
297:                file = null;
298:
299:                final String classFile = name.replace('/', File.separatorChar)
300:                        + ".class";
301:
302:                // For each entry in the class path, search zip files and directories
303:                // for classFile. When found, open an InputStream and break
304:                // out of the loop to read the class file.
305:                final String path = classpath + File.pathSeparator;
306:
307:                if (ClassFileLoader.DEBUG) {
308:                    System.out.println("CLASSPATH = " + path);
309:                }
310:
311:                int index = 0;
312:                int end = path.indexOf(File.pathSeparator, index);
313:
314:                SEARCH: while (end >= 0) {
315:                    final String dir = path.substring(index, end);
316:
317:                    File f = new File(dir);
318:
319:                    if (f.isDirectory()) {
320:                        // The directory is really a directory. If the class file
321:                        // exists, open a stream and return.
322:                        f = new File(dir, classFile);
323:
324:                        if (f.exists()) {
325:                            try {
326:                                final InputStream in = new FileInputStream(f);
327:
328:                                if (verbose) {
329:                                    System.out.println("  [Loaded " + name
330:                                            + " from " + f.getPath() + "]");
331:                                }
332:
333:                                file = loadClassFromStream(f, in);
334:
335:                                try {
336:                                    in.close();
337:
338:                                } catch (final IOException ex) {
339:                                }
340:
341:                                break SEARCH;
342:
343:                            } catch (final FileNotFoundException ex) {
344:                            }
345:                        }
346:
347:                    } else if (dir.endsWith(".zip") || dir.endsWith(".jar")) {
348:                        // Maybe a zip file?
349:                        try {
350:                            ZipFile zip = (ZipFile) openZipFiles.get(dir);
351:
352:                            if (zip == null) {
353:                                zip = new ZipFile(f);
354:                                openZipFiles.put(dir, zip);
355:                            }
356:
357:                            final String zipEntry = classFile.replace(
358:                                    File.separatorChar, '/');
359:
360:                            final ZipEntry entry = zip.getEntry(zipEntry);
361:
362:                            if (entry != null) {
363:                                // Found the class file in the zip file.
364:                                // Open a stream and return.
365:                                if (verbose) {
366:                                    System.out.println("  [Loaded " + name
367:                                            + " from " + f.getPath() + "]");
368:                                }
369:
370:                                final InputStream in = zip
371:                                        .getInputStream(entry);
372:                                file = loadClassFromStream(f, in);
373:
374:                                try {
375:                                    in.close();
376:
377:                                } catch (final IOException ex) {
378:                                }
379:                                break SEARCH;
380:                            }
381:                        } catch (final ZipException ex) {
382:                        } catch (final IOException ex) {
383:                        }
384:                    }
385:
386:                    index = end + 1;
387:                    end = path.indexOf(File.pathSeparator, index);
388:                }
389:
390:                if (file == null) {
391:                    // The class file wasn't in the class path. Try the currnet
392:                    // directory. If not there, give up.
393:                    final File f = new File(classFile);
394:
395:                    if (!f.exists()) {
396:                        throw new ClassNotFoundException(name);
397:                    }
398:
399:                    if (verbose) {
400:                        System.out.println("  [Loaded " + name + " from "
401:                                + f.getPath() + "]");
402:                    }
403:
404:                    try {
405:                        final InputStream in = new FileInputStream(f);
406:                        file = loadClassFromStream(f, in);
407:
408:                        try {
409:                            in.close();
410:                        } catch (final IOException ex) {
411:                        }
412:                    } catch (final FileNotFoundException ex) {
413:                        throw new ClassNotFoundException(name);
414:                    }
415:                }
416:
417:                if (file == null) {
418:                    throw new ClassNotFoundException(name);
419:                }
420:
421:                addToCache(file);
422:
423:                return file;
424:            }
425:
426:            private void addToCache(ClassInfo file) {
427:                // If we've reached the cache size limit, remove the oldest file
428:                // in the cache. Then add the new file.
429:                if (cache.size() == ClassFileLoader.CACHE_LIMIT) {
430:                    cache.removeLast();
431:                }
432:
433:                cache.addFirst(file);
434:            }
435:
436:            /**
437:             * Set the directory into which commited class files should be written.
438:             * 
439:             * @param dir
440:             *            The directory.
441:             */
442:            public void setOutputDir(final File dir) {
443:                outputDir = dir;
444:            }
445:
446:            /**
447:             * Get the directory into which commited class files should be written.
448:             */
449:            public File outputDir() {
450:                return outputDir;
451:            }
452:
453:            /**
454:             * Writes a bunch of <code>byte</code>s to an output entry with the given
455:             * name.
456:             */
457:            public void writeEntry(final byte[] bytes, final String name)
458:                    throws IOException {
459:                final OutputStream os = outputStreamFor(name);
460:                os.write(bytes);
461:                os.flush();
462:                os.close();
463:            }
464:
465:            /**
466:             * Returns an <tt>OutputStream</tt> to which a class file should be
467:             * written.
468:             */
469:            public OutputStream outputStreamFor(final ClassInfo info)
470:                    throws IOException {
471:                // Format the name of the output file
472:                final String name = info.name()
473:                        .replace('/', File.separatorChar)
474:                        + ".class";
475:                return outputStreamFor(name);
476:            }
477:
478:            /**
479:             * Returns an <code>OutputStream</code> to which somed named entity is
480:             * written. Any forward slashes in the name are replaced by
481:             * <code>File.separatorChar</code>.
482:             */
483:            protected OutputStream outputStreamFor(String name)
484:                    throws IOException {
485:
486:                name = name.replace('/', File.separatorChar);
487:
488:                final File f = new File(outputDir, name);
489:
490:                if (f.exists()) {
491:                    f.delete();
492:                }
493:
494:                final File dir = new File(f.getParent());
495:                dir.mkdirs();
496:
497:                if (!dir.exists()) {
498:                    throw new RuntimeException("Couldn't create directory: "
499:                            + dir);
500:                }
501:
502:                return (new FileOutputStream(f));
503:            }
504:
505:            /**
506:             * Signifies that we are done with this <code>ClassFileLoader</code>
507:             */
508:            public void done() throws IOException {
509:                // Nothing for this guy
510:            }
511:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.