001    package org.apache.turbine.util;
002    
003    
004    /*
005     * Licensed to the Apache Software Foundation (ASF) under one
006     * or more contributor license agreements.  See the NOTICE file
007     * distributed with this work for additional information
008     * regarding copyright ownership.  The ASF licenses this file
009     * to you under the Apache License, Version 2.0 (the
010     * "License"); you may not use this file except in compliance
011     * with the License.  You may obtain a copy of the License at
012     *
013     *   http://www.apache.org/licenses/LICENSE-2.0
014     *
015     * Unless required by applicable law or agreed to in writing,
016     * software distributed under the License is distributed on an
017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018     * KIND, either express or implied.  See the License for the
019     * specific language governing permissions and limitations
020     * under the License.
021     */
022    
023    
024    import java.io.BufferedInputStream;
025    import java.io.File;
026    import java.io.FileInputStream;
027    import java.io.FileNotFoundException;
028    import java.io.InputStream;
029    import java.net.MalformedURLException;
030    import java.net.URL;
031    import java.util.Enumeration;
032    import java.util.HashMap;
033    import java.util.Map;
034    import java.util.Set;
035    import java.util.Vector;
036    
037    import javax.servlet.RequestDispatcher;
038    import javax.servlet.Servlet;
039    import javax.servlet.ServletConfig;
040    import javax.servlet.ServletContext;
041    
042    import org.apache.avalon.framework.activity.Disposable;
043    import org.apache.avalon.framework.activity.Initializable;
044    import org.apache.commons.logging.Log;
045    import org.apache.commons.logging.LogFactory;
046    import org.apache.turbine.Turbine;
047    
048    /**
049     * A class used for initialization of Turbine without a servlet container.
050     * <p>
051     * If you need to use Turbine outside of a servlet container, you can
052     * use this class for initialization of the Turbine servlet.
053     * <p>
054     * <blockquote><code><pre>
055     * TurbineConfig config = new TurbineConfig(".", "conf/TurbineResources.properties");
056     * </pre></code></blockquote>
057     * <p>
058     * All paths referenced in TurbineResources.properties and the path to
059     * the properties file itself (the second argument) will be resolved
060     * relative to the directory given as the first argument of the constructor,
061     * here - the directory where application was started. Don't worry about
062     * discarding the references to objects created above. They are not needed,
063     * once everything is initialized.
064     * <p>
065     * In order to initialize the Services Framework outside of the Turbine Servlet,
066     * you need to call the <code>init()</code> method. By default, this will
067     * initialize the Resource and Logging Services and any other services you
068     * have defined in your TurbineResources.properties file.
069     *
070     * @todo Make this class enforce the lifecycle contracts
071     *
072     * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
073     * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
074     * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
075     * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
076     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
077     * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
078     * @version $Id: TurbineConfig.java 1073174 2011-02-21 22:18:45Z tv $
079     */
080    public class TurbineConfig
081            implements ServletConfig, ServletContext, Initializable, Disposable
082    {
083        /**
084         * Servlet initialization parameter name for the path to
085         * TurbineConfiguration.xml file used by Turbine
086         */
087        public static final String CONFIGURATION_PATH_KEY = "configuration";
088    
089        /**
090         * Servlet initialization parameter name for the path to
091         * Turbine.properties file used by Turbine
092         */
093        public static final String PROPERTIES_PATH_KEY = "properties";
094    
095        /**
096         * Default value of TurbineResources.properties file path
097         * (<code>/WEB-INF/conf/TurbineResources.properties</code>).
098         */
099        public static final String PROPERTIES_PATH_DEFAULT =
100                "/WEB-INF/conf/TurbineResources.properties";
101    
102        /** Filenames are looked up in this directory. */
103        protected File root;
104    
105        /** Servlet container (or emulator) attributes. */
106        protected Map<String, Object> attributes;
107    
108        /** Turbine servlet initialization parameters. */
109        protected Map<String, String> initParams;
110    
111        /** The Turbine servlet instance used for initialization. */
112        private Turbine turbine;
113    
114        /** Logging */
115        private final Log log = LogFactory.getLog(this.getClass());
116    
117        /**
118         * Constructs a new TurbineConfig.
119         *
120         * This is the general form of the constructor. You can provide
121         * a path to search for files, and a name-value map of init
122         * parameters.
123         *
124         * <p> For the list of recognized init parameters, see
125         * {@link org.apache.turbine.Turbine} class.
126         *
127         * @param path The web application root (i.e. the path for file lookup).
128         * @param attributes Servlet container (or emulator) attributes.
129         * @param initParams initialization parameters.
130         */
131        public TurbineConfig(String path, Map<String, Object> attributes,
132                Map<String, String> initParams)
133        {
134            root = new File(path);
135            this.attributes = attributes;
136            this.initParams = initParams;
137        }
138    
139        /**
140         * @see #TurbineConfig(String path, Map attributes, Map initParams)
141         */
142        public TurbineConfig(String path, Map<String, String> initParams)
143        {
144            this(path, new HashMap<String, Object>(0), initParams);
145        }
146    
147        /**
148         * Constructs a TurbineConfig.
149         *
150         * This is a specialized constructor that allows to configure
151         * Turbine easily in the common setups.
152         *
153         * @param path The web application root (i.e. the path for file lookup).
154         * @param properties the relative path to TurbineResources.properties file
155         */
156        public TurbineConfig(String path, String properties)
157        {
158            this(path, new HashMap<String, String>(1));
159            initParams.put(PROPERTIES_PATH_KEY, properties);
160        }
161    
162        /**
163         * Causes this class to initialize itself which in turn initializes
164         * all of the Turbine Services that need to be initialized.
165         */
166        public void initialize()
167        {
168            try
169            {
170                turbine = new Turbine();
171                turbine.init(this);
172            }
173            catch (Exception e)
174            {
175                log.error("TurbineConfig: Initialization failed", e);
176            }
177        }
178    
179        /**
180         * Initialization requiring a HTTP <code>GET</code> request.
181         */
182        public void init(RunData data)
183        {
184            if (turbine != null)
185            {
186                turbine.init(data);
187            }
188        }
189    
190        /**
191         * Shutdown the Turbine System, lifecycle style
192         *
193         */
194        public void dispose()
195        {
196            if (turbine != null)
197            {
198                turbine.destroy();
199            }
200        }
201    
202        /**
203         * Returns a reference to the Turbine servlet that was initialized.
204         *
205         * @return a ServletContext reference
206         */
207        public Turbine getTurbine()
208        {
209            return turbine;
210        }
211    
212        /**
213         * Returns a reference to the object cast onto ServletContext type.
214         *
215         * @return a ServletContext reference
216         */
217        public ServletContext getServletContext()
218        {
219            return this;
220        }
221    
222        /**
223         * Translates a path relative to the web application root into an
224         * absolute path.
225         *
226         * @param path A path relative to the web application root.
227         * @return An absolute version of the supplied path, or <code>null</code>
228         * if the translated path doesn't map to a file or directory.
229         */
230        public String getRealPath(String path)
231        {
232            String result = null;
233            File f = new File(root, path);
234    
235            if (log.isDebugEnabled())
236            {
237                StringBuffer sb = new StringBuffer();
238    
239                sb.append("TurbineConfig.getRealPath: path '");
240                sb.append(path);
241                sb.append("' translated to '");
242                sb.append(f.getPath());
243                sb.append("' ");
244                sb.append(f.exists() ? "" : "not ");
245                sb.append("found");
246                log.debug(sb.toString());
247            }
248    
249            if (f.exists())
250            {
251              result = f.getPath();
252            }
253            else
254            {
255                log.error("getRealPath(\"" + path + "\") is undefined, returning null");
256            }
257    
258            return result;
259        }
260    
261        /**
262         * Retrieves an initialization parameter.
263         *
264         * @param name the name of the parameter.
265         * @return the value of the parameter.
266         */
267        public String getInitParameter(String name)
268        {
269            return initParams.get(name);
270        }
271    
272        /**
273         * Retrieves an Enumeration of initialization parameter names.
274         *
275         * @return an Enumeration of initialization parameter names.
276         */
277        public Enumeration getInitParameterNames()
278        {
279            return new Vector<String>(initParams.keySet()).elements();
280        }
281    
282        /**
283         * Returns the servlet name.
284         *
285         * Fixed value "Turbine" is returned.
286         *
287         * @return the servlet name.
288         */
289        public String getServletName()
290        {
291            return "Turbine";
292        }
293    
294        /**
295         * Returns the context name.
296         *
297         * Fixed value "Turbine" is returned
298         *
299         * @return the context name
300         */
301        public String getServletContextName()
302        {
303            return "Turbine";
304        }
305    
306        /**
307         * Returns the context path.
308         *
309         * Fixed value "/turbine" is returned
310         *
311         * @return the context path
312         */
313        public String getContextPath()
314        {
315            return "/turbine";
316            }
317    
318            /**
319         * Returns a URL to the resource that is mapped to a specified
320         * path. The path must begin with a "/" and is interpreted
321         * as relative to the current context root.
322         *
323         * @param s the path to the resource
324         * @return a URL pointing to the resource
325         * @exception MalformedURLException
326         */
327        public URL getResource(String s)
328                throws MalformedURLException
329        {
330            return new URL("file://" + getRealPath(s));
331        }
332    
333        /**
334         * Returns the resource located at the named path as
335         * an <code>InputStream</code> object.
336         *
337         * @param s the path to the resource
338         * @return an InputStream object from which the resource can be read
339         */
340        public InputStream getResourceAsStream(String s)
341        {
342            try
343            {
344                FileInputStream fis = new FileInputStream(getRealPath(s));
345                return new BufferedInputStream(fis);
346            }
347            catch (FileNotFoundException e)
348            {
349                return null;
350            }
351        }
352    
353        /**
354         * Logs an error message.
355         *
356         * @param e an Exception.
357         * @param m a message.
358         * @deprecated use log(String,Throwable) instead
359         */
360        @Deprecated
361        public void log(Exception e, String m)
362        {
363            log.info(m, e);
364        }
365    
366        /**
367         * Logs a message.
368         *
369         * @param m a message.
370         */
371        public void log(String m)
372        {
373            log.info(m);
374        }
375    
376        /**
377         * Logs an error message.
378         *
379         * @param t a Throwable object.
380         * @param m a message.
381         */
382        public void log(String m, Throwable t)
383        {
384            log.info(m, t);
385        }
386    
387        /**
388         * Returns the servlet container attribute with the given name, or
389         * null if there is no attribute by that name.
390         */
391        public Object getAttribute(String s)
392        {
393            return attributes.get(s);
394        }
395    
396        /**
397         * Returns an Enumeration containing the attribute names available
398         * within this servlet context.
399         */
400        public Enumeration getAttributeNames()
401        {
402            return new Vector<String>(attributes.keySet()).elements();
403        }
404    
405        // Unimplemented methods follow
406    
407        /**
408         * Not implemented.
409         *
410         * A method in ServletConfig or ServletContext interface that is not
411         * implemented and will throw <code>UnsuportedOperationException</code>
412         * upon invocation
413         */
414        public ServletContext getContext(String s)
415        {
416            throw new UnsupportedOperationException();
417        }
418    
419        /**
420         * Not implemented.
421         *
422         * A method in ServletConfig or ServletContext interface that is not
423         * implemented and will throw <code>UnsuportedOperationException</code>
424         * upon invocation
425         */
426        public int getMajorVersion()
427        {
428            throw new UnsupportedOperationException();
429        }
430    
431        /**
432         * Not implemented.
433         *
434         * A method in ServletConfig or ServletContext interface that is not
435         * implemented and will throw <code>UnsuportedOperationException</code>
436         * upon invocation
437         */
438        public String getMimeType(String s)
439        {
440            throw new UnsupportedOperationException();
441        }
442    
443        /**
444         * Not implemented.
445         *
446         * A method in ServletConfig or ServletContext interface that is not
447         * implemented and will throw <code>UnsuportedOperationException</code>
448         * upon invocation
449         */
450        public int getMinorVersion()
451        {
452            throw new UnsupportedOperationException();
453        }
454    
455        /**
456         * Not implemented.
457         *
458         * A method in ServletConfig or ServletContext interface that is not
459         * implemented and will throw <code>UnsuportedOperationException</code>
460         * upon invocation
461         */
462        public RequestDispatcher getNamedDispatcher(String s)
463        {
464            throw new UnsupportedOperationException();
465        }
466    
467        /**
468         * Not implemented.
469         *
470         * A method in ServletConfig or ServletContext interface that is not
471         * implemented and will throw <code>UnsuportedOperationException</code>
472         * upon invocation
473         */
474        public RequestDispatcher getRequestDispatcher(String s)
475        {
476            throw new UnsupportedOperationException();
477        }
478    
479        /**
480         * Not implemented.
481         *
482         * A method in ServletContext (2.3) interface that is not implemented and
483         * will throw <code>UnsuportedOperationException</code> upon invocation
484         */
485        public Set getResourcePaths(String s)
486        {
487            throw new UnsupportedOperationException();
488        }
489    
490        /**
491         * Not implemented.
492         *
493         * A method in ServletContext (2.3) interface that is not implemented and
494         * will throw <code>UnsuportedOperationException</code> upon invocation
495         */
496        public String getServerInfo()
497        {
498            throw new UnsupportedOperationException();
499        }
500    
501        /**
502         * Not implemented.
503         *
504         * A method in ServletContext interface that is not implemented and will
505         * throw <code>UnsuportedOperationException</code> upon invocation
506         * @deprecated As of Java Servlet API 2.1, with no direct replacement.
507         */
508        @Deprecated
509        public Servlet getServlet(String s)
510        {
511            throw new UnsupportedOperationException();
512        }
513    
514        /**
515         * Not implemented.
516         *
517         * A method in ServletContext interface that is not implemented and will
518         * throw <code>UnsuportedOperationException</code> upon invocation
519         * @deprecated As of Java Servlet API 2.1, with no replacement.
520         */
521        @Deprecated
522        public Enumeration getServletNames()
523        {
524            throw new UnsupportedOperationException();
525        }
526    
527        /**
528         * Not implemented.
529         *
530         * A method in ServletContext interface that is not implemented and will
531         * throw <code>UnsuportedOperationException</code> upon invocation
532         * @deprecated As of Java Servlet API 2.0, with no replacement.
533         */
534        @Deprecated
535        public Enumeration getServlets()
536        {
537            throw new UnsupportedOperationException();
538        }
539    
540        /**
541         * Not implemented.
542         *
543         * A method in ServletContext interface that is not implemented and will
544         * throw <code>UnsuportedOperationException</code> upon invocation
545         */
546        public void removeAttribute(String s)
547        {
548            throw new UnsupportedOperationException();
549        }
550    
551        /**
552         * Not implemented.
553         *
554         * A method in ServletContext interface that is not implemented and will
555         * throw <code>UnsuportedOperationException</code> upon invocation
556         */
557        public void setAttribute(String s, Object o)
558        {
559            throw new UnsupportedOperationException();
560        }
561    }