View Javadoc
1   /*
2    * Copyright (c) 2002-2017, 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.plugins.xmlpage.service;
35  
36  import fr.paris.lutece.portal.service.resource.Resource;
37  import fr.paris.lutece.portal.service.resource.ResourceLoader;
38  import fr.paris.lutece.portal.service.util.AppException;
39  import fr.paris.lutece.portal.service.util.AppLogService;
40  import fr.paris.lutece.portal.service.util.AppPathService;
41  import fr.paris.lutece.portal.service.util.AppPropertiesService;
42  import fr.paris.lutece.util.filesystem.DirectoryNotFoundException;
43  import fr.paris.lutece.util.filesystem.FileSystemUtil;
44  
45  import java.io.File;
46  import java.io.FileInputStream;
47  import java.io.IOException;
48  
49  import java.util.ArrayList;
50  import java.util.Collection;
51  import java.util.Enumeration;
52  import java.util.HashMap;
53  import java.util.HashSet;
54  import java.util.Iterator;
55  import java.util.Map;
56  import java.util.Properties;
57  import java.util.Set;
58  import java.util.StringTokenizer;
59  
60  
61  /**
62   *
63   * This class delivers XML Page configuration from property files
64   */
65  public class XmlPageLoaderProperties implements ResourceLoader
66  {
67      private static final String PROPERTY_XMLPAGE_FILES_PATH = "xmlpage.properties.files.path";
68      private static final String PROPERTY_GROUP_PATH_SOURCES = "group.path.sources";
69      private static final String PROPERTY_GROUP_PATH_RESOURCES = "group.path.resources";
70      private static final String PROPERTY_GROUP_PATH_XML = "group.path.xml";
71      private static final String PROPERTY_GROUP_PATH_XSL = "group.path.xsl";
72      private static final String PROPERTY_GROUP_PATH_XSD = "group.path.xsd";
73      private static final String PROPERTY_GROUP_LOCK_PUBLICATION_PATH = "group.lock.publication.file";
74      private static final String PROPERTY_GROUP_LOCK_TRANSFERT_PATH = "group.lock.transfert.file";
75      private static final String PROPERTY_GROUP_EXTENSION_COPY = "group.extension.copy";
76      private static final String PROPERTY_GROUP_DISPLAY_LINK = "group.display.link";
77      private static final String PROPERTY_GROUP_MAIL_SENDER_NAME = "group.mail.sender.name";
78      private static final String PROPERTY_GROUP_MAIL_SENDER_EMAIL = "group.mail.sender.email";
79      private static final String PROPERTY_GROUP_MAIL_RECIPIENT_LIST = "group.mail.recipient.list";
80      private static final String PROPERTY_GROUP_MAIL_VALIDATION_OK_SUBJECT = "group.mail.validation.ok.subject";
81      private static final String PROPERTY_GROUP_MAIL_VALIDATION_KO_SUBJECT = "group.mail.validation.ko.subject";
82      private static final String PROPERTY_GROUP_MAIL_PUBLICATION_OK_SUBJECT = "group.mail.publication.ok.subject";
83      private static final String PROPERTY_GROUP_MAIL_PUBLICATION_KO_SUBJECT = "group.mail.publication.ko.subject";
84      private static final String PROPERTY_GROUP_RESERVED_KEY = "group";
85      private static final String PROPERTY_FILE_XML_FILE = ".xml.file";
86      private static final String PROPERTY_FILE_TITLE = ".title";
87      private static final String PROPERTY_FILE_XSL_PART = ".xsl.";
88      private static final String PROPERTY_FILE_XSL_FILE_SUFFIXE = ".file";
89      private static final String PROPERTY_FILE_IS_VALIDATION_REQUIRED = ".validation.isRequired";
90      private static final String PROPERTY_FILE_XSD_SCHEMA = ".validation.xsd.file";
91      private static final String EXTENSION_XMLPAGE_PROPERTY_FILE = ".properties";
92      private static final String BOOLEAN_TRUE_VALUE = "1";
93      private static final String PATH_SEPARATOR = "/";
94      private static final String SEPARATOR_LIST_EXTENSION = ",";
95      private static final String SEPARATOR_FILE_EXTENSION = ".";
96      private static final String SEPARATOR_PROPERTY_KEY = ".";
97  
98      /**
99       * Implementation of the ResourceLoader interface
100      * @return A collection of resources
101      */
102     public Collection getResources(  )
103     {
104         Collection listXmlPageElement = new ArrayList(  );
105         String strRootDirectory = AppPathService.getWebAppPath(  );
106 
107         // get the files in the configured reference directory for xmlpage
108         String strPath = AppPropertiesService.getProperty( PROPERTY_XMLPAGE_FILES_PATH );
109 
110         try
111         {
112             Collection<File> listFiles = FileSystemUtil.getFiles( strRootDirectory, strPath );
113 
114             for ( File file : listFiles )
115             {
116                 String strFileName = file.getName(  );
117 
118                 // for each file that is a .properties file, load the properties in the XmlpageGroup structure
119                 // and add the initialized xmlpages from that structure into the list of resources to return.
120                 if ( strFileName.endsWith( EXTENSION_XMLPAGE_PROPERTY_FILE ) )
121                 {
122                     Properties properties = loadPropertiesFromFile( file );
123                     Map xmlPagesMap = loadListXmlPage( properties );
124                     listXmlPageElement.addAll( xmlPagesMap.values(  ) );
125                 }
126             }
127         }
128         catch ( DirectoryNotFoundException e )
129         {
130             throw new AppException( e.getMessage(  ), e );
131         }
132 
133         return listXmlPageElement;
134     }
135 
136     /**
137      * Implementation of the ResourceLoader interface
138      * @param strPageId The resource Id
139      * @return The Resource
140      */
141     public Resource getResource( String strPageId )
142     {
143         Resource resource = null;
144 
145         // get the files in the configured reference directory for xmlpage
146         String strRootDirectory = AppPathService.getWebAppPath(  );
147         String strPath = AppPropertiesService.getProperty( PROPERTY_XMLPAGE_FILES_PATH );
148 
149         try
150         {
151             // loop in all propertie files and look for the given page name.
152             // if found : stop and return the corresponding XmlPage
153             for ( File file : FileSystemUtil.getFiles( strRootDirectory, strPath ) )
154             {
155                 String strFileName = file.getName(  );
156 
157                 if ( strFileName.endsWith( EXTENSION_XMLPAGE_PROPERTY_FILE ) )
158                 {
159                     Properties properties = loadPropertiesFromFile( file );
160 
161                     if ( checkExistXmlPage( properties, strPageId ) )
162                     {
163                         resource = loadXmlPage( properties, strPageId );
164 
165                         break;
166                     }
167                 }
168             }
169         }
170         catch ( DirectoryNotFoundException e )
171         {
172             throw new AppException( e.getMessage(  ), e );
173         }
174 
175         return resource;
176     }
177 
178     /**
179      * Get All XmlPageGroup from all the properties definied for this plugin
180      * This method return a collection of XmlPageGroup objects.
181      * Each XmlPageGroup provides all the group properties and a list of XmlPage object found for the group.
182      * This method - and the XmlPageGroup structure - is only used by the deamon responsible
183      * for the copy and validation of the files.
184      * @return Collection of XmlPageGroup
185      */
186     public static Collection getAllXmlPageByGroup(  )
187     {
188         Collection listXmlPageGroup = new ArrayList(  );
189 
190         // get the files in the configured reference directory for xmlpage
191         String strRootDirectory = AppPathService.getWebAppPath(  );
192         String strPath = AppPropertiesService.getProperty( PROPERTY_XMLPAGE_FILES_PATH );
193         Collection<File> listFiles;
194 
195         try
196         {
197             for ( File file : FileSystemUtil.getFiles( strRootDirectory, strPath ) )
198             {
199                 String strFileName = file.getName(  );
200 
201                 // for each file that is a .properties file, load the properties in the XmlpageGroup structure
202                 // (containing initialized xmlpages) and add the initialized structure in the list of groups to return.
203                 if ( strFileName.endsWith( EXTENSION_XMLPAGE_PROPERTY_FILE ) )
204                 {
205                     XmlPageGroup xmlPageGroup = loadXmlPageGroup( file );
206                     listXmlPageGroup.add( xmlPageGroup );
207                 }
208             }
209         }
210         catch ( DirectoryNotFoundException e )
211         {
212             throw new AppException( e.getMessage(  ), e );
213         }
214 
215         return listXmlPageGroup;
216     }
217 
218     /**
219      * Return the set of properties
220      * @param file The Property File to load
221      * @return the properties found in the given file
222      */
223     private static Properties loadPropertiesFromFile( File file )
224     {
225         AppLogService.debug( "XmlPageLoaderProperties - loadPropertiesFromFile(" + file.getName(  ) + ")" );
226 
227         Properties properties = new Properties(  );
228 
229         try
230         {
231             FileInputStream is = new FileInputStream( file );
232             properties.load( is );
233         }
234         catch ( IOException e )
235         {
236             AppLogService.error( e.getMessage(  ), e );
237         }
238 
239         return properties;
240     }
241 
242     /**
243      * Return the list of different XML File managed
244      * @param properties describing the group
245      * @return the list of all XML Files name
246      */
247     private static Set findAllXmlPageNames( Properties properties )
248     {
249         Enumeration enumPropertiesNames = properties.propertyNames(  );
250         HashSet listXmlPageName = new HashSet(  );
251 
252         while ( enumPropertiesNames.hasMoreElements(  ) )
253         {
254             String strPropertyName = (String) enumPropertiesNames.nextElement(  );
255             String strXmlPageName = strPropertyName.substring( 0, strPropertyName.indexOf( SEPARATOR_PROPERTY_KEY ) );
256             listXmlPageName.add( strXmlPageName );
257         }
258 
259         // Delete all reserved words
260         listXmlPageName.remove( PROPERTY_GROUP_RESERVED_KEY );
261 
262         return listXmlPageName;
263     }
264 
265     /**
266      * Check that the given set of properties contains information about the asked page.
267      * @param properties describing the group
268      * @param strXmlPageName the XML page name
269      * @return true if the page name exist for this set of properties, false otherwise.
270      */
271     private static boolean checkExistXmlPage( Properties properties, String strXmlPageName )
272     {
273         return findAllXmlPageNames( properties ).contains( strXmlPageName );
274     }
275 
276     /**
277      * Return the XML page corresponding to
278      * @param properties describing the group
279      * @param strXmlPageName the XML page name
280      * @return the XmlPageElement object
281      */
282     private static XmlPageElement loadXmlPage( Properties properties, String strXmlPageName )
283     {
284         // load data common to the whole group
285         String strXmlFilesDirectoryPath = AppPathService.getWebAppPath(  )
286                                                         .concat( properties.getProperty( PROPERTY_GROUP_PATH_XML ) );
287         String strXslFilesDirectoryPath = AppPathService.getWebAppPath(  )
288                                                         .concat( properties.getProperty( PROPERTY_GROUP_PATH_XSL ) );
289         String strResourceFilesDirectoryPath = properties.getProperty( PROPERTY_GROUP_PATH_RESOURCES );
290 
291         // load page data and initialize XmlPageElement
292         XmlPageElement xmlPageElement = new XmlPageElement(  );
293         xmlPageElement.setName( strXmlPageName );
294         xmlPageElement.setTitle( properties.getProperty( strXmlPageName + PROPERTY_FILE_TITLE ) );
295         xmlPageElement.setXmlFilesDirectoryPath( strXmlFilesDirectoryPath );
296         xmlPageElement.setXslFilesDirectoryPath( strXslFilesDirectoryPath );
297         xmlPageElement.setDisplayLink( properties.getProperty( PROPERTY_GROUP_DISPLAY_LINK ) );
298         xmlPageElement.setResourceFilesDirectoryPath( strResourceFilesDirectoryPath );
299         xmlPageElement.setXmlFileName( properties.getProperty( strXmlPageName + PROPERTY_FILE_XML_FILE ) );
300         xmlPageElement.setXsdSchema( properties.getProperty( strXmlPageName + PROPERTY_FILE_XSD_SCHEMA ) );
301 
302         String strIsValidationRequired = properties.getProperty( strXmlPageName + PROPERTY_FILE_IS_VALIDATION_REQUIRED );
303         Boolean bIsValidationRequired = ( BOOLEAN_TRUE_VALUE.equals( strIsValidationRequired ) ) ? Boolean.TRUE
304                                                                                                  : Boolean.FALSE;
305         xmlPageElement.setIsValidationRequired( bIsValidationRequired );
306 
307         // load the xsl styles configuration into the XslContent structure
308         xmlPageElement.setListXslContent( getMapXslContent( properties, strXmlPageName ) );
309 
310         return xmlPageElement;
311     }
312 
313     /**
314      * Return the list of XML Files for one propertie file
315      * @param properties describing the group
316      * @return the list of XML Files
317      */
318     private static Map loadListXmlPage( Properties properties )
319     {
320         // get the page names in the propertie set
321         Set listXmlPageName = findAllXmlPageNames( properties );
322         Map listXmlPage = new HashMap( listXmlPageName.size(  ) );
323         Iterator itListXmlPageName = listXmlPageName.iterator(  );
324 
325         while ( itListXmlPageName.hasNext(  ) )
326         {
327             String strXmlPageName = (String) itListXmlPageName.next(  );
328             XmlPageElement xmlPageElement = loadXmlPage( properties, strXmlPageName );
329             listXmlPage.put( strXmlPageName, xmlPageElement );
330         }
331 
332         return listXmlPage;
333     }
334 
335     /**
336      * find XSL keys into properties for the specific strFileName
337      * @param properties describing the group
338      * @param strXmlPageName name of the Xml page
339      * @return Map contening all XSL informations for different outputs of this XML file
340      */
341     private static Map getMapXslContent( Properties properties, String strXmlPageName )
342     {
343         Map mapResult = new HashMap(  );
344 
345         Enumeration enumPropKeys = properties.keys(  );
346 
347         while ( enumPropKeys.hasMoreElements(  ) )
348         {
349             String strPropKey = (String) enumPropKeys.nextElement(  );
350 
351             if ( strPropKey.startsWith( strXmlPageName + PROPERTY_FILE_XSL_PART ) &&
352                     strPropKey.endsWith( PROPERTY_FILE_XSL_FILE_SUFFIXE ) )
353             {
354                 XmlPageXslContent xmlPageXslContent = new XmlPageXslContent(  );
355                 String strPropOutput = strPropKey.substring( ( strXmlPageName + PROPERTY_FILE_XSL_PART ).length(  ),
356                         strPropKey.lastIndexOf( SEPARATOR_PROPERTY_KEY ) );
357                 xmlPageXslContent.setFileName( properties.getProperty( strXmlPageName + PROPERTY_FILE_XSL_PART +
358                         strPropOutput + PROPERTY_FILE_XSL_FILE_SUFFIXE ) );
359                 mapResult.put( strPropOutput, xmlPageXslContent );
360             }
361         }
362 
363         return mapResult;
364     }
365 
366     /**
367      * Return the group of XML Pages
368      * @param file The Property File to load
369      * @return xmlPageGroup the initialized structure containing the group infos and the XmlPageElement objects loaded from the properties
370      */
371     private static XmlPageGroup loadXmlPageGroup( File file )
372     {
373         AppLogService.debug( "XmlPageLoaderProperties - loadXmlPageGroup(" + file.getName(  ) + ")" );
374 
375         XmlPageGroup xmlPageGroup = new XmlPageGroup(  );
376         String strFileName = file.getName(  );
377         String strGroupId = strFileName.substring( 0, strFileName.lastIndexOf( SEPARATOR_FILE_EXTENSION ) );
378 
379         Properties properties = loadPropertiesFromFile( file );
380 
381         // read page data in the properties file
382         // set the information relative to the group
383         xmlPageGroup.setName( strGroupId );
384         xmlPageGroup.setInputFilesDirectoryPath( properties.getProperty( PROPERTY_GROUP_PATH_SOURCES ) );
385         xmlPageGroup.setXsdFilesDirectoryPath( AppPathService.getWebAppPath(  ).concat( PATH_SEPARATOR )
386                                                              .concat( properties.getProperty( PROPERTY_GROUP_PATH_XSD ) ) );
387         xmlPageGroup.setLockPublicationPath( properties.getProperty( PROPERTY_GROUP_LOCK_PUBLICATION_PATH ) );
388         xmlPageGroup.setLockTransfertPath( properties.getProperty( PROPERTY_GROUP_LOCK_TRANSFERT_PATH ) );
389         xmlPageGroup.setMailSenderName( properties.getProperty( PROPERTY_GROUP_MAIL_SENDER_NAME ) );
390         xmlPageGroup.setMailSenderEmail( properties.getProperty( PROPERTY_GROUP_MAIL_SENDER_EMAIL ) );
391         xmlPageGroup.setMailRecipientList( properties.getProperty( PROPERTY_GROUP_MAIL_RECIPIENT_LIST ) );
392         xmlPageGroup.setMailPublicationKoSubject( properties.getProperty( PROPERTY_GROUP_MAIL_PUBLICATION_KO_SUBJECT ) );
393         xmlPageGroup.setMailPublicationOkSubject( properties.getProperty( PROPERTY_GROUP_MAIL_PUBLICATION_OK_SUBJECT ) );
394         xmlPageGroup.setMailValidationKoSubject( properties.getProperty( PROPERTY_GROUP_MAIL_VALIDATION_KO_SUBJECT ) );
395         xmlPageGroup.setMailValidationOkSubject( properties.getProperty( PROPERTY_GROUP_MAIL_VALIDATION_OK_SUBJECT ) );
396         xmlPageGroup.setListExtensionFileCopy( getListExtensionFileCopy( properties ) );
397 
398         // set the information for the pages found
399         xmlPageGroup.setListXmlPageElement( loadListXmlPage( properties ) );
400 
401         AppLogService.debug( "xmlPageGroup = " + xmlPageGroup );
402 
403         return xmlPageGroup;
404     }
405 
406     /**
407      * read the properties and extract the file's extension that have to be copied without any control
408      * @param properties describing the group
409      * @return list of file's extension for direct copy
410      */
411     private static Set getListExtensionFileCopy( Properties properties )
412     {
413         String strExtensionGroup = properties.getProperty( PROPERTY_GROUP_EXTENSION_COPY );
414         Set listExtensionFileCopy = new HashSet(  );
415 
416         // extracts each item (separated by a comma) from the file's extensions
417         StringTokenizer strTokens = new StringTokenizer( strExtensionGroup, SEPARATOR_LIST_EXTENSION );
418 
419         while ( strTokens.hasMoreTokens(  ) )
420         {
421             String strName = strTokens.nextToken(  );
422             listExtensionFileCopy.add( strName );
423         }
424 
425         return listExtensionFileCopy;
426     }
427 }