1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 }