View Javadoc

1   package org.apache.turbine.services.template.mapper;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache Turbine" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import java.util.ArrayList;
58  import java.util.Arrays;
59  import java.util.List;
60  
61  import org.apache.commons.lang.StringUtils;
62  
63  import org.apache.turbine.modules.Loader;
64  
65  import org.apache.commons.logging.Log;
66  import org.apache.commons.logging.LogFactory;
67  
68  import org.apache.turbine.services.template.TemplateService;
69  
70  /***
71   * This mapper tries to map Template names to class names. If no direct match
72   * is found, it tries matches "upwards" in the package hierarchy until either
73   * a match is found or the root is hit. Then it returns the name of the
74   * default class from the TemplateEngineService.
75   *
76   * 1. about.directions.Driving     &lt;- direct matching the template to the class name
77   * 2. about.directions.Default     &lt;- matching the package, class name is Default
78   * 3. about.Default                &lt;- stepping up in the package hierarchy, looking for Default
79   * 4. Default                      &lt;- Class called "Default" without package
80   * 5. VelocityScreen               &lt;- The class configured by the Service (VelocityService) to
81   *
82   * Please note, that no actual packages are searched. This is the scope of the
83   * TemplateEngine Loader which is passed at construction time.
84   *
85   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
86   * @version $Id: ClassMapper.java,v 1.1 2003/07/22 10:58:49 henning Exp $
87   */
88  
89  public class ClassMapper
90      extends BaseMapper
91      implements Mapper
92  {
93      /**</package-summary/html">The loader for actually trying out the package names *//package-summary.html">em>* The loader for actually trying out the package names */
94      private Loader loader = null;
95  
96      /*** Logging */
97      private static Log log = LogFactory.getLog(ClassMapper.class);
98  
99      /***
100      * Default C'tor. If you use this C'tor, you must use
101      * the bean setter to set the various properties needed for
102      * this mapper before first usage.
103      */
104     public ClassMapper()
105     {
106     }
107 
108     /***
109      * Get the Loader value.
110      * @return the Loader value.
111      */
112     public Loader getLoader()
113     {
114         return loader;
115     }
116 
117     /***
118      * Set the Loader value.
119      * @param loader The new Loader value.
120      */
121     public void setLoader(Loader loader)
122     {
123         this.loader = loader;
124         log.debug("Loader is " + this.loader);
125     }
126 
127     /***
128      * Strip off a possible extension, replace all "," with "."
129      * Look through the given package path until a match is found.
130      *
131      * @param template The template name.
132      * @return A class name for the given template.
133      */
134     public String doMapping(String template)
135     {
136         log.debug("doMapping(" + template + ")");
137 
138         // Copy our elements into an array
139         List components
140             = new ArrayList(Arrays.asList(StringUtils.split(
141                                               template,
142                                               String.valueOf(TemplateService.TEMPLATE_PARTS_SEPARATOR))));
143         int componentSize = components.size() - 1 ;
144 
145         // This method never gets an empty string passed.
146         // So this is never < 0
147         String className = (String) components.get(componentSize);
148         components.remove(componentSize--);
149 
150         log.debug("className is " + className);
151 
152         // Strip off a possible Extension
153         int dotIndex = className.lastIndexOf(TemplateService.EXTENSION_SEPARATOR);
154         className = (dotIndex < 0) ? className : className.substring(0, dotIndex);
155 
156         // This is an optimization. If the name we're looking for is
157         // already the default name for the template, don't do a "first run"
158         // which looks for an exact match.
159         boolean firstRun = !className.equals(TemplateService.DEFAULT_NAME);
160 
161         for(;;)
162         {
163             String pkg = StringUtils.join(components.iterator(), String.valueOf(separator));
164             StringBuffer testName = new StringBuffer();
165 
166             log.debug("classPackage is now: " + pkg);
167 
168             if (!components.isEmpty())
169             {
170                 testName.append(pkg);
171                 testName.append(separator);
172             }
173 
174             testName.append((firstRun)
175                 ? className
176                 : TemplateService.DEFAULT_NAME);
177 
178             log.debug("Looking for " + testName);
179             try
180             {
181                 loader.getAssembler(testName.toString());
182                 log.debug("Found it, returning " + testName);
183                 return testName.toString();
184             }
185             catch (Exception e)
186             {
187                 // Not found. Go on.
188             }
189 
190             if (firstRun)
191             {
192                 firstRun = false;
193             }
194             else
195             {
196                 if (components.isEmpty())
197                 {
198                     break; // for(;;)
199                 }
200                 components.remove(componentSize--);
201             }
202         }
203 
204         log.debug("Returning default");
205         return getDefaultName(template);
206     }
207 }
208 
209 
210 
211