View Javadoc
1   /*
2    * Copyright (c) 2002-2025, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.service.template;
35  
36  import fr.paris.lutece.portal.service.datastore.DatastoreService;
37  import fr.paris.lutece.portal.service.i18n.I18nService;
38  import fr.paris.lutece.portal.service.i18n.I18nTemplateMethod;
39  import fr.paris.lutece.portal.service.plugin.Plugin;
40  import fr.paris.lutece.portal.service.plugin.PluginService;
41  import fr.paris.lutece.portal.service.util.AppLogService;
42  import fr.paris.lutece.util.html.HtmlTemplate;
43  
44  import java.util.Locale;
45  import java.util.Map;
46  
47  /**
48   * This Service is used to retreive HTML templates, stored as files in the WEB-INF/templates directory of the webapp, to build the user interface. It provides a
49   * cache feature to prevent from loading file each time it is asked.
50   */
51  public final class AppTemplateService
52  {
53      // Variables
54      private static String _strTemplateDefaultPath;
55      private static IFreeMarkerTemplateService _freeMarkerTemplateService;
56  
57      /**
58       * Protected constructor
59       */
60      private AppTemplateService( )
61      {
62      }
63  
64      /**
65       * Initializes the service with the templates's path
66       * 
67       * @param strTemplatePath
68       *            The template path
69       */
70      public static void init( String strTemplatePath )
71      {
72          _strTemplateDefaultPath = strTemplatePath;
73          getFreeMarkerTemplateService( ).setSharedVariable( "i18n", new I18nTemplateMethod( ) );
74      }
75  
76      /**
77       * Initializes auto-includes and auto-imports for plugins.
78       */
79      public static void initMacros( )
80      {
81          // register core (commons declared in core.xml)
82          Plugin corePlugin = PluginService.getCore( );
83          addPluginAutoIncludes( corePlugin );
84          addPluginAutoImports( corePlugin );
85  
86          // register plugins
87          for ( Plugin plugin : PluginService.getPluginList( ) )
88          {
89              addPluginAutoIncludes( plugin );
90              addPluginAutoImports( plugin );
91          }
92  
93          // activate current commons stored in the datastore
94          CommonsService.activateCommons( CommonsService.getCurrentCommonsKey( ) );
95      }
96  
97      /**
98       * Adds the plugin auto-includes.
99       *
100      * @param plugin
101      *            the plugin
102      */
103     private static void addPluginAutoIncludes( Plugin plugin )
104     {
105         for ( String strFileName : plugin.getFreeMarkerAutoIncludes( ) )
106         {
107             AppLogService.info( "New freemarker autoinclude : {} from {}", strFileName, plugin.getName( ) );
108             getFreeMarkerTemplateService( ).addPluginAutoInclude( strFileName );
109         }
110     }
111 
112     /**
113      * Adds the plugin auto-imports.
114      *
115      * @param plugin
116      *            the plugin
117      */
118     private static void addPluginAutoImports( Plugin plugin )
119     {
120         for ( Map.Entry<String, String> importEntry : plugin.getFreeMarkerAutoImports( ).entrySet( ) )
121         {
122             AppLogService.info( "New freemarker autoimport : {} as {} from {}", importEntry.getValue( ), importEntry.getKey( ), plugin.getName( ) );
123             getFreeMarkerTemplateService( ).addPluginAutoImport( importEntry.getKey( ), importEntry.getValue( ) );
124         }
125     }
126 
127     /**
128      * Reset the cache
129      */
130     public static void resetCache( )
131     {
132         getFreeMarkerTemplateService( ).resetCache( );
133     }
134 
135     /**
136      * Resets the configuration cache
137      */
138     public static void resetConfiguration( )
139     {
140         getFreeMarkerTemplateService( ).resetConfiguration( );
141     }
142 
143     /**
144      * Returns a reference on a template object (load the template or get it from the cache if present.)
145      *
146      * @param strTemplate
147      *            The name of the template
148      * @return The template object.
149      */
150     public static HtmlTemplate getTemplate( String strTemplate )
151     {
152         return getTemplate( strTemplate, _strTemplateDefaultPath );
153     }
154 
155     /**
156      * Returns a reference on a template object (load the template or get it from the cache if present.)
157      *
158      * @param strTemplate
159      *            The name of the template
160      * @param strPath
161      *            The specific path to load the template
162      * @return The template object.
163      * @since 1.3.1
164      */
165     public static HtmlTemplate getTemplate( String strTemplate, String strPath )
166     {
167         return getTemplate( strTemplate, strPath, null, null );
168     }
169 
170     // //////////////////////////////////////////////////////////////////////////
171     // v1.5
172 
173     /**
174      * Returns a reference on a template object (load the template or get it from the cache if present.)
175      *
176      * @param strTemplate
177      *            The name of the template
178      * @param locale
179      *            The current locale to localize the template
180      * @return The template object.
181      * @since 1.5
182      */
183     public static HtmlTemplate getTemplate( String strTemplate, Locale locale )
184     {
185         return getTemplate( strTemplate, _strTemplateDefaultPath, locale, null );
186     }
187 
188     /**
189      * Returns a reference on a template object (load the template or get it from the cache if present.)
190      * 
191      * @param strTemplate
192      *            The name of the template
193      * @param locale
194      *            The current locale to localize the template
195      * @param model
196      *            the model to use for loading
197      * @return The template object.
198      * @since 1.5
199      */
200     public static HtmlTemplate getTemplate( String strTemplate, Locale locale, Object model )
201     {
202         HtmlTemplate template;
203 
204         // Load the template from the file
205         template = getTemplate( strTemplate, _strTemplateDefaultPath, locale, model );
206 
207         return template;
208     }
209 
210     /**
211      * Returns a reference on a template object (load the template or get it from the cache if present.)
212      *
213      * @param strTemplate
214      *            The name of the template
215      * @param strPath
216      *            The specific path to load the template
217      * @param locale
218      *            The current locale to localize the template
219      * @param model
220      *            the model to use for loading
221      * @return The template object.
222      * @since 1.5
223      */
224     public static HtmlTemplate getTemplate( String strTemplate, String strPath, Locale locale, Object model )
225     {
226         HtmlTemplate template;
227 
228         // Load the template from the file
229         template = loadTemplate( strPath, strTemplate, locale, model );
230 
231         return template;
232     }
233 
234     /**
235      * Returns a reference on a template object  using the template data passed in parameter or getting from cache if present
236      *
237      *
238      * @param strFreemarkerTemplateData
239      *            The content of the template
240      * @param locale
241      *            The current {@link Locale} to localize the template
242      * @param model
243      *            The model
244      * @return The template object
245      * @since 1.5
246      */
247     public static HtmlTemplate getTemplateFromStringFtl( String strFreemarkerTemplateData, Locale locale, Object model )
248     {
249         HtmlTemplate template = getFreeMarkerTemplateService( ).loadTemplateFromStringFtl( strFreemarkerTemplateData, locale, model );
250 
251         if ( locale != null )
252         {
253             String strLocalized = I18nService.localize( template.getHtml( ), locale );
254             template = new HtmlTemplate( strLocalized );
255         }
256         return template;
257     }
258     
259     
260     /**
261      * Returns a reference on a template object using the template data passed in parameter or getting from cache if present
262      *
263      * @param strFreemarkerTemplateName The name of the template ( Must be a Fully qualified name for example skin.plugins.myplugin.manage_my_objects )
264      * @param strFreemarkerTemplateData
265      *            The content of the template
266      * @param locale
267      *            The current {@link Locale} to localize the template
268      * @param model
269      *            The model
270      * @param bResetCache true if the template stored in cache must be updated by the content of the strFreemarkerTemplateDa            
271      * @return The template object
272      * @since 7.0.5
273      */
274     public static HtmlTemplate getTemplateFromStringFtl( String strFreemarkerTemplateName,String strFreemarkerTemplateData, Locale locale, Object model,boolean bResetCache )
275     {
276         HtmlTemplate template = getFreeMarkerTemplateService( ).loadTemplateFromStringFtl( strFreemarkerTemplateName,strFreemarkerTemplateData, locale, model,bResetCache );
277 
278         if ( locale != null )
279         {
280             String strLocalized = I18nService.localize( template.getHtml( ), locale );
281             template = new HtmlTemplate( strLocalized );
282         }
283         return template;
284     }
285 
286     /**
287      * Load the template from the file
288      * 
289      * @param strTemplate
290      *            The name of the template
291      * @param strPath
292      *            The specific path to load the template
293      * @param locale
294      *            The current locale to localize the template
295      * @param model
296      *            the model to use for loading
297      * @return The loaded template
298      */
299     private static HtmlTemplate loadTemplate( String strPath, String strTemplate, Locale locale, Object model )
300     {
301         HtmlTemplate template;
302         template = getFreeMarkerTemplateService( ).loadTemplate( strPath, strTemplate, locale, model );
303 
304         if ( locale != null )
305         {
306             String strLocalized = I18nService.localize( template.getHtml( ), locale );
307             template = new HtmlTemplate( strLocalized );
308         }
309 
310         template = new HtmlTemplate( DatastoreService.replaceKeys( template.getHtml( ) ) );
311 
312         return template;
313     }
314 
315     /**
316      * Get the instance of free marker template service
317      * 
318      * @return the instance of free marker template service
319      */
320     private static IFreeMarkerTemplateService getFreeMarkerTemplateService( )
321     {
322         if ( _freeMarkerTemplateService == null )
323         {
324             _freeMarkerTemplateService = FreeMarkerTemplateService.getInstance( );
325             _freeMarkerTemplateService.init( _strTemplateDefaultPath );
326         }
327 
328         return _freeMarkerTemplateService;
329     }
330 }