View Javadoc

1   /*
2    * $Id: EnhancedTilesApplicationContext.java 527536 2007-04-11 15:44:51Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.tiles.context.enhanced;
22  
23  import java.io.IOException;
24  import java.net.URL;
25  import java.util.Enumeration;
26  import java.util.HashSet;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.tiles.TilesApplicationContext;
33  
34  /***
35   * ApplicationContext decorator used to provide
36   * enhancements to the standard context.
37   *
38   * Specifically, it provides:
39   * <ul>
40   *   <li>Ability to load resources from the classpath</li>
41   *   <li>Ability to retrieve multiple resources of the same name</li>
42   * </ul>
43   *
44   * Future features will include:
45   * <ul>
46   *   <li>Ability to utilize wildcards in resource pathcs</li>
47   * </ul>
48   *
49   * @since Tiles 2.0
50   * @version $Rev: 527536 $ $Date: 2007-04-11 17:44:51 +0200 (Wed, 11 Apr 2007) $
51   */
52  public class EnhancedTilesApplicationContext implements TilesApplicationContext {
53  
54      /***
55       * The logging object.
56       */
57      private static final Log LOG =
58          LogFactory.getLog(EnhancedTilesApplicationContext.class);
59  
60      /***
61       * The root context to be wrapped.
62       */
63      private TilesApplicationContext rootContext;
64  
65      /***
66       * Constructor.
67       *
68       * @param rootContext The root context to use.
69       */
70      public EnhancedTilesApplicationContext(TilesApplicationContext rootContext) {
71          this.rootContext = rootContext;
72      }
73  
74  
75      /***
76       * Returns the root context.
77       *
78       * @return The root context.
79       */
80      public TilesApplicationContext getRootContext() {
81          return rootContext;
82      }
83  
84      /***
85       * Sets the root context.
86       *
87       * @param rootContext The root context.
88       */
89      public void setRootContext(TilesApplicationContext rootContext) {
90          this.rootContext = rootContext;
91      }
92  
93      /*** {@inheritDoc} */
94      public Map<String, Object> getApplicationScope() {
95          return rootContext.getApplicationScope();
96      }
97  
98      /*** {@inheritDoc} */
99      public Map<String, String> getInitParams() {
100         return rootContext.getInitParams();
101     }
102 
103     /*** {@inheritDoc} */
104     public URL getResource(String path) throws IOException {
105         URL rootUrl = rootContext.getResource(path);
106         if (rootUrl == null) {
107             Set<URL> resources = getResources(path);
108             resources.remove(null);
109             if (resources.size() > 0) {
110                 rootUrl = resources.toArray(new URL[resources.size()])[0];
111             }
112         }
113         return rootUrl;
114     }
115 
116     /*** {@inheritDoc} */
117     public Set<URL> getResources(String path) throws IOException {
118         Set<URL> resources = new HashSet<URL>();
119         resources.addAll(rootContext.getResources(path));
120         resources.addAll(getClasspathResources(path));
121         return resources;
122     }
123 
124     /***
125      * Searches for resources in the classpath, given a path.
126      *
127      * @param path The path to search into.
128      * @return The set of found URLs.
129      * @throws IOException If something goes wrong during search.
130      */
131     public Set<URL> getClasspathResources(String path) throws IOException {
132         Set<URL> resources = new HashSet<URL>();
133         resources.addAll(searchResources(getClass().getClassLoader(), path));
134 
135         ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
136         if (contextLoader != null) {
137             resources.addAll(searchResources(contextLoader, path));
138         }
139 
140         if (resources.size() == 0 && path.startsWith("/")) {
141             return getClasspathResources(path.substring(1));
142         }
143 
144         return resources;
145     }
146 
147     /***
148      * Searches for resources in the classpath, given a path, using a class
149      * loader.
150      *
151      * @param loader The class loader to use.
152      * @param path The path to search into.
153      * @return The set of found URLs.
154      */
155     protected Set<URL> searchResources(ClassLoader loader, String path) {
156         Set<URL> resources = new HashSet<URL>();
157         try {
158             Enumeration<URL> e = loader.getResources(path);
159             while (e.hasMoreElements()) {
160                 resources.add(e.nextElement());
161             }
162         } catch (IOException e) {
163             LOG.warn("Unable to retrieved resources from classloader: "
164                     + loader, e);
165         }
166         return resources;
167     }
168 }