001package 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
024import java.io.BufferedInputStream;
025import java.io.File;
026import java.io.FileInputStream;
027import java.io.FileNotFoundException;
028import java.io.InputStream;
029import java.net.MalformedURLException;
030import java.net.URL;
031import java.util.Enumeration;
032import java.util.HashMap;
033import java.util.Map;
034import java.util.Set;
035import java.util.Vector;
036
037import javax.servlet.RequestDispatcher;
038import javax.servlet.Servlet;
039import javax.servlet.ServletConfig;
040import javax.servlet.ServletContext;
041
042import org.apache.avalon.framework.activity.Disposable;
043import org.apache.avalon.framework.activity.Initializable;
044import org.apache.commons.logging.Log;
045import org.apache.commons.logging.LogFactory;
046import 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 1709648 2015-10-20 17:08:10Z tv $
079 */
080public 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     * Constructs a new TurbineConfig.
141     *
142     * This is the general form of the constructor. You can provide
143     * a path to search for files, and a name-value map of init
144     * parameters.
145     *
146     * <p> For the list of recognized init parameters, see
147     * {@link org.apache.turbine.Turbine} class.
148     *
149     * @param path The web application root (i.e. the path for file lookup).
150     * @param initParams initialization parameters.
151     */
152    public TurbineConfig(String path, Map<String, String> initParams)
153    {
154        this(path, new HashMap<String, Object>(0), initParams);
155    }
156
157    /**
158     * Constructs a TurbineConfig.
159     *
160     * This is a specialized constructor that allows to configure
161     * Turbine easily in the common setups.
162     *
163     * @param path The web application root (i.e. the path for file lookup).
164     * @param properties the relative path to TurbineResources.properties file
165     */
166    public TurbineConfig(String path, String properties)
167    {
168        this(path, new HashMap<String, String>(1));
169        initParams.put(PROPERTIES_PATH_KEY, properties);
170    }
171
172    /**
173     * Causes this class to initialize itself which in turn initializes
174     * all of the Turbine Services that need to be initialized.
175     */
176    @Override
177    public void initialize()
178    {
179        try
180        {
181            turbine = new Turbine();
182            turbine.init(this);
183        }
184        catch (Exception e)
185        {
186            log.error("TurbineConfig: Initialization failed", e);
187        }
188    }
189
190    /**
191     * Initialization requiring a HTTP <code>GET</code> request.
192     * @param data the Turbine request
193     */
194    public void init(RunData data)
195    {
196        if (turbine != null)
197        {
198            turbine.init(data);
199        }
200    }
201
202    /**
203     * Shutdown the Turbine System, lifecycle style
204     *
205     */
206    @Override
207    public void dispose()
208    {
209        if (turbine != null)
210        {
211            turbine.destroy();
212        }
213    }
214
215    /**
216     * Returns a reference to the Turbine servlet that was initialized.
217     *
218     * @return a ServletContext reference
219     */
220    public Turbine getTurbine()
221    {
222        return turbine;
223    }
224
225    /**
226     * Returns a reference to the object cast onto ServletContext type.
227     *
228     * @return a ServletContext reference
229     */
230    @Override
231    public ServletContext getServletContext()
232    {
233        return this;
234    }
235
236    /**
237     * Translates a path relative to the web application root into an
238     * absolute path.
239     *
240     * @param path A path relative to the web application root.
241     * @return An absolute version of the supplied path, or <code>null</code>
242     * if the translated path doesn't map to a file or directory.
243     */
244    @Override
245    public String getRealPath(String path)
246    {
247        String result = null;
248        File f = new File(root, path);
249
250        if (log.isDebugEnabled())
251        {
252            StringBuilder sb = new StringBuilder();
253
254            sb.append("TurbineConfig.getRealPath: path '");
255            sb.append(path);
256            sb.append("' translated to '");
257            sb.append(f.getPath());
258            sb.append("' ");
259            sb.append(f.exists() ? "" : "not ");
260            sb.append("found");
261            log.debug(sb.toString());
262        }
263
264        if (f.exists())
265        {
266          result = f.getPath();
267        }
268        else
269        {
270            log.error("getRealPath(\"" + path + "\") is undefined, returning null");
271        }
272
273        return result;
274    }
275
276    /**
277     * Retrieves an initialization parameter.
278     *
279     * @param name the name of the parameter.
280     * @return the value of the parameter.
281     */
282    @Override
283    public String getInitParameter(String name)
284    {
285        return initParams.get(name);
286    }
287
288    /**
289     * Retrieves an Enumeration of initialization parameter names.
290     *
291     * @return an Enumeration of initialization parameter names.
292     */
293    @Override
294    public Enumeration<String> getInitParameterNames()
295    {
296        return new Vector<String>(initParams.keySet()).elements();
297    }
298
299    /**
300     * Returns the servlet name.
301     *
302     * Fixed value "Turbine" is returned.
303     *
304     * @return the servlet name.
305     */
306    @Override
307    public String getServletName()
308    {
309        return "Turbine";
310    }
311
312    /**
313     * Returns the context name.
314     *
315     * Fixed value "Turbine" is returned
316     *
317     * @return the context name
318     */
319    @Override
320    public String getServletContextName()
321    {
322        return "Turbine";
323    }
324
325    /**
326     * Returns the context path.
327     *
328     * Fixed value "/turbine" is returned
329     *
330     * @return the context path
331     */
332    @Override
333    public String getContextPath()
334    {
335        return "/turbine";
336        }
337
338        /**
339     * Returns a URL to the resource that is mapped to a specified
340     * path. The path must begin with a "/" and is interpreted
341     * as relative to the current context root.
342     *
343     * @param s the path to the resource
344     * @return a URL pointing to the resource
345     * @exception MalformedURLException
346     */
347    @Override
348    public URL getResource(String s)
349            throws MalformedURLException
350    {
351        return new URL("file://" + getRealPath(s));
352    }
353
354    /**
355     * Returns the resource located at the named path as
356     * an <code>InputStream</code> object.
357     *
358     * @param s the path to the resource
359     * @return an InputStream object from which the resource can be read
360     */
361    @Override
362    public InputStream getResourceAsStream(String s)
363    {
364        try
365        {
366            FileInputStream fis = new FileInputStream(getRealPath(s));
367            return new BufferedInputStream(fis);
368        }
369        catch (FileNotFoundException e)
370        {
371            return null;
372        }
373    }
374
375    /**
376     * Logs an error message.
377     *
378     * @param e an Exception.
379     * @param m a message.
380     * @deprecated use log(String,Throwable) instead
381     */
382    @Override
383    @Deprecated
384    public void log(Exception e, String m)
385    {
386        log.info(m, e);
387    }
388
389    /**
390     * Logs a message.
391     *
392     * @param m a message.
393     */
394    @Override
395    public void log(String m)
396    {
397        log.info(m);
398    }
399
400    /**
401     * Logs an error message.
402     *
403     * @param t a Throwable object.
404     * @param m a message.
405     */
406    @Override
407    public void log(String m, Throwable t)
408    {
409        log.info(m, t);
410    }
411
412    /**
413     * Returns the servlet container attribute with the given name, or
414     * null if there is no attribute by that name.
415     */
416    @Override
417    public Object getAttribute(String s)
418    {
419        return attributes.get(s);
420    }
421
422    /**
423     * Returns an Enumeration containing the attribute names available
424     * within this servlet context.
425     */
426    @Override
427    public Enumeration<String> getAttributeNames()
428    {
429        return new Vector<String>(attributes.keySet()).elements();
430    }
431
432    // Unimplemented methods follow
433
434    /**
435     * Not implemented.
436     *
437     * A method in ServletConfig or ServletContext interface that is not
438     * implemented and will throw <code>UnsuportedOperationException</code>
439     * upon invocation
440     */
441    @Override
442    public ServletContext getContext(String s)
443    {
444        throw new UnsupportedOperationException();
445    }
446
447    /**
448     * Not implemented.
449     *
450     * A method in ServletConfig or ServletContext interface that is not
451     * implemented and will throw <code>UnsuportedOperationException</code>
452     * upon invocation
453     */
454    @Override
455    public int getMajorVersion()
456    {
457        throw new UnsupportedOperationException();
458    }
459
460    /**
461     * Not implemented.
462     *
463     * A method in ServletConfig or ServletContext interface that is not
464     * implemented and will throw <code>UnsuportedOperationException</code>
465     * upon invocation
466     */
467    @Override
468    public String getMimeType(String s)
469    {
470        throw new UnsupportedOperationException();
471    }
472
473    /**
474     * Not implemented.
475     *
476     * A method in ServletConfig or ServletContext interface that is not
477     * implemented and will throw <code>UnsuportedOperationException</code>
478     * upon invocation
479     */
480    @Override
481    public int getMinorVersion()
482    {
483        throw new UnsupportedOperationException();
484    }
485
486    /**
487     * Not implemented.
488     *
489     * A method in ServletConfig or ServletContext interface that is not
490     * implemented and will throw <code>UnsuportedOperationException</code>
491     * upon invocation
492     */
493    @Override
494    public RequestDispatcher getNamedDispatcher(String s)
495    {
496        throw new UnsupportedOperationException();
497    }
498
499    /**
500     * Not implemented.
501     *
502     * A method in ServletConfig or ServletContext interface that is not
503     * implemented and will throw <code>UnsuportedOperationException</code>
504     * upon invocation
505     */
506    @Override
507    public RequestDispatcher getRequestDispatcher(String s)
508    {
509        throw new UnsupportedOperationException();
510    }
511
512    /**
513     * Not implemented.
514     *
515     * A method in ServletContext (2.3) interface that is not implemented and
516     * will throw <code>UnsuportedOperationException</code> upon invocation
517     */
518    @Override
519    public Set<String> getResourcePaths(String s)
520    {
521        throw new UnsupportedOperationException();
522    }
523
524    /**
525     * Not implemented.
526     *
527     * A method in ServletContext (2.3) interface that is not implemented and
528     * will throw <code>UnsuportedOperationException</code> upon invocation
529     */
530    @Override
531    public String getServerInfo()
532    {
533        throw new UnsupportedOperationException();
534    }
535
536    /**
537     * Not implemented.
538     *
539     * A method in ServletContext interface that is not implemented and will
540     * throw <code>UnsuportedOperationException</code> upon invocation
541     * @deprecated As of Java Servlet API 2.1, with no direct replacement.
542     */
543    @Override
544    @Deprecated
545    public Servlet getServlet(String s)
546    {
547        throw new UnsupportedOperationException();
548    }
549
550    /**
551     * Not implemented.
552     *
553     * A method in ServletContext interface that is not implemented and will
554     * throw <code>UnsuportedOperationException</code> upon invocation
555     * @deprecated As of Java Servlet API 2.1, with no replacement.
556     */
557    @Override
558    @Deprecated
559    public Enumeration<String> getServletNames()
560    {
561        throw new UnsupportedOperationException();
562    }
563
564    /**
565     * Not implemented.
566     *
567     * A method in ServletContext interface that is not implemented and will
568     * throw <code>UnsuportedOperationException</code> upon invocation
569     * @deprecated As of Java Servlet API 2.0, with no replacement.
570     */
571    @Override
572    @Deprecated
573    public Enumeration<Servlet> getServlets()
574    {
575        throw new UnsupportedOperationException();
576    }
577
578    /**
579     * Not implemented.
580     *
581     * A method in ServletContext interface that is not implemented and will
582     * throw <code>UnsuportedOperationException</code> upon invocation
583     */
584    @Override
585    public void removeAttribute(String s)
586    {
587        throw new UnsupportedOperationException();
588    }
589
590    /**
591     * Not implemented.
592     *
593     * A method in ServletContext interface that is not implemented and will
594     * throw <code>UnsuportedOperationException</code> upon invocation
595     */
596    @Override
597    public void setAttribute(String s, Object o)
598    {
599        throw new UnsupportedOperationException();
600    }
601}