##### Coverage Report - org.webmacro.servlet.Servlet22Broker

Classes in this File | Line Coverage | Branch Coverage | Complexity
Servlet22Broker |
70% | 66/94
38% | 21/54
| 4.3;4.3

1 |  |
     /*
2 |  |
      * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
3 |  |
      *
4 |  |
      * Redistribution and use in source and binary forms, with or without
5 |  |
      * modification, are permitted under the terms of either of the following
6 |  |
      * Open Source licenses:
7 |  |
      *
8 |  |
      * The GNU General Public License, version 2, or any later version, as
9 |  |
      * published by the Free Software Foundation
10 |  |
      * (http://www.fsf.org/copyleft/gpl.html);
11 |  |
      *
12 |  |
      *  or
13 |  |
      *
14 |  |
      * The Semiotek Public License (http://webmacro.org/LICENSE.)
15 |  |
      *
16 |  |
      * This software is provided "as is", with NO WARRANTY, not even the
17 |  |
      * implied warranties of fitness to purpose, or merchantability. You
18 |  |
      * assume all risks and liabilities associated with its use.
19 |  |
      *
20 |  |
      * See www.webmacro.org for more information on the WebMacro project.
21 |  |
      */
22 |  |
23 |  |
24 |  |
     package org.webmacro.servlet;
25 |  |
26 |  |
     import org.slf4j.Logger;
27 |  |
     import org.slf4j.LoggerFactory;
28 |  |
29 |  |
     import org.webmacro.Broker;
30 |  |
     import org.webmacro.InitException;
31 |  |
32 |  |
     import javax.servlet.Servlet;
33 |  |
     import javax.servlet.ServletContext;
34 |  |
     import java.io.File;
35 |  |
     import java.io.InputStream;
36 |  |
     import java.net.MalformedURLException;
37 |  |
     import java.net.URL;
38 |  |
     import java.util.Enumeration;
39 |  |
     import java.util.Properties;
40 |  |
41 |  |
     /**
42 |  |
      * An implementation of Broker tailored for Servlet 2.2
43 |  |
      * environments.  Loads templates and other resources from the servlet
44 |  |
      * context (WAR file), writes log messages to the servlet log, and loads
45 |  |
      * properties from the WAR file context parameters.
46 |  |
      *
47 |  |
      * @author Brian Goetz
48 |  |
      * @author Marc Palmer (wj5@wangjammers.org)
49 |  |
      * @since 0.96
50 |  |
      */
51 |  |
52 |  |
     public class Servlet22Broker extends ServletBroker
53 |  |
     {
54 |  |
55 | 2 |
         static Logger _log =  LoggerFactory.getLogger(Servlet22Broker.class);
56 |  |
         protected final ClassLoader _servletClassLoader;
57 |  |
         protected String _templatePrefix;
58 |  |
59 |  |
         /**
60 |  |
          * Creates the broker looking in WEB-INF first
61 |  |
          * for WebMacro.properties before looking
62 |  |
          * in the application root.
63 |  |
          */
64 |  |
         protected Servlet22Broker (ServletContext sc,
65 |  |
                                  ClassLoader cl,
66 |  |
                                  Properties additionalProperties) throws InitException
67 |  |
         {
68 | 2 |
             super(sc);
69 | 2 |
             _servletClassLoader = cl;
70 | 2 |
             String propertySource = WEBMACRO_DEFAULTS;
71 | 2 |
             loadDefaultSettings();
72 | 2 |
             boolean loaded = loadSettings("WEB-INF/" + WEBMACRO_PROPERTIES, true);
73 | 2 |
             if (loaded)
74 | 0 |
                 propertySource += ", " + "WEB-INF/" + WEBMACRO_PROPERTIES;
75 |  |
             else
76 |  |
             {
77 | 2 |
                 loadSettings(WEBMACRO_PROPERTIES, true);
78 | 2 |
                 propertySource += ", " + WEBMACRO_PROPERTIES;
79 |  |
             }
80 | 2 |
             propertySource += ", (WAR file)";
81 | 2 |
             loadServletSettings(Broker.SETTINGS_PREFIX);
82 | 2 |
             if (additionalProperties != null && additionalProperties.keySet().size() > 0)
83 |  |
             {
84 | 0 |
                 propertySource += ", (additional Properties)";
85 | 0 |
                 loadSettings(additionalProperties);
86 |  |
             }
87 | 2 |
             propertySource += ", (System Properties)";
88 | 2 |
             loadSystemSettings();
89 |  |
90 | 2 |
             _log.info("Loaded settings from " + propertySource);
91 | 2 |
             init();
92 | 2 |
         }
93 |  |
94 |  |
         protected void loadServletSettings (String prefix)
95 |  |
                 throws InitException
96 |  |
         {
97 | 2 |
             Properties p = new Properties();
98 | 2 |
             Enumeration e = _servletContext.getInitParameterNames();
99 | 2 |
             if (e != null)
100 |  |
             {
101 | 2 |
                 String dotPrefix = (prefix == null) ? "" : prefix + ".";
102 | 4 |
                 while (e.hasMoreElements())
103 |  |
                 {
104 | 2 |
                     String key = (String) e.nextElement();
105 | 2 |
                     if (prefix == null)
106 | 0 |
                         p.setProperty(key, _servletContext.getInitParameter(key));
107 | 2 |
                     else if (key.startsWith(dotPrefix))
108 | 0 |
                         p.setProperty(key, _servletContext.getInitParameter(key)
109 |  |
                                 .substring(dotPrefix.length()));
110 | 2 |
                 }
111 |  |
             }
112 | 2 |
             _config.load(p, prefix);
113 | 2 |
         }
114 |  |
115 |  |
         protected void init () throws InitException
116 |  |
         {
117 | 2 |
             super.init();
118 | 2 |
             String s = getSetting("Servlet22Broker.TemplateLocation");
119 | 2 |
             if (s == null || s.trim().equals(""))
120 | 2 |
                 _templatePrefix = null;
121 |  |
             else
122 | 0 |
                 _templatePrefix = (s.endsWith("/")) ? s : s + "/";
123 | 2 |
         }
124 |  |
125 |  |
126 |  |
         public static Broker getBroker (Servlet s, Properties additionalProperties) throws InitException
127 |  |
         {
128 | 22 |
             ServletContext sc = s.getServletConfig().getServletContext();
129 | 22 |
             ClassLoader cl = s.getClass().getClassLoader();
130 | 22 |
             return _getBroker(sc, cl, additionalProperties, true,
131 |  |
                 s.getClass().getName());
132 |  |
         }
133 |  |
134 |  |
         /**
135 |  |
          * Get a Servlet API 2.2 compatible broker for the ServletContext specified.
136 |  |
          *
137 |  |
          * @param sc The Servlet context
138 |  |
          * @param cl A ClassLoader to use, presumably the webapp classloader
139 |  |
          * @param additionalProperties
140 |  |
          * @return The broker for the servlet context.
141 |  |
          * @throws InitException
142 |  |
          * @since 2.1 JSDK
143 |  |
          */
144 |  |
         public static Broker getBroker(ServletContext sc, ClassLoader cl,
145 |  |
             Properties additionalProperties) throws InitException
146 |  |
         {
147 | 0 |
             return _getBroker(sc, cl, additionalProperties, false,
148 |  |
                 sc.toString());
149 |  |
         }
150 |  |
151 |  |
         /**
152 |  |
          * Get an existing instance of the Servlet 2.2 broker or create a new one.
153 |  |
          *
154 |  |
          * Templates will be retrieved relative to the ServletContext root
155 |  |
          * and classes loaded from the ClassLoader passed in.
156 |  |
          *
157 |  |
          * NOTE: Templates will <b>not</b> be loaded from the classpath.
158 |  |
          *
159 |  |
          * @param sc The ServletContext to template access
160 |  |
          * @param cl The ClassLoader for class loading, typically servlet or
161 |  |
          *           JSP page's class loader
162 |  |
          * @param additionalProperties
163 |  |
          * @param fromServlet true if it is actually an initialization derived from
164 |  |
          *                    a Servlet instance passed in - just for nicer logging output
165 |  |
          * @param servletOrContextName Name of the servlet or context originating this broker,
166 |  |
          *                             for nicer logging
167 |  |
          *
168 |  |
          * @throws org.webmacro.InitException
169 |  |
          * @since 2.1
170 |  |
          */
171 |  |
         private static Broker _getBroker(ServletContext sc, ClassLoader cl,
172 |  |
             Properties additionalProperties, boolean fromServlet,
173 |  |
             String servletOrContextName) throws InitException
174 |  |
         {
175 |  |
             Broker result;
176 |  |
             try
177 |  |
             {
178 | 22 |
                 Object key = sc;
179 | 22 |
                 if (additionalProperties != null && additionalProperties.keySet().size() > 0)
180 | 0 |
                     key = new PropertiesPair(sc, additionalProperties);
181 |  |
182 | 22 |
                 Broker b = findBroker(key);
183 | 22 |
                 if (b == null)
184 |  |
                 {
185 | 2 |
                     b = new Servlet22Broker(sc, cl, additionalProperties);
186 | 2 |
                     register(key, b);
187 |  |
                 }
188 |  |
                 else
189 | 20 |
                     _log.info(
190 |  |
                         (fromServlet ? "Servlet " : "ServletContext ")
191 |  |
                         + servletOrContextName
192 |  |
                         + " joining Broker" + " " + b.getName());
193 | 22 |
                 result = b;
194 |  |
             }
195 | 0 |
             catch (InitException e)
196 |  |
             {
197 | 0 |
                 _log.error("Failed to initialized WebMacro from "+
198 |  |
                         (fromServlet ? "Servlet " : "ServletContext ")
199 |  |
                         + servletOrContextName);
200 | 0 |
                 throw e;
201 | 22 |
             }
202 | 22 |
             return result;
203 |  |
         }
204 |  |
205 |  |
         /**
206 |  |
          * Get a resource (file) from the the Broker's class loader.
207 |  |
          */
208 |  |
         public URL getResource (String name)
209 |  |
         {
210 |  |
             try
211 |  |
             {
212 |  |
                 // NOTE: Tomcat4 needs a leading '/'.
213 |  |
                 // However, when loading resources from the class-loader, they
214 |  |
                 // may _not_ start with a leading '/'. So we have to build
215 |  |
                 // up two different names. Ugly!
216 | 348 |
                 String contextName = name;
217 | 348 |
                 if (name.startsWith("/"))
218 |  |
                 {
219 | 0 |
                     name = name.substring(1);
220 |  |
                 }
221 |  |
                 else
222 |  |
                 {
223 | 348 |
                     StringBuffer b = new StringBuffer(name.length() + 1);
224 | 348 |
                     b.append("/");
225 | 348 |
                     b.append(name);
226 | 348 |
                     contextName = b.toString();
227 |  |
                 }
228 | 348 |
                 URL u = _servletContext.getResource(contextName);
229 | 348 |
                 if (u != null && u.getProtocol().equals("file"))
230 |  |
                 {
231 | 0 |
                     File f = new File(u.getFile());
232 | 0 |
                     if (!f.exists())
233 | 0 |
                         u = null;
234 |  |
                 }
235 | 348 |
                 if (u == null)
236 |  |
                 {
237 | 348 |
                     u = _servletClassLoader.getResource(name);
238 |  |
                 }
239 | 348 |
                 if (u == null)
240 | 180 |
                     u = super.getResource(name);
241 | 348 |
                 return u;
242 |  |
             }
243 | 0 |
             catch (MalformedURLException e)
244 |  |
             {
245 | 0 |
                 _log.warn("MalformedURLException caught in " +
246 |  |
                         "ServletBroker.getResource for " + name);
247 | 0 |
                 return null;
248 |  |
             }
249 |  |
         }
250 |  |
251 |  |
         /**
252 |  |
          * Get a resource (file) from the Broker's class loader.
253 |  |
          */
254 |  |
         public InputStream getResourceAsStream (String name)
255 |  |
         {
256 | 0 |
             InputStream is = _servletContext.getResourceAsStream(name);
257 | 0 |
             if (is == null)
258 | 0 |
                 is = _servletClassLoader.getResourceAsStream(name);
259 | 0 |
             if (is == null)
260 | 0 |
                 is = super.getResourceAsStream(name);
261 | 0 |
             return is;
262 |  |
         }
263 |  |
264 |  |
         /**
265 |  |
          * Get a template; kind of like getting a resource, but might come
266 |  |
          * from a different place.
267 |  |
          */
268 |  |
         public URL getTemplate (String name)
269 |  |
         {
270 | 344 |
             if (_templatePrefix == null)
271 | 344 |
                 return getResource(name);
272 |  |
             else
273 |  |
             {
274 | 0 |
                 URL u = getResource(_templatePrefix + name);
275 | 0 |
                 return (u != null) ? u : getResource(name);
276 |  |
             }
277 |  |
         }
278 |  |
279 |  |
         /**
280 |  |
          * Loads a class by name. Uses the servlet classloader to load the
281 |  |
          * class. If the class is not found uses the Broker classForName
282 |  |
          * implementation.
283 |  |
          */
284 |  |
         public Class classForName (String name) throws ClassNotFoundException
285 |  |
         {
286 | 92 |
             Class cls = null;
287 |  |
             try
288 |  |
             {
289 | 92 |
                 cls = _servletClassLoader.loadClass(name);
290 |  |
             }
291 | 0 |
             catch (ClassNotFoundException e)
292 |  |
             {
293 | 92 |
             }
294 |  |
295 | 92 |
             if (cls == null)
296 | 0 |
                 cls = super.classForName(name);
297 |  |
298 | 92 |
             return cls;
299 |  |
         }
300 |  |
301 |  |
     }