View Javadoc
1   /*
2    * Copyright (c) 2002-2021, 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.announce.web;
35  
36  import fr.paris.lutece.plugins.announce.service.EntryTypeService;
37  import fr.paris.lutece.plugins.genericattributes.business.Entry;
38  import fr.paris.lutece.plugins.genericattributes.business.EntryHome;
39  import fr.paris.lutece.plugins.genericattributes.business.Field;
40  import fr.paris.lutece.plugins.genericattributes.business.FieldHome;
41  import fr.paris.lutece.plugins.genericattributes.service.entrytype.IEntryTypeService;
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.util.AppPathService;
46  import fr.paris.lutece.portal.util.mvc.admin.MVCAdminJspBean;
47  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
48  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
49  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
50  import fr.paris.lutece.portal.util.mvc.utils.MVCUtils;
51  import fr.paris.lutece.util.string.StringUtil;
52  import fr.paris.lutece.util.url.UrlItem;
53  
54  import org.apache.commons.lang3.StringUtils;
55  
56  import java.util.HashMap;
57  import java.util.List;
58  import java.util.Map;
59  
60  import javax.servlet.http.HttpServletRequest;
61  
62  /**
63   * JspBean to manage category fields
64   */
65  @Controller( controllerJsp = "ManageCategoryFields.jsp", controllerPath = "jsp/admin/plugins/announce/", right = AnnounceUserJspBean.RIGHT_MANAGE_ANNOUNCE )
66  public class CategoryFieldJspBean extends MVCAdminJspBean
67  {
68      private static final long serialVersionUID = -1505164256615633838L;
69  
70      // Properties
71      private static final String PROPERTY_CREATE_FIELD_TITLE = "announce.createField.title";
72      private static final String PROPERTY_MODIFY_FIELD_TITLE = "announce.modifyField.title";
73  
74      // Urls
75      private static final String JSP_URL_MANAGE_CATEGORY_FIELDS = "jsp/admin/plugins/announce/ManageCategoryFields.jsp";
76  
77      // Marks
78      private static final String MARK_FIELD = "field";
79      private static final String MARK_ENTRY_LIST = "entry_list";
80      private static final String MARK_ENTRY_TYPE_LIST = "entry_type_list";
81  
82      // Messages
83      private static final String MESSAGE_CONFIRM_REMOVE_FIELD = "announce.message.confirmRemoveField";
84      private static final String MESSAGE_MANDATORY_FIELD = "portal.util.message.mandatoryField";
85      private static final String MESSAGE_FIELD_VALUE_FIELD = "announce.message.error.field_value_field";
86  
87      // Views
88      private static final String VIEW_GET_CREATE_FIELD = "getCreateField";
89      private static final String VIEW_GET_MODIFY_FIELD = "getModifyField";
90      private static final String VIEW_GET_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS = "getModifyFieldCC";
91      private static final String VIEW_GET_CONFIRM_REMOVE_FIELD = "getConfirmRemoveField";
92  
93      // Actions
94      private static final String ACTION_DO_CREATE_FIELD = "doCreateField";
95      private static final String ACTION_DO_MODIFY_FIELD = "doModifyField";
96      private static final String ACTION_DO_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS = "doModifyFieldCC";
97      private static final String ACTION_DO_MOVE_FIELD_UP = "doMoveFieldUp";
98      private static final String ACTION_DO_MOVE_FIELD_DOWN = "doMoveFieldDown";
99      private static final String ACTION_DO_REMOVE_FIELD = "doRemoveField";
100 
101     // Parameters
102     private static final String PARAMETER_ID_ENTRY = "id_entry";
103     private static final String PARAMETER_ID_FIELD = "id_field";
104     private static final String PARAMETER_CANCEL = "cancel";
105     private static final String PARAMETER_APPLY = "apply";
106     private static final String PARAMETER_TITLE = "title";
107     private static final String PARAMETER_VALUE = "value";
108     private static final String PARAMETER_DEFAULT_VALUE = "default_value";
109     private static final String PARAMETER_NO_DISPLAY_TITLE = "no_display_title";
110     private static final String PARAMETER_COMMENT = "comment";
111     private static final String FIELD_TITLE_FIELD = "announce.createField.labelTitle";
112     private static final String FIELD_VALUE_FIELD = "announce.createField.labelValue";
113 
114     // Templates
115     private static final String TEMPLATE_CREATE_FIELD = "admin/plugins/announce/create_field.html";
116     private static final String TEMPLATE_MODIFY_FIELD_WITH_CONDITIONAL_QUESTION = "admin/plugins/announce/modify_field_with_conditional_question.html";
117     private static final String TEMPLATE_MODIFY_FIELD = "admin/plugins/announce/modify_field.html";
118 
119     /**
120      * Gets the field creation page
121      * 
122      * @param request
123      *            The HTTP request
124      * @return the field creation page
125      */
126     @View( VIEW_GET_CREATE_FIELD )
127     public String getCreateField( HttpServletRequest request )
128     {
129         Entry entry = EntryHome.findByPrimaryKey( Integer.parseInt( request.getParameter( PARAMETER_ID_ENTRY ) ) );
130         Field field = new Field( );
131         field.setParentEntry( entry );
132 
133         Map<String, Object> model = new HashMap<>( );
134         model.put( MARK_FIELD, field );
135 
136         return getPage( PROPERTY_CREATE_FIELD_TITLE, TEMPLATE_CREATE_FIELD, model );
137     }
138 
139     /**
140      * Get the page to modify a field without displaying its conditional questions
141      * 
142      * @param request
143      *            The request
144      * @return The HTML content to display, or the next URL to redirect to
145      */
146     @View( VIEW_GET_MODIFY_FIELD )
147     public String getModifyField( HttpServletRequest request )
148     {
149         return getModifyField( request, false );
150     }
151 
152     /**
153      * Get the page to modify a field with its conditional questions
154      * 
155      * @param request
156      *            The request
157      * @return The HTML content to display, or the next URL to redirect to
158      */
159     @View( VIEW_GET_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS )
160     public String getModifyFieldWithConditionalQuestions( HttpServletRequest request )
161     {
162         return getModifyField( request, true );
163     }
164 
165     /**
166      * Gets the field modification page
167      * 
168      * @param request
169      *            The HTTP request
170      * @param bWithConditionalQuestion
171      *            true if the field is associate to conditionals questions
172      * @return the field modification page
173      */
174     private String getModifyField( HttpServletRequest request, boolean bWithConditionalQuestion )
175     {
176         if ( StringUtils.isEmpty( request.getParameter( PARAMETER_ID_FIELD ) ) || !StringUtils.isNumeric( request.getParameter( PARAMETER_ID_FIELD ) ) )
177         {
178             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
179         }
180 
181         int nIdField = Integer.parseInt( request.getParameter( PARAMETER_ID_FIELD ) );
182         Field field = FieldHome.findByPrimaryKey( nIdField );
183         Entry entry = EntryHome.findByPrimaryKey( field.getParentEntry( ).getIdEntry( ) );
184 
185         field.setParentEntry( entry );
186 
187         HashMap<String, Object> model = new HashMap<>( );
188         model.put( MARK_FIELD, field );
189 
190         String strTemplateName;
191 
192         if ( bWithConditionalQuestion )
193         {
194             model.put( MARK_ENTRY_TYPE_LIST, EntryTypeService.getInstance( ).getEntryTypeReferenceList( ) );
195             model.put( MARK_ENTRY_LIST, field.getConditionalQuestions( ) );
196             strTemplateName = TEMPLATE_MODIFY_FIELD_WITH_CONDITIONAL_QUESTION;
197         }
198         else
199         {
200             strTemplateName = TEMPLATE_MODIFY_FIELD;
201         }
202 
203         return getPage( PROPERTY_MODIFY_FIELD_TITLE, strTemplateName, model );
204     }
205 
206     /**
207      * Perform creation field
208      * 
209      * @param request
210      *            The HTTP request
211      * @return The URL to go after performing the action
212      */
213     @Action( ACTION_DO_CREATE_FIELD )
214     public String doCreateField( HttpServletRequest request )
215     {
216         if ( StringUtils.isEmpty( request.getParameter( PARAMETER_ID_ENTRY ) ) || !StringUtils.isNumeric( request.getParameter( PARAMETER_ID_ENTRY ) ) )
217         {
218             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
219         }
220 
221         int nIdEntry = Integer.parseInt( request.getParameter( PARAMETER_ID_ENTRY ) );
222 
223         if ( request.getParameter( PARAMETER_CANCEL ) == null )
224         {
225             Entry entry = new Entry( );
226             entry.setIdEntry( nIdEntry );
227 
228             Field field = new Field( );
229             field.setParentEntry( entry );
230 
231             String strError = getFieldData( request, field );
232 
233             if ( strError != null )
234             {
235                 return redirect( request, strError );
236             }
237 
238             FieldHome.create( field );
239         }
240 
241         return redirect( request, CategoryEntryJspBean.getURLModifyEntry( request, nIdEntry ) );
242     }
243 
244     /**
245      * Perform modification field
246      * 
247      * @param request
248      *            The HTTP request
249      * @return The URL to go after performing the action
250      */
251     @Action( ACTION_DO_MODIFY_FIELD )
252     public String doModifyField( HttpServletRequest request )
253     {
254         return doModifyField( request, false );
255     }
256 
257     /**
258      * Perform modification field
259      * 
260      * @param request
261      *            The HTTP request
262      * @return The URL to go after performing the action
263      */
264     @Action( ACTION_DO_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS )
265     public String doModifyFieldWithConditionalQuestions( HttpServletRequest request )
266     {
267         return doModifyField( request, true );
268     }
269 
270     /**
271      * Perform modification field
272      * 
273      * @param request
274      *            The HTTP request
275      * @param bWithConditionalQuestion
276      *            True if the field to modify accepts conditional questions
277      * @return The URL to go after performing the action
278      */
279     private String doModifyField( HttpServletRequest request, boolean bWithConditionalQuestion )
280     {
281         String strIdField = request.getParameter( PARAMETER_ID_FIELD );
282 
283         if ( StringUtils.isEmpty( strIdField ) || !StringUtils.isNumeric( strIdField ) )
284         {
285             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
286         }
287 
288         Field field = null;
289         int nIdField = Integer.parseInt( strIdField );
290 
291         field = FieldHome.findByPrimaryKey( nIdField );
292 
293         if ( request.getParameter( PARAMETER_CANCEL ) == null )
294         {
295             String strError = getFieldData( request, field );
296 
297             if ( strError != null )
298             {
299                 return strError;
300             }
301 
302             FieldHome.update( field );
303         }
304 
305         if ( request.getParameter( PARAMETER_APPLY ) == null )
306         {
307             return redirect( request, CategoryEntryJspBean.getURLModifyEntry( request, field.getParentEntry( ).getIdEntry( ) ) );
308         }
309 
310         return redirect( request, bWithConditionalQuestion ? VIEW_GET_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS : VIEW_GET_MODIFY_FIELD, PARAMETER_ID_FIELD,
311                 nIdField );
312     }
313 
314     /**
315      * Gets the confirmation page before deleting a field
316      * 
317      * @param request
318      *            The HTTP request
319      * @return the confirmation page before deleting a field
320      */
321     @View( VIEW_GET_CONFIRM_REMOVE_FIELD )
322     public String getConfirmRemoveField( HttpServletRequest request )
323     {
324         String strIdField = request.getParameter( PARAMETER_ID_FIELD );
325 
326         if ( StringUtils.isEmpty( strIdField ) || !StringUtils.isNumeric( strIdField ) )
327         {
328             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
329         }
330 
331         UrlItem url = new UrlItem( JSP_URL_MANAGE_CATEGORY_FIELDS );
332         url.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_DO_REMOVE_FIELD );
333         url.addParameter( PARAMETER_ID_FIELD, strIdField );
334 
335         return redirect( request, AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_FIELD, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION ) );
336     }
337 
338     /**
339      * Perform the suppression of a field
340      * 
341      * @param request
342      *            The HTTP request
343      * @return The URL to go after performing the action
344      */
345     @Action( ACTION_DO_REMOVE_FIELD )
346     public String doRemoveField( HttpServletRequest request )
347     {
348         String strIdField = request.getParameter( PARAMETER_ID_FIELD );
349 
350         if ( StringUtils.isEmpty( strIdField ) || !StringUtils.isNumeric( strIdField ) )
351         {
352             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
353         }
354 
355         int nIdField = Integer.parseInt( strIdField );
356 
357         if ( nIdField != -1 )
358         {
359             Field field = FieldHome.findByPrimaryKey( nIdField );
360 
361             if ( field != null )
362             {
363                 FieldHome.remove( nIdField );
364 
365                 return redirect( request, CategoryEntryJspBean.getURLModifyEntry( request, field.getParentEntry( ).getIdEntry( ) ) );
366             }
367         }
368 
369         return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
370     }
371 
372     /**
373      * Move a field up
374      * 
375      * @param request
376      *            The request
377      * @return The next URL to redirect to
378      */
379     @Action( ACTION_DO_MOVE_FIELD_UP )
380     public String doMoveFieldUp( HttpServletRequest request )
381     {
382         return doMoveField( request, true );
383     }
384 
385     /**
386      * Move a field up
387      * 
388      * @param request
389      *            The request
390      * @return The next URL to redirect to
391      */
392     @Action( ACTION_DO_MOVE_FIELD_DOWN )
393     public String doMoveFieldDown( HttpServletRequest request )
394     {
395         return doMoveField( request, false );
396     }
397 
398     /**
399      * Move a field up or down
400      * 
401      * @param request
402      *            The request
403      * @param bMoveUp
404      *            True to move the field up, false to move it down
405      * @return The next URL to redirect to
406      */
407     public String doMoveField( HttpServletRequest request, boolean bMoveUp )
408     {
409         String strIdField = request.getParameter( PARAMETER_ID_FIELD );
410 
411         if ( StringUtils.isEmpty( strIdField ) || !StringUtils.isNumeric( strIdField ) )
412         {
413             return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
414         }
415 
416         int nIdField = Integer.parseInt( strIdField );
417 
418         List<Field> listField;
419         Field field = FieldHome.findByPrimaryKey( nIdField );
420 
421         listField = FieldHome.getFieldListByIdEntry( field.getParentEntry( ).getIdEntry( ) );
422 
423         int nIndexField = getIndexFieldInFieldList( nIdField, listField );
424 
425         if ( nIndexField != ( listField.size( ) ) )
426         {
427             int nNewPosition;
428             Field fieldToInversePosition;
429             fieldToInversePosition = listField.get( bMoveUp ? ( nIndexField - 1 ) : ( nIndexField + 1 ) );
430             nNewPosition = fieldToInversePosition.getPosition( );
431             fieldToInversePosition.setPosition( field.getPosition( ) );
432             field.setPosition( nNewPosition );
433             FieldHome.update( field );
434             FieldHome.update( fieldToInversePosition );
435 
436             return redirect( request, CategoryEntryJspBean.getURLModifyEntry( request, field.getParentEntry( ).getIdEntry( ) ) );
437         }
438 
439         return redirect( request, CategoryJspBean.getUrlManageCategories( request ) );
440     }
441 
442     /**
443      * Get the request data and if there is no error insert the data in the field specified in parameter. return null if there is no error or else return the
444      * error page URL
445      * 
446      * @param request
447      *            the request
448      * @param field
449      *            field
450      * @return null if there is no error or else return the error page URL
451      */
452     private String getFieldData( HttpServletRequest request, Field field )
453     {
454         String strTitle = request.getParameter( PARAMETER_TITLE );
455         String strValue = request.getParameter( PARAMETER_VALUE );
456         String strDefaultValue = request.getParameter( PARAMETER_DEFAULT_VALUE );
457         String strNoDisplayTitle = request.getParameter( PARAMETER_NO_DISPLAY_TITLE );
458         String strComment = request.getParameter( PARAMETER_COMMENT );
459 
460         String strFieldError = null;
461 
462         if ( StringUtils.isEmpty( strTitle ) )
463         {
464             strFieldError = FIELD_TITLE_FIELD;
465         }
466         else
467             if ( StringUtils.isEmpty( strValue ) )
468             {
469                 strFieldError = FIELD_VALUE_FIELD;
470             }
471             else
472                 if ( !StringUtil.checkCodeKey( strValue ) )
473                 {
474                     return AdminMessageService.getMessageUrl( request, MESSAGE_FIELD_VALUE_FIELD, AdminMessage.TYPE_STOP );
475                 }
476 
477         if ( strFieldError != null )
478         {
479             Object [ ] tabRequiredFields = {
480                     I18nService.getLocalizedString( strFieldError, getLocale( ) )
481             };
482 
483             return AdminMessageService.getMessageUrl( request, MESSAGE_MANDATORY_FIELD, tabRequiredFields, AdminMessage.TYPE_STOP );
484         }
485 
486         field.setCode( IEntryTypeService.FIELD_ANSWER_CHOICE );
487         field.setTitle( strTitle );
488         field.setValue( strValue );
489         field.setComment( strComment );
490 
491         field.setDefaultValue( strDefaultValue != null );
492         field.setNoDisplayTitle( strNoDisplayTitle != null );
493 
494         return null; // No error
495     }
496 
497     /**
498      * Return the index in the list of the field whose key is specified in parameter
499      * 
500      * @param nIdField
501      *            the key of the field
502      * @param listField
503      *            the list of field
504      * @return the index in the list of the field whose key is specified in parameter
505      */
506     private static int getIndexFieldInFieldList( int nIdField, List<Field> listField )
507     {
508         int nIndex = 0;
509 
510         for ( Field field : listField )
511         {
512             if ( field.getIdField( ) == nIdField )
513             {
514                 return nIndex;
515             }
516 
517             nIndex++;
518         }
519 
520         return nIndex;
521     }
522 
523     /**
524      * Get the URL to modify a field. The field is assumed to allow conditional questions.
525      * 
526      * @param request
527      *            The request
528      * @param nIdField
529      *            The id of the field
530      * @return The URL of the page to modify the field
531      */
532     public static String getUrlModifyField( HttpServletRequest request, int nIdField )
533     {
534         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + JSP_URL_MANAGE_CATEGORY_FIELDS );
535         urlItem.addParameter( MVCUtils.PARAMETER_VIEW, VIEW_GET_MODIFY_FIELD_WITH_CONDITIONAL_QUESTIONS );
536         urlItem.addParameter( PARAMETER_ID_FIELD, nIdField );
537 
538         return urlItem.getUrl( );
539     }
540 }