View Javadoc
1   /*
2    * Copyright (c) 2002-2020, 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.suggest.web;
35  
36  import fr.paris.lutece.plugins.suggest.business.ExportFormat;
37  import fr.paris.lutece.plugins.suggest.business.ExportFormatHome;
38  import fr.paris.lutece.plugins.suggest.service.ExportFormatResourceIdService;
39  import fr.paris.lutece.plugins.suggest.utils.SuggestUtils;
40  import fr.paris.lutece.portal.business.rbac.RBAC;
41  import fr.paris.lutece.portal.service.fileupload.FileUploadService;
42  import fr.paris.lutece.portal.service.i18n.I18nService;
43  import fr.paris.lutece.portal.service.message.AdminMessage;
44  import fr.paris.lutece.portal.service.message.AdminMessageService;
45  import fr.paris.lutece.portal.service.plugin.Plugin;
46  import fr.paris.lutece.portal.service.rbac.RBACService;
47  import fr.paris.lutece.portal.service.template.AppTemplateService;
48  import fr.paris.lutece.portal.service.util.AppLogService;
49  import fr.paris.lutece.portal.service.util.AppPathService;
50  import fr.paris.lutece.portal.service.util.AppPropertiesService;
51  import fr.paris.lutece.portal.web.admin.PluginAdminPageJspBean;
52  import fr.paris.lutece.portal.web.constants.Parameters;
53  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
54  import fr.paris.lutece.util.html.HtmlTemplate;
55  import fr.paris.lutece.util.html.Paginator;
56  import fr.paris.lutece.util.url.UrlItem;
57  
58  import org.apache.commons.fileupload.FileItem;
59  
60  import org.xml.sax.InputSource;
61  import org.xml.sax.XMLReader;
62  
63  import java.io.ByteArrayInputStream;
64  import java.io.IOException;
65  import java.io.OutputStream;
66  
67  import java.util.HashMap;
68  import java.util.List;
69  import java.util.Locale;
70  import java.util.Map;
71  
72  import javax.servlet.http.HttpServletRequest;
73  import javax.servlet.http.HttpServletResponse;
74  
75  import javax.xml.parsers.SAXParser;
76  import javax.xml.parsers.SAXParserFactory;
77  import javax.xml.stream.XMLInputFactory;
78  
79  /**
80   *
81   * class ExportFormatJspBean
82   *
83   */
84  public class ExportFormatJspBean extends PluginAdminPageJspBean
85  {
86      private static final long serialVersionUID = 2892557628133467782L;
87  
88      // templates
89      private static final String TEMPLATE_MANAGE_EXPORT = "admin/plugins/suggest/manage_export_format.html";
90      private static final String TEMPLATE_CREATE_EXPORT = "admin/plugins/suggest/create_export_format.html";
91      private static final String TEMPLATE_MODIFY_EXPORT = "admin/plugins/suggest/modify_export_format.html";
92  
93      // Markers
94      private static final String MARK_EXPORT_LIST = "export_list";
95      private static final String MARK_EXPORT = "export";
96      private static final String MARK_PAGINATOR = "paginator";
97      private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
98  
99      // parameters form
100     private static final String PARAMETER_ID_EXPORT = "id_export";
101     private static final String PARAMETER_TITLE = "title";
102     private static final String PARAMETER_DESCRIPTION = "description";
103     private static final String PARAMETER_EXTENSION = "extension";
104     private static final String PARAMETER_PAGE_INDEX = "page_index";
105 
106     // other constants
107     private static final String EMPTY_STRING = "";
108     private static final String CONSTANT_MIME_TYPE_OCTETSTREAM = "application/octet-stream";
109 
110     // message
111     private static final String MESSAGE_CONFIRM_REMOVE_EXPORT = "suggest.message.confirmRemoveExportFormat";
112     private static final String MESSAGE_MANDATORY_FIELD = "suggest.message.mandatory.field";
113     private static final String MESSAGE_ERROR_DURING_DOWNLOAD_FILE = "suggest.message.errorDuringDownloadFile";
114     private static final String MESSAGE_YOU_ARE_NOT_ALLOWED_TO_DOWLOAD_THIS_FILE = "suggest.message.youAreNotAllowedToDownloadFile";
115     private static final String FIELD_TITLE = "suggest.createExportFormat.labelTitle";
116     private static final String FIELD_DESCRIPTION = "suggest.createExportFormat.labelDescription";
117     private static final String FIELD_EXTENSION = "suggest.createExportFormat.labelExtension";
118     private static final String FIELD_XSL = "suggest.createExportFormat.labelXsl";
119     private static final String MESSAGE_STYLESHEET_NOT_VALID = "suggest.message.stylesheetNotValid";
120 
121     // properties
122     private static final String PROPERTY_ITEM_PER_PAGE = "suggest.itemsPerPage";
123     private static final String PROPERTY_MANAGE_EXPORT_FORMAT_TITLE = "suggest.manageExportFormat.pageTitle";
124     private static final String PROPERTY_MODIFY_EXPORT_FORMAT_TITLE = "suggest.modifyExportFormat.title";
125     private static final String PROPERTY_CREATE_EXPORT_FORMAT_TITLE = "suggest.createExportFormat.title";
126 
127     // Jsp Definition
128     private static final String JSP_MANAGE_EXPORT_FORMAT = "jsp/admin/plugins/suggest/ManageExportFormat.jsp";
129     private static final String JSP_DO_REMOVE_EXPORT_FORMAT = "jsp/admin/plugins/suggest/DoRemoveExportFormat.jsp";
130 
131     // session fields
132     private int _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_ITEM_PER_PAGE, 15 );
133     private String _strCurrentPageIndexExport;
134     private int _nItemsPerPageExportFormat;
135 
136     /**
137      * Return management export format ( list of export format )
138      * 
139      * @param request
140      *            The Http request
141      * @return Html ExportFormat
142      */
143     public String getManageExportFormat( HttpServletRequest request )
144     {
145         Plugin plugin = getPlugin( );
146         Locale locale = getLocale( );
147         Map<String, Object> model = new HashMap<>( );
148         List<ExportFormat> listExportFormat = ExportFormatHome.getList( plugin );
149         listExportFormat = (List<ExportFormat>) RBACService.getAuthorizedCollection( listExportFormat, ExportFormatResourceIdService.PERMISSION_MANAGE,
150                 getUser( ) );
151         _strCurrentPageIndexExport = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndexExport );
152         _nItemsPerPageExportFormat = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPageExportFormat, _nDefaultItemsPerPage );
153 
154         Paginator<ExportFormat> paginator = new Paginator<>( listExportFormat, _nItemsPerPageExportFormat, getJspManageExportFormat( request ),
155                 PARAMETER_PAGE_INDEX, _strCurrentPageIndexExport );
156 
157         model.put( MARK_PAGINATOR, paginator );
158         model.put( MARK_NB_ITEMS_PER_PAGE, EMPTY_STRING + _nItemsPerPageExportFormat );
159         model.put( MARK_EXPORT_LIST, paginator.getPageItems( ) );
160         setPageTitleProperty( PROPERTY_MANAGE_EXPORT_FORMAT_TITLE );
161 
162         HtmlTemplate templateList = AppTemplateService.getTemplate( TEMPLATE_MANAGE_EXPORT, locale, model );
163 
164         return getAdminPage( templateList.getHtml( ) );
165     }
166 
167     /**
168      * Gets the export format creation page
169      * 
170      * @param request
171      *            The HTTP request
172      * @return The export format creation page
173      */
174     public String getCreateExportFormat( HttpServletRequest request )
175     {
176         if ( !RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
177         {
178             return getManageExportFormat( request );
179         }
180 
181         Locale locale = getLocale( );
182         Map<String, Object> model = new HashMap<>( );
183         setPageTitleProperty( PROPERTY_CREATE_EXPORT_FORMAT_TITLE );
184 
185         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_EXPORT, locale, model );
186 
187         return getAdminPage( template.getHtml( ) );
188     }
189 
190     /**
191      * Perform the export format creation
192      * 
193      * @param request
194      *            The HTTP request
195      * @return The URL to go after performing the action
196      */
197     public String doCreateExportFormat( HttpServletRequest request )
198     {
199         if ( !RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
200         {
201             return getJspManageExportFormat( request );
202         }
203 
204         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
205         ExportFormatsiness/ExportFormat.html#ExportFormat">ExportFormat exportFormat = new ExportFormat( );
206         String strError = getExportFormatData( multipartRequest, exportFormat );
207 
208         if ( strError != null )
209         {
210             return strError;
211         }
212 
213         ExportFormatHome.create( exportFormat, getPlugin( ) );
214 
215         return getJspManageExportFormat( request );
216     }
217 
218     /**
219      * Gets the export format modification page
220      * 
221      * @param request
222      *            The HTTP request
223      * @return The export format creation page
224      */
225     public String getModifyExportFormat( HttpServletRequest request )
226     {
227         Plugin plugin = getPlugin( );
228         Locale locale = getLocale( );
229         ExportFormat exportFormat;
230         String strIdExport = request.getParameter( PARAMETER_ID_EXPORT );
231         Map<String, Object> model = new HashMap<>( );
232         int nIdExport = -1;
233 
234         if ( ( strIdExport != null ) && !strIdExport.equals( EMPTY_STRING )
235                 && RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, strIdExport, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
236         {
237             try
238             {
239                 nIdExport = Integer.parseInt( strIdExport );
240             }
241             catch( NumberFormatException ne )
242             {
243                 AppLogService.error( ne.getMessage( ), ne );
244 
245                 return getManageExportFormat( request );
246             }
247         }
248         else
249         {
250             return getManageExportFormat( request );
251         }
252 
253         exportFormat = ExportFormatHome.findByPrimaryKey( nIdExport, plugin );
254         model.put( MARK_EXPORT, exportFormat );
255         setPageTitleProperty( PROPERTY_MODIFY_EXPORT_FORMAT_TITLE );
256 
257         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_EXPORT, locale, model );
258 
259         return getAdminPage( template.getHtml( ) );
260     }
261 
262     /**
263      * Perform the export format modification
264      * 
265      * @param request
266      *            The HTTP request
267      * @return The URL to go after performing the action
268      */
269     public String doModifyExportFormat( HttpServletRequest request )
270     {
271         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
272         Plugin plugin = getPlugin( );
273         ExportFormat exportFormat;
274         String strIdExport = multipartRequest.getParameter( PARAMETER_ID_EXPORT );
275         int nIdExport = -1;
276 
277         if ( ( strIdExport != null ) && !strIdExport.equals( EMPTY_STRING )
278                 && RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, strIdExport, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
279         {
280             try
281             {
282                 nIdExport = Integer.parseInt( strIdExport );
283             }
284             catch( NumberFormatException ne )
285             {
286                 AppLogService.error( ne.getMessage( ), ne );
287 
288                 return getHomeUrl( request );
289             }
290         }
291         else
292         {
293             return getHomeUrl( request );
294         }
295 
296         exportFormat = ExportFormatHome.findByPrimaryKey( nIdExport, plugin );
297 
298         String strError = getExportFormatData( multipartRequest, exportFormat );
299 
300         if ( strError != null )
301         {
302             return strError;
303         }
304 
305         ExportFormatHome.update( exportFormat, getPlugin( ) );
306 
307         return getJspManageExportFormat( request );
308     }
309 
310     /**
311      * Gets the confirmation page of delete export format
312      * 
313      * @param request
314      *            The HTTP request
315      * @return the confirmation page of delete export format
316      */
317     public String getConfirmRemoveExportFormat( HttpServletRequest request )
318     {
319         if ( request.getParameter( PARAMETER_ID_EXPORT ) == null )
320         {
321             return getHomeUrl( request );
322         }
323 
324         String strIdExport = request.getParameter( PARAMETER_ID_EXPORT );
325         UrlItem url = new UrlItem( JSP_DO_REMOVE_EXPORT_FORMAT );
326         url.addParameter( PARAMETER_ID_EXPORT, strIdExport );
327 
328         return AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_EXPORT, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
329     }
330 
331     /**
332      * Perform the export format supression
333      * 
334      * @param request
335      *            The HTTP request
336      * @return The URL to go after performing the action
337      */
338     public String doRemoveExportFormat( HttpServletRequest request )
339     {
340         String strIdExport = request.getParameter( PARAMETER_ID_EXPORT );
341         int nIdExport = -1;
342 
343         if ( ( request.getParameter( PARAMETER_ID_EXPORT ) == null )
344                 || !RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, strIdExport, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
345         {
346             return getJspManageExportFormat( request );
347         }
348 
349         try
350         {
351             nIdExport = Integer.parseInt( strIdExport );
352         }
353         catch( NumberFormatException ne )
354         {
355             AppLogService.error( ne.getMessage( ), ne );
356 
357             return getHomeUrl( request );
358         }
359 
360         if ( nIdExport != -1 )
361         {
362             ExportFormatHome.remove( nIdExport, getPlugin( ) );
363         }
364 
365         return getJspManageExportFormat( request );
366     }
367 
368     /**
369      * Get the request data and if there is no error insert the data in the exportFormat object specified in parameter. return null if there is no error or else
370      * return the error page url
371      * 
372      * @param multipartRequest
373      *            the request
374      * @param exportFormat
375      *            the exportFormat Object
376      * @return null if there is no error or else return the error page url
377      */
378     private String getExportFormatData( MultipartHttpServletRequest multipartRequest, ExportFormat exportFormat )
379     {
380         String strTitle = multipartRequest.getParameter( PARAMETER_TITLE );
381         String strDescription = multipartRequest.getParameter( PARAMETER_DESCRIPTION );
382         String strExtension = multipartRequest.getParameter( PARAMETER_EXTENSION );
383 
384         String strFieldError = EMPTY_STRING;
385         FileItem fileSource = multipartRequest.getFile( Parameters.STYLESHEET_SOURCE );
386         String strFilename = FileUploadService.getFileNameOnly( fileSource );
387 
388         if ( ( strTitle == null ) || strTitle.trim( ).equals( EMPTY_STRING ) )
389         {
390             strFieldError = FIELD_TITLE;
391         }
392 
393         else
394             if ( ( strDescription == null ) || strDescription.trim( ).equals( EMPTY_STRING ) )
395             {
396                 strFieldError = FIELD_DESCRIPTION;
397             }
398             else
399                 if ( ( strExtension == null ) || strExtension.trim( ).equals( EMPTY_STRING ) )
400                 {
401                     strFieldError = FIELD_EXTENSION;
402                 }
403 
404                 else
405                     if ( ( strFilename == null ) || ( strFilename.equals( "" ) && ( exportFormat.getXsl( ) == null ) ) )
406                     {
407                         strFieldError = FIELD_XSL;
408                     }
409 
410         // Mandatory fields
411         if ( !strFieldError.equals( EMPTY_STRING ) )
412         {
413             Object [ ] tabRequiredFields = {
414                 I18nService.getLocalizedString( strFieldError, getLocale( ) )
415             };
416 
417             return AdminMessageService.getMessageUrl( multipartRequest, MESSAGE_MANDATORY_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
418         }
419 
420         byte [ ] baXslSource = fileSource.get( );
421 
422         // Check the XML validity of the XSL stylesheet
423         if ( ( strFilename != null ) && !strFilename.equals( "" ) && ( isValid( baXslSource ) != null ) )
424         {
425             Object [ ] args = {
426                 isValid( baXslSource )
427             };
428 
429             return AdminMessageService.getMessageUrl( multipartRequest, MESSAGE_STYLESHEET_NOT_VALID, args, AdminMessage.TYPE_STOP );
430         }
431 
432         exportFormat.setTitle( strTitle );
433         exportFormat.setDescription( strDescription );
434         exportFormat.setExtension( strExtension );
435 
436         if ( ( strFilename != null ) && !strFilename.equals( "" ) )
437         {
438             exportFormat.setXsl( baXslSource );
439         }
440 
441         return null;
442     }
443 
444     /**
445      * write in the http response the value of the response whose identifier is specified in the request if there is no response return a error
446      * 
447      * @param request
448      *            the http request
449      * @param response
450      *            The http response
451      * @return The URL to go after performing the action
452      */
453     public String doDownloadXslFile( HttpServletRequest request, HttpServletResponse response )
454     {
455         Plugin plugin = getPlugin( );
456         ExportFormat exportFormat;
457         String strIdExport = request.getParameter( PARAMETER_ID_EXPORT );
458         int nIdExport = -1;
459 
460         if ( ( strIdExport != null ) && !strIdExport.equals( EMPTY_STRING )
461                 && RBACService.isAuthorized( ExportFormat.RESOURCE_TYPE, strIdExport, ExportFormatResourceIdService.PERMISSION_MANAGE, getUser( ) ) )
462         {
463             try
464             {
465                 nIdExport = Integer.parseInt( strIdExport );
466             }
467             catch( NumberFormatException ne )
468             {
469                 AppLogService.error( ne.getMessage( ), ne );
470 
471                 return AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DURING_DOWNLOAD_FILE, AdminMessage.TYPE_STOP );
472             }
473         }
474         else
475         {
476             return AdminMessageService.getMessageUrl( request, MESSAGE_YOU_ARE_NOT_ALLOWED_TO_DOWLOAD_THIS_FILE, AdminMessage.TYPE_STOP );
477         }
478 
479         exportFormat = ExportFormatHome.findByPrimaryKey( nIdExport, plugin );
480 
481         if ( exportFormat != null )
482         {
483             try
484             {
485                 byte [ ] byteFileOutPut = exportFormat.getXsl( );
486                 SuggestUtils.addHeaderResponse( request, response, exportFormat.getTitle( ) + ".xsl" );
487                 response.setContentType( CONSTANT_MIME_TYPE_OCTETSTREAM );
488                 response.setContentLength( byteFileOutPut.length );
489 
490                 OutputStream os = response.getOutputStream( );
491                 os.write( byteFileOutPut );
492                 os.close( );
493             }
494             catch( IOException e )
495             {
496                 AppLogService.error( e.getMessage( ), e );
497 
498                 return AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DURING_DOWNLOAD_FILE, AdminMessage.TYPE_STOP );
499             }
500         }
501 
502         return getJspManageExportFormat( request );
503     }
504 
505     /**
506      * Use parsing for validate the modify xsl file
507      * 
508      * @param baXslSource
509      *            the xsl source
510      * @return the message exception when the validation is false
511      */
512     private String isValid( byte [ ] baXslSource )
513     {
514         String strError = null;
515 
516         try
517         {
518             SAXParserFactory factory = SAXParserFactory.newInstance( );
519             ( ( XMLReader) factory ).setProperty( XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE );
520             SAXParser analyzer = factory.newSAXParser( );
521             InputSource is = new InputSource( new ByteArrayInputStream( baXslSource ) );
522             analyzer.getXMLReader( ).parse( is );
523         }
524         catch( Exception e )
525         {
526             strError = e.getMessage( );
527         }
528 
529         return strError;
530     }
531 
532     /**
533      * return the url of manage export format
534      * 
535      * @param request
536      *            the request
537      * @return the url of manage export format
538      */
539     private String getJspManageExportFormat( HttpServletRequest request )
540     {
541         return AppPathService.getBaseUrl( request ) + JSP_MANAGE_EXPORT_FORMAT;
542     }
543 }