1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.chain.web;
18
19
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.List;
23 import javax.servlet.ServletContext;
24 import org.apache.commons.chain.Catalog;
25 import org.apache.commons.chain.config.ConfigParser;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29
30 /**
31 * <p>Utility methods for loading class loader and web application resources
32 * to configure a {@link Catalog}. These methods are shared between
33 * <code>ChainListener</code> and <code>ChainServlet</code>.</p>
34 *
35 * @author Craig R. McClanahan
36 * @author Ted Husted
37 */
38
39 final class ChainResources {
40
41
42 // ---------------------------------------------------------- Static Methods
43
44
45 /**
46 * <p>Parse the specified class loader resources.</p>
47 *
48 * @param resources Comma-delimited list of resources (or <code>null</code>)
49 * @param parser {@link ConfigParser} to use for parsing
50 */
51 static void parseClassResources(String resources,
52 ConfigParser parser) {
53
54 if (resources == null) {
55 return;
56 }
57 Log log = LogFactory.getLog(ChainResources.class);
58 ClassLoader loader =
59 Thread.currentThread().getContextClassLoader();
60 if (loader == null) {
61 loader = ChainResources.class.getClassLoader();
62 }
63 String[] paths = getResourcePaths(resources);
64 String path = null;
65 try {
66 for (int i = 0; i < paths.length; i++) {
67 path = paths[i];
68 URL url = loader.getResource(path);
69 if (url == null) {
70 throw new IllegalStateException
71 ("Missing chain config resource '" + path + "'");
72 }
73 if (log.isDebugEnabled()) {
74 log.debug("Loading chain config resource '" + path + "'");
75 }
76 parser.parse(url);
77 }
78 } catch (Exception e) {
79 throw new RuntimeException
80 ("Exception parsing chain config resource '" + path + "': "
81 + e.getMessage());
82 }
83
84 }
85
86
87 /**
88 * <p>Parse the specified class loader resources.</p>
89 *
90 * @param catalog {@link Catalog} we are populating
91 * @param resources Comma-delimited list of resources (or <code>null</code>)
92 * @param parser {@link ConfigParser} to use for parsing
93 *
94 * @deprecated Use the variant that does not take a catalog, on a
95 * configuration resource containing "catalog" element(s)
96 */
97 static void parseClassResources(Catalog catalog, String resources,
98 ConfigParser parser) {
99
100 if (resources == null) {
101 return;
102 }
103 Log log = LogFactory.getLog(ChainResources.class);
104 ClassLoader loader =
105 Thread.currentThread().getContextClassLoader();
106 if (loader == null) {
107 loader = ChainResources.class.getClassLoader();
108 }
109 String[] paths = getResourcePaths(resources);
110 String path = null;
111 try {
112 for (int i = 0; i < paths.length; i++) {
113 path = paths[i];
114 URL url = loader.getResource(path);
115 if (url == null) {
116 throw new IllegalStateException
117 ("Missing chain config resource '" + path + "'");
118 }
119 if (log.isDebugEnabled()) {
120 log.debug("Loading chain config resource '" + path + "'");
121 }
122 parser.parse(catalog, url);
123 }
124 } catch (Exception e) {
125 throw new RuntimeException
126 ("Exception parsing chain config resource '" + path + "': "
127 + e.getMessage());
128 }
129
130 }
131
132
133 /**
134 * <p>Parse the specified web application resources.</p>
135 *
136 * @param context <code>ServletContext</code> for this web application
137 * @param resources Comma-delimited list of resources (or <code>null</code>)
138 * @param parser {@link ConfigParser} to use for parsing
139 */
140 static void parseWebResources(ServletContext context,
141 String resources,
142 ConfigParser parser) {
143
144 if (resources == null) {
145 return;
146 }
147 Log log = LogFactory.getLog(ChainResources.class);
148 String[] paths = getResourcePaths(resources);
149 String path = null;
150 try {
151 for (int i = 0; i < paths.length; i++) {
152 path = paths[i];
153 URL url = context.getResource(path);
154 if (url == null) {
155 throw new IllegalStateException
156 ("Missing chain config resource '" + path + "'");
157 }
158 if (log.isDebugEnabled()) {
159 log.debug("Loading chain config resource '" + path + "'");
160 }
161 parser.parse(url);
162 }
163 } catch (Exception e) {
164 throw new RuntimeException
165 ("Exception parsing chain config resource '" + path + "': "
166 + e.getMessage());
167 }
168
169 }
170
171
172 /**
173 * <p>Parse the specified web application resources.</p>
174 *
175 * @param catalog {@link Catalog} we are populating
176 * @param context <code>ServletContext</code> for this web application
177 * @param resources Comma-delimited list of resources (or <code>null</code>)
178 * @param parser {@link ConfigParser} to use for parsing
179 *
180 * @deprecated Use the variant that does not take a catalog, on a
181 * configuration resource containing "catalog" element(s)
182 */
183 static void parseWebResources(Catalog catalog, ServletContext context,
184 String resources,
185 ConfigParser parser) {
186
187 if (resources == null) {
188 return;
189 }
190 Log log = LogFactory.getLog(ChainResources.class);
191 String[] paths = getResourcePaths(resources);
192 String path = null;
193 try {
194 for (int i = 0; i < paths.length; i++) {
195 path = paths[i];
196 URL url = context.getResource(path);
197 if (url == null) {
198 throw new IllegalStateException
199 ("Missing chain config resource '" + path + "'");
200 }
201 if (log.isDebugEnabled()) {
202 log.debug("Loading chain config resource '" + path + "'");
203 }
204 parser.parse(catalog, url);
205 }
206 } catch (Exception e) {
207 throw new RuntimeException
208 ("Exception parsing chain config resource '" + path + "': "
209 + e.getMessage());
210 }
211
212 }
213
214
215 /**
216 * <p> Parse the resource string into an array of paths. Empty entries will
217 * be skipped. (That is, all entries in the array are non-empty paths.)</p>
218 *
219 * @param resources A comma-delimited list of resource paths (or
220 * <code>null</code>).
221 *
222 * @return An array of non-empty paths. The array itself may be empty.
223 *
224 * @since Chain 1.1
225 */
226 static String[] getResourcePaths(String resources) {
227 List paths = new ArrayList();
228
229 if (resources != null) {
230 String path;
231 int comma;
232
233 while ((comma = resources.indexOf(',')) >= 0) {
234 path = resources.substring(0, comma).trim();
235 if (path.length() > 0) {
236 paths.add(path);
237 }
238 resources = resources.substring(comma + 1);
239 }
240 resources = resources.trim();
241 if (resources.length() > 0) {
242 paths.add(resources);
243 }
244 }
245
246 return (String[]) paths.toArray(new String[0]);
247 }
248
249
250 }