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.forms.business;
35  
36  import javax.validation.constraints.NotEmpty;
37  import javax.validation.constraints.Size;
38  
39  import org.apache.commons.lang3.StringUtils;
40  import org.apache.commons.lang3.math.NumberUtils;
41  
42  import fr.paris.lutece.portal.business.file.File;
43  import fr.paris.lutece.portal.service.rbac.RBACResource;
44  import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupResource;
45  
46  import java.sql.Date;
47  import java.sql.Timestamp;
48  import java.util.Base64;
49  import java.util.Comparator;
50  import java.util.List;
51  
52  /**
53   * This is the business class for the object Form
54   */
55  public class Form implements AdminWorkgroupResource, RBACResource, Comparator<Form>
56  {
57  
58      /**
59       * Form resource type
60       */
61      public static final String RESOURCE_TYPE = "FORMS_FORM";
62  
63      /**
64       * State of forms that are enabled
65       */
66      public static final int STATE_ENABLE = 1;
67  
68      /**
69       * State of forms that are disabled
70       */
71      public static final int STATE_DISABLE = 0;
72  
73      // Variables declarations
74      private int _nId;
75  
76      @NotEmpty( message = "#i18n{forms.validation.form.Title.notEmpty}" )
77      @Size( max = 255, message = "#i18n{forms.validation.form.Title.size}" )
78      private String _strTitle;
79  
80      @Size( max = 255, message = "#i18n{forms.validation.form.Description.size}" )
81      private String _strDescription;
82  
83      private Timestamp _dateCreation;
84  
85      private Timestamp _dateAvailabilityStartDate;
86  
87      private Timestamp _dateAvailabilityEndDate;
88  
89      private Timestamp _dateUpdate;
90  
91      private String _strWorkgroup;
92  
93      private List<FormAction> _listActions;
94  
95      private int _nIdWorkflow;
96  
97      private boolean _bAuthentificationNeeded;
98  
99      @NotEmpty( message = "#i18n{forms.validation.form.Breadcrumb.notEmpty}" )
100     @Size( max = 255, message = "#i18n{forms.validation.form.Breadcrumb.size}" )
101     private String _strBreadcrumbName;
102 
103     @Size( max = 255, message = "#i18n{forms.validation.form.ReturnUrl.size}" )
104     private String _strReturnUrl;
105 
106     private boolean _bDisplaySummary;
107     private int _nMaxNumberResponse;
108     private boolean _bOneResponseByUser;
109 
110     private int _nCurrentNumberResponse;
111 
112     private boolean _bCaptchaStepInitial;
113     private boolean _bCaptchaStepFinal;
114     private boolean _bCaptchaRecap;
115 
116     private boolean _bCountResponses;
117 
118     private String _labelFinalButton;
119 
120     private String _strUnavailableMessage;
121 
122     private File _logo;
123 
124     private int _nIdCategory;
125     
126     private boolean _bBackupEnabled;
127     
128     /**
129      *  Access to responses management on FO by role
130      **/
131     private boolean _bAccessToResponsesByRole;
132 
133     /**
134      * Default constructor
135      */
136     public Form( )
137     {
138         super( );
139     }
140 
141     /**
142      * Copy constructor
143      * 
144      * Leaves out dynamic data
145      * 
146      * @param source
147      *            source Form to copy
148      */
149     Formorm" href="../../../../../../fr/paris/lutece/plugins/forms/business/Form.html#Form">Form( Form source )
150     {
151         _bAccessToResponsesByRole = source._bAccessToResponsesByRole;
152         _bAuthentificationNeeded = source._bAuthentificationNeeded;
153         _bBackupEnabled = source._bBackupEnabled;
154         _bCaptchaRecap = source._bCaptchaRecap;
155         _bCaptchaStepFinal = source._bCaptchaStepFinal;
156         _bCaptchaStepInitial = source._bCaptchaStepInitial;
157         _bCountResponses = source._bCountResponses;
158         _bDisplaySummary = source._bDisplaySummary;
159         _bOneResponseByUser = source._bOneResponseByUser;
160         _dateAvailabilityEndDate = source._dateAvailabilityEndDate;
161         _dateAvailabilityStartDate = source._dateAvailabilityStartDate;
162         _dateCreation = source._dateCreation;
163         _dateUpdate = source._dateUpdate;
164         _labelFinalButton = source._labelFinalButton;
165         // _listActions = null;
166         _logo = source._logo;
167         // _nCurrentNumberResponse = 0;
168         _nId = source._nId;
169         _nIdCategory = source._nIdCategory;
170         _nIdWorkflow = source._nIdWorkflow;
171         _nMaxNumberResponse = source._nMaxNumberResponse;
172         _strBreadcrumbName = source._strBreadcrumbName;
173         _strDescription = source._strDescription;
174         _strReturnUrl = source._strReturnUrl;
175         _strTitle = source._strTitle;
176         _strUnavailableMessage = source._strUnavailableMessage;
177         _strWorkgroup = source._strWorkgroup;
178     }
179 
180     /**
181      * Returns the Id
182      * 
183      * @return The Id
184      */
185     public int getId( )
186     {
187         return _nId;
188     }
189 
190     /**
191      * Sets the Id
192      * 
193      * @param nId
194      *            The Id
195      */
196     public void setId( int nId )
197     {
198         _nId = nId;
199     }
200 
201     /**
202      * Returns the Title
203      * 
204      * @return The Title
205      */
206     public String getTitle( )
207     {
208         return _strTitle;
209     }
210 
211     /**
212      * Sets the Title
213      * 
214      * @param strTitle
215      *            The Title
216      */
217     public void setTitle( String strTitle )
218     {
219         _strTitle = strTitle;
220     }
221 
222     /**
223      * Returns the Description
224      * 
225      * @return The Description
226      */
227     public String getDescription( )
228     {
229         return _strDescription;
230     }
231 
232     /**
233      * Sets the Description
234      * 
235      * @param strDescription
236      *            The Description
237      */
238     public void setDescription( String strDescription )
239     {
240         _strDescription = strDescription;
241     }
242 
243     /**
244      * Returns the CreationDate
245      * 
246      * @return The CreationDate
247      */
248     public Timestamp getCreationDate( )
249     {
250         return _dateCreation;
251     }
252 
253     /**
254      * Sets the CreationDate
255      * 
256      * @param creationDate
257      *            The CreationDate
258      */
259     public void setCreationDate( Timestamp creationDate )
260     {
261         _dateCreation = creationDate;
262     }
263 
264     /**
265      * Returns the UpdateDate
266      * 
267      * @return The UpdateDate
268      */
269     public Timestamp getUpdateDate( )
270     {
271         return _dateUpdate;
272     }
273 
274     /**
275      * Sets the UpdateDate
276      * 
277      * @param dateUpdate
278      *            The UpdateDate
279      */
280     public void setUpdateDate( Timestamp dateUpdate )
281     {
282 
283         _dateUpdate = dateUpdate;
284     }
285 
286     /**
287      * Returns the AvailabilityStartDate
288      * 
289      * @return The AvailabilityStartDate
290      */
291     public Timestamp getAvailabilityStartDate( )
292     {
293         return _dateAvailabilityStartDate;
294     }
295 
296     /**
297      * Sets the AvailabilityStartDate
298      * 
299      * @param dateAvailabilityStartDate
300      *            The AvailabilityStartDate
301      */
302     public void setAvailabilityStartDate( Timestamp dateAvailabilityStartDate )
303     {
304         _dateAvailabilityStartDate = dateAvailabilityStartDate;
305     }
306 
307     /**
308      * Returns the AvailabilityEndDate
309      * 
310      * @return The AvailabilityEndDate
311      */
312     public Timestamp getAvailabilityEndDate( )
313     {
314         return _dateAvailabilityEndDate;
315     }
316 
317     /**
318      * Sets the AvailabilityEndDate
319      * 
320      * @param dateAvailabilityEndDate
321      *            The AvailabilityEndDate
322      */
323     public void setAvailabilityEndDate( Timestamp dateAvailabilityEndDate )
324     {
325         _dateAvailabilityEndDate = dateAvailabilityEndDate;
326     }
327 
328     /**
329      * {@inheritDoc}
330      */
331     @Override
332     public String getResourceTypeCode( )
333     {
334         return RESOURCE_TYPE;
335     }
336 
337     /**
338      * {@inheritDoc}
339      */
340     @Override
341     public String getResourceId( )
342     {
343         return StringUtils.EMPTY + _nId;
344     }
345 
346     /**
347      * {@inheritDoc}
348      */
349     @Override
350     public String getWorkgroup( )
351     {
352         return _strWorkgroup;
353     }
354 
355     /**
356      * set the work group associate to the form
357      * 
358      * @param workGroup
359      *            the work group associate to the form
360      */
361     public void setWorkgroup( String workGroup )
362     {
363         _strWorkgroup = workGroup;
364     }
365 
366     /**
367      *
368      * @return a list of action can be use for the form
369      */
370     public List<FormAction> getActions( )
371     {
372         return _listActions;
373     }
374 
375     /**
376      * set a list of action can be use for the form
377      * 
378      * @param formActions
379      *            a list of action must be use for the form
380      */
381     public void setActions( List<FormAction> formActions )
382     {
383         _listActions = formActions;
384     }
385 
386     /**
387      * Returns the active status of a form by checking if we are currently within its availability period
388      * 
389      * @return true if the form is active
390      */
391     public boolean isActive( )
392     {
393         boolean bActive = false;
394         Date dToday = new Date( System.currentTimeMillis( ) );
395 
396         if ( _dateAvailabilityStartDate != null && _dateAvailabilityStartDate.before( dToday )
397                 && ( _dateAvailabilityEndDate == null || _dateAvailabilityEndDate.after( dToday ) ) )
398         {
399             bActive = true;
400         }
401         if ( _dateAvailabilityStartDate == null && ( _dateAvailabilityEndDate != null && _dateAvailabilityEndDate.after( dToday ) ) )
402         {
403             bActive = true;
404         }
405 
406         return bActive;
407     }
408 
409     /**
410      * Getter for id_workflow
411      * 
412      * @return the _nIdWorkflow
413      */
414     public int getIdWorkflow( )
415     {
416         return _nIdWorkflow;
417     }
418 
419     /**
420      * setter for id_workflow
421      * 
422      * @param nIdWorkflow
423      *            the Id Workflow to set
424      */
425     public void setIdWorkflow( int nIdWorkflow )
426     {
427         _nIdWorkflow = nIdWorkflow;
428     }
429 
430     /**
431      * @return the _bAuthentificationNeeded
432      */
433     public boolean isAuthentificationNeeded( )
434     {
435         return _bAuthentificationNeeded;
436     }
437 
438     /**
439      * @param bAuthentificationNeeded
440      *            the bAuthentificationNeeded to set
441      */
442     public void setAuthentificationNeeded( boolean bAuthentificationNeeded )
443     {
444         this._bAuthentificationNeeded = bAuthentificationNeeded;
445     }
446 
447     /**
448      * Returns the BreadcrumbName
449      * 
450      * @return The BreadcrumbName
451      */
452     public String getBreadcrumbName( )
453     {
454         return _strBreadcrumbName;
455     }
456 
457     /**
458      * Sets the Title
459      * 
460      * @param strBreadcrumbName
461      *            The breadcrumb bean name
462      */
463     public void setBreadcrumbName( String strBreadcrumbName )
464     {
465         _strBreadcrumbName = strBreadcrumbName;
466     }
467 
468     /**
469      * Returns the return URL
470      * 
471      * @return The return URL
472      */
473     public String getReturnUrl( )
474     {
475         return _strReturnUrl;
476     }
477 
478     /**
479      * Sets the return URL
480      * 
481      * @param strReturnUrl
482      *            The form return page URL
483      */
484     public void setReturnUrl( String strReturnUrl )
485     {
486         _strReturnUrl = strReturnUrl;
487     }
488 
489     /**
490      * Tells if the summary must be displayed
491      * 
492      * @return {@code true} if the summary must be displayed, {@code false} otherwise
493      */
494     public boolean isDisplaySummary( )
495     {
496         return _bDisplaySummary;
497     }
498 
499     /**
500      * Sets if the summary must be displayed
501      * 
502      * @param bDisplaySummary
503      *            {@code true} if the summary must be displayed, {@code false} otherwise
504      */
505     public void setDisplaySummary( boolean bDisplaySummary )
506     {
507         _bDisplaySummary = bDisplaySummary;
508     }
509 
510     /**
511      * Returns the number Max of response form
512      * 
513      * @return The number max of reponse for
514      */
515     public int getMaxNumberResponse( )
516     {
517         return _nMaxNumberResponse;
518     }
519 
520     /**
521      * Sets the number Max of response form
522      * 
523      * @param nMaxNumberResponse
524      *            The number max of reponse form
525      */
526     public void setMaxNumberResponse( int nMaxNumberResponse )
527     {
528         _nMaxNumberResponse = nMaxNumberResponse;
529     }
530 
531     /**
532      * Check the user can only submit one form.
533      * 
534      * @return true if the user can submit just one form
535      */
536     public boolean isOneResponseByUser( )
537     {
538         return _bOneResponseByUser;
539     }
540 
541     /**
542      * set true if the user can submit just once the form
543      * 
544      * @param bOneResponseByUser
545      *            true if the user can submit just one form
546      */
547     public void setOneResponseByUser( boolean bOneResponseByUser )
548     {
549         _bOneResponseByUser = bOneResponseByUser;
550     }
551 
552     /**
553      * @return the nCurrentNumberResponse
554      */
555     public int getCurrentNumberResponse( )
556     {
557         return _nCurrentNumberResponse;
558     }
559 
560     /**
561      * @param nCurrentNumberResponse
562      *            the nCurrentNumberResponse to set
563      */
564     public void setCurrentNumberResponse( int nCurrentNumberResponse )
565     {
566         _nCurrentNumberResponse = nCurrentNumberResponse;
567     }
568 
569     /**
570      * @return the bCaptchaStepInitial
571      */
572     public boolean isCaptchaStepInitial( )
573     {
574         return _bCaptchaStepInitial;
575     }
576 
577     /**
578      * @param bCaptchaStepInitial
579      *            the bCaptchaStepInitial to set
580      */
581     public void setCaptchaStepInitial( boolean bCaptchaStepInitial )
582     {
583         _bCaptchaStepInitial = bCaptchaStepInitial;
584     }
585 
586     /**
587      * @return the bCaptchaStepFinal
588      */
589     public boolean isCaptchaStepFinal( )
590     {
591         return _bCaptchaStepFinal;
592     }
593 
594     /**
595      * @param bCaptchaStepFinal
596      *            the bCaptchaStepFinel to set
597      */
598     public void setCaptchaStepFinal( boolean bCaptchaStepFinal )
599     {
600         _bCaptchaStepFinal = bCaptchaStepFinal;
601     }
602 
603     /**
604      * @return the bCaptchaRecap
605      */
606     public boolean isCaptchaRecap( )
607     {
608         return _bCaptchaRecap;
609     }
610 
611     /**
612      * @param bCaptchaRecap
613      *            the bCaptchaRecap to set
614      */
615     public void setCaptchaRecap( boolean bCaptchaRecap )
616     {
617         _bCaptchaRecap = bCaptchaRecap;
618     }
619 
620     /**
621      * @return the bCountResponse
622      */
623     public boolean isCountResponses( )
624     {
625         return _bCountResponses;
626     }
627 
628     /**
629      * @param bCountResponse
630      *            the bCountResponse to set
631      */
632     public void setCountResponses( boolean bCountResponse )
633     {
634         _bCountResponses = bCountResponse;
635     }
636 
637     /**
638      * @return the labelFinalButton
639      */
640     public String getLabelFinalButton( )
641     {
642         return _labelFinalButton;
643     }
644 
645     /**
646      * @param labelFinalButton
647      *            the labelFinalButton to set
648      */
649     public void setLabelFinalButton( String labelFinalButton )
650     {
651         _labelFinalButton = labelFinalButton;
652     }
653 
654     /**
655      * @return the strUnavailableMessage
656      */
657     public String getUnavailableMessage( )
658     {
659         return _strUnavailableMessage;
660     }
661 
662     /**
663      * @param strUnavailableMessage
664      *            the strUnavailableMessage to set
665      */
666     public void setUnavailableMessage( String strUnavailableMessage )
667     {
668         _strUnavailableMessage = strUnavailableMessage;
669     }
670 
671     /**
672      * @return the logo
673      */
674     public File getLogo( )
675     {
676         return _logo;
677     }
678 
679     /**
680      * @param logo
681      *            the logo to set
682      */
683     public void setLogo( File logo )
684     {
685         _logo = logo;
686     }
687 
688     /**
689      * Get the content of the logo as base64
690      * 
691      * @return
692      */
693     public String getLogoBase64( )
694     {
695         if ( _logo == null || _logo.getPhysicalFile( ) == null )
696         {
697             return null;
698         }
699         return Base64.getEncoder( ).encodeToString( _logo.getPhysicalFile( ).getValue( ) );
700     }
701 
702     /**
703      * @return the id of the category linked to the form
704      */
705     public int getIdCategory( )
706     {
707         return _nIdCategory;
708     }
709 
710     /**
711      * @param _nIdCategory
712      *            the _nIdCategory to set
713      */
714     public void setIdCategory( int nIdCategory )
715     {
716         this._nIdCategory = nIdCategory;
717     }
718 
719     /**
720      * @return the bBackupEnabled
721      */
722     public boolean isBackupEnabled( )
723     {
724         return _bBackupEnabled;
725     }
726 
727     /**
728      * @param bBackupEnabled the bBackupEnabled to set
729      */
730     public void setBackupEnabled( boolean bBackupEnabled )
731     {
732         _bBackupEnabled = bBackupEnabled;
733     }
734 
735     /**
736      * @return the id of the category linked to the form
737      */
738     public FormCategory getCategory( )
739     {
740         return FormCategoryHome.findByPrimaryKey( _nIdCategory );
741     }
742     /**
743      * Returns true if the access to responses management on FO is based on the roles, false otherwise
744      * @return true if the access to responses management on FO is based on the roles, false otherwise
745      */ 
746      public boolean isAccessToResponsesByRole()
747      {
748          return _bAccessToResponsesByRole;
749      }
750  
751     /**
752      * Sets the AccessToResponsesByRole
753      * @param bAccessToResponsesByRole The AccessToResponsesByRole
754      */ 
755      public void setAccessToResponsesByRole( boolean bAccessToResponsesByRole )
756      {
757          _bAccessToResponsesByRole = bAccessToResponsesByRole;
758      }
759     /**
760      * Custom comparator for Availability Period sorting
761      */
762 	@Override
763 	public int compare(Formref="../../../../../../fr/paris/lutece/plugins/forms/business/Form.html#Form">Form form1, Form form2) {
764 		int nComparisonResult = NumberUtils.INTEGER_ZERO;
765 		if (form1 == null) {
766 			if (form2 != null) {
767 				nComparisonResult = NumberUtils.INTEGER_MINUS_ONE;
768 			}
769 		} else {
770 			if (form2 == null) {
771 				nComparisonResult = NumberUtils.INTEGER_ONE;
772 			} else {
773 				nComparisonResult = compareFormsAviability(form1, form2);
774 			}
775 		}
776 		return nComparisonResult;
777 	}
778 	
779 	private int compareFormsAviability(Formref="../../../../../../fr/paris/lutece/plugins/forms/business/Form.html#Form">Form form1, Form form2) {
780 		int nComparisonResult = NumberUtils.INTEGER_ZERO;
781 		if (form1.isActive()) {
782 			if (!form2.isActive()) {
783 				nComparisonResult = NumberUtils.INTEGER_ONE;
784 			}
785 		} else {
786 			if (form2.isActive()) {
787 				nComparisonResult = NumberUtils.INTEGER_MINUS_ONE;
788 			} else {
789 				boolean bIsSoonToBeActivatedForm1 = isSoonToBeActivated(form1);
790 				boolean bIsSoonToBeActivatedForm2 = isSoonToBeActivated(form2);
791 				if (bIsSoonToBeActivatedForm1 && !bIsSoonToBeActivatedForm2) {
792 					nComparisonResult = NumberUtils.INTEGER_ONE;
793 				} else if (!bIsSoonToBeActivatedForm1 && bIsSoonToBeActivatedForm2) {
794 					nComparisonResult = NumberUtils.INTEGER_MINUS_ONE;
795 				}
796 			}
797 		}
798 		return nComparisonResult;
799 	}
800 	
801 	/**
802 	 * Returns the soon to be activated status of a form
803 	 * @param form
804 	 * @return true if the form is soon to be activated, false otherwise
805 	 */
806 	private boolean isSoonToBeActivated(Form form) {
807 		Date dToday = new Date(System.currentTimeMillis());
808 		if (form != null && form.getAvailabilityStartDate() != null && form.getAvailabilityStartDate().after(dToday) ) {
809 			return true;
810 		}
811 		return false;
812 	}
813 }