View Javadoc
1   /*
2    * Copyright (c) 2002-2022, 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.resource;
35  
36  import fr.paris.lutece.portal.service.cache.AbstractCacheableService;
37  import fr.paris.lutece.portal.service.util.AppLogService;
38  import fr.paris.lutece.portal.service.util.AppPropertiesService;
39  
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.StringTokenizer;
45  
46  /**
47   * This abstract Class provides a standard way for application to deliver resources using multiple loaders and an optional cache.
48   * 
49   * @since v1.4.1
50   */
51  public abstract class ResourceService extends AbstractCacheableService
52  {
53      // Constants
54      private static final String DELIMITER = ",";
55      private static final String UNDEFINED_SERVICE_NAME = "Undefined Service Name";
56  
57      // Variables
58      private String _strName = UNDEFINED_SERVICE_NAME;
59      private List<ResourceLoader> _listLoaders = new ArrayList<>( );
60  
61      /**
62       *
63       */
64      protected ResourceService( )
65      {
66          String strLoadersProperty = getLoadersProperty( );
67  
68          if ( ( strLoadersProperty != null ) && ( !strLoadersProperty.equals( "" ) ) )
69          {
70              initLoaders( strLoadersProperty );
71          }
72          else
73          {
74              AppLogService.error( "Resource service : Loaders property key is missing" );
75          }
76      }
77  
78      // Methods to overide
79      /**
80       * Gets the name of the property that list all loaders
81       * 
82       * @return The property key
83       */
84      protected abstract String getLoadersProperty( );
85  
86      /**
87       * Initialize loaders
88       * 
89       * @param strKey
90       *            The property key that contains all loaders class
91       */
92      protected void initLoaders( String strKey )
93      {
94          String strLoaders = AppPropertiesService.getProperty( strKey );
95          StringTokenizer st = new StringTokenizer( strLoaders, DELIMITER );
96  
97          while ( st.hasMoreTokens( ) )
98          {
99              String strLoaderClassName = st.nextToken( );
100             addLoader( strLoaderClassName );
101         }
102     }
103 
104     /**
105      * Set the service name
106      * 
107      * @param strName
108      *            The service name
109      */
110     protected void setName( String strName )
111     {
112         _strName = strName;
113     }
114 
115     /**
116      * Get the service name
117      * 
118      * @return The service name
119      */
120     public String getName( )
121     {
122         return _strName;
123     }
124 
125     /**
126      * Set the service name by reading a property
127      * 
128      * @param strKey
129      *            The name key
130      */
131     protected void setNameKey( String strKey )
132     {
133         setName( AppPropertiesService.getProperty( strKey, UNDEFINED_SERVICE_NAME ) );
134     }
135 
136     /**
137      * Defines whether the cache is enable or disable reading a property
138      * 
139      * @param strKey
140      *            The key name of the cache
141      */
142     protected void setCacheKey( String strKey )
143     {
144         String strCache = AppPropertiesService.getProperty( strKey, "false" );
145 
146         if ( strCache.equals( "true" ) )
147         {
148             initCache( getName( ) );
149         }
150     }
151 
152     /**
153      * Add a new loader to the service
154      * 
155      * @param strLoaderClassName
156      *            The loader class name
157      */
158     protected void addLoader( String strLoaderClassName )
159     {
160         try
161         {
162             ResourceLoader/../../../fr/paris/lutece/portal/service/resource/ResourceLoader.html#ResourceLoader">ResourceLoader loader = (ResourceLoader) Class.forName( strLoaderClassName ).newInstance( );
163             _listLoaders.add( loader );
164         }
165         catch( IllegalAccessException | InstantiationException | ClassNotFoundException e )
166         {
167             AppLogService.error( e.getMessage( ), e );
168         }
169     }
170 
171     /**
172      * Returns a resource by its Id
173      * 
174      * @param strId
175      *            The resource Id
176      * @return A resource
177      */
178     protected Resource getResource( String strId )
179     {
180         Resource resource = null;
181 
182         if ( isCacheEnable( ) )
183         {
184             resource = (Resource) getFromCache( strId );
185 
186             if ( resource == null )
187             {
188                 resource = loadResource( strId );
189 
190                 if ( resource != null )
191                 {
192                     putInCache( strId, resource );
193                 }
194             }
195         }
196         else
197         {
198             resource = loadResource( strId );
199         }
200 
201         return resource;
202     }
203 
204     /**
205      * Load a resource by its Id
206      * 
207      * @param strId
208      *            The resource Id
209      * @return A resource
210      */
211     private Resource loadResource( String strId )
212     {
213         Resource resource = null;
214         Iterator<ResourceLoader> i = _listLoaders.iterator( );
215 
216         while ( i.hasNext( ) && ( resource == null ) )
217         {
218             ResourceLoader loader = i.next( );
219             resource = loader.getResource( strId );
220         }
221 
222         return resource;
223     }
224 
225     /**
226      * Load all resources
227      * 
228      * @return A collection of resources
229      */
230     protected Collection<Resource> getResources( )
231     {
232         List<Resource> listResources = new ArrayList<>( );
233         Iterator<ResourceLoader> i = _listLoaders.iterator( );
234 
235         while ( i.hasNext( ) )
236         {
237             ResourceLoader loader = i.next( );
238             Collection<Resource> colResources = loader.getResources( );
239             Iterator<Resource> j = colResources.iterator( );
240 
241             while ( j.hasNext( ) )
242             {
243                 Resource resource = j.next( );
244                 listResources.add( resource );
245             }
246         }
247 
248         return listResources;
249     }
250 }