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.plugins.genericattributes.util;
35  
36  import java.util.ArrayList;
37  import java.util.List;
38  import java.util.Locale;
39  import java.util.Optional;
40  
41  import javax.servlet.http.HttpServletRequest;
42  
43  import org.apache.commons.collections.CollectionUtils;
44  import org.apache.commons.fileupload.FileItem;
45  import org.apache.commons.lang3.StringUtils;
46  
47  import fr.paris.lutece.plugins.genericattributes.business.Entry;
48  import fr.paris.lutece.plugins.genericattributes.business.Field;
49  import fr.paris.lutece.plugins.genericattributes.business.GenericAttributeError;
50  import fr.paris.lutece.plugins.genericattributes.business.MandatoryError;
51  import fr.paris.lutece.plugins.genericattributes.service.entrytype.IEntryTypeService;
52  import fr.paris.lutece.portal.business.regularexpression.RegularExpression;
53  import fr.paris.lutece.portal.service.fileupload.FileUploadService;
54  import fr.paris.lutece.portal.service.i18n.I18nService;
55  import fr.paris.lutece.portal.service.message.AdminMessage;
56  import fr.paris.lutece.portal.service.message.AdminMessageService;
57  import fr.paris.lutece.portal.service.regularexpression.RegularExpressionService;
58  import fr.paris.lutece.portal.service.util.AppPropertiesService;
59  import fr.paris.lutece.util.filesystem.FileSystemUtil;
60  
61  /**
62   * Utility class of plugin generic attributes
63   */
64  public final class FileAttributesUtils
65  {
66      public static final String PROPERTY_MESSAGE_ERROR_UPLOADING_FILE_MAX_FILES = "genericattributes.message.error.uploading_file.max_files";
67      public static final String PROPERTY_MESSAGE_ERROR_UPLOADING_FILE_FILE_MAX_SIZE = "genericattributes.message.error.uploading_file.file_max_size";
68      public static final String PROPERTY_UPLOAD_FILE_DEFAULT_MAX_SIZE = "genericattributes.upload.file.default_max_size";
69  
70      private FileAttributesUtils( )
71      {
72          // Empty Contructor
73      }
74  
75      public static GenericAttributeError checkFileSize( Entry entry, List<FileItem> listUploadedFileItems, List<FileItem> listFileItemsToUpload, Locale locale )
76      {
77          GenericAttributeError error = null;
78          Field fieldFileMaxSize = entry.getFieldByCode( IEntryTypeService.FIELD_FILE_MAX_SIZE );
79          int nMaxSize = GenericAttributesUtils.CONSTANT_ID_NULL;
80  
81          if ( ( fieldFileMaxSize != null ) && StringUtils.isNotBlank( fieldFileMaxSize.getValue( ) ) && StringUtils.isNumeric( fieldFileMaxSize.getValue( ) ) )
82          {
83              nMaxSize = GenericAttributesUtils.convertStringToInt( fieldFileMaxSize.getValue( ) );
84          }
85  
86          // If no max size defined in the db, then fetch the default max size from the
87          // properties file
88          if ( nMaxSize == GenericAttributesUtils.CONSTANT_ID_NULL )
89          {
90              nMaxSize = AppPropertiesService.getPropertyInt( PROPERTY_UPLOAD_FILE_DEFAULT_MAX_SIZE, 5242880 );
91          }
92  
93          // If nMaxSize == -1, then no size limit
94          if ( ( nMaxSize != GenericAttributesUtils.CONSTANT_ID_NULL ) && ( listFileItemsToUpload != null ) && ( listUploadedFileItems != null ) )
95          {
96              boolean bHasFileMaxSizeError = false;
97              List<FileItem> listFileItems = new ArrayList<>( );
98              listFileItems.addAll( listUploadedFileItems );
99              listFileItems.addAll( listFileItemsToUpload );
100 
101             for ( FileItem fileItem : listFileItems )
102             {
103                 if ( fileItem.getSize( ) > nMaxSize )
104                 {
105                     bHasFileMaxSizeError = true;
106 
107                     break;
108                 }
109             }
110 
111             if ( bHasFileMaxSizeError )
112             {
113                 Object [ ] params = {
114                         nMaxSize
115                 };
116                 String strMessage = I18nService.getLocalizedString( PROPERTY_MESSAGE_ERROR_UPLOADING_FILE_FILE_MAX_SIZE, params, locale );
117                 error = new GenericAttributeError( );
118                 error.setMandatoryError( false );
119                 error.setTitleQuestion( entry.getTitle( ) );
120                 error.setErrorMessage( strMessage );
121             }
122         }
123         return error;
124     }
125 
126     public static GenericAttributeError checkNumberFiles( Entry entry, List<FileItem> listUploadedFileItems, List<FileItem> listFileItemsToUpload,
127             Locale locale )
128     {
129         GenericAttributeError error = null;
130         Field fieldMaxFiles = entry.getFieldByCode( IEntryTypeService.FIELD_MAX_FILES );
131 
132         // By default, max file is set at 1
133         int nMaxFiles = 1;
134 
135         if ( ( fieldMaxFiles != null ) && StringUtils.isNotBlank( fieldMaxFiles.getValue( ) ) && StringUtils.isNumeric( fieldMaxFiles.getValue( ) ) )
136         {
137             nMaxFiles = GenericAttributesUtils.convertStringToInt( fieldMaxFiles.getValue( ) );
138         }
139 
140         if ( ( listUploadedFileItems != null ) && ( listFileItemsToUpload != null ) )
141         {
142             int nNbFiles = listUploadedFileItems.size( ) + listFileItemsToUpload.size( );
143 
144             if ( nNbFiles > nMaxFiles )
145             {
146                 Object [ ] params = {
147                         nMaxFiles
148                 };
149                 String strMessage = I18nService.getLocalizedString( PROPERTY_MESSAGE_ERROR_UPLOADING_FILE_MAX_FILES, params, locale );
150                 error = new GenericAttributeError( );
151                 error.setMandatoryError( false );
152                 error.setTitleQuestion( entry.getTitle( ) );
153                 error.setErrorMessage( strMessage );
154 
155                 return error;
156             }
157         }
158 
159         return error;
160     }
161 
162     /**
163      * Check the entry data
164      * 
165      * @param request
166      *            the HTTP request
167      * @param locale
168      *            the locale
169      * @return the error message url if there is an error, an empty string otherwise
170      */
171     public static String checkEntryData( HttpServletRequest request, Locale locale )
172     {
173         String strTitle = request.getParameter( IEntryTypeService.PARAMETER_TITLE );
174         String strMaxFiles = request.getParameter( IEntryTypeService.PARAMETER_MAX_FILES );
175         String strFileMaxSize = request.getParameter( IEntryTypeService.PARAMETER_FILE_MAX_SIZE );
176         String strFieldError = StringUtils.EMPTY;
177 
178         if ( StringUtils.isBlank( strTitle ) )
179         {
180             strFieldError = IEntryTypeService.ERROR_FIELD_TITLE;
181         }
182         else
183             if ( StringUtils.isBlank( strMaxFiles ) )
184             {
185                 strFieldError = IEntryTypeService.ERROR_FIELD_MAX_FILES;
186             }
187             else
188                 if ( StringUtils.isBlank( strFileMaxSize ) )
189                 {
190                     strFieldError = IEntryTypeService.ERROR_FIELD_FILE_MAX_SIZE;
191                 }
192 
193         if ( StringUtils.isNotBlank( strFieldError ) )
194         {
195             Object [ ] tabRequiredFields = {
196                     I18nService.getLocalizedString( strFieldError, locale )
197             };
198 
199             return AdminMessageService.getMessageUrl( request, IEntryTypeService.MESSAGE_MANDATORY_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
200         }
201 
202         if ( !StringUtils.isNumeric( strMaxFiles ) )
203         {
204             strFieldError = IEntryTypeService.ERROR_FIELD_MAX_FILES;
205         }
206         else
207             if ( !StringUtils.isNumeric( strFileMaxSize ) )
208             {
209                 strFieldError = IEntryTypeService.ERROR_FIELD_FILE_MAX_SIZE;
210             }
211 
212         if ( StringUtils.isNotBlank( strFieldError ) )
213         {
214             Object [ ] tabRequiredFields = {
215                     I18nService.getLocalizedString( strFieldError, locale )
216             };
217 
218             return AdminMessageService.getMessageUrl( request, IEntryTypeService.MESSAGE_NUMERIC_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
219         }
220 
221         return StringUtils.EMPTY;
222     }
223 
224     /**
225      * Check the record field data
226      * 
227      * @param entry
228      *            The entry
229      * @param listFilesSource
230      *            the list of source files to upload
231      * @param locale
232      *            the locale
233      * @return The error if there is any
234      */
235     public static GenericAttributeError checkResponseData( Entry entry, List<FileItem> listFilesSource, Locale locale )
236     {
237         for ( FileItem fileSource : listFilesSource )
238         {
239             // Check mandatory attribute
240             String strFilename = Optional.ofNullable( fileSource ).map( FileUploadService::getFileNameOnly ).orElse( StringUtils.EMPTY );
241 
242             if ( entry.isMandatory( ) && StringUtils.isBlank( strFilename ) )
243             {
244                 return new MandatoryError( entry, locale );
245             }
246 
247             String strMimeType = FileSystemUtil.getMIMEType( strFilename );
248 
249             // Check mime type with regular expressions
250             List<RegularExpression> listRegularExpression = entry.getFields( ).get( 0 ).getRegularExpressionList( );
251 
252             if ( StringUtils.isNotBlank( strFilename ) && CollectionUtils.isNotEmpty( listRegularExpression )
253                     && RegularExpressionService.getInstance( ).isAvailable( ) )
254             {
255                 for ( RegularExpression regularExpression : listRegularExpression )
256                 {
257                     if ( !RegularExpressionService.getInstance( ).isMatches( strMimeType, regularExpression ) )
258                     {
259                         GenericAttributeErrorbutes/business/GenericAttributeError.html#GenericAttributeError">GenericAttributeError error = new GenericAttributeError( );
260                         error.setMandatoryError( false );
261                         error.setTitleQuestion( entry.getTitle( ) );
262                         error.setErrorMessage( regularExpression.getErrorMessage( ) );
263 
264                         return error;
265                     }
266                 }
267             }
268         }
269 
270         return null;
271     }
272 
273     /**
274      * Set the list of fields
275      * 
276      * @param entry
277      *            The entry
278      * @param request
279      *            the HTTP request
280      */
281     public static void createOrUpdateFileFields( Entry entry, HttpServletRequest request )
282     {
283         String strFileMaxSize = request.getParameter( IEntryTypeService.PARAMETER_FILE_MAX_SIZE );
284         int nFileMaxSize = GenericAttributesUtils.convertStringToInt( strFileMaxSize );
285 
286         String strMaxFiles = request.getParameter( IEntryTypeService.PARAMETER_MAX_FILES );
287         int nMaxFiles = GenericAttributesUtils.convertStringToInt( strMaxFiles );
288 
289         String strExportBinary = request.getParameter( IEntryTypeService.PARAMETER_EXPORT_BINARY );
290 
291         GenericAttributesUtils.createOrUpdateField( entry, IEntryTypeService.FIELD_FILE_MAX_SIZE, null, String.valueOf( nFileMaxSize ) );
292         GenericAttributesUtils.createOrUpdateField( entry, IEntryTypeService.FIELD_MAX_FILES, null, String.valueOf( nMaxFiles ) );
293         GenericAttributesUtils.createOrUpdateField( entry, IEntryTypeService.FIELD_FILE_BINARY, null,
294                 Boolean.toString( StringUtils.isNotBlank( strExportBinary ) ) );
295     }
296 }