View Javadoc

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