View Javadoc
1   /*
2    * Copyright (c) 2002-2023, 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.document.web;
35  
36  import fr.paris.lutece.plugins.document.business.DocumentResource;
37  import fr.paris.lutece.plugins.document.business.DocumentType;
38  import fr.paris.lutece.plugins.document.business.DocumentTypeHome;
39  import fr.paris.lutece.plugins.document.business.attributes.AttributeTypeHome;
40  import fr.paris.lutece.plugins.document.business.attributes.AttributeTypeParameter;
41  import fr.paris.lutece.plugins.document.business.attributes.DocumentAttribute;
42  import fr.paris.lutece.plugins.document.business.attributes.DocumentAttributeHome;
43  import fr.paris.lutece.plugins.document.service.AttributeManager;
44  import fr.paris.lutece.plugins.document.service.AttributeService;
45  import fr.paris.lutece.plugins.document.service.metadata.MetadataService;
46  import fr.paris.lutece.plugins.document.utils.IntegerUtils;
47  import fr.paris.lutece.portal.business.regularexpression.RegularExpression;
48  import fr.paris.lutece.portal.service.cache.CacheService;
49  import fr.paris.lutece.portal.service.fileupload.FileUploadService;
50  import fr.paris.lutece.portal.service.i18n.I18nService;
51  import fr.paris.lutece.portal.service.message.AdminMessage;
52  import fr.paris.lutece.portal.service.message.AdminMessageService;
53  import fr.paris.lutece.portal.service.regularexpression.RegularExpressionService;
54  import fr.paris.lutece.portal.service.template.AppTemplateService;
55  import fr.paris.lutece.portal.service.util.AppPropertiesService;
56  import fr.paris.lutece.portal.web.admin.PluginAdminPageJspBean;
57  import fr.paris.lutece.portal.web.constants.Messages;
58  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
59  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
60  import fr.paris.lutece.util.ReferenceList;
61  import fr.paris.lutece.util.html.HtmlTemplate;
62  import fr.paris.lutece.util.html.Paginator;
63  import fr.paris.lutece.util.string.StringUtil;
64  import fr.paris.lutece.util.url.UrlItem;
65  
66  import org.apache.commons.fileupload.FileItem;
67  import org.apache.commons.lang3.StringUtils;
68  
69  import org.xml.sax.InputSource;
70  
71  import java.io.ByteArrayInputStream;
72  
73  import java.util.ArrayList;
74  import java.util.Arrays;
75  import java.util.HashMap;
76  import java.util.List;
77  import java.util.Map;
78  
79  import javax.servlet.http.HttpServletRequest;
80  
81  import javax.xml.parsers.SAXParser;
82  import javax.xml.parsers.SAXParserFactory;
83  
84  
85  /**
86   * JSP Bean for document type management
87   */
88  public class DocumentTypeJspBean extends PluginAdminPageJspBean
89  {
90      public static final String RIGHT_DOCUMENT_TYPES_MANAGEMENT = "DOCUMENT_TYPES_MANAGEMENT";
91      private static final String TEMPLATE_MANAGE_DOCUMENT_TYPES = "admin/plugins/document/manage_document_types.html";
92      private static final String TEMPLATE_CREATE_DOCUMENT_TYPE = "admin/plugins/document/create_document_type.html";
93      private static final String TEMPLATE_MODIFY_DOCUMENT_TYPE = "admin/plugins/document/modify_document_type.html";
94      private static final String TEMPLATE_ADD_ATTRIBUTE = "admin/plugins/document/add_document_type_attribute.html";
95      private static final String TEMPLATE_MODIFY_ATTRIBUTE = "admin/plugins/document/modify_document_type_attribute.html";
96      private static final String PROPERTY_PAGE_TITLE_CREATE_DOCUMENT_TYPE = "document.create_document_type.pageTitle";
97      private static final String PROPERTY_PAGE_TITLE_MODIFY_DOCUMENT_TYPE = "document.modify_document_type.pageTitle";
98      private static final String PROPERTY_PAGE_TITLE_ADD_ATTRIBUTE = "document.add_document_type_attribute.pageTitle";
99      private static final String PROPERTY_PAGE_TITLE_MODIFY_ATTRIBUTE = "document.modify_document_type_attribute.pageTitle";
100     private static final String PROPERTY_CANNOT_DELETE_DOCUMENTS = "document.message.cannotRemoveTypeDocuments";
101     private static final String PROPERTY_CONFIRM_DELETE_TYPE = "document.message.confirmDeleteType";
102     private static final String PROPERTY_CONFIRM_DELETE_ATTRIBUTE = "document.message.confirmDeleteAttribute";
103     private static final String PROPERTY_NO_THUMBNAIL_ATTRIBUTE = "document.documentType.noThumbnailAttribute";
104     private static final String PROPERTY_CODE_ATTRIBUTE_BAD_FORMAT_CREATE = "document.add_document_type_attribute.codeAttribute.badFormat";
105     private static final String PROPERTY_CODE_ATTRIBUTE_BAD_FORMAT_MODIFY = "document.modify_document_type_attribute.codeAttribute.badFormat";
106     private static final String PROPERTY_REGULAR_EXPRESSION_PER_PAGE = "document.regularExpressionPerPage";
107     private static final String MESSAGE_DOCUMENT_ALREADY_EXIST = "document.message.documentType.errorAlreadyExist";
108     private static final String MARK_DOCUMENT_TYPES_LIST = "document_types_list";
109     private static final String MARK_THUMBNAIL_ATTRIBUTES_LIST = "thumbnail_attributes_list";
110     private static final String MARK_DOCUMENT_TYPE = "document_type";
111     private static final String MARK_ATTRIBUTE_TYPES_LIST = "attribute_types_list";
112     private static final String MARK_DOCUMENT_TYPE_CODE = "document_type_code";
113     private static final String MARK_ATTRIBUTE_TYPE_CODE = "attribute_type_code";
114     private static final String MARK_ATTRIBUTE_TYPE_NAME = "attribute_type_name";
115     private static final String MARK_ATTRIBUTE_EXTRAS_PARAMETERS = "attribute_parameters";
116     private static final String MARK_ATTRIBUTE = "attribute";
117     private static final String MARK_METADATA_HANDLERS_LIST = "metadata_handlers_list";
118     private static final String MARK_REGULAR_EXPRESSION_TO_ADD_LIST = "regular_expression_to_add_list";
119     private static final String MARK_REGULAR_EXPRESSION_ADDED_LIST = "regular_expression_added_list";
120     private static final String MARK_PAGINATOR = "paginator";
121     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
122     private static final String MARK_NB_REGULAR_EXPRESSION = "nb_regular_expression";
123     private static final String PARAMETER_DOCUMENT_TYPE_CODE = "document_type_code";
124     private static final String PARAMETER_NAME = "name";
125     private static final String PARAMETER_OLD_CODE = "old_code";
126     private static final String PARAMETER_CODE = "code";
127     private static final String PARAMETER_DESCRIPTION = "description";
128     private static final String PARAMETER_THUMBNAIL_ATTRIBUTE = "thumbnail_attribute";
129     private static final String PARAMETER_ICON_URL = "icon_url";
130     private static final String PARAMETER_REQUIRED = "required";
131     private static final String PARAMETER_SEARCHABLE = "searchable";
132     private static final String PARAMETER_ATTRIBUTE_TYPE_CODE = "attribute_type_code";
133     private static final String PARAMETER_ATTRIBUTE_ID = "attribute_id";
134     private static final String PARAMETER_INDEX = "index";
135     private static final String PARAMETER_METADATA = "metadata";
136     private static final String PARAMETER_STYLESHEET_TYPE = "stylesheet_type";
137     private static final String PARAMETER_STYLESHEET_ADMIN = "stylesheet_admin";
138     private static final String PARAMETER_STYLESHEET_CONTENT = "stylesheet_content";
139     private static final String PARAMETER_UPDATE_STYLESHEET_ADMIN = "stylesheet_admin_update";
140     private static final String PARAMETER_UPDATE_STYLESHEET_CONTENT = "stylesheet_content_update";
141     private static final String PARAMETER_EXPRESSION_ID = "expression_id";
142     private static final String PARAMETER_APPLY = "apply";
143     private static final String PARAMETER_CANCEL = "cancel";
144     private static final String PARAMETER_SAVE = "save";
145     private static final String PARAMETER_SESSION = "session";
146     private static final String JSP_MODIFY_DOCUMENT_TYPE = "ModifyDocumentType.jsp";
147     private static final String JSP_DELETE_DOCUMENT_TYPE = "jsp/admin/plugins/document/DoDeleteDocumentType.jsp";
148     private static final String JSP_DELETE_ATTRIBUTE = "jsp/admin/plugins/document/DoDeleteAttribute.jsp";
149     private static final String JSP_MODIFY_DOCUMENT_TYPE_ATTRIBUTE = "ModifyDocumentTypeAttribute.jsp";
150     private static final String JSP_ADD_DOCUMENT_TYPE_ATTRIBUTE = "AddDocumentTypeAttribute.jsp";
151     private static final String MESSAGE_STYLESHEET_NOT_VALID = "portal.style.message.stylesheetNotValid";
152     private static final String CHECK_ON = "on";
153     private static final String STYLESHEET_CONTENT_TYPE = "text/plain";
154     private static final String SEPARATOR = "_";
155     private static final String FILE_EXTENSION = ".xsl";
156     private static final Object UPDATE_VALUE = "true";
157     private static final String PATTERN_CODE = "[a-zA-Z0-9_\\-]+";
158     private static final int NO_THUMBNAIL_ATTRIBUTE = 0;
159     private String _strDocumentTypeCode;
160     private int _nItemsPerPage;
161     private int _nDefaultItemsPerPage;
162     private String _strCurrentPageIndex;
163     private DocumentAttribute _attribute;
164 
165     /**
166      * Gets the Document Types Management Page
167      * @param request The HTTP request
168      * @return The Document Types Management Page
169      */
170     public String getManageDocumentTypes( HttpServletRequest request )
171     {
172         Map<String, Object> model = new HashMap<String, Object>(  );
173         model.put( MARK_DOCUMENT_TYPES_LIST, DocumentTypeHome.findAll(  ) );
174 
175         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_DOCUMENT_TYPES, getLocale(  ), model );
176 
177         return getAdminPage( template.getHtml(  ) );
178     }
179 
180     /**
181      * Gets the document type creation page
182      * @param request The HTTP request
183      * @return The document type creation page
184      */
185     public String getCreateDocumentType( HttpServletRequest request )
186     {
187         setPageTitleProperty( PROPERTY_PAGE_TITLE_CREATE_DOCUMENT_TYPE );
188 
189         Map<String, Object> model = new HashMap<String, Object>(  );
190         model.put( MARK_METADATA_HANDLERS_LIST, MetadataService.getMetadataHandlersList(  ) );
191 
192         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_DOCUMENT_TYPE, getLocale(  ), model );
193 
194         return getAdminPage( template.getHtml(  ) );
195     }
196 
197     /**
198      * Perform the document type creation
199      * @param request The HTTP request
200      * @return The URL to go after performing the action
201      */
202     public String doCreateDocumentType( HttpServletRequest request )
203     {
204         String strName = request.getParameter( PARAMETER_NAME );
205         String strDescription = request.getParameter( PARAMETER_DESCRIPTION );
206         String strCode = request.getParameter( PARAMETER_CODE );
207         String strMetadata = request.getParameter( PARAMETER_METADATA );
208 
209         // Mandatory fields
210         if ( StringUtils.isBlank( strName ) || StringUtils.isBlank( strDescription ) || StringUtils.isBlank( strCode ) )
211         {
212             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
213         }
214 
215         // Check Accentuated Character
216         if ( !checkDocumentTypeCodePattern( strCode ) )
217         {
218             return AdminMessageService.getMessageUrl( request, Messages.MESSAGE_STRING_FORMAT, AdminMessage.TYPE_STOP );
219         }
220 
221         if ( DocumentTypeHome.findByPrimaryKey( strCode ) != null )
222         {
223             return AdminMessageService.getMessageUrl( request, MESSAGE_DOCUMENT_ALREADY_EXIST, AdminMessage.TYPE_STOP );
224         }
225 
226         DocumentTypeusiness/DocumentType.html#DocumentType">DocumentType documentType = new DocumentType(  );
227         documentType.setName( strName );
228         documentType.setCode( strCode );
229         documentType.setDescription( strDescription );
230         documentType.setMetadataHandler( strMetadata );
231         DocumentTypeHome.create( documentType );
232 
233         return JSP_MODIFY_DOCUMENT_TYPE + "?document_type_code=" + strCode;
234     }
235 
236     /**
237      * Gets the document type modification page
238      * @param request The HTTP request
239      * @return The document type modification page
240      */
241     public String getModifyDocumentType( HttpServletRequest request )
242     {
243         setPageTitleProperty( PROPERTY_PAGE_TITLE_MODIFY_DOCUMENT_TYPE );
244 
245         String strDocumentTypeCode = request.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
246 
247         if ( strDocumentTypeCode != null )
248         {
249             _strDocumentTypeCode = strDocumentTypeCode;
250         }
251         else
252         {
253             strDocumentTypeCode = _strDocumentTypeCode;
254         }
255 
256         DocumentType documentType = DocumentTypeHome.findByPrimaryKey( strDocumentTypeCode );
257 
258         if ( documentType == null )
259         {
260             return getManageDocumentTypes( request );
261         }
262 
263         ReferenceList listAttributeTypes = AttributeTypeHome.getAttributeTypesList( getLocale(  ) );
264         Map<String, Object> model = new HashMap<String, Object>(  );
265         model.put( MARK_DOCUMENT_TYPE, documentType );
266         model.put( MARK_THUMBNAIL_ATTRIBUTES_LIST, getThumbnailAttributesList( documentType ) );
267         model.put( MARK_METADATA_HANDLERS_LIST, MetadataService.getMetadataHandlersList(  ) );
268         model.put( MARK_ATTRIBUTE_TYPES_LIST, listAttributeTypes );
269 
270         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_DOCUMENT_TYPE, getLocale(  ), model );
271 
272         return getAdminPage( template.getHtml(  ) );
273     }
274 
275     /**
276      * Perform document type modification creation
277      * @param request The HTTP request
278      * @return The URL to go after performing the action
279      */
280     public String doModifyDocumentType( HttpServletRequest request )
281     {
282         String strOldCode = request.getParameter( PARAMETER_OLD_CODE );
283         String strCode = request.getParameter( PARAMETER_CODE );
284         String strName = request.getParameter( PARAMETER_NAME );
285         String strDescription = request.getParameter( PARAMETER_DESCRIPTION );
286         String strIconUrl = request.getParameter( PARAMETER_ICON_URL );
287         String strThumbnailAttribute = request.getParameter( PARAMETER_THUMBNAIL_ATTRIBUTE );
288         int nThumbnailAttribute = IntegerUtils.convert( strThumbnailAttribute );
289         String strMetadata = request.getParameter( PARAMETER_METADATA );
290 
291         // Check Accentuated Character
292         if ( !checkDocumentTypeCodePattern( strCode ) )
293         {
294             return AdminMessageService.getMessageUrl( request, Messages.MESSAGE_STRING_FORMAT, AdminMessage.TYPE_STOP );
295         }
296 
297         // Mandatory fields
298         if ( StringUtils.isBlank( strName ) || StringUtils.isBlank( strDescription ) || StringUtils.isBlank( strCode ) )
299         {
300             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, AdminMessage.TYPE_STOP );
301         }
302 
303         DocumentType documentType = DocumentTypeHome.findByPrimaryKey( strOldCode );
304         documentType.setOldCode( strOldCode );
305         documentType.setCode( strCode );
306         documentType.setName( strName );
307         documentType.setDefaultThumbnailUrl( strIconUrl );
308         documentType.setThumbnailAttributeId( nThumbnailAttribute );
309         documentType.setDescription( strDescription );
310         documentType.setMetadataHandler( strMetadata );
311         DocumentTypeHome.update( documentType );
312 
313         return getHomeUrl( request );
314     }
315 
316     /**
317      * Gets ttribute creation page
318      * @param request The HTTP request
319      * @return the html template
320      */
321     public String getAddAttribute( HttpServletRequest request )
322     {
323         setPageTitleProperty( PROPERTY_PAGE_TITLE_ADD_ATTRIBUTE );
324 
325         String strAttributeTypeCode = request.getParameter( PARAMETER_ATTRIBUTE_TYPE_CODE );
326         AttributeManager manager = AttributeService.getInstance(  ).getManager( strAttributeTypeCode );
327         _strDocumentTypeCode = request.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
328 
329         Map<String, Object> model = new HashMap<String, Object>(  );
330         model.put( MARK_ATTRIBUTE_TYPE_CODE, strAttributeTypeCode );
331 
332         //        model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS , manager.getExtraParameters(  getLocale() ) );
333         String strSession = request.getParameter( PARAMETER_SESSION );
334 
335         if ( StringUtils.isNotBlank( strSession ) )
336         {
337             model.put( MARK_ATTRIBUTE, _attribute );
338             model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS,
339                 manager.getCreateParametersFormHtml( _attribute.getParameters(  ), getLocale(  ) ) );
340         }
341         else
342         {
343             _attribute = new DocumentAttribute(  );
344             model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS, manager.getCreateParametersFormHtml( getLocale(  ) ) );
345         }
346 
347         ReferenceList listAttributeTypes = AttributeTypeHome.getAttributeTypesList( getLocale(  ) );
348         model.put(MARK_ATTRIBUTE_TYPE_NAME, listAttributeTypes.toMap( ).get(strAttributeTypeCode) );
349 
350         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADD_ATTRIBUTE, getLocale(  ), model );
351 
352         return getAdminPage( template.getHtml(  ) );
353     }
354 
355     /**
356      * Perform attribute creation
357      * @param request The HTTP request
358      * @return The URL to go after performing the action
359      */
360     public String doAddAttribute( HttpServletRequest request )
361     {
362         _attribute = new DocumentAttribute(  );
363 
364         boolean bIsValid = validateCodeAttribute( request );
365 
366         if ( !bIsValid )
367         {
368             return AdminMessageService.getMessageUrl( request, PROPERTY_CODE_ATTRIBUTE_BAD_FORMAT_CREATE,
369                 AdminMessage.TYPE_STOP );
370         }
371 
372         getAttributeData( request, _attribute );
373 
374         // The user has not clicked on "save", then there are some operations to proceed
375         String strSave = request.getParameter( PARAMETER_SAVE );
376 
377         if ( StringUtils.isBlank( strSave ) )
378         {
379             String strAttributeTypeCode = request.getParameter( PARAMETER_ATTRIBUTE_TYPE_CODE );
380             UrlItem url = new UrlItem( JSP_ADD_DOCUMENT_TYPE_ATTRIBUTE );
381             url.addParameter( PARAMETER_SESSION, PARAMETER_SESSION );
382             url.addParameter( PARAMETER_ATTRIBUTE_TYPE_CODE, strAttributeTypeCode );
383             url.addParameter( PARAMETER_DOCUMENT_TYPE_CODE, _strDocumentTypeCode );
384 
385             return url.getUrl(  );
386         }
387 
388         String strValidateMessage = getAttributeValidationMessage( _attribute );
389 
390         if ( strValidateMessage != null )
391         {
392             return AdminMessageService.getMessageUrl( request, strValidateMessage, AdminMessage.TYPE_STOP );
393         }
394 
395         DocumentAttributeHome.create( _attribute );
396 
397         if ( request.getParameter( PARAMETER_APPLY ) != null )
398         {
399             UrlItem url = new UrlItem( JSP_MODIFY_DOCUMENT_TYPE_ATTRIBUTE );
400             url.addParameter( PARAMETER_ATTRIBUTE_ID, _attribute.getId(  ) );
401 
402             return url.getUrl(  );
403         }
404 
405         return JSP_MODIFY_DOCUMENT_TYPE;
406     }
407 
408     /**
409      * Perform attribute modification
410      * @param request The HTTP request
411      * @return The URL to go after performing the action
412      */
413     public String doModifyAttribute( HttpServletRequest request )
414     {
415         if ( request.getParameter( PARAMETER_CANCEL ) != null )
416         {
417             UrlItem url = new UrlItem( JSP_MODIFY_DOCUMENT_TYPE );
418 
419             return url.getUrl(  );
420         }
421 
422         String strAttributeId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
423         int nAttributeId = IntegerUtils.convert( strAttributeId );
424         _attribute = DocumentAttributeHome.findByPrimaryKey( nAttributeId );
425 
426         boolean bIsValid = validateCodeAttribute( request );
427 
428         if ( !bIsValid )
429         {
430             return AdminMessageService.getMessageUrl( request, PROPERTY_CODE_ATTRIBUTE_BAD_FORMAT_MODIFY,
431                 AdminMessage.TYPE_STOP );
432         }
433 
434         getAttributeData( request, _attribute );
435 
436         // The user has not clicked on "save", then there are some operations to proceed
437         String strSave = request.getParameter( PARAMETER_SAVE );
438 
439         if ( StringUtils.isBlank( strSave ) )
440         {
441             UrlItem url = new UrlItem( JSP_MODIFY_DOCUMENT_TYPE_ATTRIBUTE );
442             url.addParameter( PARAMETER_SESSION, PARAMETER_SESSION );
443             url.addParameter( PARAMETER_ATTRIBUTE_ID, nAttributeId );
444 
445             return url.getUrl(  );
446         }
447 
448         String strValidateMessage = getAttributeValidationMessage( _attribute );
449 
450         if ( strValidateMessage != null )
451         {
452             return AdminMessageService.getMessageUrl( request, strValidateMessage, AdminMessage.TYPE_STOP );
453         }
454 
455         DocumentAttributeHome.update( _attribute );
456 
457         return JSP_MODIFY_DOCUMENT_TYPE;
458     }
459 
460     private void getAttributeData( HttpServletRequest request, DocumentAttribute attribute )
461     {
462         String strName = request.getParameter( PARAMETER_NAME );
463         String strCode = request.getParameter( PARAMETER_CODE ).trim(  ).toLowerCase(  );
464         String strDescription = request.getParameter( PARAMETER_DESCRIPTION );
465         String strRequired = request.getParameter( PARAMETER_REQUIRED );
466         String strSearchable = request.getParameter( PARAMETER_SEARCHABLE );
467         String strAttributeTypeCode = request.getParameter( PARAMETER_ATTRIBUTE_TYPE_CODE );
468         String[] arrayStrValues;
469         List<String> listValues = new ArrayList<String>(  );
470         List<AttributeTypeParameter> listParameters;
471         AttributeManager manager = AttributeService.getInstance(  ).getManager( strAttributeTypeCode );
472 
473         String strSave = request.getParameter( PARAMETER_SAVE );
474 
475         if ( StringUtils.isBlank( strSave ) )
476         {
477             listParameters = manager.getValueParameters( request, getLocale(  ) );
478         }
479         else
480         {
481             listParameters = manager.getExtraParameters( getLocale(  ) );
482 
483             for ( AttributeTypeParameter parameter : listParameters )
484             {
485                 arrayStrValues = request.getParameterValues( parameter.getName(  ) );
486 
487                 if ( arrayStrValues != null )
488                 {
489                     listValues.addAll( Arrays.asList( arrayStrValues ) );
490                 }
491 
492                 parameter.setValueList( listValues );
493                 listValues.clear(  );
494             }
495         }
496 
497         attribute.setName( strName );
498         attribute.setCode( strCode );
499         attribute.setDescription( strDescription );
500         attribute.setRequired( ( strRequired != null ) && ( strRequired.equals( CHECK_ON ) ) );
501         attribute.setSearchable( ( strSearchable != null ) && ( strSearchable.equals( CHECK_ON ) ) );
502         attribute.setCodeDocumentType( _strDocumentTypeCode );
503         attribute.setCodeAttributeType( strAttributeTypeCode );
504 
505         if ( attribute.getAttributeOrder(  ) == 0 )
506         {
507             // Order is not defined (creation). Put this attribute at the end of the list
508             DocumentType documentType = DocumentTypeHome.findByPrimaryKey( _strDocumentTypeCode );
509             attribute.setAttributeOrder( documentType.getAttributes(  ).size(  ) + 1 );
510         }
511 
512         attribute.setParameters( listParameters );
513     }
514 
515     /**
516      * Validate if the code has no spaces and no caps
517      * @param request the HTTPrequest
518      * @return true if the codeAttribute is valid, false otherwise
519      */
520     private boolean validateCodeAttribute( HttpServletRequest request )
521     {
522         String strCode = request.getParameter( PARAMETER_CODE ).trim(  ).toLowerCase(  );
523 
524         if ( ( strCode != null ) && ( strCode.length(  ) == 0 ) )
525         {
526             return true;
527         }
528 
529         boolean isOK = false;
530 
531         if ( ( strCode != null ) && ( strCode.length(  ) > 0 ) )
532         {
533             isOK = StringUtil.checkCodeKey( strCode );
534         }
535 
536         return isOK;
537     }
538 
539     private String getAttributeValidationMessage( DocumentAttribute attribute )
540     {
541         String strMessage = null;
542 
543         // Mandatory fields
544         if ( StringUtils.isBlank( attribute.getName(  ) ) || StringUtils.isBlank( attribute.getDescription(  ) ) ||
545                 StringUtils.isBlank( attribute.getCode(  ) ) )
546         {
547             return Messages.MANDATORY_FIELDS;
548         }
549 
550         AttributeManager manager = AttributeService.getInstance(  ).getManager( attribute.getCodeAttributeType(  ) );
551         String strValidationErrorMessageKey = manager.validateValueParameters( attribute.getParameters(  ),
552                 getLocale(  ) );
553 
554         if ( strValidationErrorMessageKey != null )
555         {
556             return strValidationErrorMessageKey;
557         }
558 
559         return strMessage;
560     }
561 
562     /**
563      * Gets the modification page
564      * @param request The HTTP request
565      * @return The modification page
566      */
567     public String getModifyAttribute( HttpServletRequest request )
568     {
569         setPageTitleProperty( PROPERTY_PAGE_TITLE_MODIFY_ATTRIBUTE );
570 
571         String strAttributeId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
572         int nAttributeId = IntegerUtils.convert( strAttributeId );
573         DocumentAttribute attribute = DocumentAttributeHome.findByPrimaryKey( nAttributeId );
574 
575         if ( attribute == null )
576         {
577             return getManageDocumentTypes( request );
578         }
579 
580         AttributeManager manager = AttributeService.getInstance(  ).getManager( attribute.getCodeAttributeType(  ) );
581 
582         UrlItem url = new UrlItem( request.getRequestURI(  ) );
583         url.addParameter( PARAMETER_ATTRIBUTE_ID, nAttributeId );
584 
585         ReferenceList refListRegularExpressionToAdd = new ReferenceList(  );
586         List<RegularExpression> listRegularExpressionAdded = new ArrayList<RegularExpression>(  );
587 
588         // Checks if the regularexpression plugin is enabled
589         if ( RegularExpressionService.getInstance(  ).isAvailable(  ) )
590         {
591             // Gets the list of regular expressions already added
592             for ( Integer nExpressionId : DocumentAttributeHome.getListRegularExpressionKeyByIdAttribute( nAttributeId ) )
593             {
594                 listRegularExpressionAdded.add( RegularExpressionService.getInstance(  )
595                                                                         .getRegularExpressionByKey( nExpressionId ) );
596             }
597 
598             // Defines the reference list of regular expressions which could be added
599             for ( RegularExpression regularExpression : RegularExpressionService.getInstance(  )
600                                                                                 .getAllRegularExpression(  ) )
601             {
602                 if ( !listRegularExpressionAdded.contains( regularExpression ) )
603                 {
604                     refListRegularExpressionToAdd.addItem( regularExpression.getIdExpression(  ),
605                         regularExpression.getTitle(  ) );
606                 }
607             }
608         }
609 
610         // Paginator
611         _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
612         _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_REGULAR_EXPRESSION_PER_PAGE, 10 );
613         _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage,
614                 _nDefaultItemsPerPage );
615 
616         LocalizedPaginator<RegularExpression> paginator = new LocalizedPaginator<RegularExpression>( listRegularExpressionAdded,
617                 _nItemsPerPage, url.getUrl(  ), Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex, getLocale(  ) );
618 
619         Map<String, Object> model = new HashMap<String, Object>(  );
620 
621         model.put( MARK_DOCUMENT_TYPE_CODE, _strDocumentTypeCode );
622         model.put( MARK_ATTRIBUTE_TYPE_CODE, attribute.getCodeAttributeType(  ) );
623 
624         //        model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS , listParameters );
625         String strSession = request.getParameter( PARAMETER_SESSION );
626 
627         if ( StringUtils.isNotBlank( strSession ) )
628         {
629             model.put( MARK_ATTRIBUTE, _attribute );
630             model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS,
631                 manager.getCreateParametersFormHtml( _attribute.getParameters(  ), getLocale(  ) ) );
632         }
633         else
634         {
635             _attribute = new DocumentAttribute(  );
636             model.put( MARK_ATTRIBUTE, attribute );
637             model.put( MARK_ATTRIBUTE_EXTRAS_PARAMETERS,
638                 manager.getModifyParametersFormHtml( getLocale(  ), nAttributeId ) );
639         }
640 
641         // Regular expressions
642         model.put( MARK_REGULAR_EXPRESSION_TO_ADD_LIST, refListRegularExpressionToAdd );
643         model.put( MARK_PAGINATOR, paginator );
644         model.put( MARK_REGULAR_EXPRESSION_ADDED_LIST, paginator.getPageItems(  ) );
645         model.put( MARK_NB_ITEMS_PER_PAGE, "" + _nItemsPerPage );
646         model.put( MARK_NB_REGULAR_EXPRESSION, paginator.getItemsCount(  ) );
647 
648         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_ATTRIBUTE, getLocale(  ), model );
649 
650         return getAdminPage( template.getHtml(  ) );
651     }
652 
653     /**
654      * Confirm the deletion of a document type
655      * @param request The HTTP request
656      * @return The URL to go after performing the action
657      */
658     public String doConfirmDelete( HttpServletRequest request )
659     {
660         String strCode = request.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
661         String strDeleteUrl = JSP_DELETE_DOCUMENT_TYPE + "?" + PARAMETER_DOCUMENT_TYPE_CODE + "=" + strCode;
662         String strUrl = AdminMessageService.getMessageUrl( request, PROPERTY_CONFIRM_DELETE_TYPE, strDeleteUrl,
663                 AdminMessage.TYPE_CONFIRMATION );
664 
665         // Check if this type has documents
666         if ( DocumentTypeHome.checkDocuments( strCode ) )
667         {
668             strUrl = AdminMessageService.getMessageUrl( request, PROPERTY_CANNOT_DELETE_DOCUMENTS,
669                     AdminMessage.TYPE_STOP );
670         }
671 
672         return strUrl;
673     }
674 
675     /**
676      * Perform the deletion of a document type
677      * @param request The HTTP request
678      * @return The URL to go after performing the action
679      */
680     public String doDeleteDocumentType( HttpServletRequest request )
681     {
682         String strCode = request.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
683 
684         if ( strCode != null )
685         {
686             DocumentType documentType = DocumentTypeHome.findByPrimaryKey( strCode );
687 
688             List<DocumentAttribute> listDocumentAttributes = documentType.getAttributes(  );
689 
690             if ( listDocumentAttributes != null )
691             {
692                 for ( DocumentAttribute docAttribute : listDocumentAttributes )
693                 {
694                     DocumentAttributeHome.remove( docAttribute.getId(  ) );
695                 }
696             }
697 
698             DocumentTypeHome.remove( strCode );
699         }
700 
701         return getHomeUrl( request );
702     }
703 
704     /**
705      * Confirm the deletion of an attribute
706      * @param request The HTTP request
707      * @return The URL to go after performing the action
708      */
709     public String doConfirmDeleteAttribute( HttpServletRequest request )
710     {
711         String strId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
712         String strDeleteUrl = JSP_DELETE_ATTRIBUTE + "?" + PARAMETER_ATTRIBUTE_ID + "=" + strId;
713         String strUrl = AdminMessageService.getMessageUrl( request, PROPERTY_CONFIRM_DELETE_ATTRIBUTE, strDeleteUrl,
714                 AdminMessage.TYPE_CONFIRMATION );
715 
716         return strUrl;
717     }
718 
719     /**
720      * Perform the attribute deletion
721      * @param request The HTTP request
722      * @return The URL to go after performing the action
723      */
724     public String doDeleteAttribute( HttpServletRequest request )
725     {
726         String strId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
727         int nId = IntegerUtils.convert( strId );
728         DocumentAttributeHome.remove( nId );
729 
730         return JSP_MODIFY_DOCUMENT_TYPE;
731     }
732 
733     /**
734      * Perform the move up action
735      * @param request The HTTP request
736      * @return The URL to go after performing the action
737      */
738     public String doAttributeMoveUp( HttpServletRequest request )
739     {
740         String strIndex = request.getParameter( PARAMETER_INDEX );
741         int nIndex = IntegerUtils.convert( strIndex );
742 
743         if ( nIndex > 1 )
744         {
745             DocumentType documentType = DocumentTypeHome.findByPrimaryKey( _strDocumentTypeCode );
746             List<DocumentAttribute> list = documentType.getAttributes(  );
747             DocumentAttribute attribute1 = list.get( nIndex - 1 );
748             DocumentAttribute attribute2 = list.get( nIndex - 2 );
749             DocumentTypeHome.reorderAttributes( attribute1.getId(  ), nIndex - 1, attribute2.getId(  ), nIndex );
750         }
751 
752         return JSP_MODIFY_DOCUMENT_TYPE;
753     }
754 
755     /**
756      * Perform the move down action
757      * @param request The HTTP request
758      * @return The URL to go after performing the action
759      */
760     public String doAttributeMoveDown( HttpServletRequest request )
761     {
762         String strIndex = request.getParameter( PARAMETER_INDEX );
763         int nIndex = IntegerUtils.convert( strIndex );
764         DocumentType documentType = DocumentTypeHome.findByPrimaryKey( _strDocumentTypeCode );
765         List<DocumentAttribute> list = documentType.getAttributes(  );
766 
767         if ( nIndex < list.size(  ) )
768         {
769             DocumentAttribute attribute1 = list.get( nIndex - 1 );
770             DocumentAttribute attribute2 = list.get( nIndex );
771             DocumentTypeHome.reorderAttributes( attribute1.getId(  ), nIndex + 1, attribute2.getId(  ), nIndex );
772         }
773 
774         return JSP_MODIFY_DOCUMENT_TYPE;
775     }
776 
777     /**
778      * Save the uploaded Sytlesheets
779      * @param request The {@link HttpServletRequest}
780      * @return the home url
781      */
782     public String doLoadStyleSheets( HttpServletRequest request )
783     {
784         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
785         String strErrorUrl = getStyleSheets( multipartRequest );
786 
787         if ( strErrorUrl != null )
788         {
789             return strErrorUrl;
790         }
791 
792         //Displays the list of the stylesheet files
793         return getHomeUrl( request );
794     }
795 
796     private ReferenceList getThumbnailAttributesList( DocumentType documentType )
797     {
798         ReferenceList list = new ReferenceList(  );
799 
800         String strNoAttribute = I18nService.getLocalizedString( PROPERTY_NO_THUMBNAIL_ATTRIBUTE, getLocale(  ) );
801         list.addItem( NO_THUMBNAIL_ATTRIBUTE, strNoAttribute );
802 
803         for ( DocumentAttribute attribute : documentType.getAttributes(  ) )
804         {
805             AttributeManager manager = AttributeService.getInstance(  ).getManager( attribute.getCodeAttributeType(  ) );
806 
807             if ( manager.canBeUsedAsThumbnail(  ) )
808             {
809                 list.addItem( attribute.getId(  ), attribute.getName(  ) );
810             }
811         }
812 
813         return list;
814     }
815 
816     /**
817      * Reads stylesheet's data
818      * @param multipartRequest The request
819      * @return An error message URL or null if no error
820      */
821     private String getStyleSheets( MultipartHttpServletRequest multipartRequest )
822     {
823         String strErrorUrl = null;
824 
825         String strCode = multipartRequest.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
826         String strUpdateStylesheetAdmin = multipartRequest.getParameter( PARAMETER_UPDATE_STYLESHEET_ADMIN );
827         String strUpdateStylesheetContent = multipartRequest.getParameter( PARAMETER_UPDATE_STYLESHEET_CONTENT );
828 
829         // Gets XSL for the back office if defined
830         FileItem fileXslAdmin = multipartRequest.getFile( PARAMETER_STYLESHEET_ADMIN );
831         String strFilename = FileUploadService.getFileNameOnly( fileXslAdmin );
832 
833         if ( ( strUpdateStylesheetAdmin != null ) && strUpdateStylesheetAdmin.equals( UPDATE_VALUE ) &&
834                 ( strFilename != null ) && ( !strFilename.equals( "" ) ) )
835         {
836             byte[] baXslAdmin = fileXslAdmin.get(  );
837 
838             // Check the XML validity of the XSL stylesheet
839             if ( isValid( baXslAdmin ) != null )
840             {
841                 Object[] args = { isValid( baXslAdmin ) };
842 
843                 return AdminMessageService.getMessageUrl( multipartRequest, MESSAGE_STYLESHEET_NOT_VALID, args,
844                     AdminMessage.TYPE_STOP );
845             }
846 
847             DocumentTypeHome.setAdminStyleSheet( baXslAdmin, strCode );
848         }
849 
850         // Gets XSL for the back office if defined
851         FileItem fileXslContent = multipartRequest.getFile( PARAMETER_STYLESHEET_CONTENT );
852         strFilename = FileUploadService.getFileNameOnly( fileXslContent );
853 
854         if ( ( strUpdateStylesheetContent != null ) && strUpdateStylesheetContent.equals( UPDATE_VALUE ) &&
855                 ( strFilename != null ) && ( !strFilename.equals( "" ) ) )
856         {
857             byte[] baXslContent = fileXslContent.get(  );
858 
859             // Check the XML validity of the XSL stylesheet
860             if ( isValid( baXslContent ) != null )
861             {
862                 Object[] args = { isValid( baXslContent ) };
863 
864                 return AdminMessageService.getMessageUrl( multipartRequest, MESSAGE_STYLESHEET_NOT_VALID, args,
865                     AdminMessage.TYPE_STOP );
866             }
867 
868             DocumentTypeHome.setContentStyleSheet( baXslContent, strCode );
869         }
870 
871         //clear the cache
872         CacheService.resetCaches(  );
873 
874         return strErrorUrl;
875     }
876 
877     /**
878      * Get the XSL specified in parameters
879      * @param request The {@link HttpServletRequest}
880      * @return A {@link DocumentResource} (name, content and contentType)
881      */
882     public DocumentResource getStyleSheetFile( HttpServletRequest request )
883     {
884         String strDocumentTypeCode = request.getParameter( PARAMETER_DOCUMENT_TYPE_CODE );
885         String strStylesheetType = request.getParameter( PARAMETER_STYLESHEET_TYPE );
886         DocumentResourceDocumentResource.html#DocumentResource">DocumentResource documentResource = new DocumentResource(  );
887         documentResource.setContentType( STYLESHEET_CONTENT_TYPE );
888         documentResource.setName( strDocumentTypeCode + SEPARATOR + strStylesheetType + FILE_EXTENSION );
889 
890         if ( strDocumentTypeCode != null )
891         {
892             _strDocumentTypeCode = strDocumentTypeCode;
893         }
894         else
895         {
896             strDocumentTypeCode = _strDocumentTypeCode;
897         }
898 
899         DocumentType documentType = DocumentTypeHome.findByPrimaryKey( strDocumentTypeCode );
900 
901         if ( strStylesheetType.equals( PARAMETER_STYLESHEET_ADMIN ) )
902         {
903             documentResource.setContent( documentType.getAdminXsl(  ) );
904         }
905 
906         if ( strStylesheetType.equals( PARAMETER_STYLESHEET_CONTENT ) )
907         {
908             documentResource.setContent( documentType.getContentServiceXsl(  ) );
909         }
910 
911         return documentResource;
912     }
913 
914     /**
915      * Use parsing for validate the modify xsl file
916      *
917      * @param baXslSource The XSL source
918      * @return the message exception when the validation is false
919      */
920     private String isValid( byte[] baXslSource )
921     {
922         String strError = null;
923 
924         try
925         {
926             SAXParserFactory factory = SAXParserFactory.newInstance(  );
927             SAXParser analyzer = factory.newSAXParser(  );
928             InputSource is = new InputSource( new ByteArrayInputStream( baXslSource ) );
929             analyzer.getXMLReader(  ).parse( is );
930         }
931         catch ( Exception e )
932         {
933             strError = e.getMessage(  );
934         }
935 
936         return strError;
937     }
938 
939     /**
940      * Inserts a regular expression in the attribute
941      *
942      * @param request The HTTP request
943      * @return The URL to go after performing the action
944      */
945     public String doInsertRegularExpression( HttpServletRequest request )
946     {
947         // Gets the document attribute identifier
948         String strAttributeId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
949         int nAttributeId = IntegerUtils.convert( strAttributeId );
950 
951         // Gets the selected regular expression
952         String strExpressionId = request.getParameter( PARAMETER_EXPRESSION_ID );
953 
954         if ( IntegerUtils.isNumeric( strExpressionId ) )
955         {
956             int nExpressionId = IntegerUtils.convert( strExpressionId );
957 
958             boolean bIsDuplicated = false;
959 
960             for ( Integer nCurrentExpression : DocumentAttributeHome.getListRegularExpressionKeyByIdAttribute( 
961                     nAttributeId ) )
962             {
963                 if ( nExpressionId == nCurrentExpression )
964                 {
965                     bIsDuplicated = true;
966 
967                     break;
968                 }
969             }
970 
971             if ( !bIsDuplicated )
972             {
973                 // Inserts a regular expression in the attribute
974                 DocumentAttributeHome.insertRegularExpression( nAttributeId, nExpressionId );
975             }
976         }
977 
978         UrlItem url = new UrlItem( JSP_MODIFY_DOCUMENT_TYPE_ATTRIBUTE );
979         url.addParameter( PARAMETER_ATTRIBUTE_ID, nAttributeId );
980 
981         return url.getUrl(  );
982     }
983 
984     /**
985      * Deletes a regular expression in the attribute
986      *
987      * @param request The HTTP request
988      * @return The URL to go after performing the action
989      */
990     public String doDeleteRegularExpression( HttpServletRequest request )
991     {
992         // Gets the document attribute identifier
993         String strAttributeId = request.getParameter( PARAMETER_ATTRIBUTE_ID );
994         int nAttributeId = IntegerUtils.convert( strAttributeId );
995 
996         // Gets the selected regular expression
997         String strExpressionId = request.getParameter( PARAMETER_EXPRESSION_ID );
998         int nExpressionId = IntegerUtils.convert( strExpressionId );
999 
1000         // Deletes a regular expression in the attribute
1001         DocumentAttributeHome.deleteRegularExpression( nAttributeId, nExpressionId );
1002 
1003         UrlItem url = new UrlItem( JSP_MODIFY_DOCUMENT_TYPE_ATTRIBUTE );
1004         url.addParameter( PARAMETER_ATTRIBUTE_ID, nAttributeId );
1005 
1006         return url.getUrl(  );
1007     }
1008 
1009     /**
1010      * Check if there is no diacritics character
1011      * @param strInput The input string
1012      * @return
1013      */
1014     private boolean checkDocumentTypeCodePattern( String strInput )
1015     {
1016         return strInput.matches( PATTERN_CODE );
1017     }
1018 }