Source Code Cross Referenced for ResourceManagerImpl.java in  » Template-Engine » Velocity » org » apache » velocity » runtime » resource » 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 » Template Engine » Velocity » org.apache.velocity.runtime.resource 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.runtime.resource;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.
020:         */
021:
022:        import java.io.IOException;
023:        import java.io.InputStream;
024:        import java.util.ArrayList;
025:        import java.util.Iterator;
026:        import java.util.List;
027:        import java.util.Vector;
028:
029:        import org.apache.commons.collections.ExtendedProperties;
030:        import org.apache.velocity.exception.ParseErrorException;
031:        import org.apache.velocity.exception.ResourceNotFoundException;
032:        import org.apache.velocity.runtime.RuntimeConstants;
033:        import org.apache.velocity.runtime.RuntimeServices;
034:        import org.apache.velocity.runtime.log.Log;
035:        import org.apache.velocity.runtime.resource.loader.ResourceLoader;
036:        import org.apache.velocity.runtime.resource.loader.ResourceLoaderFactory;
037:        import org.apache.velocity.util.ClassUtils;
038:        import org.apache.velocity.util.StringUtils;
039:
040:        /**
041:         * Class to manage the text resource for the Velocity Runtime.
042:         *
043:         * @author  <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
044:         * @author  <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
045:         * @author  <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
046:         * @author  <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
047:         * @author  <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
048:         * @version  $Id: ResourceManagerImpl.java 490011 2006-12-24 12:19:09Z henning $
049:         */
050:        public class ResourceManagerImpl implements  ResourceManager {
051:
052:            /** A template resources. */
053:            public static final int RESOURCE_TEMPLATE = 1;
054:
055:            /** A static content resource. */
056:            public static final int RESOURCE_CONTENT = 2;
057:
058:            /** token used to identify the loader internally. */
059:            private static final String RESOURCE_LOADER_IDENTIFIER = "_RESOURCE_LOADER_IDENTIFIER_";
060:
061:            /** Object implementing ResourceCache to be our resource manager's Resource cache. */
062:            protected ResourceCache globalCache = null;
063:
064:            /** The List of templateLoaders that the Runtime will use to locate the InputStream source of a template. */
065:            protected final List resourceLoaders = new ArrayList();
066:
067:            /**
068:             * This is a list of the template input stream source initializers, basically properties for a particular template stream
069:             * source. The order in this list reflects numbering of the properties i.e.
070:             *
071:             * <p>&lt;loader-id&gt;.resource.loader.&lt;property&gt; = &lt;value&gt;</p>
072:             */
073:            private final List sourceInitializerList = new ArrayList();
074:
075:            /**
076:             * Has this Manager been initialized?
077:             */
078:            private boolean isInit = false;
079:
080:            /** switch to turn off log notice when a resource is found for the first time. */
081:            private boolean logWhenFound = true;
082:
083:            /** The internal RuntimeServices object. */
084:            protected RuntimeServices rsvc = null;
085:
086:            /** Logging. */
087:            protected Log log = null;
088:
089:            /**
090:             * Initialize the ResourceManager.
091:             *
092:             * @param  rsvc  The Runtime Services object which is associated with this Resource Manager.
093:             *
094:             * @throws  Exception
095:             */
096:            public synchronized void initialize(final RuntimeServices rsvc)
097:                    throws Exception {
098:                if (isInit) {
099:                    log.warn("Re-initialization of ResourceLoader attempted!");
100:                    return;
101:                }
102:
103:                ResourceLoader resourceLoader = null;
104:
105:                this .rsvc = rsvc;
106:                log = rsvc.getLog();
107:
108:                log.debug("Default ResourceManager initializing. ("
109:                        + this .getClass() + ")");
110:
111:                assembleResourceLoaderInitializers();
112:
113:                for (Iterator it = sourceInitializerList.iterator(); it
114:                        .hasNext();) {
115:                    /**
116:                     * Resource loader can be loaded either via class name or be passed
117:                     * in as an instance.
118:                     */
119:                    ExtendedProperties configuration = (ExtendedProperties) it
120:                            .next();
121:
122:                    String loaderClass = StringUtils.nullTrim(configuration
123:                            .getString("class"));
124:                    ResourceLoader loaderInstance = (ResourceLoader) configuration
125:                            .get("instance");
126:
127:                    if (loaderInstance != null) {
128:                        resourceLoader = loaderInstance;
129:                    } else if (loaderClass != null) {
130:                        resourceLoader = ResourceLoaderFactory.getLoader(rsvc,
131:                                loaderClass);
132:                    } else {
133:                        log
134:                                .error("Unable to find '"
135:                                        + configuration
136:                                                .getString(RESOURCE_LOADER_IDENTIFIER)
137:                                        + ".resource.loader.class' specification in configuration."
138:                                        + " This is a critical value.  Please adjust configuration.");
139:
140:                        continue; // for(...
141:                    }
142:
143:                    resourceLoader.commonInit(rsvc, configuration);
144:                    resourceLoader.init(configuration);
145:                    resourceLoaders.add(resourceLoader);
146:                }
147:
148:                /*
149:                 * now see if this is overridden by configuration
150:                 */
151:
152:                logWhenFound = rsvc.getBoolean(
153:                        RuntimeConstants.RESOURCE_MANAGER_LOGWHENFOUND, true);
154:
155:                /*
156:                 *  now, is a global cache specified?
157:                 */
158:
159:                String cacheClassName = rsvc
160:                        .getString(RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS);
161:
162:                Object cacheObject = null;
163:
164:                if (org.apache.commons.lang.StringUtils
165:                        .isNotEmpty(cacheClassName)) {
166:
167:                    try {
168:                        cacheObject = ClassUtils.getNewInstance(cacheClassName);
169:                    } catch (ClassNotFoundException cnfe) {
170:                        log
171:                                .error("The specified class for ResourceCache ("
172:                                        + cacheClassName
173:                                        + ") does not exist or is not accessible to the current classloader.");
174:                        cacheObject = null;
175:                    }
176:
177:                    if (!(cacheObject instanceof  ResourceCache)) {
178:                        log
179:                                .error("The specified class for ResourceCache ("
180:                                        + cacheClassName
181:                                        + ") does not implement "
182:                                        + ResourceCache.class.getName()
183:                                        + " ResourceManager. Using default ResourceCache implementation.");
184:                        cacheObject = null;
185:                    }
186:                }
187:
188:                /*
189:                 *  if we didn't get through that, just use the default.
190:                 */
191:                if (cacheObject == null) {
192:                    cacheObject = new ResourceCacheImpl();
193:                }
194:
195:                globalCache = (ResourceCache) cacheObject;
196:
197:                globalCache.initialize(rsvc);
198:
199:                log.trace("Default ResourceManager initialization complete.");
200:            }
201:
202:            /**
203:             * This will produce a List of Hashtables, each hashtable contains the intialization info for a particular resource loader. This
204:             * Hashtable will be passed in when initializing the the template loader.
205:             */
206:            private void assembleResourceLoaderInitializers() {
207:                Vector resourceLoaderNames = rsvc.getConfiguration().getVector(
208:                        RuntimeConstants.RESOURCE_LOADER);
209:                StringUtils.trimStrings(resourceLoaderNames);
210:
211:                for (Iterator it = resourceLoaderNames.iterator(); it.hasNext();) {
212:
213:                    /*
214:                     * The loader id might look something like the following:
215:                     *
216:                     * file.resource.loader
217:                     *
218:                     * The loader id is the prefix used for all properties
219:                     * pertaining to a particular loader.
220:                     */
221:                    String loaderName = (String) it.next();
222:                    StringBuffer loaderID = new StringBuffer(loaderName);
223:                    loaderID.append(".").append(
224:                            RuntimeConstants.RESOURCE_LOADER);
225:
226:                    ExtendedProperties loaderConfiguration = rsvc
227:                            .getConfiguration().subset(loaderID.toString());
228:
229:                    /*
230:                     *  we can't really count on ExtendedProperties to give us an empty set
231:                     */
232:
233:                    if (loaderConfiguration == null) {
234:                        log
235:                                .warn("ResourceManager : No configuration information for resource loader named '"
236:                                        + loaderName + "'. Skipping.");
237:
238:                        continue;
239:                    }
240:
241:                    /*
242:                     *  add the loader name token to the initializer if we need it
243:                     *  for reference later. We can't count on the user to fill
244:                     *  in the 'name' field
245:                     */
246:
247:                    loaderConfiguration.setProperty(RESOURCE_LOADER_IDENTIFIER,
248:                            loaderName);
249:
250:                    /*
251:                     * Add resources to the list of resource loader
252:                     * initializers.
253:                     */
254:                    sourceInitializerList.add(loaderConfiguration);
255:                }
256:            }
257:
258:            /**
259:             * Gets the named resource. Returned class type corresponds to specified type (i.e. <code>Template</code> to <code>
260:             * RESOURCE_TEMPLATE</code>).
261:             *
262:             * @param  resourceName  The name of the resource to retrieve.
263:             * @param  resourceType  The type of resource (<code>RESOURCE_TEMPLATE</code>, <code>RESOURCE_CONTENT</code>, etc.).
264:             * @param  encoding  The character encoding to use.
265:             *
266:             * @return  Resource with the template parsed and ready.
267:             *
268:             * @throws  ResourceNotFoundException  if template not found from any available source.
269:             * @throws  ParseErrorException  if template cannot be parsed due to syntax (or other) error.
270:             * @throws  Exception  if a problem in parse
271:             */
272:            public synchronized Resource getResource(final String resourceName,
273:                    final int resourceType, final String encoding)
274:                    throws ResourceNotFoundException, ParseErrorException,
275:                    Exception {
276:                /*
277:                 * Check to see if the resource was placed in the cache.
278:                 * If it was placed in the cache then we will use
279:                 * the cached version of the resource. If not we
280:                 * will load it.
281:                 *
282:                 * Note: the type is included in the key to differentiate ContentResource
283:                 * (static content from #include) with a Template.
284:                 */
285:
286:                String resourceKey = resourceType + resourceName;
287:                Resource resource = globalCache.get(resourceKey);
288:
289:                if (resource != null) {
290:                    /*
291:                     *  refresh the resource
292:                     */
293:
294:                    try {
295:                        refreshResource(resource, encoding);
296:                    } catch (ResourceNotFoundException rnfe) {
297:                        /*
298:                         *  something exceptional happened to that resource
299:                         *  this could be on purpose,
300:                         *  so clear the cache and try again
301:                         */
302:
303:                        globalCache.remove(resourceKey);
304:
305:                        return getResource(resourceName, resourceType, encoding);
306:                    } catch (ParseErrorException pee) {
307:                        log.error("ResourceManager.getResource() exception",
308:                                pee);
309:                        throw pee;
310:                    } catch (RuntimeException re) {
311:                        throw re;
312:                    } catch (Exception e) {
313:                        log.error("ResourceManager.getResource() exception", e);
314:                        throw e;
315:                    }
316:                } else {
317:                    try {
318:                        /*
319:                         *  it's not in the cache, so load it.
320:                         */
321:
322:                        resource = loadResource(resourceName, resourceType,
323:                                encoding);
324:
325:                        if (resource.getResourceLoader().isCachingOn()) {
326:                            globalCache.put(resourceKey, resource);
327:                        }
328:                    } catch (ResourceNotFoundException rnfe) {
329:                        log.error("ResourceManager : unable to find resource '"
330:                                + resourceName + "' in any resource loader.");
331:                        throw rnfe;
332:                    } catch (ParseErrorException pee) {
333:                        log
334:                                .error(
335:                                        "ResourceManager.getResource() parse exception",
336:                                        pee);
337:                        throw pee;
338:                    } catch (RuntimeException re) {
339:                        throw re;
340:                    } catch (Exception e) {
341:                        log.error(
342:                                "ResourceManager.getResource() exception new",
343:                                e);
344:                        throw e;
345:                    }
346:                }
347:
348:                return resource;
349:            }
350:
351:            /**
352:             * Loads a resource from the current set of resource loaders.
353:             *
354:             * @param  resourceName  The name of the resource to retrieve.
355:             * @param  resourceType  The type of resource (<code>RESOURCE_TEMPLATE</code>, <code>RESOURCE_CONTENT</code>, etc.).
356:             * @param  encoding  The character encoding to use.
357:             *
358:             * @return  Resource with the template parsed and ready.
359:             *
360:             * @throws  ResourceNotFoundException  if template not found from any available source.
361:             * @throws  ParseErrorException  if template cannot be parsed due to syntax (or other) error.
362:             * @throws  Exception  if a problem in parse
363:             */
364:            protected Resource loadResource(String resourceName,
365:                    int resourceType, String encoding)
366:                    throws ResourceNotFoundException, ParseErrorException,
367:                    Exception {
368:                Resource resource = ResourceFactory.getResource(resourceName,
369:                        resourceType);
370:
371:                resource.setRuntimeServices(rsvc);
372:
373:                resource.setName(resourceName);
374:                resource.setEncoding(encoding);
375:
376:                /*
377:                 * Now we have to try to find the appropriate
378:                 * loader for this resource. We have to cycle through
379:                 * the list of available resource loaders and see
380:                 * which one gives us a stream that we can use to
381:                 * make a resource with.
382:                 */
383:
384:                long howOldItWas = 0;
385:
386:                for (Iterator it = resourceLoaders.iterator(); it.hasNext();) {
387:                    ResourceLoader resourceLoader = (ResourceLoader) it.next();
388:                    resource.setResourceLoader(resourceLoader);
389:
390:                    /*
391:                     *  catch the ResourceNotFound exception
392:                     *  as that is ok in our new multi-loader environment
393:                     */
394:
395:                    try {
396:
397:                        if (resource.process()) {
398:                            /*
399:                             *  FIXME  (gmj)
400:                             *  moved in here - technically still
401:                             *  a problem - but the resource needs to be
402:                             *  processed before the loader can figure
403:                             *  it out due to to the new
404:                             *  multi-path support - will revisit and fix
405:                             */
406:
407:                            if (logWhenFound && log.isDebugEnabled()) {
408:                                log.debug("ResourceManager : found "
409:                                        + resourceName + " with loader "
410:                                        + resourceLoader.getClassName());
411:                            }
412:
413:                            howOldItWas = resourceLoader
414:                                    .getLastModified(resource);
415:
416:                            break;
417:                        }
418:                    } catch (ResourceNotFoundException rnfe) {
419:                        /*
420:                         *  that's ok - it's possible to fail in
421:                         *  multi-loader environment
422:                         */
423:                    }
424:                }
425:
426:                /*
427:                 * Return null if we can't find a resource.
428:                 */
429:                if (resource.getData() == null) {
430:                    throw new ResourceNotFoundException(
431:                            "Unable to find resource '" + resourceName + "'");
432:                }
433:
434:                /*
435:                 *  some final cleanup
436:                 */
437:
438:                resource.setLastModified(howOldItWas);
439:                resource.setModificationCheckInterval(resource
440:                        .getResourceLoader().getModificationCheckInterval());
441:
442:                resource.touch();
443:
444:                return resource;
445:            }
446:
447:            /**
448:             * Takes an existing resource, and 'refreshes' it. This generally means that the source of the resource is checked for changes
449:             * according to some cache/check algorithm and if the resource changed, then the resource data is reloaded and re-parsed.
450:             *
451:             * @param  resource  resource to refresh
452:             * @param  encoding  character encoding of the resource to refresh.
453:             *
454:             * @throws  ResourceNotFoundException  if template not found from current source for this Resource
455:             * @throws  ParseErrorException  if template cannot be parsed due to syntax (or other) error.
456:             * @throws  Exception  if a problem in parse
457:             */
458:            protected void refreshResource(final Resource resource,
459:                    final String encoding) throws ResourceNotFoundException,
460:                    ParseErrorException, Exception {
461:
462:                /*
463:                 * The resource knows whether it needs to be checked
464:                 * or not, and the resource's loader can check to
465:                 * see if the source has been modified. If both
466:                 * these conditions are true then we must reload
467:                 * the input stream and parse it to make a new
468:                 * AST for the resource.
469:                 */
470:                if (resource.requiresChecking()) {
471:                    /*
472:                     *  touch() the resource to reset the counters
473:                     */
474:
475:                    resource.touch();
476:
477:                    if (resource.isSourceModified()) {
478:                        /*
479:                         *  now check encoding info.  It's possible that the newly declared
480:                         *  encoding is different than the encoding already in the resource
481:                         *  this strikes me as bad...
482:                         */
483:
484:                        if (!org.apache.commons.lang.StringUtils.equals(
485:                                resource.getEncoding(), encoding)) {
486:                            log.warn("Declared encoding for template '"
487:                                    + resource.getName()
488:                                    + "' is different on reload. Old = '"
489:                                    + resource.getEncoding() + "' New = '"
490:                                    + encoding);
491:
492:                            resource.setEncoding(encoding);
493:                        }
494:
495:                        /*
496:                         *  read how old the resource is _before_
497:                         *  processing (=>reading) it
498:                         */
499:                        long howOldItWas = resource.getResourceLoader()
500:                                .getLastModified(resource);
501:
502:                        /*
503:                         *  read in the fresh stream and parse
504:                         */
505:
506:                        resource.process();
507:
508:                        /*
509:                         *  now set the modification info and reset
510:                         *  the modification check counters
511:                         */
512:
513:                        resource.setLastModified(howOldItWas);
514:                    }
515:                }
516:            }
517:
518:            /**
519:             * Gets the named resource. Returned class type corresponds to specified type (i.e. <code>Template</code> to <code>
520:             * RESOURCE_TEMPLATE</code>).
521:             *
522:             * @param  resourceName  The name of the resource to retrieve.
523:             * @param  resourceType  The type of resource (<code>RESOURCE_TEMPLATE</code>, <code>RESOURCE_CONTENT</code>, etc.).
524:             *
525:             * @return  Resource with the template parsed and ready.
526:             *
527:             * @throws  ResourceNotFoundException  if template not found from any available source.
528:             * @throws  ParseErrorException  if template cannot be parsed due to syntax (or other) error.
529:             * @throws  Exception  if a problem in parse
530:             *
531:             * @deprecated  Use {@link #getResource(String resourceName, int resourceType, String encoding )}
532:             */
533:            public Resource getResource(String resourceName, int resourceType)
534:                    throws ResourceNotFoundException, ParseErrorException,
535:                    Exception {
536:                return getResource(resourceName, resourceType,
537:                        RuntimeConstants.ENCODING_DEFAULT);
538:            }
539:
540:            /**
541:             * Determines if a template exists, and returns name of the loader that provides it. This is a slightly less hokey way to
542:             * support the Velocity.templateExists() utility method, which was broken when per-template encoding was introduced. We can
543:             * revisit this.
544:             *
545:             * @param  resourceName  Name of template or content resource
546:             *
547:             * @return  class name of loader than can provide it
548:             */
549:            public String getLoaderNameForResource(String resourceName) {
550:                /*
551:                 *  loop through our loaders...
552:                 */
553:                for (Iterator it = resourceLoaders.iterator(); it.hasNext();) {
554:                    ResourceLoader resourceLoader = (ResourceLoader) it.next();
555:
556:                    InputStream is = null;
557:
558:                    /*
559:                     *  if we find one that can provide the resource,
560:                     *  return the name of the loaders's Class
561:                     */
562:                    try {
563:                        is = resourceLoader.getResourceStream(resourceName);
564:
565:                        if (is != null) {
566:                            return resourceLoader.getClass().toString();
567:                        }
568:                    } catch (ResourceNotFoundException rnfe) {
569:                        /*
570:                         * this isn't a problem.  keep going
571:                         */
572:                    } finally {
573:
574:                        /*
575:                         *  if we did find one, clean up because we were
576:                         *  returned an open stream
577:                         */
578:                        if (is != null) {
579:
580:                            try {
581:                                is.close();
582:                            } catch (IOException supressed) {
583:                            }
584:                        }
585:                    }
586:                }
587:
588:                return null;
589:            }
590:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.