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.util;
35  
36  import java.io.File;
37  import java.io.FileInputStream;
38  import java.io.IOException;
39  import java.security.GeneralSecurityException;
40  import java.util.LinkedHashMap;
41  import java.util.Map;
42  import java.util.Properties;
43  
44  import org.apache.commons.lang3.ArrayUtils;
45  
46  import fr.paris.lutece.portal.service.security.RsaService;
47  import fr.paris.lutece.portal.service.util.AppLogService;
48  import fr.paris.lutece.portal.service.util.AppPropertiesService;
49  
50  /**
51   * This class provides utility methods to read values of the properties stored in the .properties file of the application.
52   */
53  public class PropertiesService
54  {
55      // Static variables
56      private String _strRootPath;
57      private Properties _properties = new Properties( );
58      private Map<String, String> _mapPropertiesFiles = new LinkedHashMap<>( );
59  
60      public final String RSA_KEY_PREFIX = "PROTECTED::RSA::";
61      private final String MESSAGE_CIPHERED_PROPERTY_SECURITY_EXCEPTION = "A ciphered property security exception occured." ;
62      
63      /**
64       * Constructor should define the base root path for properties files
65       * 
66       * @param strRootPath
67       *            The root path
68       */
69      public PropertiesService( String strRootPath )
70      {
71          _strRootPath = ( strRootPath.endsWith( "/" ) ) ? strRootPath : ( strRootPath + "/" );
72      }
73  
74      /**
75       * Add properties from a properties file
76       * 
77       * @param strRelativePath
78       *            Relative path from the root path
79       * @param strFilename
80       *            The filename of the properties file (ie: config.properties)
81       */
82      public void addPropertiesFile( String strRelativePath, String strFilename )
83      {
84          String strFullPath = _strRootPath + ( ( strRelativePath.endsWith( "/" ) ) ? strRelativePath : ( strRelativePath + "/" ) ) + strFilename;
85          _mapPropertiesFiles.put( strFilename, strFullPath );
86          loadFile( strFullPath );
87      }
88  
89      /**
90       * Add properties from all files found in a given directory
91       * 
92       * @param strRelativePath
93       *            Relative path from the root path
94       */
95      public void addPropertiesDirectory( String strRelativePath )
96      {
97          File directory = new File( _strRootPath + strRelativePath );
98  
99          if ( directory.exists( ) )
100         {
101             File [ ] listFile = directory.listFiles( );
102 
103             if ( ArrayUtils.isNotEmpty( listFile ) )
104             {
105                 for ( File file : listFile )
106                 {
107                     if ( file.getName( ).endsWith( ".properties" ) )
108                     {
109                         String strFullPath = file.getAbsolutePath( );
110                         _mapPropertiesFiles.put( file.getName( ), strFullPath );
111                         loadFile( strFullPath );
112                     }
113                 }
114             }
115         }
116     }
117 
118     /**
119      * Load properties of a file
120      * 
121      * @param strFullPath
122      *            The absolute path of the properties file
123      */
124     private void loadFile( String strFullPath )
125     {
126         loadFile( strFullPath, _properties );
127     }
128 
129     /**
130      * Load properties of a file
131      * 
132      * @param strFullPath
133      *            The absolute path of the properties file
134      * @param props
135      *            properties to load into
136      * @throws java.io.IOException
137      *             If an error occurs reading the file
138      */
139     private void loadFile( String strFullPath, Properties props )
140     {
141         try ( FileInputStream fis = new FileInputStream( new File( strFullPath ) ) )
142         {
143             props.load( fis );
144         }
145         catch( IOException ex )
146         {
147             AppLogService.error( "Error loading property file : {}", ex.getMessage( ), ex );
148         }
149     }
150 
151     /**
152      * Reload a properties file .
153      * 
154      * @param strFilename
155      *            The filename of the properties file
156      */
157     public void reload( String strFilename )
158     {
159         String strFullPath = _mapPropertiesFiles.get( strFilename );
160         loadFile( strFullPath );
161     }
162 
163     /**
164      * Reload all properties files
165      * 
166      */
167     public void reloadAll( )
168     {
169         Properties newProperties = new Properties( );
170 
171         for ( String strFullPath : _mapPropertiesFiles.values( ) )
172         {
173             loadFile( strFullPath, newProperties );
174         }
175 
176         _properties = newProperties;
177     }
178 
179     /**
180      * Returns the value of a variable defined in the .properties file of the application as a String
181      *
182      * @param strProperty
183      *            The variable name
184      * @return The variable value read in the properties file
185      */
186     public String getProperty( String strProperty )
187     {
188     	String strValue = _properties.getProperty( strProperty ) ;
189     	
190     	if ( strValue != null && strValue.startsWith( RSA_KEY_PREFIX ) )
191 		{
192 			try 
193 			{
194 				return RsaService.decryptRsa( strValue.substring( RSA_KEY_PREFIX.length( ) ) );
195 			} 
196 			catch ( GeneralSecurityException e ) 
197 			{
198 				AppLogService.error( MESSAGE_CIPHERED_PROPERTY_SECURITY_EXCEPTION, e );
199 			}
200 		}
201 
202    		return strValue;
203     }
204 
205     /**
206      * Returns the value of a variable defined in the .properties file of the application as a String
207      *
208      * @param strProperty
209      *            The variable name
210      * @param strDefault
211      *            The default value which is returned if no value is found for the variable in the .properties file.
212      * @return The variable value read in the properties file
213      */
214     public String getProperty( String strProperty, String strDefault )
215     {
216         return _properties.getProperty( strProperty, strDefault );
217     }
218 
219     /**
220      * Returns the value of a variable defined in the .properties file of the application as an int
221      *
222      * @param strProperty
223      *            The variable name
224      * @param nDefault
225      *            The default value which is returned if no value is found for the variable in the .properties file, or if the value is not numeric
226      * @return The variable value read in the properties file
227      */
228     public int getPropertyInt( String strProperty, int nDefault )
229     {
230         String strValue = AppPropertiesService.getProperty( strProperty );
231         int nValue = nDefault;
232 
233         try
234         {
235             if ( strValue != null )
236             {
237                 nValue = Integer.parseInt( strValue );
238             }
239         }
240         catch( NumberFormatException e )
241         {
242             AppLogService.info( e.getMessage( ), e );
243         }
244 
245         return nValue;
246     }
247 
248     /**
249      * Returns the value of a variable defined in the .properties file of the application as an long
250      *
251      * @param strProperty
252      *            The variable name
253      * @param lDefault
254      *            The default value which is returned if no value is found for the variable in the le downloadFile .properties. .properties file.
255      * @return The variable value read in the properties file
256      */
257     public long getPropertyLong( String strProperty, long lDefault )
258     {
259         String strValue = AppPropertiesService.getProperty( strProperty );
260         long lValue = lDefault;
261 
262         try
263         {
264             if ( strValue != null )
265             {
266                 lValue = Long.parseLong( strValue );
267             }
268         }
269         catch( NumberFormatException e )
270         {
271             AppLogService.info( e.getMessage( ), e );
272         }
273 
274         return lValue;
275     }
276 
277     /**
278      * Returns the value of a variable defined in the .properties file of the application as an boolean
279      *
280      * @param strProperty
281      *            The variable name
282      * @param bDefault
283      *            The default value which is returned if no value is found for the variable in the le downloadFile .properties. .properties file.
284      * @return The variable value read in the properties file
285      */
286     public boolean getPropertyBoolean( String strProperty, boolean bDefault )
287     {
288         String strValue = AppPropertiesService.getProperty( strProperty );
289         boolean bValue = bDefault;
290 
291         if ( strValue != null )
292         {
293             bValue = strValue.equalsIgnoreCase( "true" );
294         }
295 
296         return bValue;
297     }
298 
299     /**
300      * Gets properties
301      * 
302      * @return All properties
303      */
304     public Properties getProperties( )
305     {
306         return _properties;
307     }
308 }