View Javadoc

1   package org.apache.turbine.services.template.mapper;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.List;
25  
26  import org.apache.commons.lang.StringUtils;
27  
28  import org.apache.turbine.modules.Loader;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  
33  import org.apache.turbine.services.template.TemplateService;
34  
35  /***
36   * This mapper tries to map Template names to class names. If no direct match
37   * is found, it tries matches "upwards" in the package hierarchy until either
38   * a match is found or the root is hit. Then it returns the name of the
39   * default class from the TemplateEngineService.
40   *
41   * 1. about.directions.Driving     <- direct matching the template to the class name
42   * 2. about.directions.Default     <- matching the package, class name is Default
43   * 3. about.Default                <- stepping up in the package hierarchy, looking for Default
44   * 4. Default                      <- Class called "Default" without package
45   * 5. VelocityScreen               <- The class configured by the Service (VelocityService) to
46   *
47   * Please note, that no actual packages are searched. This is the scope of the
48   * TemplateEngine Loader which is passed at construction time.
49   *
50   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
51   * @version $Id: ClassMapper.java 534527 2007-05-02 16:10:59Z tv $
52   */
53  
54  public class ClassMapper
55      extends BaseMapper
56      implements Mapper
57  {
58      /**</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 */
59      private Loader loader = null;
60  
61      /*** Logging */
62      private static Log log = LogFactory.getLog(ClassMapper.class);
63  
64      /***
65       * Default C'tor. If you use this C'tor, you must use
66       * the bean setter to set the various properties needed for
67       * this mapper before first usage.
68       */
69      public ClassMapper()
70      {
71      }
72  
73      /***
74       * Get the Loader value.
75       * @return the Loader value.
76       */
77      public Loader getLoader()
78      {
79          return loader;
80      }
81  
82      /***
83       * Set the Loader value.
84       * @param loader The new Loader value.
85       */
86      public void setLoader(Loader loader)
87      {
88          this.loader = loader;
89          log.debug("Loader is " + this.loader);
90      }
91  
92      /***
93       * Strip off a possible extension, replace all "," with "."
94       * Look through the given package path until a match is found.
95       *
96       * @param template The template name.
97       * @return A class name for the given template.
98       */
99      public String doMapping(String template)
100     {
101         log.debug("doMapping(" + template + ")");
102 
103         // Copy our elements into an array
104         List components
105             = new ArrayList(Arrays.asList(StringUtils.split(
106                                               template,
107                                               String.valueOf(TemplateService.TEMPLATE_PARTS_SEPARATOR))));
108         int componentSize = components.size() - 1 ;
109 
110         // This method never gets an empty string passed.
111         // So this is never < 0
112         String className = (String) components.get(componentSize);
113         components.remove(componentSize--);
114 
115         log.debug("className is " + className);
116 
117         // Strip off a possible Extension
118         int dotIndex = className.lastIndexOf(TemplateService.EXTENSION_SEPARATOR);
119         className = (dotIndex < 0) ? className : className.substring(0, dotIndex);
120 
121         // This is an optimization. If the name we're looking for is
122         // already the default name for the template, don't do a "first run"
123         // which looks for an exact match.
124         boolean firstRun = !className.equals(TemplateService.DEFAULT_NAME);
125 
126         for(;;)
127         {
128             String pkg = StringUtils.join(components.iterator(), String.valueOf(separator));
129             StringBuffer testName = new StringBuffer();
130 
131             log.debug("classPackage is now: " + pkg);
132 
133             if (!components.isEmpty())
134             {
135                 testName.append(pkg);
136                 testName.append(separator);
137             }
138 
139             testName.append((firstRun)
140                 ? className
141                 : TemplateService.DEFAULT_NAME);
142 
143             log.debug("Looking for " + testName);
144             try
145             {
146                 loader.getAssembler(testName.toString());
147                 log.debug("Found it, returning " + testName);
148                 return testName.toString();
149             }
150             catch (Exception e)
151             {
152                 // Not found. Go on.
153             }
154 
155             if (firstRun)
156             {
157                 firstRun = false;
158             }
159             else
160             {
161                 if (components.isEmpty())
162                 {
163                     break; // for(;;)
164                 }
165                 components.remove(componentSize--);
166             }
167         }
168 
169         log.debug("Returning default");
170         return getDefaultName(template);
171     }
172 }
173 
174 
175 
176