View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de 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.portal;
35  
36  import fr.paris.lutece.portal.business.style.Theme;
37  import fr.paris.lutece.portal.service.content.PageData;
38  import fr.paris.lutece.portal.service.database.AppConnectionService;
39  import fr.paris.lutece.portal.service.i18n.I18nService;
40  import fr.paris.lutece.portal.service.plugin.Plugin;
41  import fr.paris.lutece.portal.service.plugin.PluginService;
42  import fr.paris.lutece.portal.service.spring.SpringContextService;
43  import fr.paris.lutece.portal.service.util.AppLogService;
44  import fr.paris.lutece.portal.service.util.AppPropertiesService;
45  import fr.paris.lutece.util.ReferenceList;
46  
47  import org.apache.commons.lang.StringUtils;
48  
49  import org.springframework.beans.factory.BeanDefinitionStoreException;
50  import org.springframework.beans.factory.CannotLoadBeanClassException;
51  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
52  
53  import java.util.ArrayList;
54  import java.util.Collection;
55  import java.util.Locale;
56  
57  import javax.servlet.http.Cookie;
58  import javax.servlet.http.HttpServletRequest;
59  import javax.servlet.http.HttpServletResponse;
60  
61  
62  /**
63   * ThemesService
64   */
65  public final class ThemesService
66  {
67      public static final String GLOBAL_THEME = "default";
68      private static final String THEME_PLUGIN_NAME = "theme";
69      private static final String BEAN_THEME_SERVICE = "theme.themeService";
70      private static final String COOKIE_NAME = "theme";
71      private static final String THEME_TEST = "theme_test";
72  
73      // PROPERTIES
74      private static final String PROPERTY_USE_GLOBAL_THEME = "portal.style.label.useGlobalTheme";
75      private static final String PROPERTY_DEFAULT_CODE_THEME = "themes.default.code";
76      private static final String PROPERTY_DEFAULT_PATH_CSS = "themes.default.css";
77      private static final String PROPERTY_DEFAULT_PATH_JS = "themes.default.js";
78      private static final String PROPERTY_DEFAULT_PATH_IMAGE = "themes.default.images";
79      private static final String PROPERTY_DEFAULT_AUTHOR_URL = "themes.default.author_url";
80      private static final String PROPERTY_DEFAULT_AUTHOR = "themes.default.author";
81      private static final String PROPERTY_DEFAULT_LICENCE = "themes.default.licence";
82      private static final String PROPERTY_DEFAULT_DESCRIPTION = "themes.default.name";
83      private static final String PROPERTY_DEFAULT_VERSION = "themes.default.version";
84  
85      // MESSAGES
86      private static final String MESSAGE_THEME_NOT_AVAILABLE = "Theme service not available.";
87  
88      /**
89       * Private constructor
90       */
91      private ThemesService(  )
92      {
93      }
94  
95      /**
96       * Get the theme code depending of the different priorities. The priorities are :
97       * <ol>
98       * <li>the theme of test (in case you want to test a page with a specific theme)</li>
99       * <li>the theme choosen by the user</li>
100      * <li>the global theme : the one choosen in the back office for the whole site</li>
101      * <li>the page theme : a theme specified for a page</li>
102      * </ol>
103      *
104      * @param data The PageData object
105      * @param request The HttpServletRequest
106      * @return the theme
107      */
108     public static Theme getTheme( PageData data, HttpServletRequest request )
109     {
110         String strTheme = StringUtils.EMPTY;
111 
112         // The code_theme of the page
113         String strPageTheme = data.getTheme(  );
114 
115         if ( ( strPageTheme != null ) && ( strPageTheme.compareToIgnoreCase( GLOBAL_THEME ) != 0 ) )
116         {
117             strTheme = strPageTheme;
118         }
119 
120         // The theme of the user
121         String strUserTheme = getUserTheme( request );
122 
123         if ( strUserTheme != null )
124         {
125             strTheme = strUserTheme;
126         }
127 
128         // the test theme (choosen for a page to test the different theme from the backoffice theme section)
129         String themeTest = request.getParameter( THEME_TEST );
130 
131         if ( themeTest != null )
132         {
133             strTheme = themeTest;
134         }
135 
136         Theme theme = getGlobalTheme( strTheme );
137 
138         return theme;
139     }
140 
141     /**
142      * Gets the theme selected by the user
143      *
144      * @param request The HTTP request
145      * @return The theme if available otherwise null
146      */
147     public static String getUserTheme( HttpServletRequest request )
148     {
149         try
150         {
151             IThemeService themeService = getThemeService(  );
152 
153             return themeService.getUserTheme( request );
154         }
155         catch ( ThemeNotAvailableException e )
156         {
157             return null;
158         }
159     }
160 
161     /**
162      * Sets the users theme using a cookie
163      * @param request The HTTP request
164      * @param response The HTTP response
165      * @param strTheme The Theme code
166      */
167     public static void setUserTheme( HttpServletRequest request, HttpServletResponse response, String strTheme )
168     {
169         Cookie cookie = new Cookie( COOKIE_NAME, strTheme );
170         response.addCookie( cookie );
171     }
172 
173     /**
174      * Returns the global theme
175      *
176      * @return the global theme
177      */
178     public static String getGlobalTheme(  )
179     {
180         Theme theme = getGlobalTheme( StringUtils.EMPTY );
181 
182         return theme.getCodeTheme(  );
183     }
184 
185     /**
186      * Returns the global theme Object
187      *
188      * @return the global theme Object
189      */
190     public static Theme getGlobalThemeObject(  )
191     {
192         return getGlobalTheme( StringUtils.EMPTY );
193     }
194 
195     /**
196      * Returns the global theme
197      * @param strTheme The theme
198      * @return the global theme
199      */
200     public static Theme getGlobalTheme( String strTheme )
201     {
202         Theme theme = null;
203 
204         try
205         {
206             IThemeService themeService = getThemeService(  );
207 
208             if ( StringUtils.isBlank( strTheme ) )
209             {
210                 theme = themeService.getGlobalTheme(  );
211             }
212             else
213             {
214                 theme = themeService.getTheme( strTheme );
215             }
216         }
217         catch ( ThemeNotAvailableException e )
218         {
219             theme = getDefaultTheme(  );
220         }
221 
222         return theme;
223     }
224 
225     /**
226      * Sets the global theme
227      *
228      * @param strGlobalTheme The global theme
229      */
230     public static void setGlobalTheme( String strGlobalTheme )
231     {
232         IThemeService themeService;
233 
234         try
235         {
236             themeService = getThemeService(  );
237             themeService.setGlobalTheme( strGlobalTheme );
238         }
239         catch ( ThemeNotAvailableException e )
240         {
241             AppLogService.info( MESSAGE_THEME_NOT_AVAILABLE );
242         }
243     }
244 
245     /**
246      * Returns a reference list which contains all the themes
247      * @param locale The Locale
248      * @return a reference list
249      */
250     public static ReferenceList getPageThemes( Locale locale )
251     {
252         ReferenceList listThemes = new ReferenceList(  );
253 
254         try
255         {
256             IThemeService themeService = getThemeService(  );
257             listThemes = themeService.getThemes(  );
258         }
259         catch ( ThemeNotAvailableException e )
260         {
261             AppLogService.info( MESSAGE_THEME_NOT_AVAILABLE );
262         }
263 
264         String strGlobalTheme = I18nService.getLocalizedString( PROPERTY_USE_GLOBAL_THEME, locale );
265         listThemes.addItem( GLOBAL_THEME, strGlobalTheme );
266 
267         return listThemes;
268     }
269 
270     /**
271      * Get the theme service
272      * @return the theme service
273      * @throws ThemeNotAvailableException If the theme is not available
274      */
275     private static IThemeService getThemeService(  ) throws ThemeNotAvailableException
276     {
277         IThemeService themeService = null;
278 
279         if ( !isAvailable(  ) )
280         {
281             throw new ThemeNotAvailableException(  );
282         }
283 
284         try
285         {
286             themeService = SpringContextService.getBean( BEAN_THEME_SERVICE );
287         }
288         catch ( BeanDefinitionStoreException e )
289         {
290             throw new ThemeNotAvailableException(  );
291         }
292         catch ( NoSuchBeanDefinitionException e )
293         {
294             throw new ThemeNotAvailableException(  );
295         }
296         catch ( CannotLoadBeanClassException e )
297         {
298             throw new ThemeNotAvailableException(  );
299         }
300 
301         return themeService;
302     }
303 
304     /**
305      * Return the default theme in properties
306      * @return the default theme
307      */
308     private static Theme getDefaultTheme(  )
309     {
310         Theme theme = new Theme(  );
311         String strCodeTheme = AppPropertiesService.getProperty( PROPERTY_DEFAULT_CODE_THEME );
312         String strPathCss = AppPropertiesService.getProperty( PROPERTY_DEFAULT_PATH_CSS );
313         String strPathImages = AppPropertiesService.getProperty( PROPERTY_DEFAULT_PATH_IMAGE );
314         String strPathJs = AppPropertiesService.getProperty( PROPERTY_DEFAULT_PATH_JS );
315         String strThemeAuthor = AppPropertiesService.getProperty( PROPERTY_DEFAULT_AUTHOR );
316         String strThemeAuthorUrl = AppPropertiesService.getProperty( PROPERTY_DEFAULT_AUTHOR_URL );
317         String strThemeDescription = AppPropertiesService.getProperty( PROPERTY_DEFAULT_DESCRIPTION );
318         String strThemeLicence = AppPropertiesService.getProperty( PROPERTY_DEFAULT_LICENCE );
319         String strThemeVersion = AppPropertiesService.getProperty( PROPERTY_DEFAULT_VERSION );
320 
321         theme.setCodeTheme( strCodeTheme );
322         theme.setPathCss( strPathCss );
323         theme.setPathImages( strPathImages );
324         theme.setPathJs( strPathJs );
325         theme.setThemeAuthor( strThemeAuthor );
326         theme.setThemeAuthorUrl( strThemeAuthorUrl );
327         theme.setThemeDescription( strThemeDescription );
328         theme.setThemeLicence( strThemeLicence );
329         theme.setThemeVersion( strThemeVersion );
330 
331         return theme;
332     }
333 
334     /**
335      * Check if the theme service is available. It must have the following requirement to be
336      * available :
337      * <ul>
338      * <li>The <code>plugin-theme</code> is activated</li>
339      * <li>The pool of the <code>plugin-theme</code> is defined</li>
340      * </ul>
341      * @return true if it is available, false otherwise
342      */
343     public static boolean isAvailable(  )
344     {
345         Plugin pluginTheme = PluginService.getPlugin( THEME_PLUGIN_NAME );
346 
347         return PluginService.isPluginEnable( THEME_PLUGIN_NAME ) && ( pluginTheme.getDbPoolName(  ) != null ) &&
348         !AppConnectionService.NO_POOL_DEFINED.equals( pluginTheme.getDbPoolName(  ) );
349     }
350 
351     /**
352      * Create a new theme
353      * @param theme the theme
354      * @return The theme
355      */
356     public static Theme create( Theme theme )
357     {
358         try
359         {
360             IThemeService themeService = getThemeService(  );
361 
362             return themeService.create( theme );
363         }
364         catch ( ThemeNotAvailableException e )
365         {
366             AppLogService.info( MESSAGE_THEME_NOT_AVAILABLE );
367 
368             return null;
369         }
370     }
371 
372     /**
373      * Update a theme
374      * @param theme the theme to update
375      * @return The updated theme
376      */
377     public static Theme update( Theme theme )
378     {
379         try
380         {
381             IThemeService themeService = getThemeService(  );
382 
383             return themeService.update( theme );
384         }
385         catch ( ThemeNotAvailableException e )
386         {
387             AppLogService.info( MESSAGE_THEME_NOT_AVAILABLE );
388 
389             return null;
390         }
391     }
392 
393     /**
394      * Remove a theme
395      * @param strCodeTheme the code theme
396      */
397     public static void remove( String strCodeTheme )
398     {
399         try
400         {
401             IThemeService themeService = getThemeService(  );
402             themeService.remove( strCodeTheme );
403         }
404         catch ( ThemeNotAvailableException e )
405         {
406             AppLogService.info( MESSAGE_THEME_NOT_AVAILABLE );
407         }
408     }
409 
410     /**
411      * Get a collection of themes
412      * @return a collection of themes
413      */
414     public static Collection<Theme> getThemesList(  )
415     {
416         Collection<Theme> listThemes = new ArrayList<Theme>(  );
417 
418         try
419         {
420             IThemeService themeService = getThemeService(  );
421             listThemes = themeService.getThemesList(  );
422         }
423         catch ( ThemeNotAvailableException e )
424         {
425             Theme theme = getDefaultTheme(  );
426             listThemes.add( theme );
427         }
428 
429         return listThemes;
430     }
431 
432     /**
433      * Get the list of themes as a {@link ReferenceList}
434      * @return a {@link ReferenceList}
435      */
436     public static ReferenceList getThemes(  )
437     {
438         ReferenceList listThemes = new ReferenceList(  );
439 
440         try
441         {
442             IThemeService themeService = getThemeService(  );
443             listThemes = themeService.getThemes(  );
444         }
445         catch ( ThemeNotAvailableException e )
446         {
447             Theme theme = getDefaultTheme(  );
448             listThemes.addItem( theme.getCodeTheme(  ), theme.getThemeDescription(  ) );
449         }
450 
451         return listThemes;
452     }
453 
454     /**
455      * Check if the theme is valid
456      * @param strCodeTheme the code theme
457      * @return true if it is valid, false otherwise
458      */
459     public static boolean isValidTheme( String strCodeTheme )
460     {
461         boolean bIsValidTheme = false;
462 
463         try
464         {
465             IThemeService themeService = getThemeService(  );
466             bIsValidTheme = themeService.isValidTheme( strCodeTheme );
467         }
468         catch ( ThemeNotAvailableException e )
469         {
470             Theme theme = getDefaultTheme(  );
471             bIsValidTheme = theme.getCodeTheme(  ).equals( strCodeTheme );
472         }
473 
474         return bIsValidTheme;
475     }
476 }