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.participatoryideation.web;
35  
36  import java.util.ArrayList;
37  import java.util.Collection;
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  import javax.servlet.http.HttpServletRequest;
43  
44  import org.apache.commons.lang.StringUtils;
45  
46  import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistory;
47  import fr.paris.lutece.plugins.extend.business.extender.history.ResourceExtenderHistoryFilter;
48  import fr.paris.lutece.plugins.extend.modules.comment.business.Comment;
49  import fr.paris.lutece.plugins.extend.modules.comment.business.CommentFilter;
50  import fr.paris.lutece.plugins.extend.modules.comment.service.CommentService;
51  import fr.paris.lutece.plugins.extend.modules.comment.service.ICommentService;
52  import fr.paris.lutece.plugins.extend.modules.follow.service.extender.FollowResourceExtender;
53  import fr.paris.lutece.plugins.extend.service.extender.history.IResourceExtenderHistoryService;
54  import fr.paris.lutece.plugins.extend.service.extender.history.ResourceExtenderHistoryService;
55  import fr.paris.lutece.plugins.participatoryideation.business.proposal.Proposal;
56  import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalHome;
57  import fr.paris.lutece.plugins.participatoryideation.business.proposal.ProposalSearcher;
58  import fr.paris.lutece.plugins.participatoryideation.service.IdeationStaticService;
59  import fr.paris.lutece.plugins.participatoryideation.service.ProposalService;
60  import fr.paris.lutece.plugins.participatoryideation.service.campaign.IdeationCampaignDataProvider;
61  import fr.paris.lutece.plugins.participatoryideation.util.ParticipatoryIdeationConstants;
62  import fr.paris.lutece.portal.service.message.SiteMessage;
63  import fr.paris.lutece.portal.service.message.SiteMessageException;
64  import fr.paris.lutece.portal.service.message.SiteMessageService;
65  import fr.paris.lutece.portal.service.security.LuteceUser;
66  import fr.paris.lutece.portal.service.security.SecurityService;
67  import fr.paris.lutece.portal.service.security.UserNotSignedException;
68  import fr.paris.lutece.portal.service.spring.SpringContextService;
69  import fr.paris.lutece.portal.service.util.AppPathService;
70  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
71  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
72  import fr.paris.lutece.portal.util.mvc.utils.MVCUtils;
73  import fr.paris.lutece.portal.util.mvc.xpage.MVCApplication;
74  import fr.paris.lutece.portal.util.mvc.xpage.annotations.Controller;
75  import fr.paris.lutece.portal.web.xpages.XPage;
76  import freemarker.ext.beans.BeansWrapper;
77  
78  /**
79   * This class provides the user interface to view Proposal xpages
80   */
81  
82  @Controller( xpageName = "myProjects", pageTitleI18nKey = "participatoryideation.xpage.proposalSubscriber.pageTitle", pagePathI18nKey = "participatoryideation.xpage.proposalSubscriber.pagePathLabel" )
83  public class ProposalSubscriberXPage extends MVCApplication
84  {
85      /**
86       *
87       */
88      private static final long serialVersionUID = 2703580251118435168L;
89  
90      private static final String TEMPLATE_VIEW_SUBSCRIBER_PROPOSAL = "/skin/plugins/participatoryideation/view_subscriber_proposals.html";
91  
92      // Jsp redirections
93      private static final String JSP_PORTAL = "jsp/site/Portal.jsp";
94      // Parameters
95      private static final String PARAMETER_PAGE = "page";
96  
97      private static final String PARAMETER_PROPOSAL_ID = "proposal_id";
98      private static final String PARAMETER_CONFIRM_REMOVE_PROPOSAL = "confirm_remove_proposal";
99      // private static final String PARAMETER_CONF = "conf";
100 
101     // Markers
102     private static final String MARK_PROJECTS_SUBMITTED = "projectsSubmitted";
103     private static final String MARK_PROJECTS_PARTICIPATE = "projectsParticipate";
104     private static final String MARK_PROJECTS_COMMENTED = "projectsCommented";
105 
106     // Properties
107 
108     private static final String PROPERTY_CONFIRM_REMOVE_PROPOSAL = "participatoryideation.messages.confirmRemoveProposal";
109     private static final String MESSAGE_INFO_PROPOSAL_REMOVED = "participatoryideation.message.removed.succes";
110     private static final String MESSAGE_NOT_AUTHORIZED = "participatoryideation.messages.not.authorized";
111     private static final String MESSAGE_CAMPAIGN_IDEATION_CLOSED_DELETE = "participatoryideation.messages.campaign.ideation.closed.delete";
112 
113     // Views
114 
115     private static final String VIEW_SUBSCRIBER_PROPOSAL = "viewSubscriberProposals";
116 
117     // Actions
118     private static final String ACTION_DELETE_PROPOSAL = "actionDeleteProposal";
119     // session variable
120     private static ICommentService _commentService;
121     private IResourceExtenderHistoryService _resourceExtenderHistoryService = SpringContextService.getBean( ResourceExtenderHistoryService.BEAN_SERVICE );
122 
123     /**
124      * Returns the proposals for user
125      *
126      * @param request
127      *            The Http request
128      * @return The HT
129      */
130 
131     @View( value = VIEW_SUBSCRIBER_PROPOSAL, defaultView = true )
132     public XPage getSubscriberProposals( HttpServletRequest request ) throws UserNotSignedException
133     {
134         String strLuteceUserName = "guid";
135 
136         LuteceUser user = checkUserAuthorized( request );
137         if ( user != null )
138             strLuteceUserName = user.getName( );
139 
140         ProposalSearcheron/business/proposal/ProposalSearcher.html#ProposalSearcher">ProposalSearcher _proposalSearcher = new ProposalSearcher( );
141         _proposalSearcher.setLuteceUserName( strLuteceUserName );
142         _proposalSearcher.setIsPublished( true );
143 
144         Collection<Proposal> proposalsSubmitted = ProposalHome.getProposalsListSearch( _proposalSearcher );
145 
146         CommentFilter _commentFilter = new CommentFilter( );
147         _commentFilter.setLuteceUserName( strLuteceUserName );
148 
149         Collection<Proposal> proposalsCommented = getProposalsCommentedByUser(
150                 getCommentService( ).findByResource( "*", Proposal.PROPERTY_RESOURCE_TYPE, _commentFilter, 0, 10000, false ) );
151 
152         ResourceExtenderHistoryFilter filter = new ResourceExtenderHistoryFilter( );
153 
154         filter.setExtenderType( FollowResourceExtender.RESOURCE_EXTENDER );
155         filter.setUserGuid( strLuteceUserName );
156         filter.setExtendableResourceType( Proposal.PROPERTY_RESOURCE_TYPE );
157         // filter.setIdExtendableResource("*");
158 
159         List<ResourceExtenderHistory> listHistories = _resourceExtenderHistoryService.findByFilter( filter );
160 
161         Collection<Proposal> proposalsParticipate = getProposalsParticipatedByUser( listHistories );
162 
163         Map<String, Object> model = getModel( );
164 
165         model.put( MARK_PROJECTS_SUBMITTED, proposalsSubmitted );
166         model.put( MARK_PROJECTS_PARTICIPATE, proposalsParticipate );
167         model.put( MARK_PROJECTS_COMMENTED, proposalsCommented );
168 
169         BeansWrapper wrapper = BeansWrapper.getDefaultInstance( );
170 
171         IdeationStaticService.getInstance( ).fillAllStaticContent( model );
172 
173         return getXPage( TEMPLATE_VIEW_SUBSCRIBER_PROPOSAL, request.getLocale( ), model );
174     }
175 
176     /**
177      * Get the confirmation page before removing a proposal
178      * 
179      * @param request
180      *            The request
181      * @return The HTML content if the site message could not be displayed
182      * @throws SiteMessageException
183      *             If a site message needs to be displayed
184      * @throws UserNotSignedException
185      */
186     @Action( ACTION_DELETE_PROPOSAL )
187     public XPage getDeleteProposal( HttpServletRequest request ) throws SiteMessageException, UserNotSignedException
188     {
189         String strConfirmRemoveProposal = request.getParameter( PARAMETER_CONFIRM_REMOVE_PROPOSAL );
190         int nIdProposal = Integer.parseInt( request.getParameter( PARAMETER_PROPOSAL_ID ) );
191         String strLuteceUserName = "guid";
192         LuteceUser user = checkUserAuthorized( request );
193         if ( user != null )
194             strLuteceUserName = user.getName( );
195 
196         Proposal proposal = ProposalHome.findByPrimaryKey( nIdProposal );
197 
198         if ( !IdeationCampaignDataProvider.getInstance( ).isDuring( proposal.getCodeCampaign( ), ParticipatoryIdeationConstants.IDEATION ) )
199         {
200             SiteMessageService.setMessage( request, MESSAGE_CAMPAIGN_IDEATION_CLOSED_DELETE, SiteMessage.TYPE_ERROR );
201         }
202 
203         if ( strConfirmRemoveProposal != null )
204         {
205 
206             ProposalSearcheron/business/proposal/ProposalSearcher.html#ProposalSearcher">ProposalSearcher _proposalSearcher = new ProposalSearcher( );
207             _proposalSearcher.setLuteceUserName( strLuteceUserName );
208             _proposalSearcher.setIsPublished( true );
209             Collection<Proposal> proposalsSubmitted = ProposalHome.getProposalsListSearch( _proposalSearcher );
210             Boolean delete = false;
211 
212             for ( Proposal id : proposalsSubmitted )
213             {
214                 if ( id.getId( ) == proposal.getId( ) )
215                 {
216                     delete = true;
217                     break;
218                 }
219             }
220             if ( delete )
221             {
222                 proposal.setStatusPublic( Proposal.Status.STATUS_SUPPRIME_PAR_USAGER );
223                 ProposalService.getInstance( ).removeProposal( proposal );
224                 addInfo( MESSAGE_INFO_PROPOSAL_REMOVED, request.getLocale( ) );
225 
226                 return redirect( request, AppPathService.getBaseUrl( request ) + getActionFullUrl( VIEW_SUBSCRIBER_PROPOSAL ) );
227             }
228             else
229             {
230                 SiteMessageService.setMessage( request, MESSAGE_NOT_AUTHORIZED, SiteMessage.TYPE_STOP );
231             }
232 
233         }
234         Map<String, Object> requestParameters = new HashMap<String, Object>( );
235         requestParameters.put( PARAMETER_PAGE, "myProjects" );
236         requestParameters.put( MVCUtils.PARAMETER_ACTION, ACTION_DELETE_PROPOSAL );
237         requestParameters.put( PARAMETER_PROPOSAL_ID, nIdProposal );
238         requestParameters.put( PARAMETER_CONFIRM_REMOVE_PROPOSAL, "1" );
239         SiteMessageService.setMessage( request, PROPERTY_CONFIRM_REMOVE_PROPOSAL, SiteMessage.TYPE_CONFIRMATION, JSP_PORTAL, requestParameters );
240 
241         // Never return null because the setMessage method throw an exception
242         return null;
243     }
244 
245     private LuteceUser checkUserAuthorized( HttpServletRequest request ) throws UserNotSignedException
246     {
247         LuteceUser user = null;
248         if ( SecurityService.isAuthenticationEnable( ) )
249         {
250             user = SecurityService.getInstance( ).getRemoteUser( request );
251             if ( user == null )
252             {
253                 throw new UserNotSignedException( );
254             }
255         }
256         return user;
257     }
258 
259     /**
260      * Get the comment service
261      * 
262      * @return the comment service
263      */
264     private static ICommentService getCommentService( )
265     {
266         if ( _commentService == null )
267         {
268             _commentService = SpringContextService.getBean( CommentService.BEAN_SERVICE );
269         }
270         return _commentService;
271     }
272 
273     /**
274      * get the proposals List
275      * 
276      * @param listComments
277      * @return
278      */
279     private Collection<Proposal> getProposalsCommentedByUser( Collection<Comment> listComments )
280     {
281 
282         Collection<Proposal> proposalsList = new ArrayList<Proposal>( );
283         List<Integer> IdExtendableResourceList = new ArrayList<Integer>( );
284         for ( Comment comment : listComments )
285         {
286 
287             String idRessource = comment.getIdExtendableResource( );
288 
289             if ( idRessource != null && StringUtils.isNotEmpty( idRessource ) && StringUtils.isNumeric( idRessource ) )
290             {
291                 int nIdProposal = Integer.parseInt( idRessource );
292                 Proposal proposal = ProposalHome.findByPrimaryKey( nIdProposal );
293                 if ( proposal != null && ProposalService.getInstance( ).isPublished( proposal ) && !IdExtendableResourceList.contains( nIdProposal ) )
294                 {
295                     proposalsList.add( proposal );
296                     IdExtendableResourceList.add( nIdProposal );
297                 }
298             }
299         }
300 
301         return proposalsList;
302     }
303 
304     /**
305      * get the proposals List
306      * 
307      * @param listFollow
308      * @return
309      */
310     private Collection<Proposal> getProposalsParticipatedByUser( Collection<ResourceExtenderHistory> listFollow )
311     {
312 
313         Collection<Proposal> proposalsList = new ArrayList<Proposal>( );
314         for ( ResourceExtenderHistory follow : listFollow )
315         {
316 
317             String idRessource = follow.getIdExtendableResource( );
318 
319             if ( idRessource != null && StringUtils.isNotEmpty( idRessource ) && StringUtils.isNumeric( idRessource ) )
320             {
321                 int nIdProposal = Integer.parseInt( idRessource );
322                 Proposal proposal = ProposalHome.findByPrimaryKey( nIdProposal );
323                 if ( proposal != null && ProposalService.getInstance( ).isPublished( proposal ) )
324                 {
325                     proposalsList.add( proposal );
326                 }
327             }
328         }
329 
330         return proposalsList;
331     }
332 
333 }