View Javadoc

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 }