Source Code Cross Referenced for CarResources.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » car » 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 » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.car 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2002 The JA-SIG Collaborative.  All rights reserved.
002:         *  See license distributed with this file and
003:         *  available online at http://www.uportal.org/license.html
004:         */
005:
006:        package org.jasig.portal.car;
007:
008:        import java.io.File;
009:        import java.io.FileFilter;
010:        import java.io.IOException;
011:        import java.io.InputStream;
012:        import java.net.URL;
013:        import java.util.Enumeration;
014:        import java.util.Hashtable;
015:        import java.util.Iterator;
016:        import java.util.Map;
017:        import java.util.Properties;
018:        import java.util.StringTokenizer;
019:        import java.util.Vector;
020:        import java.util.Map.Entry;
021:        import java.util.jar.JarFile;
022:        import java.util.zip.ZipEntry;
023:
024:        import javax.servlet.Servlet;
025:        import javax.servlet.ServletContext;
026:
027:        import org.apache.commons.logging.Log;
028:        import org.apache.commons.logging.LogFactory;
029:        import org.jasig.portal.PortalException;
030:        import org.jasig.portal.PortalSessionManager;
031:        import org.jasig.portal.properties.PropertiesManager;
032:        import org.jasig.portal.utils.SAX2BufferImpl;
033:        import org.xml.sax.ContentHandler;
034:        import org.xml.sax.SAXException;
035:
036:        /**
037:         * Provides access to resources stored in channel archive files or CARs for
038:         * short. 
039:         * @author Mark Boyd  {@link <a href="mailto:mark.boyd@engineer.com">mark.boyd@engineer.com</a>}
040:         * @version $Revision: 36690 $
041:         */
042:        public class CarResources {
043:
044:            // static, class variables
045:            private static final Log log = LogFactory
046:                    .getLog(CarResources.class);
047:            private static CarResources instance = null;
048:            private static CarClassLoader loader = null;
049:
050:            public final static String RCS_ID = "@(#) $Header$";
051:
052:            static final String DEPLOYMENT_DESCRIPTOR = "META-INF/comp.xml";
053:            private static final String WELL_KNOWN_DIR = "/WEB-INF/cars";
054:            private static final String CAR_DIR_PROP_NAME = "org.jasig.portal.car.CarResources.directory";
055:
056:            public static final String CAR_WORKER_ID = "carRsrc";
057:            public static final String CAR_RESOURCE_PARM = CAR_WORKER_ID;
058:            private static final Map.Entry[] ENTRY_ARRAY = new Map.Entry[] {};
059:            private static final String[] STRING_ARRAY = new String[] {};
060:
061:            // instance variables
062:
063:            private Hashtable resourceJars = new Hashtable();
064:            private Hashtable carsByJars = new Hashtable();
065:            private Hashtable carContents = new Hashtable();
066:            private Hashtable carsByPath = new Hashtable();
067:
068:            private SAX2BufferImpl services = new SAX2BufferImpl();
069:            private Properties workers = new Properties();
070:            private boolean carsLoaded = false;
071:
072:            private Vector jarsWithDescriptors = new Vector();
073:
074:            private String carDirPath = null;
075:            private boolean carDirExists = false;
076:
077:            /**
078:               A fileFilter for obtaining a list of CARs.
079:             */
080:            private FileFilter carFilter = new FileFilter() {
081:                public boolean accept(File path) {
082:                    return path.getName().endsWith(".car");
083:                }
084:            };
085:
086:            /**
087:               A fileFilter for obtaining a list of directories.
088:             */
089:            private FileFilter dirFilter = new FileFilter() {
090:                public boolean accept(File file) {
091:                    return file.isDirectory();
092:                }
093:            };
094:
095:            static {
096:                instance = new CarResources();
097:                loader = new CarClassLoader(CarResources.class.getClassLoader());
098:                instance.processDescriptors();
099:            }
100:
101:            /**
102:               Instantiate a CarResources object and load information about all CARs
103:               and their contained resources.
104:             */
105:            private CarResources() {
106:                try {
107:                    loadCars();
108:                } catch (Exception e) {
109:                    log.error("An Exception occurred while loading "
110:                            + "channel archives. Any channels "
111:                            + "deployed via CARs will not be " + "available.",
112:                            e);
113:                }
114:            }
115:
116:            /**
117:             * Process the descriptors of the channel archives if any.
118:             */
119:            private void processDescriptors() {
120:                if (carsLoaded == true) {
121:                    for (Enumeration jars = jarsWithDescriptors.elements(); jars
122:                            .hasMoreElements();) {
123:                        JarFile jarFile = null;
124:                        try {
125:                            jarFile = (JarFile) jars.nextElement();
126:                            DescriptorHandler handler = new DescriptorHandler(
127:                                    jarFile);
128:                            handler.getWorkers(workers);
129:                            handler.getServices(services);
130:                        } catch (Exception e) {
131:                            log.error(
132:                                    "An Exception occurred while processing deployment "
133:                                            + "descriptor "
134:                                            + DEPLOYMENT_DESCRIPTOR + " in "
135:                                            + jarFile.getName() + ". ", e);
136:                        }
137:                    }
138:                }
139:            }
140:
141:            /**
142:               Return the single instance of CarResources.
143:             */
144:            public static CarResources getInstance() {
145:                return instance;
146:            }
147:
148:            /**
149:               Return the single instance of CarClassLoader.
150:             */
151:            public ClassLoader getClassLoader() {
152:                return loader;
153:            }
154:
155:            /**
156:               Return a File object representing the well-known channel archive base
157:               directory '/WEB-INF/cars' where channel archives are located.
158:             */
159:            private File getWellKnownDir() {
160:                Servlet servlet = PortalSessionManager.getInstance();
161:
162:                if (servlet == null)
163:                    return null;
164:
165:                ServletContext ctx = servlet.getServletConfig()
166:                        .getServletContext();
167:                String carDirRealPath = ctx.getRealPath(WELL_KNOWN_DIR);
168:
169:                if (carDirRealPath == null) {
170:                    log.error("Channel Archives will not be "
171:                            + " loaded. Unable to aquire the real "
172:                            + "path to '" + WELL_KNOWN_DIR + "'. This "
173:                            + "can occur if the portal is deployed "
174:                            + "as a WAR and directories can not be "
175:                            + "created within its directory "
176:                            + "structure. Alternatively, you can "
177:                            + "specify a fully qualified path as "
178:                            + "the value of a '" + CAR_DIR_PROP_NAME
179:                            + "' property in portal.properties.");
180:                    return null;
181:                }
182:
183:                File carDir = new File(carDirRealPath);
184:
185:                if (!carDir.exists()) {
186:                    if (log.isInfoEnabled())
187:                        log.info("Channel Archives can not be "
188:                                + " loaded. CAR directory '" + carDirRealPath
189:                                + "' does not exist.");
190:                    return null;
191:                }
192:                carDirExists = true;
193:                this .carDirPath = carDirRealPath;
194:                return carDir;
195:            }
196:
197:            /**
198:               Return a File object representing the channel archive base
199:               directory whose fully-qualified path is specified by the
200:               'org.jasig.portal.car.CarResources.directory' property in
201:               portal.properties.
202:             */
203:            private File getPropertySpecifiedDir() {
204:                String carDirPath = null;
205:                File carDir = null;
206:
207:                try {
208:                    carDirPath = PropertiesManager
209:                            .getProperty(CAR_DIR_PROP_NAME);
210:                    carDir = new File(carDirPath);
211:                } catch (RuntimeException re) {
212:                    if (log.isInfoEnabled())
213:                        log.info("CAR directory property '" + CAR_DIR_PROP_NAME
214:                                + "' not specified. Defaulting to "
215:                                + "well-known directory '" + WELL_KNOWN_DIR
216:                                + "'.");
217:                    return null;
218:                }
219:
220:                if (!carDir.exists()) {
221:                    log.error("CAR directory '" + carDirPath
222:                            + "' specified by property '" + CAR_DIR_PROP_NAME
223:                            + "' does not exist. "
224:                            + "Channel Archives can not be "
225:                            + "loaded from this directory.");
226:                    return null;
227:                }
228:                carDirExists = true;
229:                this .carDirPath = carDirPath;
230:                return carDir;
231:            }
232:
233:            /**
234:               Load information about all installed CARs and their contained resources.
235:             */
236:            private void loadCars() {
237:                File carDir = getPropertySpecifiedDir();
238:
239:                if (carDir == null)
240:                    carDir = getWellKnownDir();
241:
242:                if (carDir != null) {
243:                    scanDir(carDir);
244:                    if (log.isInfoEnabled())
245:                        log.info("Channel Archives Loaded: "
246:                                + carsByPath.size() + " from '"
247:                                + this .carDirPath + "'");
248:                }
249:                carsLoaded = true;
250:            }
251:
252:            /**
253:               Scan the passed in directory loading any cars there-in and calling
254:               this method for any nested directories.
255:             */
256:            private void scanDir(File dir) {
257:
258:                // first get all of the cars in this directory
259:                File[] cars = dir.listFiles(carFilter);
260:
261:                if (cars != null && cars.length != 0)
262:                    for (int i = 0; i < cars.length; i++)
263:                        loadCarEntries(cars[i]);
264:
265:                // now get all of the sub-directories to be scanned
266:                File[] dirs = dir.listFiles(dirFilter);
267:
268:                if (dirs != null && dirs.length != 0)
269:                    for (int i = 0; i < dirs.length; i++)
270:                        scanDir(dirs[i]);
271:            }
272:
273:            /**
274:               Load information about the passed in CAR and any contained resources.
275:             */
276:            private void loadCarEntries(File car) {
277:                JarFile jar = null;
278:
279:                try {
280:                    jar = new JarFile(car);
281:                } catch (IOException ioe) {
282:                    log.error("CAR "
283:                            + getCarPath(car)
284:                            + " could not be loaded. Details: "
285:                            + (ioe.getMessage() != null ? ioe.getMessage()
286:                                    : ioe.getClass().getName()), ioe);
287:                    return;
288:                }
289:                Vector entryList = new Vector();
290:                carsByJars.put(jar, car);
291:                carsByPath.put(getCarPath(car), car);
292:
293:                Enumeration entries = jar.entries();
294:
295:                while (entries.hasMoreElements()) {
296:                    ZipEntry entry = (ZipEntry) entries.nextElement();
297:
298:                    if (!entry.isDirectory()) {
299:                        String name = entry.getName();
300:
301:                        if (name.equals(DEPLOYMENT_DESCRIPTOR)) {
302:                            jarsWithDescriptors.add(jar);
303:                        } else
304:                            // add to map of which jar holds this resource
305:                            resourceJars.put(name, jar);
306:
307:                        // add to list of contents for this car
308:                        entryList.add(name);
309:                    }
310:                }
311:                carContents.put(car, entryList);
312:            }
313:
314:            /**
315:               Push into the passed in properties object workers defined 
316:               in any component archive's deployment descriptor.
317:             */
318:            public void getWorkers(Properties workers) {
319:                for (Iterator itr = this .workers.entrySet().iterator(); itr
320:                        .hasNext();) {
321:                    Map.Entry entry = (Entry) itr.next();
322:                    if (!workers.containsKey(entry.getKey()))
323:                        workers.put(entry.getKey(), entry.getValue());
324:                }
325:            }
326:
327:            /**
328:               Returns true if any archive included a deployment descriptor.
329:             */
330:            public boolean hasDescriptors() {
331:                return jarsWithDescriptors.size() > 0;
332:            }
333:
334:            /**
335:               Push into the passed in content handler events for any services declared
336:               in any component archive's deployment descriptor.
337:             */
338:            public void getServices(ContentHandler contentHandler)
339:                    throws SAXException {
340:                this .services.outputBuffer(contentHandler);
341:            }
342:
343:            /**
344:               Return an input stream for reading the raw bytes making up the resource
345:               contained in one of the installed CARs. Returns null if the resource
346:               is not found.
347:
348:             */
349:            public InputStream getResourceAsStream(String resource)
350:                    throws PortalException {
351:                JarFile jar = (JarFile) resourceJars.get(resource);
352:
353:                if (jar == null)
354:                    return null;
355:
356:                ZipEntry entry = jar.getEntry(resource);
357:
358:                if (entry == null)
359:                    return null;
360:
361:                try {
362:                    return jar.getInputStream(entry);
363:                } catch (IOException ioe) {
364:                    throw new PortalException("Unable to get input stream for "
365:                            + resource);
366:                }
367:            }
368:
369:            /**
370:               Return the size of the indicated resource or -1 if the resource is not
371:               found or its size is unknown.
372:             */
373:            public long getResourceSize(String resource) {
374:                JarFile jar = (JarFile) resourceJars.get(resource);
375:
376:                if (jar == null)
377:                    return -1;
378:
379:                ZipEntry entry = jar.getEntry(resource);
380:
381:                if (entry == null)
382:                    return -1;
383:                return entry.getSize();
384:            }
385:
386:            /**
387:               Returns a URL to the requested entry if found in one of the installed
388:               CARs or null if not found.
389:             */
390:            public URL findResource(String entry) {
391:                if (entry == null)
392:                    return null;
393:
394:                // resolve entries that refer to a parent directory
395:                // using a regular expression.
396:                entry = resolveRegExpr(entry);
397:
398:                JarFile jar = (JarFile) resourceJars.get(entry);
399:                if (jar == null)
400:                    return null;
401:                File carFile = (File) carsByJars.get(jar);
402:                if (carFile == null) // should never happen!
403:                    return null;
404:                String url = "jar:file:" + carFile.getAbsolutePath() + "!/"
405:                        + entry;
406:                try {
407:                    return new URL(url);
408:                } catch (java.net.MalformedURLException me) {
409:                }
410:                return null;
411:            }
412:
413:            /**
414:               Returns the path of the CAR containing the indicated resource. This
415:               path is relative to the CAR directory configured via the property in
416:               portal.properties. If a CAR for that entry is not found it
417:               returns null.
418:             */
419:            public String getContainingCarPath(String entry) {
420:                if (entry == null)
421:                    return null;
422:                JarFile jar = (JarFile) resourceJars.get(entry);
423:                if (jar == null)
424:                    return null;
425:                File carFile = (File) carsByJars.get(jar);
426:                if (carFile == null) // should never happen!
427:                    return null;
428:                return getCarPath(carFile);
429:            }
430:
431:            /**
432:               Returns true if the indicated resource is available, false otherwise.
433:               The resource is identified by its complete path within the CAR file.
434:             */
435:            public boolean containsResource(String resource) {
436:                return resourceJars.containsKey(resource);
437:            }
438:
439:            /**
440:               Returns a String array of car file paths relative to the car directory
441:               specified via the property in portal.properties.
442:             */
443:            public String[] listCars() {
444:                Map.Entry[] entries = null;
445:
446:                entries = (Map.Entry[]) carsByJars.entrySet().toArray(
447:                        ENTRY_ARRAY);
448:                String[] carNames = new String[entries.length];
449:
450:                for (int i = 0; i < entries.length; i++)
451:                    carNames[i] = getCarPath((File) entries[i].getValue());
452:                return carNames;
453:            }
454:
455:            /**
456:               Returns a list of resources available in the car identified by the
457:               passed in relative car file path name. This name is the path to the
458:               car file relative to the car directory. If no car file is found for
459:               the passed-in path then null is returned.
460:             */
461:            public String[] listCarResources(String carPath) {
462:                File car = (File) carsByPath.get(carPath);
463:                if (car == null)
464:                    return null;
465:
466:                Vector contents = (Vector) carContents.get(car);
467:
468:                if (contents == null)
469:                    return null; // should never happen
470:
471:                return (String[]) contents.toArray(STRING_ARRAY);
472:            }
473:
474:            /**
475:               Return the path of a car file relative to the car directory.
476:             */
477:            private String getCarPath(File car) {
478:                String carPath = car.getAbsolutePath();
479:                return carPath.substring(carDirPath.length() + 1);
480:            }
481:
482:            /**
483:               Returns an enumeration of String objects each containing the path of a
484:               resource available from the installed CARs.
485:             */
486:            public String[] listAllResources() {
487:                return (String[]) resourceJars.keySet().toArray(STRING_ARRAY);
488:            }
489:
490:            /**
491:             * Home-grown version of the String replace method.  This one replaces
492:             * the supplied String (generally a regular expression '../') with the
493:             * supplied replacement.  It returns the original String as is if no
494:             * matches were found or a modified version of it if matches were found.
495:             *
496:             * @param entry  the String to search for the regExpr.
497:             * @param regExpr the regular expression to find and replace
498:             * @param replacement the String to replace the regExpr with
499:             * @return A modified String of match(es) were found, otherwise the
500:             *         original String unmodified.
501:             **/
502:            private String replace(String entry, String regExpr,
503:                    String replacement) {
504:                String copy = entry;
505:                int beginIdx = 0;
506:                int endIdx = copy.indexOf(regExpr);
507:                StringBuffer buff = new StringBuffer();
508:
509:                while (endIdx != -1) {
510:                    // grab portion of the copied string up to the
511:                    // reg expr.
512:                    String newStr = copy.substring(beginIdx, endIdx);
513:
514:                    // replace original version of copy(ed) string with
515:                    // only a substring from the reg expr (+3 for reg expr
516:                    // length) to the end of the string
517:                    copy = copy.substring(endIdx + 3, copy.length());
518:
519:                    // append the string taken up to the reg expr to the
520:                    // buffer and add a replacement character to replace
521:                    // the reg expr.
522:                    buff.append(newStr).append(replacement);
523:
524:                    // see if another reg expr exists in the remaining
525:                    // copy(ed) string.
526:                    endIdx = copy.indexOf(regExpr);
527:
528:                    // if there are no more reg expr in the copy(ed) string,
529:                    // append the copy and call it good.
530:                    if (endIdx == -1)
531:                        buff.append(copy);
532:                }
533:
534:                // if there was a reg expr in the original entry, then the
535:                // buffer wouldn't be 0 length.
536:                if (buff.toString().length() > 0)
537:                    entry = buff.toString();
538:
539:                if (log.isDebugEnabled())
540:                    log.debug("CarResources replace() - returned entry is: "
541:                            + entry);
542:                return entry;
543:            }
544:
545:            /**
546:             * Resolves the String entry and removes any regular expression
547:             * patterns that would indicate a directory move (i.e. '../').
548:             * The returned String is the supplied 'entry' String minus the
549:             * '../' pattern and the directory directly preceding it if any.
550:             *
551:             * @param entry the String entry to resolve
552:             * @return the modified String minus the reg expr.
553:             **/
554:            private String resolveRegExpr(String entry) {
555:                // first it's necessary to replace any reg expr '../'
556:                // with a different character, in this case a '~'.
557:                // this allows the StringTokenizer to parse the
558:                // entry into the appropriate tokens.
559:                String replacement = "~";
560:                entry = replace(entry, "../", replacement);
561:
562:                // now the real fun starts.  If the entry had been modified,
563:                // (i.e. had a reg expr), then it will now be tokenized so
564:                // that a new String can be constructed.
565:                if (entry.indexOf(replacement) != -1) {
566:                    String delim = "/";
567:                    StringBuffer sb = new StringBuffer();
568:
569:                    if (log.isDebugEnabled())
570:                        log.debug("CarResources resolveRegExpr() - "
571:                                + " Parsing resource name: " + entry);
572:
573:                    StringTokenizer st = new StringTokenizer(entry, replacement);
574:                    int tokens = st.countTokens();
575:                    int count = 1;
576:
577:                    while (st.hasMoreTokens()) {
578:                        // parse each token separately to correctly climb back
579:                        // up a directory
580:                        String token = st.nextToken();
581:
582:                        if (log.isDebugEnabled())
583:                            log.debug("CarResources resolveRegExpr() - "
584:                                    + "Token is now: " + token);
585:
586:                        StringTokenizer st1 = new StringTokenizer(token, delim);
587:                        int childTokens = st1.countTokens();
588:                        int childCount = 1;
589:
590:                        while (st1.hasMoreTokens()) {
591:                            String childToken = st1.nextToken();
592:
593:                            if (log.isDebugEnabled())
594:                                log.debug("CarResources resolveRegExpr() - "
595:                                        + "Child token is: " + childToken);
596:
597:                            // if there are more child tokens, then add the most
598:                            // recent one to the buffer along with the delimiter
599:                            if (childCount < childTokens) {
600:                                sb.append(childToken);
601:                                sb.append(delim);
602:                            } else if (count == tokens) {
603:                                // if the original entry began with '../', like
604:                                // ( ../somedir ),
605:                                // then this would basically remove the ../ and
606:                                // return the rest of the string unchanged.
607:                                sb.append(childToken);
608:                            } else
609:                                // ignore last token
610:                                break;
611:                            childCount++;
612:                        }
613:                        count++;
614:                    }
615:                    entry = sb.toString();
616:                }
617:
618:                if (log.isDebugEnabled())
619:                    log.debug("CarResources resolveRegExpr() - "
620:                            + "resolved entry is: " + entry);
621:                return entry;
622:            }
623:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.