Source Code Cross Referenced for CachedJarsPackageManager.java in  » Scripting » jython » org » python » core » 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 » Scripting » jython » org.python.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) Corporation for National Research Initiatives
002:        // Copyright 2000 Samuele Pedroni
003:
004:        package org.python.core;
005:
006:        import java.io.BufferedInputStream;
007:        import java.io.BufferedOutputStream;
008:        import java.io.DataInputStream;
009:        import java.io.DataOutputStream;
010:        import java.io.EOFException;
011:        import java.io.File;
012:        import java.io.FileInputStream;
013:        import java.io.FileOutputStream;
014:        import java.io.IOException;
015:        import java.io.InputStream;
016:        import java.lang.reflect.Modifier;
017:        import java.net.URL;
018:        import java.net.URLConnection;
019:        import java.security.AccessControlException;
020:        import java.util.Enumeration;
021:        import java.util.Hashtable;
022:        import java.util.Vector;
023:        import java.util.zip.ZipEntry;
024:        import java.util.zip.ZipInputStream;
025:
026:        /**
027:         * Abstract package manager that gathers info about statically known classes
028:         * from a set of jars. This info can be eventually cached. Off-the-shelf this
029:         * class offers a local file-system based cache impl.
030:         */
031:        public abstract class CachedJarsPackageManager extends PackageManager {
032:
033:            /**
034:             * Message log method - hook. This default impl does nothing.
035:             * 
036:             * @param msg message text
037:             */
038:            protected void message(String msg) {
039:            }
040:
041:            /**
042:             * Warning log method - hook. This default impl does nothing.
043:             * 
044:             * @param warn warning text
045:             */
046:            protected void warning(String warn) {
047:            }
048:
049:            /**
050:             * Comment log method - hook. This default impl does nothing.
051:             * 
052:             * @param msg message text
053:             */
054:            protected void comment(String msg) {
055:            }
056:
057:            /**
058:             * Debug log method - hook. This default impl does nothing.
059:             * 
060:             * @param msg message text
061:             */
062:            protected void debug(String msg) {
063:            }
064:
065:            /**
066:             * Filter class/pkg by name helper method - hook. The default impl. is used
067:             * by {@link #addJarToPackages} in order to filter out classes whose name
068:             * contains '$' (e.g. inner classes,...). Should be used or overriden by
069:             * derived classes too. Also to be used in {@link #doDir}.
070:             * 
071:             * @param name class/pkg name
072:             * @param pkg if true, name refers to a pkg
073:             * @return true if name must be filtered out
074:             */
075:            protected boolean filterByName(String name, boolean pkg) {
076:                return name.indexOf('$') != -1;
077:            }
078:
079:            /**
080:             * Filter class by access perms helper method - hook. The default impl. is
081:             * used by {@link #addJarToPackages} in order to filter out non-public
082:             * classes. Should be used or overriden by derived classes too. Also to be
083:             * used in {@link #doDir}. Access perms can be read with
084:             * {@link #checkAccess}.
085:             * 
086:             * @param name class name
087:             * @param acc class access permissions as int
088:             * @return true if name must be filtered out
089:             */
090:            protected boolean filterByAccess(String name, int acc) {
091:                return (acc & Modifier.PUBLIC) != Modifier.PUBLIC;
092:            }
093:
094:            private boolean indexModified;
095:
096:            private Hashtable jarfiles;
097:
098:            private static String vectorToString(Vector vec) {
099:                int n = vec.size();
100:                StringBuffer ret = new StringBuffer();
101:                for (int i = 0; i < n; i++) {
102:                    ret.append((String) vec.elementAt(i));
103:                    if (i < n - 1) {
104:                        ret.append(",");
105:                    }
106:                }
107:                return ret.toString();
108:            }
109:
110:            // Add a single class from zipFile to zipPackages
111:            // Only add valid, public classes
112:            private void addZipEntry(Hashtable zipPackages, ZipEntry entry,
113:                    ZipInputStream zip) throws IOException {
114:                String name = entry.getName();
115:                // System.err.println("entry: "+name);
116:                if (!name.endsWith(".class")) {
117:                    return;
118:                }
119:
120:                char sep = '/';
121:                int breakPoint = name.lastIndexOf(sep);
122:                if (breakPoint == -1) {
123:                    breakPoint = name.lastIndexOf('\\');
124:                    sep = '\\';
125:                }
126:
127:                String packageName;
128:                if (breakPoint == -1) {
129:                    packageName = "";
130:                } else {
131:                    packageName = name.substring(0, breakPoint).replace(sep,
132:                            '.');
133:                }
134:
135:                String className = name.substring(breakPoint + 1,
136:                        name.length() - 6);
137:
138:                if (filterByName(className, false)) {
139:                    return;
140:                }
141:
142:                Vector[] vec = (Vector[]) zipPackages.get(packageName);
143:                if (vec == null) {
144:                    vec = new Vector[] { new Vector(), new Vector() };
145:                    zipPackages.put(packageName, vec);
146:                }
147:                int access = checkAccess(zip);
148:                if ((access != -1) && !filterByAccess(name, access)) {
149:                    vec[0].addElement(className);
150:                } else {
151:                    vec[1].addElement(className);
152:                }
153:            }
154:
155:            // Extract all of the packages in a single jarfile
156:            private Hashtable getZipPackages(InputStream jarin)
157:                    throws IOException {
158:                Hashtable zipPackages = new Hashtable();
159:
160:                ZipInputStream zip = new ZipInputStream(jarin);
161:
162:                ZipEntry entry;
163:                while ((entry = zip.getNextEntry()) != null) {
164:                    addZipEntry(zipPackages, entry, zip);
165:                    zip.closeEntry();
166:                }
167:
168:                // Turn each vector into a comma-separated String
169:                for (Enumeration e = zipPackages.keys(); e.hasMoreElements();) {
170:                    Object key = e.nextElement();
171:                    Vector[] vec = (Vector[]) zipPackages.get(key);
172:                    String classes = vectorToString(vec[0]);
173:                    if (vec[1].size() > 0) {
174:                        classes += '@' + vectorToString(vec[1]);
175:                    }
176:                    zipPackages.put(key, classes);
177:                }
178:
179:                return zipPackages;
180:            }
181:
182:            /**
183:             * Gathers classes info from jar specified by jarurl URL. Eventually just
184:             * using previously cached info. Eventually updated info is not cached.
185:             * Persistent cache storage access goes through inOpenCacheFile() and
186:             * outCreateCacheFile().
187:             */
188:            public void addJarToPackages(java.net.URL jarurl) {
189:                addJarToPackages(jarurl, null, false);
190:            }
191:
192:            /**
193:             * Gathers classes info from jar specified by jarurl URL. Eventually just
194:             * using previously cached info. Eventually updated info is (re-)cached if
195:             * param cache is true. Persistent cache storage access goes through
196:             * inOpenCacheFile() and outCreateCacheFile().
197:             */
198:            public void addJarToPackages(URL jarurl, boolean cache) {
199:                addJarToPackages(jarurl, null, cache);
200:            }
201:
202:            /**
203:             * Gathers classes info from jar specified by File jarfile. Eventually just
204:             * using previously cached info. Eventually updated info is not cached.
205:             * Persistent cache storage access goes through inOpenCacheFile() and
206:             * outCreateCacheFile().
207:             */
208:            public void addJarToPackages(File jarfile) {
209:                addJarToPackages(null, jarfile, false);
210:            }
211:
212:            /**
213:             * Gathers classes info from jar specified by File jarfile. Eventually just
214:             * using previously cached info. Eventually updated info is (re-)cached if
215:             * param cache is true. Persistent cache storage access goes through
216:             * inOpenCacheFile() and outCreateCacheFile().
217:             */
218:            public void addJarToPackages(File jarfile, boolean cache) {
219:                addJarToPackages(null, jarfile, cache);
220:            }
221:
222:            private void addJarToPackages(URL jarurl, File jarfile,
223:                    boolean cache) {
224:                try {
225:                    boolean caching = this .jarfiles != null;
226:
227:                    URLConnection jarconn = null;
228:                    boolean localfile = true;
229:
230:                    if (jarfile == null) {
231:                        jarconn = jarurl.openConnection();
232:                        // This is necessary because 'file:' url-connections
233:                        // return always 0 through getLastModified (bug?).
234:                        // And in order to handle localfiles (from urls too)
235:                        // uniformly.
236:                        if (jarconn.getURL().getProtocol().equals("file")) {
237:                            // ??pending: need to use java2 URLDecoder.decode?
238:                            String jarfilename = jarurl.getFile();
239:                            jarfilename = jarfilename.replace('/',
240:                                    File.separatorChar);
241:                            jarfile = new File(jarfilename);
242:                        } else {
243:                            localfile = false;
244:                        }
245:                    }
246:
247:                    if (localfile && !jarfile.exists()) {
248:                        return;
249:                    }
250:
251:                    Hashtable zipPackages = null;
252:
253:                    long mtime = 0;
254:                    String jarcanon = null;
255:                    JarXEntry entry = null;
256:                    boolean brandNew = false;
257:
258:                    if (caching) {
259:
260:                        if (localfile) {
261:                            mtime = jarfile.lastModified();
262:                            jarcanon = jarfile.getCanonicalPath();
263:                        } else {
264:                            mtime = jarconn.getLastModified();
265:                            jarcanon = jarurl.toString();
266:                        }
267:
268:                        entry = (JarXEntry) this .jarfiles.get(jarcanon);
269:
270:                        if ((entry == null || !(new File(entry.cachefile)
271:                                .exists()))
272:                                && cache) {
273:                            message("processing new jar, '" + jarcanon + "'");
274:
275:                            String jarname;
276:                            if (localfile) {
277:                                jarname = jarfile.getName();
278:                            } else {
279:                                jarname = jarurl.getFile();
280:                                int slash = jarname.lastIndexOf('/');
281:                                if (slash != -1)
282:                                    jarname = jarname.substring(slash + 1);
283:                            }
284:                            jarname = jarname
285:                                    .substring(0, jarname.length() - 4);
286:
287:                            entry = new JarXEntry(jarname);
288:                            this .jarfiles.put(jarcanon, entry);
289:
290:                            brandNew = true;
291:                        }
292:
293:                        if (mtime != 0 && entry != null && entry.mtime == mtime) {
294:                            zipPackages = readCacheFile(entry, jarcanon);
295:                        }
296:
297:                    }
298:
299:                    if (zipPackages == null) {
300:                        caching = caching && cache;
301:
302:                        if (caching) {
303:                            this .indexModified = true;
304:                            if (entry.mtime != 0) {
305:                                message("processing modified jar, '" + jarcanon
306:                                        + "'");
307:                            }
308:                            entry.mtime = mtime;
309:                        }
310:
311:                        InputStream jarin;
312:                        if (jarconn == null) {
313:                            jarin = new BufferedInputStream(
314:                                    new FileInputStream(jarfile));
315:                        } else {
316:                            jarin = jarconn.getInputStream();
317:                        }
318:
319:                        zipPackages = getZipPackages(jarin);
320:
321:                        if (caching) {
322:                            writeCacheFile(entry, jarcanon, zipPackages,
323:                                    brandNew);
324:                        }
325:                    }
326:
327:                    addPackages(zipPackages, jarcanon);
328:                } catch (IOException ioe) {
329:                    // silently skip any bad directories
330:                    warning("skipping bad jar, '"
331:                            + (jarfile != null ? jarfile.toString() : jarurl
332:                                    .toString()) + "'");
333:                }
334:
335:            }
336:
337:            private void addPackages(Hashtable zipPackages, String jarfile) {
338:                for (Enumeration e = zipPackages.keys(); e.hasMoreElements();) {
339:                    String pkg = (String) e.nextElement();
340:                    String classes = (String) zipPackages.get(pkg);
341:
342:                    int idx = classes.indexOf('@');
343:                    if (idx >= 0 && Options.respectJavaAccessibility) {
344:                        classes = classes.substring(0, idx);
345:                    }
346:
347:                    makeJavaPackage(pkg, classes, jarfile);
348:                }
349:            }
350:
351:            // Read in cache file storing package info for a single .jar
352:            // Return null and delete this cachefile if it is invalid
353:            private Hashtable readCacheFile(JarXEntry entry, String jarcanon) {
354:                String cachefile = entry.cachefile;
355:                long mtime = entry.mtime;
356:
357:                debug("reading cache, '" + jarcanon + "'");
358:
359:                try {
360:                    DataInputStream istream = inOpenCacheFile(cachefile);
361:                    String old_jarcanon = istream.readUTF();
362:                    long old_mtime = istream.readLong();
363:                    if ((!old_jarcanon.equals(jarcanon))
364:                            || (old_mtime != mtime)) {
365:                        comment("invalid cache file: " + cachefile + ", "
366:                                + jarcanon + ":" + old_jarcanon + ", " + mtime
367:                                + ":" + old_mtime);
368:                        deleteCacheFile(cachefile);
369:                        return null;
370:                    }
371:                    Hashtable packs = new Hashtable();
372:                    try {
373:                        while (true) {
374:                            String packageName = istream.readUTF();
375:                            String classes = istream.readUTF();
376:                            packs.put(packageName, classes);
377:                        }
378:                    } catch (EOFException eof) {
379:                        ;
380:                    }
381:                    istream.close();
382:
383:                    return packs;
384:                } catch (IOException ioe) {
385:                    // if (cachefile.exists()) cachefile.delete();
386:                    return null;
387:                }
388:            }
389:
390:            // Write a cache file storing package info for a single .jar
391:            private void writeCacheFile(JarXEntry entry, String jarcanon,
392:                    Hashtable zipPackages, boolean brandNew) {
393:                try {
394:                    DataOutputStream ostream = outCreateCacheFile(entry,
395:                            brandNew);
396:                    ostream.writeUTF(jarcanon);
397:                    ostream.writeLong(entry.mtime);
398:                    comment("rewriting cachefile for '" + jarcanon + "'");
399:
400:                    for (Enumeration e = zipPackages.keys(); e
401:                            .hasMoreElements();) {
402:                        String packageName = (String) e.nextElement();
403:                        String classes = (String) zipPackages.get(packageName);
404:                        ostream.writeUTF(packageName);
405:                        ostream.writeUTF(classes);
406:                    }
407:                    ostream.close();
408:                } catch (IOException ioe) {
409:                    warning("can't write cache file for '" + jarcanon + "'");
410:                }
411:            }
412:
413:            /**
414:             * Initializes cache. Eventually reads back cache index. Index persistent
415:             * storage is accessed through inOpenIndex().
416:             */
417:            protected void initCache() {
418:                this .indexModified = false;
419:                this .jarfiles = new Hashtable();
420:
421:                try {
422:                    DataInputStream istream = inOpenIndex();
423:                    if (istream == null) {
424:                        return;
425:                    }
426:
427:                    try {
428:                        while (true) {
429:                            String jarcanon = istream.readUTF();
430:                            String cachefile = istream.readUTF();
431:                            long mtime = istream.readLong();
432:                            this .jarfiles.put(jarcanon, new JarXEntry(
433:                                    cachefile, mtime));
434:                        }
435:                    } catch (EOFException eof) {
436:                        ;
437:                    }
438:                    istream.close();
439:                } catch (IOException ioe) {
440:                    warning("invalid index file");
441:                }
442:
443:            }
444:
445:            /**
446:             * Write back cache index. Index persistent storage is accessed through
447:             * outOpenIndex().
448:             */
449:            public void saveCache() {
450:                if (this .jarfiles == null || !this .indexModified) {
451:                    return;
452:                }
453:
454:                this .indexModified = false;
455:
456:                comment("writing modified index file");
457:
458:                try {
459:                    DataOutputStream ostream = outOpenIndex();
460:                    for (Enumeration e = this .jarfiles.keys(); e
461:                            .hasMoreElements();) {
462:                        String jarcanon = (String) e.nextElement();
463:                        JarXEntry entry = (JarXEntry) this .jarfiles
464:                                .get(jarcanon);
465:                        ostream.writeUTF(jarcanon);
466:                        ostream.writeUTF(entry.cachefile);
467:                        ostream.writeLong(entry.mtime);
468:                    }
469:                    ostream.close();
470:                } catch (IOException ioe) {
471:                    warning("can't write index file");
472:                }
473:            }
474:
475:            // hooks for changing cache storage
476:
477:            /**
478:             * To pass a cachefile id by ref. And for internal use. See
479:             * outCreateCacheFile
480:             */
481:            public static class JarXEntry extends Object {
482:                /** cachefile id */
483:                public String cachefile;
484:
485:                public long mtime;
486:
487:                public JarXEntry(String cachefile) {
488:                    this .cachefile = cachefile;
489:                }
490:
491:                public JarXEntry(String cachefile, long mtime) {
492:                    this .cachefile = cachefile;
493:                    this .mtime = mtime;
494:                }
495:
496:            }
497:
498:            /**
499:             * Open cache index for reading from persistent storage - hook. Must Return
500:             * null if this is absent. This default impl is part of the off-the-shelf
501:             * local file-system cache impl. Can be overriden.
502:             */
503:            protected DataInputStream inOpenIndex() throws IOException {
504:                File indexFile = new File(this .cachedir, "packages.idx");
505:
506:                if (!indexFile.exists()) {
507:                    return null;
508:                }
509:
510:                DataInputStream istream = new DataInputStream(
511:                        new BufferedInputStream(new FileInputStream(indexFile)));
512:
513:                return istream;
514:            }
515:
516:            /**
517:             * Open cache index for writing back to persistent storage - hook. This
518:             * default impl is part of the off-the-shelf local file-system cache impl.
519:             * Can be overriden.
520:             */
521:            protected DataOutputStream outOpenIndex() throws IOException {
522:                File indexFile = new File(this .cachedir, "packages.idx");
523:
524:                return new DataOutputStream(new BufferedOutputStream(
525:                        new FileOutputStream(indexFile)));
526:            }
527:
528:            /**
529:             * Open cache file for reading from persistent storage - hook. This default
530:             * impl is part of the off-the-shelf local file-system cache impl. Can be
531:             * overriden.
532:             */
533:            protected DataInputStream inOpenCacheFile(String cachefile)
534:                    throws IOException {
535:                return new DataInputStream(new BufferedInputStream(
536:                        new FileInputStream(cachefile)));
537:            }
538:
539:            /**
540:             * Delete (invalidated) cache file from persistent storage - hook. This
541:             * default impl is part of the off-the-shelf local file-system cache impl.
542:             * Can be overriden.
543:             */
544:            protected void deleteCacheFile(String cachefile) {
545:                new File(cachefile).delete();
546:            }
547:
548:            /**
549:             * Create/open cache file for rewriting back to persistent storage - hook.
550:             * If create is false, cache file is supposed to exist and must be opened
551:             * for rewriting, entry.cachefile is a valid cachefile id. If create is
552:             * true, cache file must be created. entry.cachefile is a flat jarname to be
553:             * used to produce a valid cachefile id (to be put back in entry.cachefile
554:             * on exit). This default impl is part of the off-the-shelf local
555:             * file-system cache impl. Can be overriden.
556:             */
557:            protected DataOutputStream outCreateCacheFile(JarXEntry entry,
558:                    boolean create) throws IOException {
559:                File cachefile = null;
560:
561:                if (create) {
562:                    int index = 1;
563:                    String suffix = "";
564:                    String jarname = entry.cachefile;
565:                    while (true) {
566:                        cachefile = new File(this .cachedir, jarname + suffix
567:                                + ".pkc");
568:                        // System.err.println("try cachefile: "+cachefile);
569:                        if (!cachefile.exists()) {
570:                            break;
571:                        }
572:                        suffix = "$" + index;
573:                        index += 1;
574:                    }
575:                    entry.cachefile = cachefile.getCanonicalPath();
576:                } else
577:                    cachefile = new File(entry.cachefile);
578:
579:                return new DataOutputStream(new BufferedOutputStream(
580:                        new FileOutputStream(cachefile)));
581:            }
582:
583:            // for default cache (local fs based) impl
584:
585:            private File cachedir;
586:
587:            /**
588:             * Initialize off-the-shelf (default) local file-system cache impl. Must be
589:             * called before {@link #initCache}. cachedir is the cache repository
590:             * directory, this is eventually created. Returns true if dir works.
591:             */
592:            protected boolean useCacheDir(File aCachedir1) {
593:                if (aCachedir1 == null) {
594:                    return false;
595:                }
596:                try {
597:                    if (!aCachedir1.isDirectory()
598:                            && aCachedir1.mkdirs() == false) {
599:                        warning("can't create package cache dir, '"
600:                                + aCachedir1 + "'");
601:                        return false;
602:                    }
603:                } catch (AccessControlException ace) {
604:                    warning("The java security manager isn't allowing access to the package cache dir, '"
605:                            + aCachedir1 + "'");
606:                    return false;
607:                }
608:
609:                this .cachedir = aCachedir1;
610:
611:                return true;
612:            }
613:
614:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.