View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.form.modules.datevalidators.service.validator;
35  
36  import fr.paris.lutece.plugins.form.business.FormSubmit;
37  import fr.paris.lutece.plugins.form.modules.datevalidators.business.ComparatorHome;
38  import fr.paris.lutece.plugins.form.modules.datevalidators.business.OperatorHome;
39  import fr.paris.lutece.plugins.form.modules.datevalidators.business.Rule;
40  import fr.paris.lutece.plugins.form.modules.datevalidators.business.RuleHome;
41  import fr.paris.lutece.plugins.form.modules.datevalidators.business.UnitHome;
42  import fr.paris.lutece.plugins.form.modules.datevalidators.business.comparator.IComparator;
43  import fr.paris.lutece.plugins.form.modules.datevalidators.business.operator.IOperator;
44  import fr.paris.lutece.plugins.form.modules.datevalidators.business.unit.IUnit;
45  import fr.paris.lutece.plugins.form.modules.datevalidators.service.DateValidatorsPlugin;
46  import fr.paris.lutece.plugins.form.modules.datevalidators.service.DateValidatorsResourceIdService;
47  import fr.paris.lutece.plugins.form.modules.datevalidators.service.DateValidatorsService;
48  import fr.paris.lutece.plugins.form.modules.datevalidators.util.DateValidatorsConstants;
49  import fr.paris.lutece.plugins.form.service.validator.Validator;
50  import fr.paris.lutece.plugins.genericattributes.business.EntryHome;
51  import fr.paris.lutece.plugins.genericattributes.business.Entry;
52  import fr.paris.lutece.plugins.genericattributes.business.Response;
53  import fr.paris.lutece.portal.business.rbac.RBAC;
54  import fr.paris.lutece.portal.service.admin.AdminUserService;
55  import fr.paris.lutece.portal.service.message.SiteMessage;
56  import fr.paris.lutece.portal.service.message.SiteMessageException;
57  import fr.paris.lutece.portal.service.message.SiteMessageService;
58  import fr.paris.lutece.portal.service.plugin.Plugin;
59  import fr.paris.lutece.portal.service.plugin.PluginService;
60  import fr.paris.lutece.portal.service.rbac.RBACService;
61  import fr.paris.lutece.portal.service.template.AppTemplateService;
62  import fr.paris.lutece.portal.service.util.AppLogService;
63  import fr.paris.lutece.portal.service.util.AppPathService;
64  import fr.paris.lutece.portal.service.util.AppPropertiesService;
65  import fr.paris.lutece.portal.web.constants.Parameters;
66  import fr.paris.lutece.util.date.DateUtil;
67  import fr.paris.lutece.util.html.HtmlTemplate;
68  import fr.paris.lutece.util.html.Paginator;
69  import fr.paris.lutece.util.sort.AttributeComparator;
70  import fr.paris.lutece.util.url.UrlItem;
71  
72  import java.util.Collections;
73  import java.util.Date;
74  import java.util.HashMap;
75  import java.util.List;
76  import java.util.Map;
77  
78  import javax.servlet.http.HttpServletRequest;
79  
80  import org.apache.commons.lang.StringUtils;
81  
82  
83  /**
84   * DateValidator
85   */
86  public class DateValidator extends Validator
87  {
88      // Markers
89      private static final String MARK_RULE_LIST = "rule_list";
90      private static final String MARK_PERMISSION_MANAGE = "permission_manage";
91  
92      // Template
93      private static final String TEMPLATE_MANAGE_RULE = "admin/plugins/form/modules/datevalidators/manage_rule.html";
94  
95      // Plugin
96      private static Plugin _plugin;
97  
98      // Paginator
99      private int _nDefaultItemsPerPage;
100     private String _strCurrentPageIndex;
101     private int _nItemsPerPage;
102 
103     /**
104      * Returns the unique instance of the plugin
105      * @return the unique instance of the plugin
106      */
107     private static Plugin getPlugin( )
108     {
109         if ( _plugin == null )
110         {
111             _plugin = PluginService.getPlugin( DateValidatorsPlugin.PLUGIN_NAME );
112         }
113 
114         return _plugin;
115     }
116 
117     /**
118      * Returns the validator interface
119      * @param request {@link HttpServletRequest}
120      * @param nIdForm the form id
121      * @return the validator interface
122      */
123     public String getUI( HttpServletRequest request, int nIdForm )
124     {
125         _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( DateValidatorsConstants.PROPERTY_ITEMS_PER_PAGE,
126                 10 );
127         _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
128         _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage,
129                 _nDefaultItemsPerPage );
130 
131         List<Rule> listRules = RuleHome.findRulesByForm( nIdForm, getPlugin( ) );
132 
133         String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );
134         String strAscSort = null;
135 
136         if ( strSortedAttributeName != null )
137         {
138             strAscSort = request.getParameter( Parameters.SORTED_ASC );
139 
140             boolean bIsAscSort = Boolean.parseBoolean( strAscSort );
141 
142             Collections.sort( listRules, new AttributeComparator( strSortedAttributeName, bIsAscSort ) );
143         }
144 
145         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request )
146                 + DateValidatorsConstants.JSP_MANAGE_VALIDATOR );
147         urlItem.addParameter( DateValidatorsConstants.PARAMETER_ID_FORM, nIdForm );
148 
149         if ( strSortedAttributeName != null )
150         {
151             urlItem.addParameter( Parameters.SORTED_ATTRIBUTE_NAME, strSortedAttributeName );
152         }
153 
154         if ( strAscSort != null )
155         {
156             urlItem.addParameter( Parameters.SORTED_ASC, strAscSort );
157         }
158 
159         Paginator<Rule> paginator = new Paginator<Rule>( listRules, _nItemsPerPage, urlItem.getUrl( ),
160                 Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
161 
162         Map<String, Object> model = new HashMap<String, Object>( );
163         model.put( DateValidatorsConstants.MARK_PAGINATOR, paginator );
164         model.put( DateValidatorsConstants.MARK_NB_ITEMS_PER_PAGE, Integer.toString( _nItemsPerPage ) );
165         model.put( MARK_RULE_LIST, paginator.getPageItems( ) );
166         model.put( DateValidatorsConstants.MARK_ID_FORM, nIdForm );
167         model.put( DateValidatorsConstants.MARK_SORTED_ATTRIBUTE_NAME, strSortedAttributeName );
168         model.put( DateValidatorsConstants.MARK_SORTED_ASC, strAscSort );
169         model.put( DateValidatorsConstants.MARK_ENTRY_LIST, DateValidatorsService.getAuthorizedEntries( nIdForm ) );
170         model.put( DateValidatorsConstants.MARK_COMPARATOR_LIST, ComparatorHome.findAll( getPlugin( ) ) );
171         addPermissions( request, model );
172 
173         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_RULE, request.getLocale( ), model );
174 
175         return template.getHtml( );
176     }
177 
178     /**
179      * Add permissions in the model
180      * @param request {@link HttpServletRequest}
181      * @param model The model
182      */
183     private void addPermissions( HttpServletRequest request, Map<String, Object> model )
184     {
185         // Create
186         boolean bPermissionCreate = false;
187 
188         if ( RBACService.isAuthorized( Rule.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID,
189                 DateValidatorsResourceIdService.PERMISSION_RULE_CREATE, AdminUserService.getAdminUser( request ) ) )
190         {
191             bPermissionCreate = true;
192         }
193 
194         model.put( DateValidatorsConstants.MARK_PERMISSION_CREATE, bPermissionCreate );
195 
196         // Modify
197         boolean bPermissionModify = false;
198 
199         if ( RBACService.isAuthorized( Rule.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID,
200                 DateValidatorsResourceIdService.PERMISSION_RULE_MODIFY, AdminUserService.getAdminUser( request ) ) )
201         {
202             bPermissionModify = true;
203         }
204 
205         model.put( DateValidatorsConstants.MARK_PERMISSION_MODIFY, bPermissionModify );
206 
207         // Delete
208         boolean bPermissionDelete = false;
209 
210         if ( RBACService.isAuthorized( Rule.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID,
211                 DateValidatorsResourceIdService.PERMISSION_RULE_DELETE, AdminUserService.getAdminUser( request ) ) )
212         {
213             bPermissionDelete = true;
214         }
215 
216         model.put( DateValidatorsConstants.MARK_PERMISSION_DELETE, bPermissionDelete );
217 
218         // Manage calculated dates
219         boolean bPermissionManage = false;
220 
221         if ( RBACService.isAuthorized( Rule.RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID,
222                 DateValidatorsResourceIdService.PERMISSION_DATE_CALCULATED_MANAGE,
223                 AdminUserService.getAdminUser( request ) ) )
224         {
225             bPermissionManage = true;
226         }
227 
228         model.put( MARK_PERMISSION_MANAGE, bPermissionManage );
229     }
230 
231     /**
232      * Checks if the validator is associated with the form
233      * @param nIdForm the form id
234      * @return true if the validator is associated with the form, otherwise
235      *         false
236      */
237     public boolean isAssociatedWithForm( int nIdForm )
238     {
239         return ( RuleHome.findRulesByForm( nIdForm, getPlugin( ) ).size( ) > 0 );
240     }
241 
242     /**
243      * Removes the associations with the form
244      * @param nIdForm the form id
245      */
246     public void removeAssociationsWithForm( int nIdForm )
247     {
248         for ( Rule rule : RuleHome.findRulesByForm( nIdForm, getPlugin( ) ) )
249         {
250             RuleHome.remove( rule.getIdRule( ), getPlugin( ) );
251         }
252     }
253 
254     /**
255      * Validates the form
256      * @param request {@link HttpServletRequest}
257      * @param formSubmit the form submit
258      * @param formPlugin the form plugin
259      * @throws SiteMessageException throws SiteMessageException
260      */
261     public void validateForm( HttpServletRequest request, FormSubmit formSubmit, Plugin formPlugin )
262             throws SiteMessageException
263     {
264         // Checks that all rules are followed
265         for ( Rule rule : RuleHome.findRulesByForm( formSubmit.getForm( ).getIdForm( ), getPlugin( ) ) )
266         {
267             // Entry
268             if ( rule.getIdEntry2( ) != null )
269             {
270                 validateRuleEntry( request, formSubmit, formPlugin, rule );
271             }
272 
273             // Reference date
274             else if ( rule.getDateReference( ) != null )
275             {
276                 validateRuleDateReference( request, formSubmit, formPlugin, rule );
277             }
278 
279             // Calculated date
280             else if ( rule.getDateCalculated( ) != null )
281             {
282                 validateRuleDateCalculated( request, formSubmit, formPlugin, rule );
283             }
284         }
285     }
286 
287     /**
288      * Validates the rule of type entry
289      * @param request {@link HttpServletRequest}
290      * @param formSubmit the form submit
291      * @param formPlugin the form plugin
292      * @param rule the rule
293      * @throws SiteMessageException throws SiteMessageException
294      */
295     private void validateRuleEntry( HttpServletRequest request, FormSubmit formSubmit, Plugin formPlugin, Rule rule )
296             throws SiteMessageException
297     {
298         // Gets the dates
299         Date dateEntry1 = null;
300         Date dateEntry2 = null;
301 
302         for ( Response response : formSubmit.getListResponse( ) )
303         {
304             if ( response.getEntry( ).getIdEntry( ) == rule.getIdEntry1( ) )
305             {
306                 dateEntry1 = DateUtil.formatDate(response.getResponseValue( ), request.getLocale());
307             }
308             else if ( response.getEntry( ).getIdEntry( ) == rule.getIdEntry2( ) )
309             {
310                 dateEntry2 = DateUtil.formatDate(response.getResponseValue( ), request.getLocale());
311             }
312 
313             // Break
314             if ( ( dateEntry1 != null ) && ( dateEntry2 != null ) )
315             {
316                 break;
317             }
318         }
319 
320         // Gets the comparator
321         String strClassName = ComparatorHome.findByPrimaryKey( rule.getIdComparator( ), getPlugin( ) ).getClassName( );
322 
323         if ( ( dateEntry1 != null ) && ( dateEntry2 != null ) && StringUtils.isNotBlank( strClassName ) )
324         {
325             try
326             {
327                 // Instanciates the comparator
328                 IComparator comparator = (IComparator) Class.forName( strClassName ).newInstance( );
329 
330                 // Compares the dates
331                 if ( !comparator.compare( dateEntry1, dateEntry2 ) )
332                 {
333                     Entry entry1 = EntryHome.findByPrimaryKey( rule.getIdEntry1( ) );
334                     Entry entry2 = EntryHome.findByPrimaryKey( rule.getIdEntry2( ) );
335 
336                     Object[] messageArgs = { entry1.getTitle( ), entry2.getTitle( ) };
337 
338                     SiteMessageService.setMessage( request, comparator.getMessage( ), messageArgs,
339                             SiteMessage.TYPE_ERROR );
340                 }
341             }
342             catch ( InstantiationException e )
343             {
344                 AppLogService.error( e.getMessage( ), e );
345             }
346             catch ( IllegalAccessException e )
347             {
348                 AppLogService.error( e.getMessage( ), e );
349             }
350             catch ( ClassNotFoundException e )
351             {
352                 AppLogService.error( e.getMessage( ), e );
353             }
354         }
355     }
356 
357     /**
358      * Validates the rule of type reference date
359      * @param request {@link HttpServletRequest}
360      * @param formSubmit the form submit
361      * @param formPlugin the form plugin
362      * @param rule the rule
363      * @throws SiteMessageException throws SiteMessageException
364      */
365     private void validateRuleDateReference( HttpServletRequest request, FormSubmit formSubmit, Plugin formPlugin,
366             Rule rule ) throws SiteMessageException
367     {
368         // Gets the entry date
369         Date dateEntry = null;
370 
371         for ( Response response : formSubmit.getListResponse( ) )
372         {
373             if ( response.getEntry( ).getIdEntry( ) == rule.getIdEntry1( ) )
374             {
375                 dateEntry = DateUtil.formatDate(response.getResponseValue( ), request.getLocale());
376 
377                 break;
378             }
379         }
380 
381         // Gets the comparator
382         String strClassName = ComparatorHome.findByPrimaryKey( rule.getIdComparator( ), getPlugin( ) ).getClassName( );
383 
384         if ( ( dateEntry != null ) && StringUtils.isNotBlank( strClassName ) )
385         {
386             try
387             {
388                 // Instanciates the comparator
389                 IComparator comparator = (IComparator) Class.forName( strClassName ).newInstance( );
390 
391                 // Compares the dates
392                 if ( !comparator.compare( dateEntry, rule.getDateReference( ) ) )
393                 {
394                     Entry entry = EntryHome.findByPrimaryKey( rule.getIdEntry1( ) );
395                     String strDateReference = DateUtil.getDateString( rule.getDateReference( ), request.getLocale( ) );
396 
397                     Object[] messageArgs = { entry.getTitle( ), strDateReference };
398 
399                     SiteMessageService.setMessage( request, comparator.getMessage( ), messageArgs,
400                             SiteMessage.TYPE_ERROR );
401                 }
402             }
403             catch ( InstantiationException e )
404             {
405                 AppLogService.error( e.getMessage( ), e );
406             }
407             catch ( IllegalAccessException e )
408             {
409                 AppLogService.error( e.getMessage( ), e );
410             }
411             catch ( ClassNotFoundException e )
412             {
413                 AppLogService.error( e.getMessage( ), e );
414             }
415         }
416     }
417 
418     /**
419      * Validates the rule of type calculated date
420      * @param request {@link HttpServletRequest}
421      * @param formSubmit the form submit
422      * @param formPlugin the form plugin
423      * @param rule the rule
424      * @throws SiteMessageException throws SiteMessageException
425      */
426     private void validateRuleDateCalculated( HttpServletRequest request, FormSubmit formSubmit, Plugin formPlugin,
427             Rule rule ) throws SiteMessageException
428     {
429         // Gets the entry date
430         Date dateEntry = null;
431 
432         for ( Response response : formSubmit.getListResponse( ) )
433         {
434             if ( response.getEntry( ).getIdEntry( ) == rule.getIdEntry1( ) )
435             {
436                 dateEntry = DateUtil.formatDate(response.getResponseValue( ), request.getLocale());
437 
438                 break;
439             }
440         }
441 
442         // Gets the calendar field (unit)
443         String strUnitClassName = UnitHome.findByPrimaryKey( rule.getDateCalculated( ).getUnit( ).getIdUnit( ),
444                 getPlugin( ) ).getClassName( );
445         Integer nCalendarField = null;
446 
447         if ( StringUtils.isNotBlank( strUnitClassName ) )
448         {
449             try
450             {
451                 // Instantiates the unit
452                 IUnit unit = (IUnit) Class.forName( strUnitClassName ).newInstance( );
453 
454                 // Gets the calendarField
455                 nCalendarField = unit.getCalendarField( );
456             }
457             catch ( InstantiationException e )
458             {
459                 AppLogService.error( e.getMessage( ), e );
460             }
461             catch ( IllegalAccessException e )
462             {
463                 AppLogService.error( e.getMessage( ), e );
464             }
465             catch ( ClassNotFoundException e )
466             {
467                 AppLogService.error( e.getMessage( ), e );
468             }
469         }
470 
471         // Gets the calculated date (operator)
472         String strOperatorClassName = OperatorHome.findByPrimaryKey(
473                 rule.getDateCalculated( ).getOperator( ).getIdOperator( ), getPlugin( ) ).getClassName( );
474         Date dateCalculated = null;
475 
476         if ( ( nCalendarField != null ) && StringUtils.isNotBlank( strOperatorClassName ) )
477         {
478             try
479             {
480                 // Instanciates the operator
481                 IOperator operator = (IOperator) Class.forName( strOperatorClassName ).newInstance( );
482 
483                 // Calculates the date
484                 dateCalculated = operator.calculate( rule.getDateCalculated( ).getDateReference( ), nCalendarField,
485                         rule.getDateCalculated( ).getNumber( ) );
486             }
487             catch ( InstantiationException e )
488             {
489                 AppLogService.error( e.getMessage( ), e );
490             }
491             catch ( IllegalAccessException e )
492             {
493                 AppLogService.error( e.getMessage( ), e );
494             }
495             catch ( ClassNotFoundException e )
496             {
497                 AppLogService.error( e.getMessage( ), e );
498             }
499         }
500 
501         // Gets the comparator
502         String strComparatorClassName = ComparatorHome.findByPrimaryKey( rule.getIdComparator( ), getPlugin( ) )
503                 .getClassName( );
504 
505         if ( ( dateEntry != null ) && ( dateCalculated != null ) && StringUtils.isNotBlank( strComparatorClassName ) )
506         {
507             try
508             {
509                 // Instanciates the comparator
510                 IComparator comparator = (IComparator) Class.forName( strComparatorClassName ).newInstance( );
511 
512                 // Compares the dates
513                 if ( !comparator.compare( dateEntry, dateCalculated ) )
514                 {
515                     Entry entry = EntryHome.findByPrimaryKey( rule.getIdEntry1( ) );
516                     String strDateCalculated = DateUtil.getDateString( dateCalculated, request.getLocale( ) );
517 
518                     Object[] messageArgs = { entry.getTitle( ), strDateCalculated };
519 
520                     SiteMessageService.setMessage( request, comparator.getMessage( ), messageArgs,
521                             SiteMessage.TYPE_ERROR );
522                 }
523             }
524             catch ( InstantiationException e )
525             {
526                 AppLogService.error( e.getMessage( ), e );
527             }
528             catch ( IllegalAccessException e )
529             {
530                 AppLogService.error( e.getMessage( ), e );
531             }
532             catch ( ClassNotFoundException e )
533             {
534                 AppLogService.error( e.getMessage( ), e );
535             }
536         }
537     }
538 }