View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
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  package org.springframework.extensions.webscripts;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.springframework.extensions.webscripts.processor.BaseProcessor;
27  
28  /**
29   * Registry of Template Processors
30   * 
31   * If no processors are registered, the default script processor is
32   * the freemarker processor.
33   * 
34   * @author muzquiano
35   */
36  public class TemplateProcessorRegistry
37  {
38      private static final Log logger = LogFactory.getLog(TemplateProcessorRegistry.class);
39  
40      /** The default template processor */
41      private String defaultTemplateProcessorName = "freemarker";  
42      
43      /** Maps containing the template processors */
44      private Map<String, TemplateProcessor> templateProcessors = new HashMap<String, TemplateProcessor>(8);
45      private Map<String, String> templateProcessorNamesByExtension = new HashMap<String, String>(8);
46      
47      /**
48       * Sets the name of the default template processor
49       * 
50       * @param defaultTemplateProcessor    the name of the default template processor
51       */    
52      public void setDefaultTemplateProcessor(String defaultTemplateProcessorName)
53      {
54          this.defaultTemplateProcessorName = defaultTemplateProcessorName;
55      }
56  
57      /**
58       * Registers a template processor
59       * 
60       * @param   templateProcessor     the template processor to register
61       */
62      public void registerTemplateProcessor(TemplateProcessor templateProcessor)
63      {
64          registerTemplateProcessor(templateProcessor, null, null);
65      }
66      
67      /**
68       * Registers a template processor
69       * 
70       * @param   templateProcessor     the template processor to register
71       * @param   extension
72       * @param   name
73       */
74      public void registerTemplateProcessor(TemplateProcessor templateProcessor, String extension, String name)
75      {
76          if (name == null && extension == null)
77          {
78              // try to determine name and extension from processor itself        
79              if (templateProcessor instanceof BaseProcessor)
80              {
81                  name = ((BaseProcessor)templateProcessor).getName();
82                  extension = ((BaseProcessor)templateProcessor).getExtension();
83              }
84          }
85          
86          // if we have a name and extension to use, register
87          if (name != null && extension != null)
88          {            
89              this.templateProcessors.put(name, templateProcessor);
90              this.templateProcessorNamesByExtension.put(extension, name);
91              
92              if (logger.isInfoEnabled())
93              {
94                  logger.info("Registered template processor " + name + " for extension " + extension);
95              }
96          }        
97      }
98      
99      /**
100      * Gets the default template processor.
101      * 
102      * @return the default template processor
103      */
104     protected TemplateProcessor getDefaultTemplateProcessor()
105     {
106         return (TemplateProcessor) this.templateProcessors.get(this.defaultTemplateProcessorName);
107     }
108     
109     /**
110      * Returns the best fit template processor for the given path
111      * 
112      * If a template processor cannot be matched to the path, the default
113      * template processor will be returned.
114      * 
115      * @param path the path
116      * 
117      * @return the template processor
118      */
119     public TemplateProcessor getTemplateProcessor(String path)
120     {
121         TemplateProcessor processor = null;
122         
123         int i = path.lastIndexOf(".");
124         if (i > -1)
125         {
126             String extension = path.substring(i+1);
127             String templateProcessorName = (String) templateProcessorNamesByExtension.get(extension);
128             if (templateProcessorName != null)
129             {
130                 processor = (TemplateProcessor) this.templateProcessors.get(templateProcessorName);
131             }
132         }
133         
134         if (processor == null)
135         {
136             processor = getDefaultTemplateProcessor();
137         }
138         
139         return processor;
140     }
141     
142     /**
143      * Gets the template processor registered for the given extension
144      * 
145      * @param extension the extension
146      * 
147      * @return the template processor by extension
148      */
149     public TemplateProcessor getTemplateProcessorByExtension(String extension)
150     {
151         TemplateProcessor processor = null;
152         
153         String templateProcessorName = (String) templateProcessorNamesByExtension.get(extension);
154         if (templateProcessorName != null)
155         {
156             processor = (TemplateProcessor) this.templateProcessors.get(templateProcessorName);
157         }
158         
159         return processor;
160     }
161     
162     /**
163      * Returns a variation on the provided path that exists and
164      * is processable by one of the processors in this registry.
165      * 
166      * First attempts to find a template processor that contains
167      * the content located at the given path (using extension
168      * information, if available).
169      * 
170      * If no match is found, iterates over the file extensions
171      * and attempts to find a match.
172      * 
173      * Path can therefore be values like:
174      * 
175      *   testfile.ftl
176      *     - matches to file testfile.ftl using freemarker procesor
177      *     
178      *   testfile
179      *     - matches for all extensions, potentially looking at 
180      *       testfile.ftl, testfile.php, etc.
181      *       
182      * The extension annotated path is returned which will correctly
183      * dispatch to the discovered processor.
184      * 
185      * @param path the path
186      * 
187      * @return a valid processor file path or null if no match
188      */
189     public String findValidTemplatePath(String path)
190     {
191         String validTemplatePath = null;
192         
193         // look up by file extension
194         int i = path.lastIndexOf(".");
195         if (i > -1)
196         {
197             String extension = path.substring(i+1);
198             TemplateProcessor processor = getTemplateProcessorByExtension(extension);
199             if (processor != null && processor.hasTemplate(path))
200             {
201                 validTemplatePath = path;
202             }
203         }
204         
205         if (validTemplatePath == null)
206         {
207             // look across all of the extensions
208             String[] extensions = this.getRegisteredExtensions();
209             for (String extension: extensions)
210             {
211                 TemplateProcessor processor = getTemplateProcessorByExtension(extension);
212                 if (processor.hasTemplate(path + "." + extension))
213                 {
214                     validTemplatePath = path + "." + extension;
215                 }
216             }
217         }
218         
219         return validTemplatePath;
220     }    
221 
222    /**
223      * Returns the extensions with registered processors
224      * 
225      * @return the registered extensions
226      */
227     public String[] getRegisteredExtensions()
228     {
229         return templateProcessorNamesByExtension.keySet().toArray(new String[templateProcessorNamesByExtension.keySet().size()]);
230     } 
231     
232     /**
233      * Gets the extension for given processor.
234      * 
235      * @param templateProcessor the template processor
236      * 
237      * @return the extension for processor
238      */
239     public String getExtensionForProcessor(TemplateProcessor templateProcessor)
240     {
241         String ext = null;
242         
243         String[] extensions = this.getRegisteredExtensions();
244         for (String extension: extensions)
245         {
246             TemplateProcessor processor = getTemplateProcessorByExtension(extension);
247             if (processor == templateProcessor)
248             {
249                 ext = extension;
250             }
251         }
252         
253         return ext;        
254     }
255     
256     /**
257      * Resets all of the registered template processors
258      */
259     public void reset()
260     {
261         for (TemplateProcessor p : this.templateProcessors.values())
262         {
263             p.reset();
264         }
265     }    
266 
267 }