View Javadoc
1   /*
2    * Copyright (c) 2002-2020, 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 java.io.IOException;
37  import java.text.DateFormat;
38  import java.text.ParseException;
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.Date;
42  import java.util.HashMap;
43  import java.util.List;
44  import java.util.Locale;
45  import java.util.Map;
46  
47  import javax.servlet.http.HttpServletRequest;
48  import javax.validation.constraints.NotNull;
49  
50  import org.apache.commons.collections.CollectionUtils;
51  import org.apache.commons.lang.StringUtils;
52  
53  import fr.paris.lutece.plugins.announce.business.Announce;
54  import fr.paris.lutece.plugins.announce.business.AnnounceDTO;
55  import fr.paris.lutece.plugins.announce.business.AnnounceHome;
56  import fr.paris.lutece.plugins.announce.business.AnnounceSearchFilter;
57  import fr.paris.lutece.plugins.announce.business.AnnounceSearchFilterHome;
58  import fr.paris.lutece.plugins.announce.business.AnnounceSort;
59  import fr.paris.lutece.plugins.announce.business.Category;
60  import fr.paris.lutece.plugins.announce.business.CategoryHome;
61  import fr.paris.lutece.plugins.announce.business.Sector;
62  import fr.paris.lutece.plugins.announce.business.SectorHome;
63  import fr.paris.lutece.plugins.announce.service.AnnounceService;
64  import fr.paris.lutece.plugins.announce.service.AnnounceSubscriptionProvider;
65  import fr.paris.lutece.plugins.announce.service.announcesearch.AnnounceSearchService;
66  import fr.paris.lutece.plugins.announce.service.upload.AnnounceAsynchronousUploadHandler;
67  import fr.paris.lutece.plugins.announce.utils.AnnounceUtils;
68  import fr.paris.lutece.plugins.genericattributes.business.Entry;
69  import fr.paris.lutece.plugins.genericattributes.business.EntryFilter;
70  import fr.paris.lutece.plugins.genericattributes.business.EntryHome;
71  import fr.paris.lutece.plugins.genericattributes.business.Field;
72  import fr.paris.lutece.plugins.genericattributes.business.GenericAttributeError;
73  import fr.paris.lutece.plugins.genericattributes.business.Response;
74  import fr.paris.lutece.plugins.genericattributes.business.ResponseHome;
75  import fr.paris.lutece.plugins.module.announce.subscribe.business.AnnounceSubscribtionDTO;
76  import fr.paris.lutece.plugins.subscribe.web.SubscribeApp;
77  import fr.paris.lutece.portal.business.mailinglist.Recipient;
78  import fr.paris.lutece.portal.service.captcha.CaptchaSecurityService;
79  import fr.paris.lutece.portal.service.i18n.I18nService;
80  import fr.paris.lutece.portal.service.mail.MailService;
81  import fr.paris.lutece.portal.service.mailinglist.AdminMailingListService;
82  import fr.paris.lutece.portal.service.message.SiteMessage;
83  import fr.paris.lutece.portal.service.message.SiteMessageException;
84  import fr.paris.lutece.portal.service.message.SiteMessageService;
85  import fr.paris.lutece.portal.service.portal.PortalService;
86  import fr.paris.lutece.portal.service.security.LuteceUser;
87  import fr.paris.lutece.portal.service.security.SecurityService;
88  import fr.paris.lutece.portal.service.security.UserNotSignedException;
89  import fr.paris.lutece.portal.service.spring.SpringContextService;
90  import fr.paris.lutece.portal.service.template.AppTemplateService;
91  import fr.paris.lutece.portal.service.util.AppLogService;
92  import fr.paris.lutece.portal.service.util.AppPathService;
93  import fr.paris.lutece.portal.service.util.AppPropertiesService;
94  import fr.paris.lutece.portal.service.workflow.WorkflowService;
95  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
96  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
97  import fr.paris.lutece.portal.util.mvc.utils.MVCUtils;
98  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
99  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
100 import fr.paris.lutece.portal.web.LocalVariables;
101 import fr.paris.lutece.portal.web.constants.Messages;
102 import fr.paris.lutece.portal.web.constants.Parameters;
103 import fr.paris.lutece.portal.web.util.LocalizedDelegatePaginator;
104 import fr.paris.lutece.portal.web.xpages.XPage;
105 import fr.paris.lutece.util.file.FileUtil;
106 import fr.paris.lutece.util.html.AbstractPaginator;
107 import fr.paris.lutece.util.html.HtmlTemplate;
108 import fr.paris.lutece.util.html.Paginator;
109 import fr.paris.lutece.util.url.UrlItem;
110 
111 /**
112  * This class manages Announce page.
113  */
114 @Controller( xpageName = AnnounceUtils.PARAMETER_PAGE_ANNOUNCE, pageTitleI18nKey = AnnounceApp.PROPERTY_PAGE_TITLE, pagePathI18nKey = AnnounceApp.PROPERTY_PAGE_PATH )
115 public class AnnounceApp extends MVCApplication
116 {
117     // Public properties
118     /**
119      * The title of the default page
120      */
121     public static final String PROPERTY_PAGE_TITLE = "announce.page_announce.pageTitle";
122 
123     /**
124      * The default path of pages of this application
125      */
126     public static final String PROPERTY_PAGE_PATH = "announce.page_announce.pageFPathLabel";
127     private static final long serialVersionUID = 3586318619582357870L;
128     private static final String PARAMETER_USERNAME = "username";
129 
130     // Jsp redirections
131     private static final String JSP_PORTAL = "jsp/site/Portal.jsp";
132 
133     // Parameters
134     private static final String PARAMETER_FORM_SEND = "form_send";
135     private static final String PARAMETER_PAGE = "page";
136     private static final String PARAMETER_SECTOR_ID = "sector_id";
137     private static final String PARAMETER_CATEGORY_ID = "category_id";
138     private static final String PARAMETER_TITLE_ANNOUNCE = "title_announce";
139     private static final String PARAMETER_DESCRIPTION_ANNOUNCE = "description_announce";
140     private static final String PARAMETER_PRICE_ANNOUNCE = "price_announce";
141     private static final String PARAMETER_CONTACT_INFORMATION = "contact_information";
142     private static final String PARAMETER_CONFIRM_REMOVE_ANNOUNCE = "confirm_remove";
143     private static final String PARAMETER_CONFIRM_SUSPEND_ANNOUNCE = "confirm_suspend";
144     private static final String PARAMETER_ANNOUNCE_ID = "announce_id";
145     private static final String PARAMETER_KEYWORDS = "keywords";
146     private static final String PARAMETER_DATE_MIN = "date_min";
147     private static final String PARAMETER_DATE_MAX = "date_max";
148     private static final String PARAMETER_PRICE_MIN = "price_min";
149     private static final String PARAMETER_PRICE_MAX = "price_max";
150     private static final String PARAMETER_PAGE_INDEX = "page_index";
151     private static final String PARAMETER_TAGS = "tags";
152     private static final String PARAMETER_HAS_FILTER = "hasFilter";
153     private static final String PARAMETER_ID_FILTER = "id_filter";
154     private static final String PARAMETER_SORT_BY = "sortBy";
155 
156     // Actions
157     private static final String ACTION_VIEW_ANNOUNCE = "view_announce";
158     private static final String ACTION_VIEW_ANNOUNCES = "view_announces";
159     private static final String ACTION_MY_ANNOUNCES = "my_announces";
160     private static final String ACTION_MODIFY_ANNOUNCE = "modify_announce";
161     private static final String ACTION_DELETE_ANNOUNCE = "delete_announce";
162     private static final String ACTION_SUSPEND_ANNOUNCE_BY_USER = "suspend_by_user";
163     private static final String ACTION_ENABLE_ANNOUNCE_BY_USER = "enable_by_user";
164     private static final String ACTION_VIEW_SUBSCRIPTIONS = "view_subscriptions";
165     private static final String ACTION_SEARCH = "search";
166     private static final String ACTION_ADDNEW = "addnew";
167 
168     // Views
169     private static final String VIEW_DEFAULT_PAGE = "viewDefaultPage";
170 
171     // Validation flags
172     private static final int PARAMETER_ANNOUNCES_VALIDATION_GLOBAL_PARAMETERS = 0;
173     private static final int PARAMETER_ANNOUNCES_VALIDATION_YES = 1;
174     private static final int PARAMETER_ANNOUNCES_VALIDATION_NO = 2;
175 
176     // properties
177     private static final String PROPERTY_NOT_AUTHORIZED = "announce.messages.notAuthorized";
178     private static final String PROPERTY_QUOTA_EXCEEDED = "announce.messages.quotaExceeded";
179     private static final String PROPERTY_REFUSED_ACCESS = "announce.messages.refusedAccess";
180     private static final String PROPERTY_CONFIRM_REMOVE_ANNOUNCE = "announce.messages.confirmRemoveAnnounce";
181     private static final String PROPERTY_CONFIRM_SUSPEND_ANNOUNCE = "announce.messages.confirmSuspendAnnounce";
182     private static final String PROPERTY_PAGE_TITLE_SEARCH_RESULTS = "announce.search_results.pageTitle";
183     private static final String PROPERTY_PAGE_TITLE_MODIFY_ANNOUNCE = "announce.modify_announce.pageTitle";
184     private static final String PROPERTY_PAGE_TITLE_MY_ANNOUNCES = "announce.my_announces.pageTitle";
185     private static final String PROPERTY_PAGE_TITLE_CREATE_ANNOUNCE = "announce.create_announce.pageTitle";
186     private static final String PROPERTY_DEFAULT_FRONT_LIST_ANNOUNCE_PER_PAGE = "announce.front.announce.defaultItemsPerPage";
187     private static final String PROPERTY_WEBMASTER_EMAIL = "email.webmaster";
188     private static final String PROPERTY_WEBMASTER_NAME = "lutece.name";
189     private static final String PROPERTY_ANNOUNCE_NOTIFY_SUBJECT = "announce.notification.subject";
190     private static final String PROPERTY_PROD_URL = "lutece.prod.url";
191     private static final String PROPERTY_MAX_AMOUNT_ANNOUNCE = "announce.announce.qty.max";
192 
193     // Templates
194     private static final String TEMPLATE_PAGE_CREATE_ANNOUNCE_STEP_CATEGORY = "skin/plugins/announce/create_announce_step_category.html";
195     private static final String TEMPLATE_PAGE_CREATE_ANNOUNCE_STEP_FORM = "skin/plugins/announce/create_announce_step_form.html";
196     private static final String TEMPLATE_VIEW_ANNOUNCE = "skin/plugins/announce/view_announce.html";
197     private static final String TEMPLATE_VIEW_ANNOUNCES = "skin/plugins/announce/view_announces.html";
198     private static final String TEMPLATE_MY_ANNOUNCES = "skin/plugins/announce/my_announces.html";
199     private static final String TEMPLATE_MODIFY_ANNOUNCE = "skin/plugins/announce/modify_announce.html";
200     private static final String TEMPLATE_LIST_ANNOUNCES = "skin/plugins/announce/list_announces.html";
201     private static final String TEMPLATE_LIST_ANNOUNCES_BY_ID = "skin/plugins/announce/list_announces_by_id.html";
202     private static final String TEMPLATE_ANNOUNCE_NOTIFY_MESSAGE = "skin/plugins/announce/announce_notify_message.html";
203 
204     // Session keys
205     private static final String SESSION_KEY_ANNOUNCE_FILTER = "announce.session.announceSearchFilter";
206 
207     // Markers
208     private static final String MARK_LIST_FIELDS = "list_sectors";
209     private static final String MARK_LOCALE = "locale";
210     private static final String MARK_CATEGORY = "category";
211     private static final String MARK_SECTOR = "sector";
212     private static final String MARK_ANNOUNCES_LIST = "announces_list";
213     private static final String MARK_ANNOUNCES_PUBLISHED_AMOUNT = "announce_qty";
214     private static final String MARK_CONTACT_INFORMATION = "contact_information";
215     private static final String MARK_LIST_RESPONSES = "list_responses";
216     private static final String MARK_USER = "user";
217     private static final String FULL_URL = "fullurl";
218     private static final String MARK_FILTER_DATE_MIN = "filter_date_min";
219     private static final String MARK_FILTER_DATE_MAX = "filter_date_max";
220     private static final String MARK_FILTER = "filter";
221     private static final String MARK_ANNOUNCE = "announce";
222     private static final String MARK_ANNOUNCE_OWNER = "owner";
223     private static final String MARK_ANNOUNCE_OWNER_NAME = "owner_name";
224     private static final String MARK_HAS_SUBSCRIBED_TO_USER = "hasSubscribedToUser";
225     private static final String MARK_ALLOW_ACCESS = "allow_access";
226     private static final String MARK_USER_IS_AUTHOR = "user_is_author";
227     private static final String MARK_PAGINATOR = "paginator";
228     private static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
229     private static final String MARK_MODERATED = "moderated";
230     private static final String MARK_PROD_URL = "prod_url";
231     private static final String MARK_FORM_HTML = "form_html";
232     private static final String MARK_LIST_ERRORS = "list_errors";
233     private static final String MARK_IS_EXTEND_INSTALLED = "isExtendInstalled";
234     private static final String MARK_CAPTCHA = "captcha";
235     private static final String MARK_LIST_SECTORS = "list_sectors";
236     private static final String MARK_LIST_CATEGORIES = "list_sector_categories";
237     private static final String MARK_ENTRY_LIST_GEOLOCATION = "list_entryTypeGeolocation";
238     // Messages
239     private static final String ERROR_MESSAGE_WRONG_CAPTCHA = "portal.admin.message.wrongCaptcha";
240 
241     // Constants
242     private static final String CONSTANT_BLANK_SPACE = " ";
243     private static final String CONSTANT_COMA = ",";
244     private static final String CONSTANT_POINT = ".";
245 
246     // Session keys
247     private static final String SESSION_ATTRIBUTE_MY_ANNOUNCES_ITEMS_PER_PAGE = "announce.myAnnouncesItemsPerPage";
248 
249     // defaults
250     private static final String DEFAULT_PAGE_INDEX = "1";
251     private static final CaptchaSecurityService _captchaSecurityService = new CaptchaSecurityService( );
252 
253     // private fields
254     private AnnounceService _announceService = SpringContextService.getBean( AnnounceService.BEAN_NAME );
255     private int _nDefaultItemsPerPage;
256     private String _strCurrentPageIndex;
257     private int _nItemsPerPage;
258 
259     /**
260      * Date format for filters
261      */
262     private final DateFormat _dateFormat = AnnounceService.getDateFormat( );
263 
264     /**
265      * Get the default page to display
266      * 
267      * @param request
268      *            The request
269      * @return The HTML content to display
270      */
271     @View( value = VIEW_DEFAULT_PAGE, defaultView = true )
272     public XPage getDefaultPage( HttpServletRequest request )
273     {
274         request.getSession( ).removeAttribute( SESSION_KEY_ANNOUNCE_FILTER );
275 
276         return getSearchAnnounces( request );
277     }
278 
279     /**
280      * Get the page to search for announces
281      * 
282      * @param request
283      *            The request
284      * @return The HTML content to displayed
285      */
286     @Action( ACTION_SEARCH )
287     public XPage getSearchAnnounces( HttpServletRequest request )
288     {
289         _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, DEFAULT_PAGE_INDEX );
290         _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_FRONT_LIST_ANNOUNCE_PER_PAGE, 10 );
291         _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, _nDefaultItemsPerPage );
292 
293         AnnounceSearchFilter filter = getAnnounceFilterFromRequest( request );
294 
295         int nCurrentPageIndex = ( StringUtils.isNotEmpty( _strCurrentPageIndex ) && StringUtils.isNumeric( _strCurrentPageIndex ) )
296                 ? Integer.parseInt( _strCurrentPageIndex )
297                 : 1;
298         List<Announce> listAnnouncesResults = new ArrayList<>( );
299 
300         // -------------------------SORT---------------------------------
301 
302         String strSort = ( request.getParameter( PARAMETER_SORT_BY ) == null ? "" : request.getParameter( PARAMETER_SORT_BY ) );
303         AnnounceSort anSort = AnnounceSort.DEFAULT_SORT;
304         String strUrl = getUrlSearchAnnounceSort( request, 5 );
305 
306         if ( strSort.compareTo( "date_modification" ) == 0 )
307         {
308             anSort = AnnounceSort.getAnnounceSort( AnnounceSort.SORT_DATE_MODIFICATION, false );
309             strUrl = getUrlSearchAnnounceSort( request, 1 );
310         }
311 
312         if ( strSort.compareTo( PARAMETER_TITLE_ANNOUNCE ) == 0 )
313         {
314             anSort = AnnounceSort.getAnnounceSort( AnnounceSort.SORT_TITLE, true );
315             strUrl = getUrlSearchAnnounceSort( request, 2 );
316         }
317         if ( strSort.compareTo( PARAMETER_PRICE_ANNOUNCE ) == 0 )
318         {
319             anSort = AnnounceSort.getAnnounceSort( AnnounceSort.SORT_PRICE, true );
320             strUrl = getUrlSearchAnnounceSort( request, 3 );
321         }
322         if ( strSort.compareTo( PARAMETER_DESCRIPTION_ANNOUNCE ) == 0 )
323         {
324             anSort = AnnounceSort.getAnnounceSort( AnnounceSort.SORT_DESCRIPTION, true );
325             strUrl = getUrlSearchAnnounceSort( request, 4 );
326         }
327 
328         int nNbItems = AnnounceSearchService.getInstance( ).getSearchResultsBis( filter, nCurrentPageIndex, _nItemsPerPage, listAnnouncesResults, anSort );
329 
330         // --------------------------END SORT----------------------------------
331 
332         LocalizedDelegatePaginator<Announce> paginator = new LocalizedDelegatePaginator<>( listAnnouncesResults, _nItemsPerPage, strUrl, PARAMETER_PAGE_INDEX,
333                 _strCurrentPageIndex, nNbItems, request.getLocale( ) );
334 
335         Map<String, Object> model = new HashMap<>( );
336         model.put( MARK_NB_ITEMS_PER_PAGE, Integer.toString( _nItemsPerPage ) );
337         model.put( MARK_PAGINATOR, paginator );
338         model.put( MARK_LIST_FIELDS, getSectorList( ) );
339         model.put( MARK_LOCALE, request.getLocale( ) );
340 
341         for ( Announce announce : paginator.getPageItems( ) )
342         {
343             announce.setListIdImageResponse( AnnounceHome.findListIdImageResponse( announce.getId( ) ) );
344         }
345 
346         model.put( MARK_ANNOUNCES_LIST, paginator.getPageItems( ) );
347         model.put( MARK_FILTER_DATE_MIN, ( filter.getDateMin( ) != null ) ? _dateFormat.format( filter.getDateMin( ) ) : null );
348         model.put( MARK_FILTER_DATE_MAX, ( filter.getDateMax( ) != null ) ? _dateFormat.format( filter.getDateMax( ) ) : null );
349         model.put( MARK_FILTER, filter );
350 
351         LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
352         model.put( MARK_USER, user );
353 
354         // useful if you want to work with Portal.jsp and RunStandaloneApp.jsp
355         model.put( FULL_URL, request.getRequestURL( ) );
356 
357         model.put( MARK_LIST_SECTORS, AnnounceApp.getSectorList( ) );
358         int nIdSector = ( request.getParameter( PARAMETER_SECTOR_ID ) == null ? 0 : Integer.parseInt( request.getParameter( PARAMETER_SECTOR_ID ) ) );
359         model.put( MARK_LIST_CATEGORIES, AnnounceApp.getCategoryList( nIdSector ) );
360         model.put( "sortArg", anSort.getSortColumn( ) );
361         model.put( PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
362         model.put( "nbItem", nNbItems );
363         if ( SecurityService.isAuthenticationEnable( ) )
364         {
365             model.put( MARK_USER, SecurityService.getInstance( ).getRegisteredUser( request ) );
366         }
367 
368         XPage page = getXPage( TEMPLATE_LIST_ANNOUNCES, request.getLocale( ), model );
369         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_SEARCH_RESULTS, request.getLocale( ) ) );
370 
371         return page;
372     }
373 
374     /**
375      * Get the HTML to describe a list of announces
376      * 
377      * @param request
378      *            The request
379      * @param listIdAnnounces
380      *            The list of ids of announces
381      * @param announceSort
382      *            the sort to use
383      * @return The HTML content to display
384      */
385     public static String getAnnounceListById( HttpServletRequest request, List<Integer> listIdAnnounces, AnnounceSort announceSort )
386     {
387         List<Announce> listAnnounces = AnnounceHome.findByListId( listIdAnnounces, announceSort );
388 
389         Map<String, Object> model = new HashMap<>( );
390         model.put( MARK_LIST_FIELDS, getSectorList( ) );
391         model.put( MARK_LOCALE, request.getLocale( ) );
392 
393         for ( Announce announce : listAnnounces )
394         {
395             announce.setListIdImageResponse( AnnounceHome.findListIdImageResponse( announce.getId( ) ) );
396         }
397 
398         model.put( MARK_ANNOUNCES_LIST, listAnnounces );
399 
400         LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
401         model.put( MARK_USER, user );
402 
403         // useful if you want to work with Portal.jsp and RunStandaloneApp.jsp
404         model.put( FULL_URL, request.getRequestURL( ) );
405 
406         model.put( MARK_LIST_SECTORS, AnnounceApp.getSectorList( ) );
407 
408         if ( SecurityService.isAuthenticationEnable( ) )
409         {
410             model.put( MARK_USER, SecurityService.getInstance( ).getRegisteredUser( request ) );
411         }
412 
413         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_LIST_ANNOUNCES_BY_ID, request.getLocale( ), model );
414 
415         return template.getHtml( );
416     }
417 
418     /**
419      * Get the page to create an announce
420      * 
421      * @param request
422      *            The request
423      * @return The HTML content to display
424      * @throws SiteMessageException
425      *             If a site message needs to be displayed
426      */
427     @Action( ACTION_ADDNEW )
428     public XPage getCreateAnnounce( HttpServletRequest request ) throws SiteMessageException
429     {
430         LuteceUser user = getLuteceUserAuthentication( request );
431 
432         String strCategoryId = request.getParameter( PARAMETER_CATEGORY_ID );
433         String strFormSend = request.getParameter( PARAMETER_FORM_SEND );
434         Map<String, Object> model = new HashMap<>( );
435 
436         /* CATEOGRY */
437         if ( ( strCategoryId != null ) && ( Integer.parseInt( strCategoryId ) != 0 ) )
438         {
439             Category category = CategoryHome.findByPrimaryKey( Integer.parseInt( strCategoryId ) );
440             Sector sector = SectorHome.findByPrimaryKey( category.getIdSector( ) );
441             Announce announce = null;
442 
443             /* FORM */
444             if ( strFormSend != null )
445             {
446                 announce = new Announce( );
447                 model.put( MARK_CATEGORY, category );
448 
449                 List<GenericAttributeError> listErrors = doCreateAnnounce( request, sector, category, announce, user );
450 
451                 if ( CollectionUtils.isEmpty( listErrors ) )
452                 {
453                     try
454                     {
455                         LocalVariables.getResponse( ).sendRedirect( getUrlViewAnnounce( request, announce.getId( ) ) );
456                     }
457                     catch( IOException e )
458                     {
459                         AppLogService.error( e.getMessage( ), e );
460                     }
461                 }
462 
463                 model.put( MARK_LIST_ERRORS, listErrors );
464             }
465             else
466             {
467                 AnnounceAsynchronousUploadHandler.getHandler( ).removeSessionFiles( request.getSession( ).getId( ) );
468             }
469 
470             model.put( MARK_ANNOUNCE, announce );
471             model.put( MARK_CONTACT_INFORMATION, user.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL ) );
472 
473             XPage page = getAnnounceFormHtml( request, announce, category, request.getLocale( ), model );
474             page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_CREATE_ANNOUNCE, request.getLocale( ) ) );
475 
476             return page;
477         }
478 
479         AnnounceAsynchronousUploadHandler.getHandler( ).removeSessionFiles( request.getSession( ).getId( ) );
480 
481         Collection<Announce> listAnnounces = AnnounceHome.getAnnouncesForUser( user, AnnounceSort.DEFAULT_SORT );
482 
483         if ( listAnnounces.size( ) < AppPropertiesService.getPropertyInt( PROPERTY_MAX_AMOUNT_ANNOUNCE, 20 ) )
484         {
485             model.put( MARK_LIST_FIELDS, getSectorList( ) );
486 
487             XPage page = getXPage( TEMPLATE_PAGE_CREATE_ANNOUNCE_STEP_CATEGORY, request.getLocale( ), model );
488             page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_CREATE_ANNOUNCE, request.getLocale( ) ) );
489 
490             return page;
491         }
492 
493         SiteMessageService.setMessage( request, PROPERTY_QUOTA_EXCEEDED, SiteMessage.TYPE_STOP );
494 
495         return null;
496     }
497 
498     /**
499      * Get the page to create an announce
500      * 
501      * @param request
502      *            The request
503      * @return The HTML content to display
504      * @throws SiteMessageException
505      *             If a site message needs to be displayed
506      */
507     @Action( ACTION_MODIFY_ANNOUNCE )
508     public XPage getModifyAnnounce( HttpServletRequest request ) throws SiteMessageException
509     {
510         LuteceUser user = getLuteceUserAuthentication( request );
511         int nIdAnnounce = Integer.parseInt( request.getParameter( PARAMETER_ANNOUNCE_ID ) );
512         Announce announce = getAuthorizedAnnounce( nIdAnnounce, user, request );
513 
514         String strFormSend = request.getParameter( PARAMETER_FORM_SEND );
515 
516         Map<String, Object> model = new HashMap<>( );
517         model.put( MARK_LIST_FIELDS, getSectorList( ) );
518         model.put( MARK_LOCALE, request.getLocale( ) );
519 
520         if ( strFormSend != null )
521         {
522             List<GenericAttributeError> listErrors = doModifyAnnounce( request, announce );
523 
524             if ( listErrors == null )
525             {
526                 return redirect( request, getUrlViewAnnounce( request, nIdAnnounce ) );
527             }
528 
529             model.put( MARK_LIST_ERRORS, listErrors );
530         }
531         else
532         {
533             AnnounceAsynchronousUploadHandler.getHandler( ).removeSessionFiles( request.getSession( ).getId( ) );
534         }
535 
536         Category category = CategoryHome.findByPrimaryKey( announce.getCategory( ).getId( ) );
537         Sector sector = SectorHome.findByPrimaryKey( category.getIdSector( ) );
538         boolean bModerated = true;
539 
540         // unpublish announce if category moderation is on
541         switch( category.getAnnouncesValidation( ) )
542         {
543             case PARAMETER_ANNOUNCES_VALIDATION_YES:
544                 bModerated = true;
545 
546                 break;
547 
548             case PARAMETER_ANNOUNCES_VALIDATION_NO:
549                 bModerated = false;
550 
551                 break;
552 
553             case PARAMETER_ANNOUNCES_VALIDATION_GLOBAL_PARAMETERS:
554             default:
555                 bModerated = sector.getAnnouncesValidation( );
556         }
557 
558         model.put( MARK_MODERATED, bModerated );
559         model.put( MARK_ANNOUNCE, announce );
560 
561         XPage page = getAnnounceFormHtml( request, announce, category, request.getLocale( ), model );
562         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_MODIFY_ANNOUNCE, request.getLocale( ) ) );
563 
564         return page;
565     }
566 
567     /**
568      * Get the confirmation page before removing an announce
569      * 
570      * @param request
571      *            The request
572      * @return The HTML content if the site message could not be displayed
573      * @throws SiteMessageException
574      *             If a site message needs to be displayed
575      */
576     @Action( ACTION_DELETE_ANNOUNCE )
577     public XPage getDeleteAnnounce( HttpServletRequest request ) throws SiteMessageException
578     {
579         String strConfirmRemoveAnnounce = request.getParameter( PARAMETER_CONFIRM_REMOVE_ANNOUNCE );
580         int nIdAnnounce = Integer.parseInt( request.getParameter( PARAMETER_ANNOUNCE_ID ) );
581 
582         if ( strConfirmRemoveAnnounce != null )
583         {
584             AnnounceHome.remove( nIdAnnounce );
585 
586             return redirect( request, AppPathService.getBaseUrl( request ) + getActionFullUrl( ACTION_MY_ANNOUNCES ) );
587         }
588 
589         Map<String, Object> requestParameters = new HashMap<>( );
590         requestParameters.put( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
591         requestParameters.put( MVCUtils.PARAMETER_ACTION, ACTION_DELETE_ANNOUNCE );
592         requestParameters.put( PARAMETER_ANNOUNCE_ID, nIdAnnounce );
593         requestParameters.put( PARAMETER_CONFIRM_REMOVE_ANNOUNCE, "1" );
594         SiteMessageService.setMessage( request, PROPERTY_CONFIRM_REMOVE_ANNOUNCE, SiteMessage.TYPE_CONFIRMATION, JSP_PORTAL, requestParameters );
595 
596         // Never return null because the setMessage method throw an exception
597         return null;
598     }
599 
600     /**
601      * Get the confirmation page before suspending an announce
602      * 
603      * @param request
604      *            The request
605      * @return the XPage to display
606      * @throws SiteMessageException
607      *             If a site message needs to be displayed
608      */
609     @Action( ACTION_SUSPEND_ANNOUNCE_BY_USER )
610     public XPage getSuspendAnnounceByUser( HttpServletRequest request ) throws SiteMessageException
611     {
612         String strConfirmSuspendAnnounce = request.getParameter( PARAMETER_CONFIRM_SUSPEND_ANNOUNCE );
613         int nIdAnnounce = Integer.parseInt( request.getParameter( PARAMETER_ANNOUNCE_ID ) );
614 
615         // user must be authenticated
616         LuteceUser user = getLuteceUserAuthentication( request );
617 
618         // user must be authorized to change this anounce
619         Announce announce = getAuthorizedAnnounce( nIdAnnounce, user, request );
620 
621         if ( strConfirmSuspendAnnounce != null )
622         {
623             announce.setSuspendedByUser( true );
624             AnnounceHome.setSuspendedByUser( announce );
625 
626             return redirect( request, AppPathService.getBaseUrl( request ) + getActionFullUrl( ACTION_MY_ANNOUNCES ) );
627         }
628 
629         Map<String, Object> requestParameters = new HashMap<>( );
630         requestParameters.put( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
631         requestParameters.put( MVCUtils.PARAMETER_ACTION, ACTION_SUSPEND_ANNOUNCE_BY_USER );
632         requestParameters.put( PARAMETER_ANNOUNCE_ID, nIdAnnounce );
633         requestParameters.put( PARAMETER_CONFIRM_SUSPEND_ANNOUNCE, "1" );
634         SiteMessageService.setMessage( request, PROPERTY_CONFIRM_SUSPEND_ANNOUNCE, SiteMessage.TYPE_CONFIRMATION, JSP_PORTAL, requestParameters );
635 
636         return null;
637     }
638 
639     /**
640      * Do enable an announce
641      * 
642      * @param request
643      *            The request
644      * @return The HTML to display
645      * @throws SiteMessageException
646      *             If a site message needs to be displayed
647      */
648     @Action( ACTION_ENABLE_ANNOUNCE_BY_USER )
649     public XPage enableAnnounceByUser( HttpServletRequest request ) throws SiteMessageException
650     {
651         int nIdAnnounce = Integer.parseInt( request.getParameter( PARAMETER_ANNOUNCE_ID ) );
652 
653         // user must be authenticated
654         LuteceUser user = getLuteceUserAuthentication( request );
655 
656         // user must be authorized to change this anounce
657         Announce announce = getAuthorizedAnnounce( nIdAnnounce, user, request );
658 
659         announce.setSuspendedByUser( false );
660         AnnounceHome.setSuspendedByUser( announce );
661 
662         return redirect( request, AppPathService.getBaseUrl( request ) + getActionFullUrl( ACTION_MY_ANNOUNCES ) );
663     }
664 
665     /**
666      * View an announce
667      * 
668      * @param request
669      *            The request
670      * @return The HTML content to display
671      */
672     @Action( ACTION_VIEW_ANNOUNCE )
673     public XPage getViewAnnounce( HttpServletRequest request )
674     {
675         int nIdAnnounce = Integer.parseInt( request.getParameter( PARAMETER_ANNOUNCE_ID ) );
676         Announce announce = AnnounceHome.findByPrimaryKey( nIdAnnounce );
677 
678         boolean bAllowAccess = false;
679         boolean bUserIsAuthor = false;
680 
681         LuteceUser user = null;
682 
683         Map<String, Object> model = new HashMap<>( );
684 
685         if ( SecurityService.isAuthenticationEnable( ) )
686         { // myLutece not installed or disabled
687             user = SecurityService.getInstance( ).getRegisteredUser( request );
688 
689             if ( user != null ) // user is logged
690             {
691                 model.put( MARK_USER, user );
692             }
693         }
694 
695         if ( ( ( user != null ) && user.getName( ).equals( announce.getUserName( ) ) ) )
696         {
697             bUserIsAuthor = true;
698         }
699 
700         if ( ( announce.getPublished( ) && !announce.getSuspended( ) && !announce.getSuspendedByUser( ) ) || bUserIsAuthor )
701         {
702             bAllowAccess = true;
703         }
704 
705         model.put( MARK_ALLOW_ACCESS, bAllowAccess );
706 
707         if ( bAllowAccess )
708         {
709             Collection<Response> listResponses = AnnounceHome.findListResponse( announce.getId( ), false );
710             Collection<Entry> listGeolocalisation = new ArrayList<>( );
711 
712             for ( Response response : listResponses )
713             {
714                 if ( response.getEntry( ) != null && response.getEntry( ).getEntryType( ) != null
715                         && "announce.entryTypeGeolocation".equals( response.getEntry( ).getEntryType( ).getBeanName( ) ) )
716                 {
717                     Entry entry = EntryHome.findByPrimaryKey( response.getEntry( ).getIdEntry( ) );
718                     for ( Field filed : entry.getFields( ) )
719                     {
720 
721                         if ( response.getField( ) != null && filed.getIdField( ) == response.getField( ).getIdField( ) )
722                         {
723                             response.setField( filed );
724                         }
725                     }
726 
727                     boolean bool = true;
728 
729                     for ( Entry ent : listGeolocalisation )
730                     {
731                         if ( ent.getIdEntry( ) == ( entry.getIdEntry( ) ) )
732                         {
733                             bool = false;
734                         }
735                     }
736                     if ( bool )
737                     {
738                         listGeolocalisation.add( entry );
739                     }
740                 }
741 
742             }
743 
744             model.put( MARK_ENTRY_LIST_GEOLOCATION, listGeolocalisation );
745             model.put( MARK_USER_IS_AUTHOR, bUserIsAuthor );
746             model.put( MARK_ANNOUNCE, announce );
747             model.put( MARK_LIST_RESPONSES, listResponses );
748             model.put( "width", "500px" );
749             model.put( "height", "500px" );
750             model.put( MARK_LIST_FIELDS, getSectorList( ) );
751             model.put( MARK_LOCALE, request.getLocale( ) );
752             model.put( MARK_IS_EXTEND_INSTALLED, PortalService.isExtendActivated( ) );
753 
754             Category category = CategoryHome.findByPrimaryKey( announce.getCategory( ).getId( ) );
755             announce.setCategory( category );
756         }
757 
758         XPage xpage = getXPage( TEMPLATE_VIEW_ANNOUNCE, request.getLocale( ), model );
759         xpage.setTitle( announce.getTitle( ) );
760 
761         return xpage;
762     }
763 
764     /**
765      * Gets template in order to view all the user's announces
766      * 
767      * @param request
768      *            httpRequest
769      * @return The HTML content to display
770      * @throws SiteMessageException
771      *             If a site message needs to be displayed
772      */
773     @Action( ACTION_VIEW_ANNOUNCES )
774     public XPage getViewUserAnnounces( HttpServletRequest request ) throws SiteMessageException
775     {
776         String strUserName = request.getParameter( PARAMETER_USERNAME );
777         String strUserInfo = "";
778         _strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, DEFAULT_PAGE_INDEX );
779         _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_FRONT_LIST_ANNOUNCE_PER_PAGE, 10 );
780         _nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, _nDefaultItemsPerPage );
781 
782         int nNbPlublishedAnnounces;
783 
784         List<Announce> listAnnounces = AnnounceHome.getAnnouncesForUser( strUserName, AnnounceSort.DEFAULT_SORT );
785 
786         if ( listAnnounces != null && !listAnnounces.isEmpty( ) )
787         {
788             strUserInfo = listAnnounces.get( 0 ).getUserLastName( ) + " " + listAnnounces.get( 0 ).getUserSecondName( );
789         }
790 
791         Paginator<Announce> paginator = new Paginator<>( listAnnounces, _nItemsPerPage,
792                 JSP_PORTAL + "?" + PARAMETER_PAGE + "=" + AnnounceUtils.PARAMETER_PAGE_ANNOUNCE + "&" + MVCUtils.PARAMETER_ACTION + "=" + ACTION_MY_ANNOUNCES,
793                 PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
794 
795         Map<String, Object> model = new HashMap<>( );
796         model.put( MARK_NB_ITEMS_PER_PAGE, "" + _nItemsPerPage );
797         model.put( MARK_PAGINATOR, paginator );
798 
799         for ( Announce announce : paginator.getPageItems( ) )
800         {
801             announce.setListIdImageResponse( AnnounceHome.findListIdImageResponse( announce.getId( ) ) );
802         }
803 
804         model.put( MARK_ANNOUNCES_LIST, paginator.getPageItems( ) );
805 
806         nNbPlublishedAnnounces = 0;
807 
808         for ( Announce a : listAnnounces )
809         {
810             if ( a.getPublished( ) )
811             {
812                 nNbPlublishedAnnounces++;
813             }
814         }
815 
816         LuteceUser user = null;
817 
818         if ( SecurityService.isAuthenticationEnable( ) )
819         { // myLutece not installed or disabled
820             user = SecurityService.getInstance( ).getRegisteredUser( request );
821 
822             if ( user != null ) // user is logged
823             {
824                 model.put( MARK_USER, user );
825             }
826         }
827 
828         model.put( MARK_HAS_SUBSCRIBED_TO_USER, ( user != null ) ? AnnounceSubscriptionProvider.getService( ).hasSubscribedToUser( user, strUserName ) : null );
829 
830         String strUserRealName = ( strUserInfo == null ) ? strUserName : strUserInfo;
831         model.put( MARK_ANNOUNCE_OWNER, StringUtils.isNotBlank( strUserRealName ) ? strUserRealName : strUserName );
832         model.put( MARK_ANNOUNCE_OWNER_NAME, strUserName );
833         model.put( MARK_ANNOUNCES_PUBLISHED_AMOUNT, nNbPlublishedAnnounces );
834         model.put( MARK_LIST_FIELDS, getSectorList( ) );
835         model.put( MARK_LOCALE, request.getLocale( ) );
836 
837         return getXPage( TEMPLATE_VIEW_ANNOUNCES, request.getLocale( ), model );
838     }
839 
840     /**
841      * Get the page to view the list of subscriptions of the current user
842      * 
843      * @param request
844      *            The request
845      * @return The XPage to display
846      * @throws UserNotSignedException
847      *             If the user has not signed in
848      * @throws SiteMessageException
849      *             If the authentication mode is not activated
850      */
851     @Action( ACTION_VIEW_SUBSCRIPTIONS )
852     public XPage getViewSubscriptions( HttpServletRequest request ) throws UserNotSignedException, SiteMessageException
853     {
854         if ( SecurityService.isAuthenticationEnable( ) )
855         {
856             LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
857 
858             if ( user != null )
859             {
860                 XPage page = getXPage( );
861                 page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE, request.getLocale( ) ) );
862                 page.setContent( SubscribeApp.getSubscriptionList( request ) );
863 
864                 return page;
865             }
866         }
867         else
868         {
869             SiteMessageService.setMessage( request, PROPERTY_NOT_AUTHORIZED, SiteMessage.TYPE_STOP );
870         }
871         throw new UserNotSignedException( );
872     }
873 
874     public String getInfoSubscrition( HttpServletRequest request )
875     {
876         String strUserName = request.getParameter( PARAMETER_USERNAME );
877 
878         List<AnnounceSubscribtionDTO> listSubs = AnnounceSubscriptionProvider.getService( ).getSubscriptionsToUsers( );
879         List<Announce> listAnn = AnnounceHome.getAnnouncesForUser( strUserName, AnnounceSort.DEFAULT_SORT );
880 
881         if ( listSubs != null && !listSubs.isEmpty( ) && listAnn != null && !listAnn.isEmpty( ) )
882         {
883             for ( AnnounceSubscribtionDTO sub : listSubs )
884             {
885                 for ( Announce ann : listAnn )
886                 {
887                     if ( sub.getUserId( ).compareTo( ann.getContactInformation( ) ) == 0 )
888                     {
889                         return ann.getUserLastName( ) + " " + ann.getUserSecondName( );
890                     }
891                 }
892             }
893         }
894         return "";
895     }
896 
897     /**
898      * Get the XPage to display the announces of the current user
899      * 
900      * @param request
901      *            The request
902      * @return The
903      * @throws SiteMessageException
904      *             If a site message needs to be displayed
905      */
906     @Action( ACTION_MY_ANNOUNCES )
907     public XPage getUserAnnounces( HttpServletRequest request ) throws SiteMessageException
908     {
909         XPage page = getXPage( );
910         page.setContent( getManageUserAnnounces( request ) );
911         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE_MY_ANNOUNCES, request.getLocale( ) ) );
912 
913         return page;
914     }
915 
916     /**
917      * Get the current LuteceUser, and throw an exception if the user was not found
918      * 
919      * @param request
920      *            The request
921      * @return The current Lutece User
922      * @throws SiteMessageException
923      *             If a site message needs to be displayed
924      */
925     @NotNull
926     private static LuteceUser getLuteceUserAuthentication( HttpServletRequest request ) throws SiteMessageException
927     {
928         LuteceUser user = null;
929 
930         if ( SecurityService.isAuthenticationEnable( ) )
931         { // myLutece not installed or disabled
932             user = SecurityService.getInstance( ).getRegisteredUser( request );
933 
934             if ( user == null ) // user is not logged
935             {
936                 SiteMessageService.setMessage( request, PROPERTY_NOT_AUTHORIZED, SiteMessage.TYPE_STOP );
937             }
938         }
939         else
940         {
941             SiteMessageService.setMessage( request, PROPERTY_NOT_AUTHORIZED, SiteMessage.TYPE_STOP );
942         }
943 
944         return user;
945     }
946 
947     /**
948      * Get an announce if the current user is its owner
949      * 
950      * @param nIdAnnounce
951      *            The id of the announce to get
952      * @param user
953      *            The user
954      * @param request
955      *            The request
956      * @return The announce
957      * @throws SiteMessageException
958      *             If a site message needs to be displayed
959      */
960     @NotNull
961     private Announce getAuthorizedAnnounce( int nIdAnnounce, LuteceUser user, HttpServletRequest request ) throws SiteMessageException
962     {
963         Announce announce = AnnounceHome.findByPrimaryKey( nIdAnnounce );
964 
965         if ( ( announce == null ) || !announce.getUserName( ).equals( user.getName( ) ) )
966         {
967             SiteMessageService.setMessage( request, PROPERTY_REFUSED_ACCESS, SiteMessage.TYPE_STOP );
968         }
969 
970         return announce;
971     }
972 
973     /**
974      * Do send an announce by email to admin users
975      * 
976      * @param request
977      *            The request
978      * @param announce
979      *            The announce
980      */
981     private void sendAnnounceNotification( HttpServletRequest request, Announce announce )
982     {
983         int nIdMailingList = announce.getCategory( ).getIdMailingList( );
984 
985         if ( nIdMailingList > 0 )
986         {
987             Collection<Recipient> listRecipients = AdminMailingListService.getRecipients( nIdMailingList );
988 
989             for ( Recipient recipient : listRecipients )
990             {
991                 HashMap<String, Object> model = new HashMap<>( );
992 
993                 String strSenderEmail = AppPropertiesService.getProperty( PROPERTY_WEBMASTER_EMAIL );
994                 String strSenderName = AppPropertiesService.getProperty( PROPERTY_WEBMASTER_NAME );
995                 String strSubject = I18nService.getLocalizedString( PROPERTY_ANNOUNCE_NOTIFY_SUBJECT, request.getLocale( ) );
996 
997                 // Generate the subject of the message
998                 strSubject += ( " " + announce.getCategory( ).getLabel( ) );
999 
1000                 // Generate the body of the message
1001                 model.put( MARK_PROD_URL, AppPropertiesService.getProperty( PROPERTY_PROD_URL ) );
1002                 model.put( MARK_ANNOUNCE, announce );
1003                 model.put( MARK_LIST_FIELDS, getSectorList( ) );
1004                 model.put( MARK_LOCALE, request.getLocale( ) );
1005 
1006                 HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ANNOUNCE_NOTIFY_MESSAGE, request.getLocale( ), model );
1007                 String strBody = template.getHtml( );
1008 
1009                 MailService.sendMailHtml( recipient.getEmail( ), strSenderName, strSenderEmail, strSubject, strBody );
1010             }
1011         }
1012     }
1013 
1014     /**
1015      * Do create an announce
1016      * 
1017      * @param request
1018      *            The request
1019      * @param sector
1020      *            The sector
1021      * @param category
1022      *            The category
1023      * @param announce
1024      *            The announce
1025      * @param user
1026      *            The user
1027      * @return The list of error, or null if no error was found and if the announce was created
1028      * @throws SiteMessageException
1029      *             If a site message needs to be displayed
1030      */
1031     private List<GenericAttributeError> doCreateAnnounce( HttpServletRequest request, Sector sector, Category category, Announce announce, LuteceUser user )
1032             throws SiteMessageException
1033     {
1034         String strTitleAnnounce = request.getParameter( PARAMETER_TITLE_ANNOUNCE );
1035         String strDescriptionAnnounce = request.getParameter( PARAMETER_DESCRIPTION_ANNOUNCE );
1036         String strContactInformation = request.getParameter( PARAMETER_CONTACT_INFORMATION );
1037         String strTags = request.getParameter( PARAMETER_TAGS );
1038         Double nPriceAnnounce = ( request.getParameter( PARAMETER_PRICE_ANNOUNCE ) == null ) ? 0.0
1039                 : Double.parseDouble( request.getParameter( PARAMETER_PRICE_ANNOUNCE ) );
1040 
1041         if ( StringUtils.isEmpty( strTitleAnnounce ) || StringUtils.isEmpty( strDescriptionAnnounce ) || StringUtils.isEmpty( strContactInformation )
1042                 || ( category.getDisplayPrice( ) && category.getPriceMandatory( ) && ( nPriceAnnounce == 0.0 ) ) )
1043         {
1044             SiteMessageService.setMessage( request, Messages.MANDATORY_FIELDS, SiteMessage.TYPE_STOP );
1045 
1046             return new ArrayList<>( );
1047         }
1048 
1049         switch( category.getAnnouncesValidation( ) )
1050         {
1051             case PARAMETER_ANNOUNCES_VALIDATION_YES:
1052                 announce.setPublished( false );
1053 
1054                 break;
1055 
1056             case PARAMETER_ANNOUNCES_VALIDATION_NO:
1057                 announce.setPublished( true );
1058 
1059                 break;
1060 
1061             case PARAMETER_ANNOUNCES_VALIDATION_GLOBAL_PARAMETERS:
1062             default:
1063                 announce.setPublished( !sector.getAnnouncesValidation( ) );
1064         }
1065 
1066         announce.setCategory( category );
1067         announce.setTitle( strTitleAnnounce );
1068         announce.setDescription( strDescriptionAnnounce );
1069         announce.setPrice( nPriceAnnounce );
1070         announce.setContactInformation( strContactInformation );
1071         announce.setUserName( user.getName( ) );
1072         announce.setUserLastName( user.getUserInfo( LuteceUser.NAME_GIVEN ) );
1073         announce.setUserSecondName( user.getUserInfo( LuteceUser.NAME_FAMILY ) );
1074         announce.setUserName( user.getName( ) );
1075         announce.setTags( strTags );
1076 
1077         EntryFilter filter = new EntryFilter( );
1078         filter.setIdResource( category.getId( ) );
1079         filter.setResourceType( Category.RESOURCE_TYPE );
1080         filter.setEntryParentNull( EntryFilter.FILTER_TRUE );
1081         filter.setFieldDependNull( EntryFilter.FILTER_TRUE );
1082         filter.setIdIsComment( EntryFilter.FILTER_FALSE );
1083 
1084         List<Entry> listEntryFirstLevel = EntryHome.getEntryList( filter );
1085         List<GenericAttributeError> listErrors = new ArrayList<>( );
1086 
1087         AnnounceDTO/business/AnnounceDTO.html#AnnounceDTO">AnnounceDTO announceDTO = new AnnounceDTO( announce );
1088 
1089         for ( Entry entry : listEntryFirstLevel )
1090         {
1091             listErrors.addAll( _announceService.getResponseEntry( request, entry.getIdEntry( ), request.getLocale( ), announceDTO ) );
1092         }
1093 
1094         if ( category.getDisplayCaptcha( ) && _captchaSecurityService.isAvailable( ) && !_captchaSecurityService.validate( request ) )
1095         {
1096             GenericAttributeError genAttError = new GenericAttributeError( );
1097             genAttError.setErrorMessage( I18nService.getLocalizedString( ERROR_MESSAGE_WRONG_CAPTCHA, request.getLocale( ) ) );
1098             listErrors.add( genAttError );
1099         }
1100 
1101         _announceService.convertMapResponseToList( announceDTO );
1102         announce.setListResponse( announceDTO.getListResponse( ) );
1103 
1104         if ( CollectionUtils.isNotEmpty( listErrors ) )
1105         {
1106             return listErrors;
1107         }
1108 
1109         announce.setHasPictures( false );
1110 
1111         for ( Response response : announceDTO.getListResponse( ) )
1112         {
1113             if ( ( response.getFile( ) != null ) && FileUtil.hasImageExtension( response.getFile( ).getTitle( ) ) )
1114             {
1115                 announce.setHasPictures( true );
1116 
1117                 break;
1118             }
1119         }
1120 
1121         AnnounceHome.create( announce );
1122 
1123         for ( Response response : announceDTO.getListResponse( ) )
1124         {
1125             ResponseHome.create( response );
1126             AnnounceHome.insertAnnounceResponse( announce.getId( ), response.getIdResponse( ),
1127                     ( response.getFile( ) != null ) && FileUtil.hasImageExtension( response.getFile( ).getTitle( ) ) );
1128         }
1129 
1130         if ( category.getIdWorkflow( ) > 0 )
1131         {
1132             WorkflowService.getInstance( ).getState( announce.getId( ), Announce.RESOURCE_TYPE, category.getIdWorkflow( ), category.getId( ) );
1133             WorkflowService.getInstance( ).executeActionAutomatic( announce.getId( ), Announce.RESOURCE_TYPE, category.getIdWorkflow( ), category.getId( ) );
1134         }
1135 
1136         // send mail notification only if announce is not published
1137         if ( !announce.getPublished( ) )
1138         {
1139             sendAnnounceNotification( request, announce );
1140         }
1141 
1142         AnnounceAsynchronousUploadHandler.getHandler( ).removeSessionFiles( request.getSession( ).getId( ) );
1143 
1144         return new ArrayList<>( );
1145     }
1146 
1147     /**
1148      * Do modify an announce
1149      * 
1150      * @param request
1151      *            The request
1152      * @param announce
1153      *            The announce
1154      * @return The list of errors, or null if no error occurred
1155      * @throws SiteMessageException
1156      *             If a site message needs to be displayed
1157      */
1158     private List<GenericAttributeError> doModifyAnnounce( HttpServletRequest request, Announce announce ) throws SiteMessageException
1159     {
1160         Category category = CategoryHome.findByPrimaryKey( announce.getCategory( ).getId( ) );
1161 
1162         String strTitleAnnounce = request.getParameter( PARAMETER_TITLE_ANNOUNCE );
1163         String strDescriptionAnnounce = request.getParameter( PARAMETER_DESCRIPTION_ANNOUNCE );
1164         String strContactInformation = request.getParameter( PARAMETER_CONTACT_INFORMATION );
1165         String strTags = request.getParameter( PARAMETER_TAGS );
1166         Double nPriceAnnounce = ( request.getParameter( PARAMETER_PRICE_ANNOUNCE ) == null ) ? 0.0
1167                 : Double.parseDouble( request.getParameter( PARAMETER_PRICE_ANNOUNCE ) );
1168 
1169         if ( StringUtils.isEmpty( strTitleAnnounce ) || StringUtils.isEmpty( strDescriptionAnnounce ) || StringUtils.isEmpty( strContactInformation )
1170                 || ( category.getDisplayPrice( ) && category.getPriceMandatory( ) && ( nPriceAnnounce == 0.0 ) ) )
1171         {
1172             SiteMessageService.setMessage( request, Messages.MANDATORY_FIELDS, SiteMessage.TYPE_STOP );
1173 
1174             return null;
1175         }
1176 
1177         announce.setTitle( strTitleAnnounce );
1178         announce.setDescription( strDescriptionAnnounce );
1179         announce.setContactInformation( strContactInformation );
1180         announce.setTags( strTags );
1181         announce.setPrice( nPriceAnnounce );
1182         announce.setHasNotify( 0 );
1183 
1184         Sector sector = SectorHome.findByPrimaryKey( category.getIdSector( ) );
1185 
1186         // unpublish announce if category moderation is on
1187         switch( category.getAnnouncesValidation( ) )
1188         {
1189             case PARAMETER_ANNOUNCES_VALIDATION_YES:
1190                 announce.setPublished( false );
1191 
1192                 break;
1193 
1194             case PARAMETER_ANNOUNCES_VALIDATION_NO:
1195                 announce.setPublished( true );
1196 
1197                 break;
1198 
1199             case PARAMETER_ANNOUNCES_VALIDATION_GLOBAL_PARAMETERS:
1200             default:
1201                 announce.setPublished( !sector.getAnnouncesValidation( ) );
1202         }
1203 
1204         EntryFilter filter = new EntryFilter( );
1205         filter.setIdResource( category.getId( ) );
1206         filter.setResourceType( Category.RESOURCE_TYPE );
1207         filter.setEntryParentNull( EntryFilter.FILTER_TRUE );
1208         filter.setFieldDependNull( EntryFilter.FILTER_TRUE );
1209         filter.setIdIsComment( EntryFilter.FILTER_FALSE );
1210 
1211         List<Entry> listEntryFirstLevel = EntryHome.getEntryList( filter );
1212         List<GenericAttributeError> listErrors = new ArrayList<>( );
1213 
1214         AnnounceDTO/business/AnnounceDTO.html#AnnounceDTO">AnnounceDTO announceDTO = new AnnounceDTO( announce );
1215 
1216         for ( Entry entry : listEntryFirstLevel )
1217         {
1218             listErrors.addAll( _announceService.getResponseEntry( request, entry.getIdEntry( ), request.getLocale( ), announceDTO ) );
1219         }
1220 
1221         if ( category.getDisplayCaptcha( ) && _captchaSecurityService.isAvailable( ) && !_captchaSecurityService.validate( request ) )
1222         {
1223             GenericAttributeError genAttError = new GenericAttributeError( );
1224             genAttError.setErrorMessage( I18nService.getLocalizedString( ERROR_MESSAGE_WRONG_CAPTCHA, request.getLocale( ) ) );
1225             listErrors.add( genAttError );
1226         }
1227 
1228         // If there is some errors, we redirect the user to the form page
1229         if ( CollectionUtils.isNotEmpty( listErrors ) )
1230         {
1231             _announceService.convertMapResponseToList( announceDTO );
1232             announce.setListResponse( announceDTO.getListResponse( ) );
1233 
1234             return listErrors;
1235         }
1236 
1237         _announceService.convertMapResponseToList( announceDTO );
1238         announce.setListResponse( announceDTO.getListResponse( ) );
1239 
1240         announce.setHasPictures( false );
1241 
1242         for ( Response response : announceDTO.getListResponse( ) )
1243         {
1244             if ( ( response.getFile( ) != null ) && FileUtil.hasImageExtension( response.getFile( ).getTitle( ) ) )
1245             {
1246                 announce.setHasPictures( true );
1247 
1248                 break;
1249             }
1250         }
1251 
1252         AnnounceHome.update( announce );
1253 
1254         List<Integer> listIdResponse = AnnounceHome.findListIdResponse( announce.getId( ) );
1255 
1256         for ( int nIdResponse : listIdResponse )
1257         {
1258             ResponseHome.remove( nIdResponse );
1259         }
1260 
1261         AnnounceHome.removeAnnounceResponse( announce.getId( ) );
1262 
1263         for ( Response response : announceDTO.getListResponse( ) )
1264         {
1265             ResponseHome.create( response );
1266             AnnounceHome.insertAnnounceResponse( announce.getId( ), response.getIdResponse( ),
1267                     ( response.getFile( ) != null ) && FileUtil.hasImageExtension( response.getFile( ).getTitle( ) ) );
1268         }
1269 
1270         // send mail notification only if announce is not published
1271         if ( !announce.getPublished( ) )
1272         {
1273             sendAnnounceNotification( request, announce );
1274         }
1275 
1276         return null;
1277     }
1278 
1279     /**
1280      * Get the HTML code of the form to create or modify an announce
1281      * 
1282      * @param request
1283      *            The request
1284      * @param announce
1285      *            The announce to get the form of (null to get a creation form)
1286      * @param category
1287      *            The category of the announce
1288      * @param locale
1289      *            the locale
1290      * @param model
1291      *            The model to use to display the page
1292      * @return The XPage to display, or an empty string if the form is null or not active
1293      */
1294     private XPage getAnnounceFormHtml( HttpServletRequest request, Announce announce, Category category, Locale locale, Map<String, Object> model )
1295     {
1296         if ( category == null )
1297         {
1298             return new XPage( );
1299         }
1300 
1301         Sector sector = SectorHome.findByPrimaryKey( category.getIdSector( ) );
1302 
1303         model.put( MARK_FORM_HTML, _announceService.getHtmlAnnounceForm( announce, category, locale, true, request ) );
1304         model.put( MARK_CATEGORY, category );
1305         model.put( MARK_SECTOR, sector );
1306         model.put( MARK_LIST_FIELDS, getSectorList( ) );
1307         model.put( MARK_LOCALE, request.getLocale( ) );
1308 
1309         if ( category.getDisplayCaptcha( ) && _captchaSecurityService.isAvailable( ) )
1310         {
1311             model.put( MARK_CAPTCHA, _captchaSecurityService.getHtmlCode( ) );
1312         }
1313 
1314         return getXPage( ( ( announce == null ) || ( announce.getId( ) == 0 ) ) ? TEMPLATE_PAGE_CREATE_ANNOUNCE_STEP_FORM : TEMPLATE_MODIFY_ANNOUNCE, locale,
1315                 model );
1316     }
1317 
1318     /**
1319      * Get the URL to view an announce
1320      * 
1321      * @param request
1322      *            The request
1323      * @param nIdAnnounce
1324      *            The id of the announce to view
1325      * @return The URL to view the announce
1326      */
1327     private String getUrlViewAnnounce( HttpServletRequest request, int nIdAnnounce )
1328     {
1329         UrlItem url = new UrlItem( AppPathService.getBaseUrl( request ) + getActionFullUrl( ACTION_VIEW_ANNOUNCE ) );
1330         url.addParameter( PARAMETER_ANNOUNCE_ID, nIdAnnounce );
1331 
1332         return url.getUrl( );
1333     }
1334 
1335     /**
1336      * Get the list of announces of the user
1337      * 
1338      * @param request
1339      *            The request
1340      * @return The HTML content to display
1341      * @throws SiteMessageException
1342      *             If a site message needs to be displayed
1343      */
1344     public static String getManageUserAnnounces( HttpServletRequest request ) throws SiteMessageException
1345     {
1346         LuteceUser user = getLuteceUserAuthentication( request );
1347 
1348         String strCurrentPageIndex = AbstractPaginator.getPageIndex( request, AbstractPaginator.PARAMETER_PAGE_INDEX, DEFAULT_PAGE_INDEX );
1349         int nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_FRONT_LIST_ANNOUNCE_PER_PAGE, 10 );
1350 
1351         Integer nOldItemsPerPageFromSession = (Integer) request.getSession( ).getAttribute( SESSION_ATTRIBUTE_MY_ANNOUNCES_ITEMS_PER_PAGE );
1352         int nOldItemsPerPage = ( nOldItemsPerPageFromSession != null ) ? nOldItemsPerPageFromSession : nDefaultItemsPerPage;
1353 
1354         int nItemsPerPage = AbstractPaginator.getItemsPerPage( request, AbstractPaginator.PARAMETER_ITEMS_PER_PAGE, nOldItemsPerPage, nDefaultItemsPerPage );
1355 
1356         request.getSession( ).setAttribute( SESSION_ATTRIBUTE_MY_ANNOUNCES_ITEMS_PER_PAGE, nItemsPerPage );
1357 
1358         List<Announce> listAnnounces = AnnounceHome.getAnnouncesForUser( user, AnnounceSort.DEFAULT_SORT );
1359 
1360         UrlItem urlItem = new UrlItem( AppPathService.getPortalUrl( ) );
1361 
1362         if ( StringUtils.isNotEmpty( request.getParameter( PARAMETER_PAGE ) ) )
1363         {
1364             urlItem.addParameter( PARAMETER_PAGE, request.getParameter( PARAMETER_PAGE ) );
1365         }
1366 
1367         if ( StringUtils.isNotEmpty( request.getParameter( MVCUtils.PARAMETER_ACTION ) ) )
1368         {
1369             urlItem.addParameter( MVCUtils.PARAMETER_ACTION, request.getParameter( MVCUtils.PARAMETER_ACTION ) );
1370         }
1371 
1372         if ( StringUtils.isNotEmpty( request.getParameter( MVCUtils.PARAMETER_VIEW ) ) )
1373         {
1374             urlItem.addParameter( MVCUtils.PARAMETER_VIEW, request.getParameter( MVCUtils.PARAMETER_VIEW ) );
1375         }
1376 
1377         if ( StringUtils.isNotEmpty( request.getParameter( Parameters.PAGE_ID ) ) )
1378         {
1379             urlItem.addParameter( Parameters.PAGE_ID, request.getParameter( Parameters.PAGE_ID ) );
1380         }
1381 
1382         Paginator<Announce> paginator = new Paginator<>( listAnnounces, nItemsPerPage, urlItem.getUrl( ), PARAMETER_PAGE_INDEX, strCurrentPageIndex );
1383 
1384         for ( Announce announce : paginator.getPageItems( ) )
1385         {
1386             announce.setListIdImageResponse( AnnounceHome.findListIdImageResponse( announce.getId( ) ) );
1387         }
1388 
1389         Map<String, Object> model = new HashMap<>( );
1390         model.put( MARK_LIST_FIELDS, getSectorList( ) );
1391         model.put( MARK_LOCALE, request.getLocale( ) );
1392         model.put( MARK_NB_ITEMS_PER_PAGE, Integer.toString( nItemsPerPage ) );
1393         model.put( MARK_PAGINATOR, paginator );
1394         model.put( MARK_ANNOUNCES_LIST, paginator.getPageItems( ) );
1395         model.put( MARK_USER, user );
1396 
1397         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MY_ANNOUNCES, request.getLocale( ), model );
1398 
1399         return template.getHtml( );
1400     }
1401 
1402     /**
1403      * Get the list of sectors to be displayed in the navigation menu
1404      * 
1405      * @return The list of sectors
1406      */
1407     public static Collection<Sector> getSectorList( )
1408     {
1409         Collection<Sector> listSectors = SectorHome.findAll( );
1410 
1411         for ( Sector sector : listSectors )
1412         {
1413             int nNumberAnnounces = 0;
1414             Collection<Category> categoryList = CategoryHome.findCategoriesForSector( sector );
1415             sector.setListCategories( categoryList );
1416 
1417             for ( Category category : categoryList )
1418             {
1419                 nNumberAnnounces += CategoryHome.countPublishedAnnouncesForCategory( category );
1420             }
1421 
1422             sector.setNumberAnnounces( nNumberAnnounces );
1423         }
1424 
1425         return listSectors;
1426     }
1427 
1428     /**
1429      * Get the list of sectors to be displayed in the navigation menu
1430      * 
1431      * @return The list of sectors
1432      */
1433     public static Collection<Category> getCategoryList( int idSector )
1434     {
1435         if ( idSector == 0 )
1436         {
1437             return CategoryHome.findAll( );
1438         }
1439         Sector sector = SectorHome.findByPrimaryKey( idSector );
1440         return CategoryHome.findCategoriesForSector( sector );
1441     }
1442 
1443     /**
1444      * Get the announce search filter with data contained in an HTTP request
1445      * 
1446      * @param request
1447      *            The request
1448      * @return The search filter. If the request contains no filter data, then the returned search filter is empty but never null.
1449      */
1450     public static AnnounceSearchFilter getAnnounceFilterFromRequest( HttpServletRequest request )
1451     {
1452         if ( request == null )
1453         {
1454             return new AnnounceSearchFilter( );
1455         }
1456 
1457         String strIdFilter = request.getParameter( PARAMETER_ID_FILTER );
1458 
1459         if ( StringUtils.isNotEmpty( strIdFilter ) && StringUtils.isNumeric( strIdFilter ) )
1460         {
1461             int nIdFilter = Integer.parseInt( strIdFilter );
1462             AnnounceSearchFilter filter = AnnounceSearchFilterHome.findByPrimaryKey( nIdFilter );
1463             request.getSession( ).setAttribute( SESSION_KEY_ANNOUNCE_FILTER, filter );
1464 
1465             return filter;
1466         }
1467 
1468         if ( Boolean.parseBoolean( request.getParameter( PARAMETER_HAS_FILTER ) ) )
1469         {
1470             String strKeywords = request.getParameter( PARAMETER_KEYWORDS );
1471             String strIdSector = request.getParameter( PARAMETER_SECTOR_ID );
1472             String strIdCategory = request.getParameter( PARAMETER_CATEGORY_ID );
1473             String strDateMin = request.getParameter( PARAMETER_DATE_MIN );
1474             String strDateMax = request.getParameter( PARAMETER_DATE_MAX );
1475             String strPriceMin = request.getParameter( PARAMETER_PRICE_MIN );
1476             String strPriceMax = request.getParameter( PARAMETER_PRICE_MAX );
1477             strKeywords = ( strKeywords == null ) ? StringUtils.EMPTY : strKeywords;
1478 
1479             Date formatedDateMin = null;
1480             Date formatedDateMax = null;
1481 
1482             DateFormat dateFormat = AnnounceService.getDateFormat( );
1483 
1484             if ( StringUtils.isNotEmpty( strDateMin ) )
1485             {
1486                 try
1487                 {
1488                     formatedDateMin = dateFormat.parse( strDateMin.trim( ) );
1489                 }
1490                 catch( ParseException e )
1491                 {
1492                     AppLogService.error( e );
1493                 }
1494             }
1495 
1496             if ( StringUtils.isNotEmpty( strDateMax ) )
1497             {
1498                 try
1499                 {
1500                     formatedDateMax = dateFormat.parse( strDateMax.trim( ) );
1501                 }
1502                 catch( ParseException e )
1503                 {
1504                     AppLogService.error( e );
1505                 }
1506             }
1507 
1508             AnnounceSearchFilteriness/AnnounceSearchFilter.html#AnnounceSearchFilter">AnnounceSearchFilter filter = new AnnounceSearchFilter( );
1509             filter.setKeywords( strKeywords );
1510 
1511             if ( StringUtils.isNotEmpty( strIdSector ) && StringUtils.isNumeric( strIdSector ) )
1512             {
1513                 filter.setIdSector( Integer.parseInt( strIdSector ) );
1514             }
1515 
1516             if ( StringUtils.isNotEmpty( strIdCategory ) && StringUtils.isNumeric( strIdCategory ) )
1517             {
1518                 filter.setIdCategory( Integer.parseInt( strIdCategory ) );
1519             }
1520 
1521             filter.setDateMin( formatedDateMin );
1522             filter.setDateMax( formatedDateMax );
1523 
1524             if ( StringUtils.isNotEmpty( strPriceMin ) )
1525             {
1526                 strPriceMin = strPriceMin.replace( CONSTANT_BLANK_SPACE, StringUtils.EMPTY ).trim( );
1527 
1528                 if ( StringUtils.contains( strPriceMin, CONSTANT_COMA ) )
1529                 {
1530                     strPriceMin = strPriceMin.substring( 0, strPriceMin.indexOf( CONSTANT_COMA ) );
1531                 }
1532 
1533                 if ( StringUtils.contains( strPriceMin, CONSTANT_POINT ) )
1534                 {
1535                     strPriceMin = strPriceMin.substring( 0, strPriceMin.indexOf( CONSTANT_POINT ) );
1536                 }
1537 
1538                 if ( StringUtils.isNumeric( strPriceMin ) )
1539                 {
1540                     filter.setPriceMin( Integer.parseInt( strPriceMin ) );
1541                 }
1542             }
1543 
1544             if ( StringUtils.isNotEmpty( strPriceMax ) )
1545             {
1546                 strPriceMax = strPriceMax.replace( CONSTANT_BLANK_SPACE, StringUtils.EMPTY ).trim( );
1547 
1548                 if ( StringUtils.contains( strPriceMax, CONSTANT_COMA ) )
1549                 {
1550                     strPriceMax = strPriceMax.substring( 0, strPriceMax.indexOf( CONSTANT_COMA ) );
1551                 }
1552 
1553                 if ( StringUtils.contains( strPriceMax, CONSTANT_POINT ) )
1554                 {
1555                     strPriceMax = strPriceMax.substring( 0, strPriceMax.indexOf( CONSTANT_POINT ) );
1556                 }
1557 
1558                 if ( StringUtils.isNumeric( strPriceMax ) )
1559                 {
1560                     filter.setPriceMax( Integer.parseInt( strPriceMax ) );
1561                 }
1562             }
1563 
1564             request.getSession( ).setAttribute( SESSION_KEY_ANNOUNCE_FILTER, filter );
1565 
1566             return filter;
1567         }
1568 
1569         AnnounceSearchFilter/../fr/paris/lutece/plugins/announce/business/AnnounceSearchFilter.html#AnnounceSearchFilter">AnnounceSearchFilter filter = (AnnounceSearchFilter) request.getSession( ).getAttribute( SESSION_KEY_ANNOUNCE_FILTER );
1570 
1571         if ( filter == null )
1572         {
1573             filter = new AnnounceSearchFilter( );
1574         }
1575 
1576         return filter;
1577     }
1578 
1579     /**
1580      * Get the URL to search for announces
1581      * 
1582      * @param request
1583      *            The request
1584      * @return The URL to search announces
1585      */
1586     public static String getUrlSearchAnnounceSort( HttpServletRequest request, int nSort )
1587     {
1588         return getUrlSearchAnnounceSort( request, 0, nSort );
1589     }
1590 
1591     /**
1592      * Get the URL to search for announces
1593      * 
1594      * @param request
1595      *            The request
1596      * @param nIdFilter
1597      *            The id of the filter to load, or 0 to use the filter stored in session if any
1598      * @return The URL to search announces
1599      */
1600     public static String getUrlSearchAnnounceSort( HttpServletRequest request, int nIdFilter, int nSort )
1601     {
1602         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( ) );
1603         urlItem.addParameter( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
1604         urlItem.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_SEARCH );
1605 
1606         if ( nIdFilter > 0 )
1607         {
1608             urlItem.addParameter( PARAMETER_ID_FILTER, nIdFilter );
1609         }
1610         if ( nSort == 0 )
1611         {
1612             urlItem.addParameter( PARAMETER_SORT_BY, "date_creation" );
1613         }
1614         if ( nSort == 1 )
1615         {
1616             urlItem.addParameter( PARAMETER_SORT_BY, "date_modification" );
1617         }
1618         if ( nSort == 2 )
1619         {
1620             urlItem.addParameter( PARAMETER_SORT_BY, PARAMETER_TITLE_ANNOUNCE );
1621         }
1622         if ( nSort == 3 )
1623         {
1624             urlItem.addParameter( PARAMETER_SORT_BY, PARAMETER_PRICE_ANNOUNCE );
1625         }
1626         if ( nSort == 4 )
1627         {
1628             urlItem.addParameter( PARAMETER_SORT_BY, PARAMETER_DESCRIPTION_ANNOUNCE );
1629         }
1630         if ( nSort == 5 )
1631         {
1632             urlItem.addParameter( PARAMETER_SORT_BY, "date_publication" );
1633         }
1634 
1635         return urlItem.getUrl( );
1636     }
1637 
1638     /**
1639      * Get the URL to search for announces
1640      * 
1641      * @param request
1642      *            The request
1643      * @return The URL to search announces
1644      */
1645     public static String getUrlSearchAnnounce( HttpServletRequest request )
1646     {
1647         return getUrlSearchAnnounce( request, 0 );
1648     }
1649 
1650     /**
1651      * Get the URL to search for announces
1652      * 
1653      * @param request
1654      *            The request
1655      * @param nIdFilter
1656      *            The id of the filter to load, or 0 to use the filter stored in session if any
1657      * @return The URL to search announces
1658      */
1659     public static String getUrlSearchAnnounce( HttpServletRequest request, int nIdFilter )
1660     {
1661         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( ) );
1662         urlItem.addParameter( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
1663         urlItem.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_SEARCH );
1664 
1665         if ( nIdFilter > 0 )
1666         {
1667             urlItem.addParameter( PARAMETER_ID_FILTER, nIdFilter );
1668         }
1669 
1670         return urlItem.getUrl( );
1671     }
1672 
1673     /**
1674      * Get the URl to view an announce
1675      * 
1676      * @param nIdAnnounce
1677      *            The id of the announce to view
1678      * @return The relative URL to view the announce
1679      */
1680     public static String getRelativeUrlViewAnnounce( int nIdAnnounce )
1681     {
1682         UrlItem urlItem = new UrlItem( AppPathService.getPortalUrl( ) );
1683         urlItem.addParameter( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
1684         urlItem.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_VIEW_ANNOUNCE );
1685         urlItem.addParameter( PARAMETER_ANNOUNCE_ID, nIdAnnounce );
1686 
1687         return urlItem.getUrl( );
1688     }
1689 
1690     /**
1691      * Get the URL to search for a given category
1692      * 
1693      * @param request
1694      *            The request
1695      * @param nIdCategory
1696      *            The of the category to search for
1697      * @return The URL
1698      */
1699     public static String getUrlViewCategory( HttpServletRequest request, int nIdCategory )
1700     {
1701         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( ) );
1702         urlItem.addParameter( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
1703         urlItem.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_SEARCH );
1704         urlItem.addParameter( PARAMETER_CATEGORY_ID, nIdCategory );
1705         urlItem.addParameter( PARAMETER_HAS_FILTER, Boolean.TRUE.toString( ) );
1706 
1707         return urlItem.getUrl( );
1708     }
1709 
1710     /**
1711      * Get the URL to view announces of a user
1712      * 
1713      * @param request
1714      *            The request
1715      * @param strUserName
1716      *            The name of the user to view announces of
1717      * @return The URL
1718      */
1719     public static String getUrlViewUserAnnounces( HttpServletRequest request, String strUserName )
1720     {
1721         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + AppPathService.getPortalUrl( ) );
1722         urlItem.addParameter( PARAMETER_PAGE, AnnounceUtils.PARAMETER_PAGE_ANNOUNCE );
1723         urlItem.addParameter( MVCUtils.PARAMETER_ACTION, ACTION_VIEW_ANNOUNCES );
1724         urlItem.addParameter( PARAMETER_USERNAME, strUserName );
1725 
1726         return urlItem.getUrl( );
1727     }
1728 }