View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.blog.web;
35  
36  import java.sql.Date;
37  import java.text.ParseException;
38  import java.text.SimpleDateFormat;
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.HashMap;
42  import java.util.Map;
43  
44  import javax.servlet.http.HttpServletRequest;
45  
46  import org.apache.commons.lang3.StringUtils;
47  
48  import fr.paris.lutece.plugins.blog.business.portlet.BlogListPortlet;
49  import fr.paris.lutece.plugins.blog.business.portlet.BlogListPortletHome;
50  import fr.paris.lutece.plugins.blog.business.portlet.BlogPortlet;
51  import fr.paris.lutece.plugins.blog.business.portlet.BlogPortletHome;
52  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublication;
53  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublicationHome;
54  import fr.paris.lutece.plugins.blog.business.portlet.PortletFilter;
55  import fr.paris.lutece.plugins.blog.business.portlet.PortletOrder;
56  import fr.paris.lutece.plugins.blog.service.BlogService;
57  import fr.paris.lutece.plugins.blog.service.PublishingService;
58  import fr.paris.lutece.portal.business.portlet.Portlet;
59  import fr.paris.lutece.portal.business.portlet.PortletHome;
60  import fr.paris.lutece.portal.business.portlet.PortletType;
61  import fr.paris.lutece.portal.service.i18n.I18nService;
62  import fr.paris.lutece.portal.service.portal.PortalService;
63  import fr.paris.lutece.portal.service.portlet.PortletResourceIdService;
64  import fr.paris.lutece.portal.service.portlet.PortletService;
65  import fr.paris.lutece.portal.service.rbac.RBACService;
66  import fr.paris.lutece.portal.service.template.AppTemplateService;
67  import fr.paris.lutece.portal.service.util.AppPropertiesService;
68  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
69  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
70  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
71  import fr.paris.lutece.util.ReferenceItem;
72  import fr.paris.lutece.util.html.HtmlTemplate;
73  import fr.paris.lutece.api.user.User;
74  
75  /**
76   * This class provides the user interface to manage HtmlDoc features ( manage, create, modify, remove )
77   */
78  @Controller( controllerJsp = "ManagePublicationBlogs.jsp", controllerPath = "jsp/admin/plugins/blog/", right = "BLOG_MANAGEMENT" )
79  public class BlogPublicationJspBean extends BlogJspBean
80  {
81  
82      private static final long serialVersionUID = -2768032240064881165L;
83      private static final String TEMPLATE_PUBLICATION_HTMLDOC = "/admin/plugins/blog/publication_blog.html";
84      private static final String TEMPLATE_PORTLET_PAGE_PATH = "/admin/plugins/blog/portlet_page_path.html";
85  
86      // Properties for page titles
87  
88      // Properties
89      private static final String PROPERTY_PAGE_TITLE_PUBLICATION_HTMLDOC = "blog.publication_blogpageTitle";
90      private static final String PROPERTY_DISPLAY_LATEST_PORTLETS = "blog.manage_document_publishing.labelDisplayLatestPortlets";
91  
92      // Markers
93      public static final String MARK_PORTLET_LIST = "portlet_list";
94      private static final String MARK_PORTLET_FILTER_ERROR = "portlet_filter_error";
95      private static final String MARK_ORDER_PORTLET = "order_portlet";
96      private static final String MARK_ORDER_PORTLET_ASC = "order_portlet_asc";
97      private static final String MARK_PORTLET = "portlet";
98      private static final String MARK_LIST_PAGE = "page_list";
99  
100     private static final String MARK_DOCUMENT_PORTLET_LIST = "document_portlet_list";
101     private static final String MARK_DOCUMENT_LIST_PORTLET_LIST = "document_list_portlet_list";
102     private static final String MARK_PORTLET_FILTER = "portlet_filter";
103     private static final String MARK_LABEL_DISPLAY_LATEST_PORTLETS = "label_display_latest_portlets";
104     public static final String DATE_END_PUBLICATION = AppPropertiesService.getProperty( "blog.date.end.publication", "2030-01-01 11:59:59" );
105 
106     // Properties
107 
108     // Validations
109 
110     // Views
111     private static final String VIEW_MANAGE_PUBLICATION = "manageBlogsPublication";
112 
113     // Actions
114     private static final String ACTION_PUBLISHE_DOCUMENT = "publishDocument";
115     private static final String ACTION_UNPUBLISHE_DOCUMENT = "unPublishDocument";
116 
117     // Infos
118 
119     // Filter Marks
120     // Parma
121     private static final String PARAMETER_PUBLISHED_DATE = "dateBeginPublishing";
122     private static final String PARAMETER_UNPUBLISHED_DATE = "dateEndPublishing";
123     private static final String PARAMETER_PORTLET_ID = "idPortlet";
124 
125     private static final String PARAMETER_ORDER_PORTLET = "order_portlet";
126     private static final String PARAMETER_ORDER_PORTLET_ASC = "order_portlet_asc";
127     private static final String PARAMETER_PORTLET_FILTER_TYPE = "portlet_filter_type";
128     private static final String PARAMETER_PORTLET_FILTER_VALUE = "portlet_filter_value";
129 
130     private static final String PARAMETER_IS_DISPLAY_LATEST_PORTLETS = "is_display_latest_portlets";
131 
132     // Message
133     private static final String ERROR_MESSAGE_NOT_NUMERIC_FIELD = "blog.message.notNumericField";
134     private static final String ERROR_MESSAGE_MESSAGE_MANDATORY_SEARCH_FIELD = "blog.message.mandatory.searchField";
135 
136     // Session variable to store working values
137     protected BlogPublication _blogPublication;
138 
139     /**
140      * Build the Manage View
141      * 
142      * @param request
143      *            The HTTP request
144      * @return The page
145      */
146     @View( value = VIEW_MANAGE_PUBLICATION )
147     public String getManageBlogPublication( HttpServletRequest request )
148     {
149         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
150         Object [ ] messageNumberOfMaxLatestPortletsDisplay = {
151                 String.valueOf( PortletFilter.PROPERTY_NUMBER_OF_MAX_LATEST_PORTLETS_DISPLAY )
152         };
153         String strErrorFilter = null;
154         _blogPublication = ( _blogPublication != null ) ? _blogPublication : new BlogPublication( );
155 
156         if ( _blog == null || ( _blog.getId( ) != nId ) )
157         {
158 
159             _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( nId );
160 
161         }
162         PortletOrder/business/portlet/PortletOrder.html#PortletOrder">PortletOrder pOrder = new PortletOrder( );
163         String strOrderPortlet = request.getParameter( PARAMETER_ORDER_PORTLET );
164         boolean bIsDisplayPortlets = ( ( request.getParameter( PARAMETER_IS_DISPLAY_LATEST_PORTLETS ) == null )
165                 || Boolean.valueOf( request.getParameter( PARAMETER_IS_DISPLAY_LATEST_PORTLETS ) ) );
166 
167         String strOrderPortletAsc = request.getParameter( PARAMETER_ORDER_PORTLET_ASC );
168         int nOrderPortlet = -1;
169         int nOrderPortletAsc = -1;
170 
171         Map<String, Object> model = getModel( );
172         PortletFilter portletFilter = null;
173         if ( !bIsDisplayPortlets )
174         {
175 
176             portletFilter = new PortletFilter( );
177             portletFilter.setPortletFilterType( request.getParameter( PARAMETER_PORTLET_FILTER_TYPE ) );
178             portletFilter.setDisplayLatestPortlets( bIsDisplayPortlets );
179             portletFilter.setSearchValue( request.getParameter( PARAMETER_PORTLET_FILTER_VALUE ) );
180             strErrorFilter = setFillFilter( portletFilter );
181 
182             if ( strErrorFilter != null )
183             {
184                 model.put( MARK_PORTLET_FILTER_ERROR, strErrorFilter );
185             }
186 
187         }
188 
189         if ( StringUtils.isNotBlank( strOrderPortlet ) && StringUtils.isNumeric( strOrderPortlet ) && StringUtils.isNotBlank( strOrderPortletAsc )
190                 && StringUtils.isNumeric( strOrderPortletAsc ) )
191         {
192             nOrderPortlet = Integer.parseInt( strOrderPortlet );
193             nOrderPortletAsc = Integer.parseInt( strOrderPortletAsc );
194             pOrder.setTypeOrder( nOrderPortlet );
195             pOrder.setSortAsc( nOrderPortletAsc == PortletOrder.SORT_ASC );
196         }
197 
198         Collection<ReferenceItem> listDocumentListPortlets = getListAuthorizedDocumentListPortlets( _blog.getId( ), pOrder,
199                 ( strErrorFilter == null ) ? portletFilter : null );
200         Collection<ReferenceItem> listDocumentPortlets = getListAuthorizedDocumentPortlets( _blog.getId( ), pOrder,
201                 ( strErrorFilter == null ) ? portletFilter : null );
202 
203         model.put( MARK_DOCUMENT_PORTLET_LIST, listDocumentPortlets );
204         model.put( MARK_DOCUMENT_LIST_PORTLET_LIST, listDocumentListPortlets );
205         model.put( MARK_BLOG, _blog );
206         model.put( MARK_PORTLET_LIST, PublishingService.getInstance( ).getBlogsPortletstoPublish( ) );
207 
208         model.put( MARK_ORDER_PORTLET, nOrderPortlet );
209         model.put( MARK_ORDER_PORTLET_ASC, nOrderPortletAsc );
210         model.put( MARK_PORTLET_FILTER, portletFilter );
211         model.put( MARK_LABEL_DISPLAY_LATEST_PORTLETS,
212                 I18nService.getLocalizedString( PROPERTY_DISPLAY_LATEST_PORTLETS, messageNumberOfMaxLatestPortletsDisplay, getLocale( ) ) );
213 
214         return getPage( PROPERTY_PAGE_TITLE_PUBLICATION_HTMLDOC, TEMPLATE_PUBLICATION_HTMLDOC, model );
215     }
216 
217     /**
218      * Publish a document in the portlet
219      * 
220      * @param request
221      * @return View mange publication
222      * @throws ParseException
223      */
224     @Action( ACTION_PUBLISHE_DOCUMENT )
225     public String doPublishDocument( HttpServletRequest request ) throws ParseException
226     {
227         populateBlogPublication( _blogPublication, request );
228 
229         if ( _blogPublication.getDateBeginPublishing( ) == null )
230         {
231 
232             _blogPublication.setDateBeginPublishing( new Date( System.currentTimeMillis( ) ) );
233         }
234         if ( _blogPublication.getDateEndPublishing( ) == null )
235         {
236             SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
237             _blogPublication.setDateEndPublishing( new Date( sdf.parse( DATE_END_PUBLICATION ).getTime( ) ) );
238         }
239         if ( _blogPublication.getIdPortlet( ) != 0 )
240         {
241 
242             BlogPublicationHome.create( _blogPublication );
243 
244             _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( _blogPublication.getIdBlog( ) );
245         }
246 
247         return getManageBlogPublication( request );
248 
249     }
250 
251     /**
252      * Unpublish a document in the portlet
253      * 
254      * @param request
255      *            The request
256      * @return view manage blog publication
257      */
258     @Action( ACTION_UNPUBLISHE_DOCUMENT )
259     public String doUnPublishDocument( HttpServletRequest request )
260     {
261 
262         populate( _blogPublication, request );
263 
264         BlogPublicationHome.remove( _blogPublication.getIdBlog( ), _blogPublication.getIdPortlet( ) );
265         _blog = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( _blogPublication.getIdBlog( ) );
266 
267         return getManageBlogPublication( request );
268 
269     }
270 
271     /**
272      * Populate BlogPublication object
273      * 
274      * @param blogPublication
275      *            The BlogPublication
276      * @param request
277      *            The request
278      * @throws ParseException
279      */
280     private void populateBlogPublication( BlogPublication htmldocPublication, HttpServletRequest request ) throws ParseException
281     {
282 
283         int nIdDoc = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
284         String strIdPortlet = request.getParameter( PARAMETER_PORTLET_ID );
285         int nIdPortlet = Integer.parseInt( strIdPortlet != null ? strIdPortlet : "0" );
286 
287         String dateBeginPublishingStr = request.getParameter( PARAMETER_PUBLISHED_DATE );
288         String dateEndPublishingStr = request.getParameter( PARAMETER_UNPUBLISHED_DATE );
289         java.sql.Date dateBeginPublishing = null;
290         java.sql.Date dateEndPublishing = null;
291 
292         SimpleDateFormat sdf = new SimpleDateFormat( "dd/MM/yyyy" );
293         java.util.Date parsed;
294 
295         if ( dateBeginPublishingStr != null && !dateBeginPublishingStr.isEmpty( ) )
296         {
297             parsed = sdf.parse( dateBeginPublishingStr );
298             dateBeginPublishing = new java.sql.Date( parsed.getTime( ) );
299         }
300         if ( dateEndPublishingStr != null && !dateEndPublishingStr.isEmpty( ) )
301         {
302             parsed = sdf.parse( dateEndPublishingStr );
303             dateEndPublishing = new java.sql.Date( parsed.getTime( ) );
304         }
305         int nBlogOrder = BlogListPortletHome.getMinDocBlogOrder( );
306         nBlogOrder = nBlogOrder - 1;
307 
308         htmldocPublication.setIdBlog( nIdDoc );
309         htmldocPublication.setIdPortlet( nIdPortlet );
310         htmldocPublication.setDateBeginPublishing( dateBeginPublishing );
311         htmldocPublication.setDateEndPublishing( dateEndPublishing );
312         htmldocPublication.setBlogOrder( nBlogOrder );
313 
314     }
315 
316     /**
317      * Fill the searchFilter
318      * 
319      * @param portletFilter
320      *            {@link PortletFilter}
321      * @return return error message if an error appear
322      */
323     public String setFillFilter( PortletFilter portletFilter )
324     {
325         String strErrorMessage = null;
326         String strValue;
327 
328         if ( ( portletFilter.getSearchValue( ) != null ) && !portletFilter.getSearchValue( ).trim( ).equals( "" )
329                 && ( portletFilter.getPortletFilterType( ) != null ) )
330         {
331             strValue = portletFilter.getSearchValue( ).trim( );
332 
333             if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PAGE_NAME ) )
334             {
335                 portletFilter.setPageName( strValue.split( PortletFilter.CONSTANTE_SPACE_STRING ) );
336             }
337             else
338                 if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PORTLET_NAME ) )
339                 {
340                     portletFilter.setPortletName( strValue.split( PortletFilter.CONSTANTE_SPACE_STRING ) );
341                 }
342                 else
343                     if ( portletFilter.getPortletFilterType( ).equals( PortletFilter.PAGE_ID ) )
344                     {
345                         if ( StringUtils.isNumeric( strValue ) )
346                         {
347                             portletFilter.setIdPage( Integer.parseInt( strValue ) );
348                         }
349                         else
350                         {
351                             strErrorMessage = I18nService.getLocalizedString( ERROR_MESSAGE_NOT_NUMERIC_FIELD, getLocale( ) );
352                         }
353                     }
354         }
355 
356         else
357         {
358             strErrorMessage = I18nService.getLocalizedString( ERROR_MESSAGE_MESSAGE_MANDATORY_SEARCH_FIELD, getLocale( ) );
359         }
360 
361         return strErrorMessage;
362     }
363 
364     /**
365      * Get the list of authorized portlets.
366      *
367      * Check :
368      * <ul>
369      * <li>if user is authorized to manage DocumentListPortlet</li>
370      * <li>if user is authorized to manage DocumentPortlet</li>
371      * <li>For each portlet :
372      * <ul>
373      * <li>if user is authorized to manage the linked page</li>
374      * <li>if portlet isn't in autopublication mode</li>
375      * </ul>
376      * </li>
377      * </ul>
378      *
379      * @param nDocumentId
380      *            The document id
381      * @param pOrder
382      *            The portlet order
383      * @param pFilter
384      *            The portlet filter
385      * @return A collection of {@link ReferenceItem}
386      */
387     private Collection<ReferenceItem> getListAuthorizedDocumentListPortlets( int nDocumentId, PortletOrder pOrder, PortletFilter pFilter )
388     {
389         Collection<ReferenceItem> listPortlets = new ArrayList<>( );
390 
391         // Check role PERMISSION_MANAGE for DocumentListPortlet
392         if ( RBACService.isAuthorized( PortletType.RESOURCE_TYPE, BlogListPortlet.RESOURCE_ID, PortletResourceIdService.PERMISSION_MANAGE, (User) getUser( ) ) )
393         {
394             listPortlets.addAll( BlogListPortletHome.findByFilter( nDocumentId, pOrder, pFilter ) );
395         }
396 
397         // check ROLE PERMISSION_MANAGE for PAGE and WORKGROUP
398         return filterByWorkgroup( listPortlets, pFilter );
399     }
400 
401     /**
402      * Filter the given portlets list by its workgroup
403      *
404      * @param listPortlets
405      *            a collection of {@link ReferenceItem}
406      * @param pFilter
407      *            The portlet filter
408      * @return a collection of {@link ReferenceItem}
409      */
410     private Collection<ReferenceItem> filterByWorkgroup( Collection<ReferenceItem> listPortlets, PortletFilter pFilter )
411     {
412         // check ROLE PERMISSION_MANAGE for PAGE and WORKGROUP
413         Collection<ReferenceItem> listFilteredPortlets = new ArrayList<>( );
414 
415         // Check role PERMISSION_MANAGE for workgroup and page and check if
416         // portlet isn't autopublished
417         for ( ReferenceItem item : listPortlets )
418         {
419             Portlet portlet = PortletHome.findByPrimaryKey( Integer.parseInt( item.getCode( ) ) );
420 
421             if ( ( portlet != null ) && PortletService.getInstance( ).isAuthorized( portlet, getUser( ) ) )
422             {
423                 Map<String, Object> subModel = new HashMap<>( );
424                 subModel.put( MARK_LIST_PAGE, PortalService.getPagePath( PortletHome.findByPrimaryKey( Integer.parseInt( item.getCode( ) ) ).getPageId( ) ) );
425                 subModel.put( MARK_PORTLET, item );
426 
427                 HtmlTemplate subTemplate = AppTemplateService.getTemplate( TEMPLATE_PORTLET_PAGE_PATH, getLocale( ), subModel );
428                 item.setName( subTemplate.getHtml( ) );
429 
430                 listFilteredPortlets.add( item );
431 
432                 if ( ( ( pFilter == null ) || pFilter.isDisplayLatestPortlets( ) )
433                         && ( listFilteredPortlets.size( ) >= PortletFilter.PROPERTY_NUMBER_OF_MAX_LATEST_PORTLETS_DISPLAY ) )
434                 {
435                     break;
436                 }
437             }
438         }
439 
440         return listFilteredPortlets;
441     }
442 
443     /**
444      * Get the list of authorized portlets.
445      *
446      * Check :
447      * <ul>
448      * <li>if user is authorized to manage DocumentListPortlet</li>
449      * <li>if user is authorized to manage DocumentPortlet</li>
450      * <li>For each portlet :
451      * <ul>
452      * <li>if user is authorized to manage the linked page</li>
453      * <li>if portlet isn't in autopublication mode</li>
454      * </ul>
455      * </li>
456      * </ul>
457      *
458      * @param nDocumentId
459      *            The document id
460      * 
461      * @param pOrder
462      *            The portlet order
463      * @param pFilter
464      *            The portlet filter
465      * @return A collection of {@link ReferenceItem}
466      */
467     private Collection<ReferenceItem> getListAuthorizedDocumentPortlets( int nDocumentId, PortletOrder pOrder, PortletFilter pFilter )
468     {
469         Collection<ReferenceItem> listPortlets = new ArrayList<>( );
470 
471         // Check role PERMISSION_MANAGE for DocumentPortlet
472         if ( RBACService.isAuthorized( PortletType.RESOURCE_TYPE, BlogPortlet.RESOURCE_ID, PortletResourceIdService.PERMISSION_MANAGE, (User) getUser( ) ) )
473         {
474             listPortlets.addAll( BlogPortletHome.findByFilter( nDocumentId, pOrder, pFilter ) );
475         }
476 
477         return filterByWorkgroup( listPortlets, pFilter );
478     }
479 
480 }