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.directory.business;
35  
36  import fr.paris.lutece.plugins.directory.utils.DirectoryErrorException;
37  import fr.paris.lutece.plugins.directory.utils.DirectoryUtils;
38  import fr.paris.lutece.portal.business.regularexpression.RegularExpression;
39  import fr.paris.lutece.portal.service.i18n.I18nService;
40  import fr.paris.lutece.portal.service.message.AdminMessage;
41  import fr.paris.lutece.portal.service.message.AdminMessageService;
42  import fr.paris.lutece.portal.service.plugin.Plugin;
43  import fr.paris.lutece.portal.service.regularexpression.RegularExpressionService;
44  import fr.paris.lutece.portal.service.util.AppLogService;
45  import fr.paris.lutece.portal.service.util.AppPropertiesService;
46  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
47  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
48  import fr.paris.lutece.util.ReferenceList;
49  import fr.paris.lutece.util.filesystem.FileSystemUtil;
50  import fr.paris.lutece.util.html.Paginator;
51  
52  import org.apache.commons.fileupload.FileItem;
53  import org.apache.commons.lang.StringUtils;
54  
55  import java.awt.image.BufferedImage;
56  import java.io.ByteArrayInputStream;
57  import java.io.ByteArrayOutputStream;
58  import java.io.IOException;
59  import java.util.Calendar;
60  import java.util.List;
61  import java.util.Locale;
62  
63  import javax.imageio.ImageIO;
64  import javax.servlet.http.HttpServletRequest;
65  
66  /**
67   *
68   * class EntryTypeCamera
69   *
70   */
71  public class EntryTypeCamera extends AbstractEntryTypeUpload
72  {
73      private String PROPERTY_IMAGE_TITLE = AppPropertiesService.getProperty( "directory.image.prefix.title", "default" );
74      protected static final String FIELD_THUMBNAIL_WIDTH = "directory.create_entry.label_width";
75      protected static final String FIELD_THUMBNAIL_HEIGHT = "directory.create_entry.label_width";
76      protected static final String FIELD_BIG_THUMBNAIL_WIDTH = "directory.create_entry.label_width";
77      protected static final String FIELD_BIG_THUMBNAIL_HEIGHT = "directory.create_entry.label_width";
78      protected static final String ERROR_FIELD_THUMBNAIL = "directory.create_entry.label_error_thumbnail";
79      protected static final String ERROR_FIELD_BIG_THUMBNAIL = "directory.create_entry.label_error_big_thumbnail";
80      private static final String PARAMETER_IMAGE_SHOWN_IN_RESULT_LIST = "image_shown_in_result_list";
81      private static final String PARAMETER_IMAGE_SHOWN_IN_RESULT_RECORD = "image_shown_in_result_record";
82      private static final String PARAMETER_IMAGE_TYPE = "image_type";
83      private static final String MESSAGE_ERROR_NOT_AN_IMAGE = "directory.message.error.notAnImage";
84      private static final String FIELD_IMAGE = "image_full_size";
85      private final String PREFIX_ENTRY_ID = "directory_";
86      private final String _template_create = "admin/plugins/directory/entrytypecamera/create_entry_type_camera.html";
87      private final String _template_modify = "admin/plugins/directory/entrytypecamera/modify_entry_type_camera.html";
88      private final String _template_html_code_form_entry = "admin/plugins/directory/entrytypecamera/html_code_form_entry_type_camera.html";
89      private final String _template_html_code_entry_value = "admin/plugins/directory/entrytypecamera/html_code_entry_value_type_camera.html";
90      private final String _template_html_front_code_form_entry = "skin/plugins/directory/entrytypecamera/html_code_form_entry_type_camera.html";
91      private final String _template_html_front_code_entry_value = "skin/plugins/directory/entrytypecamera/html_code_entry_value_type_camera.html";
92  
93      /**
94       * {@inheritDoc}
95       */
96      @Override
97      public String getTemplateHtmlFormEntry( boolean isDisplayFront )
98      {
99          if ( isDisplayFront )
100         {
101             return _template_html_front_code_form_entry;
102         }
103 
104         return _template_html_code_form_entry;
105     }
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public String getTemplateHtmlRecordFieldValue( boolean isDisplayFront )
112     {
113         if ( isDisplayFront )
114         {
115             return _template_html_front_code_entry_value;
116         }
117 
118         return _template_html_code_entry_value;
119     }
120 
121     /**
122      * {@inheritDoc}
123      */
124     @Override
125     public String getEntryData( HttpServletRequest request, Locale locale )
126     {
127         String strTitle = request.getParameter( PARAMETER_TITLE );
128         String strHelpMessage = ( request.getParameter( PARAMETER_HELP_MESSAGE ) != null ) ? request.getParameter( PARAMETER_HELP_MESSAGE ).trim( ) : null;
129         String strComment = request.getParameter( PARAMETER_COMMENT );
130         String strMandatory = request.getParameter( PARAMETER_MANDATORY );
131         String strIndexed = request.getParameter( PARAMETER_INDEXED );
132         String strIndexedAsTitle = request.getParameter( PARAMETER_INDEXED_AS_TITLE );
133         String strIndexedAsSummary = request.getParameter( PARAMETER_INDEXED_AS_SUMMARY );
134 
135         String strWidth = request.getParameter( PARAMETER_WIDTH );
136         String strHeight = request.getParameter( PARAMETER_HEIGHT );
137 
138         int nWidth = DirectoryUtils.convertStringToInt( strWidth );
139         int nHeight = DirectoryUtils.convertStringToInt( strHeight );
140 
141         String strShowInFormMainSearch = request.getParameter( PARAMETER_SHOWN_IN_ADVANCED_SEARCH );
142         String strShowInResultList = request.getParameter( PARAMETER_SHOWN_IN_RESULT_LIST );
143         String strShowInResultRecord = request.getParameter( PARAMETER_SHOWN_IN_RESULT_RECORD );
144         String strShowInHistory = request.getParameter( PARAMETER_SHOWN_IN_HISTORY );
145         String strShowInCompleteness = request.getParameter( PARAMETER_SHOWN_IN_COMPLETENESS );
146 
147         String strError = this.checkEntryData( request, locale );
148 
149         if ( StringUtils.isNotBlank( strError ) )
150         {
151             return strError;
152         }
153 
154         this.setTitle( strTitle );
155         this.setHelpMessage( strHelpMessage );
156         this.setComment( strComment );
157 
158         this.setFields( request );
159 
160         this.setDisplayWidth( nWidth );
161         this.setDisplayHeight( nHeight );
162 
163         this.setMandatory( strMandatory != null );
164         this.setIndexed( strIndexed != null );
165         this.setIndexedAsTitle( strIndexedAsTitle != null );
166         this.setIndexedAsSummary( strIndexedAsSummary != null );
167         this.setShownInAdvancedSearch( strShowInFormMainSearch != null );
168         this.setShownInResultList( strShowInResultList != null );
169         this.setShownInResultRecord( strShowInResultRecord != null );
170         this.setShownInHistory( strShowInHistory != null );
171         this.setShownInCompleteness( strShowInCompleteness != null );
172         // image can't be exported in csv
173         this.setShownInExport( false );
174 
175         return null;
176     }
177 
178     /**
179      * {@inheritDoc}
180      */
181     @Override
182     public String getTemplateCreate( )
183     {
184         return _template_create;
185     }
186 
187     /**
188      * {@inheritDoc}
189      */
190     @Override
191     public String getTemplateModify( )
192     {
193         return _template_modify;
194     }
195 
196     /**
197      * {@inheritDoc}
198      */
199     @Override
200     public void getRecordFieldData( Record record, List<String> lstValue, boolean bTestDirectoryError, boolean bAddNewValue, List<RecordField> listRecordField,
201             Locale locale ) throws DirectoryErrorException
202     {
203         // add Empty recordField(Use for data import)
204         RecordField recordField = new RecordField( );
205         recordField.setEntry( this );
206         listRecordField.add( recordField );
207     }
208 
209     /**
210      * {@inheritDoc}
211      */
212     @Override
213     public void getImportRecordFieldData( Record record, String strImportValue, boolean bTestDirectoryError, List<RecordField> listRecordField, Locale locale )
214             throws DirectoryErrorException
215     {
216         // add Empty recordField
217         RecordField recordField = new RecordField( );
218         recordField.setEntry( this );
219         listRecordField.add( recordField );
220     }
221 
222     /**
223      * {@inheritDoc}
224      */
225     @Override
226     public void getRecordFieldData( Record record, HttpServletRequest request, boolean bTestDirectoryError, boolean bAddNewValue,
227             List<RecordField> listRecordField, Locale locale ) throws DirectoryErrorException
228     {
229         if ( request instanceof MultipartHttpServletRequest )
230         {
231 
232             String sourceImage = request.getParameter( PREFIX_ENTRY_ID + this.getIdEntry( ) );
233 
234             if ( ( sourceImage != null ) && StringUtils.isNotEmpty( sourceImage ) )
235             {
236                 // Checks
237                 if ( bTestDirectoryError )
238                 {
239                     this.checkRecordFieldData( sourceImage, locale );
240                 }
241 
242                 File file = new File( );
243                 Calendar c = Calendar.getInstance( );
244                 String fileName = request.getParameter( PROPERTY_IMAGE_TITLE );
245 
246                 if ( fileName != null )
247                 {
248 
249                     file.setTitle( fileName + "_" + c.getTime( ) );
250 
251                 }
252                 else
253                 {
254 
255                     file.setTitle( this.getTitle( ) + "_" + c.getTime( ) );
256                 }
257                 file.setExtension( this.getFields( ).get( 2 ).getImageType( ) != null ? this.getFields( ).get( 2 ).getImageType( ) : "png" );
258                 PhysicalFile physicalFile = new PhysicalFile( );
259                 String base64Image = sourceImage.split( "," ) [1];
260                 byte [ ] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary( base64Image );
261                 physicalFile.setValue( imageBytes );
262                 file.setPhysicalFile( physicalFile );
263                 file.setTitle( this.getFields( ).get( 2 ).getImageType( ) != null ? file.getTitle( ) + "." + this.getFields( ).get( 2 ).getImageType( ) : file
264                         .getTitle( ) + "" );
265                 file.setMimeType( FileSystemUtil.getMIMEType( file.getTitle( ) ) );
266 
267                 ByteArrayInputStream bis = new ByteArrayInputStream( imageBytes );
268                 ByteArrayOutputStream tmp = new ByteArrayOutputStream( );
269 
270                 try
271                 {
272                     BufferedImage image = ImageIO.read( bis );
273                     ImageIO.write( image, this.getFields( ).get( 2 ).getImageType( ) != null ? this.getFields( ).get( 2 ).getImageType( ) : "png", tmp );
274                     bis.close( );
275                     tmp.close( );
276                     file.setSize( tmp.size( ) );
277                 }
278                 catch( IOException e )
279                 {
280                     AppLogService.error( e );
281                     throw new DirectoryErrorException( this.getTitle( ) );
282                 }
283 
284                 // Add the image to the record fields list
285                 RecordField recordField = new RecordField( );
286                 recordField.setEntry( this );
287                 recordField.setValue( FIELD_IMAGE + DirectoryUtils.CONSTANT_UNDERSCORE + 1 );
288                 recordField.setFile( file );
289                 recordField.setFileExtension( file.getExtension( ) );
290                 listRecordField.add( recordField );
291             }
292 
293             if ( bTestDirectoryError && this.isMandatory( ) && ( ( sourceImage == null ) || StringUtils.isEmpty( sourceImage ) ) )
294             {
295                 RecordField recordField = new RecordField( );
296                 recordField.setEntry( this );
297                 recordField.setValue( FIELD_IMAGE );
298                 listRecordField.add( recordField );
299 
300                 throw new DirectoryErrorException( this.getTitle( ) );
301             }
302         }
303         else
304             if ( bTestDirectoryError )
305             {
306                 throw new DirectoryErrorException( this.getTitle( ) );
307             }
308     }
309 
310     /**
311      * {@inheritDoc}
312      */
313     @Override
314     public Paginator getPaginator( int nItemPerPage, String strBaseUrl, String strPageIndexParameterName, String strPageIndex )
315     {
316         return new Paginator( this.getFields( ).get( 0 ).getRegularExpressionList( ), nItemPerPage, strBaseUrl, strPageIndexParameterName, strPageIndex );
317     }
318 
319     /**
320      * {@inheritDoc}
321      */
322     @Override
323     public ReferenceList getReferenceListRegularExpression( IEntry entry, Plugin plugin )
324     {
325         ReferenceList refListRegularExpression = null;
326 
327         if ( RegularExpressionService.getInstance( ).isAvailable( ) )
328         {
329             refListRegularExpression = new ReferenceList( );
330 
331             List<RegularExpression> listRegularExpression = RegularExpressionService.getInstance( ).getAllRegularExpression( );
332 
333             for ( RegularExpression regularExpression : listRegularExpression )
334             {
335                 if ( !entry.getFields( ).get( 0 ).getRegularExpressionList( ).contains( regularExpression ) )
336                 {
337                     refListRegularExpression.addItem( regularExpression.getIdExpression( ), regularExpression.getTitle( ) );
338                 }
339             }
340         }
341 
342         return refListRegularExpression;
343     }
344 
345     /**
346      * {@inheritDoc}
347      */
348     @Override
349     public LocalizedPaginator getPaginator( int nItemPerPage, String strBaseUrl, String strPageIndexParameterName, String strPageIndex, Locale locale )
350     {
351         return new LocalizedPaginator( this.getFields( ).get( 0 ).getRegularExpressionList( ), nItemPerPage, strBaseUrl, strPageIndexParameterName,
352                 strPageIndex, locale );
353     }
354 
355     // PROTECTED METHODS
356 
357     /**
358      * {@inheritDoc}
359      */
360     @Override
361     protected String checkEntryData( HttpServletRequest request, Locale locale )
362     {
363         String strError = super.checkEntryData( request, locale );
364 
365         if ( StringUtils.isBlank( strError ) )
366         {
367             String strFieldError = StringUtils.EMPTY;
368             String strTitle = request.getParameter( PARAMETER_TITLE );
369 
370             String strWidth = request.getParameter( PARAMETER_WIDTH );
371             String strHeight = request.getParameter( PARAMETER_HEIGHT );
372 
373             int nWidth = DirectoryUtils.convertStringToInt( strWidth );
374             int nHeight = DirectoryUtils.convertStringToInt( strHeight );
375 
376             if ( StringUtils.isBlank( strTitle ) )
377             {
378                 strFieldError = FIELD_TITLE;
379             }
380 
381             if ( !strFieldError.equals( DirectoryUtils.EMPTY_STRING ) )
382             {
383                 Object [ ] tabRequiredFields = {
384                     I18nService.getLocalizedString( strFieldError, locale )
385                 };
386 
387                 return AdminMessageService.getMessageUrl( request, MESSAGE_MANDATORY_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
388             }
389 
390             if ( ( strWidth != null ) && ( !strWidth.trim( ).equals( DirectoryUtils.EMPTY_STRING ) ) && ( nWidth == DirectoryUtils.CONSTANT_ID_NULL ) )
391             {
392                 strFieldError = FIELD_WIDTH;
393             }
394             else
395                 if ( ( strHeight != null ) && ( !strHeight.trim( ).equals( DirectoryUtils.EMPTY_STRING ) ) && ( nHeight == DirectoryUtils.CONSTANT_ID_NULL ) )
396                 {
397                     strFieldError = FIELD_HEIGHT;
398                 }
399 
400             if ( !strFieldError.equals( DirectoryUtils.EMPTY_STRING ) )
401             {
402                 Object [ ] tabRequiredFields = {
403                     I18nService.getLocalizedString( strFieldError, locale )
404                 };
405 
406                 return AdminMessageService.getMessageUrl( request, MESSAGE_NUMERIC_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
407             }
408 
409             if ( StringUtils.isNotBlank( strFieldError ) )
410             {
411                 Object [ ] tabRequiredFields = {
412                     I18nService.getLocalizedString( strFieldError, locale )
413                 };
414 
415                 return AdminMessageService.getMessageUrl( request, MESSAGE_MANDATORY_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
416             }
417         }
418 
419         return strError;
420     }
421 
422     /**
423      * {@inheritDoc}
424      */
425     @Override
426     protected void setFields( HttpServletRequest request, List<Field> listFields )
427     {
428         listFields.add( buildFieldFullSize( request ) );
429     }
430 
431     private void checkRecordFieldData( String imageSource, Locale locale ) throws DirectoryErrorException
432     {
433         BufferedImage image = null;
434 
435         if ( ( imageSource != null ) && ( imageSource.split( "," ).length > 1 ) )
436         {
437             String base64Image = imageSource.split( "," ) [1];
438             byte [ ] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary( base64Image );
439             ByteArrayInputStream bis = new ByteArrayInputStream( imageBytes );
440 
441             try
442             {
443                 image = ImageIO.read( bis );
444                 bis.close( );
445             }
446             catch( IOException e )
447             {
448                 String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_NOT_AN_IMAGE, locale );
449                 throw new DirectoryErrorException( this.getTitle( ), strErrorMessage );
450             }
451         }
452 
453         if ( ( image == null ) && StringUtils.isNotBlank( imageSource ) )
454         {
455             String strErrorMessage = I18nService.getLocalizedString( MESSAGE_ERROR_NOT_AN_IMAGE, locale );
456             throw new DirectoryErrorException( this.getTitle( ), strErrorMessage );
457         }
458     }
459 
460     // PRIVATE METHODS
461 
462     /**
463      * Build the field full size
464      * 
465      * @param request
466      *            the HTTP request
467      * @return the field
468      */
469     private Field buildFieldFullSize( HttpServletRequest request )
470     {
471         Field fieldFullImage = DirectoryUtils.findFieldByValueInTheList( FIELD_IMAGE, getFields( ) );
472 
473         if ( fieldFullImage == null )
474         {
475             fieldFullImage = new Field( );
476         }
477 
478         if ( request.getParameter( PARAMETER_IMAGE_SHOWN_IN_RESULT_LIST ) != null )
479         {
480             fieldFullImage.setShownInResultList( true );
481         }
482         else
483         {
484             fieldFullImage.setShownInResultList( false );
485         }
486 
487         if ( request.getParameter( PARAMETER_IMAGE_SHOWN_IN_RESULT_RECORD ) != null )
488         {
489             fieldFullImage.setShownInResultRecord( true );
490         }
491         else
492         {
493             fieldFullImage.setShownInResultRecord( false );
494         }
495         if ( request.getParameter( PARAMETER_IMAGE_TYPE ) != null )
496         {
497             fieldFullImage.setImageType( request.getParameter( PARAMETER_IMAGE_TYPE ) );
498         }
499         fieldFullImage.setEntry( this );
500         fieldFullImage.setValue( FIELD_IMAGE );
501 
502         return fieldFullImage;
503     }
504 
505     @Override
506     protected void checkRecordFieldData( FileItem fileItem, Locale locale ) throws DirectoryErrorException
507     {
508     }
509 }