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.blog.web;
35  
36  import fr.paris.lutece.plugins.blog.business.ContentType;
37  import fr.paris.lutece.plugins.blog.business.DocContent;
38  import fr.paris.lutece.plugins.blog.business.Blog;
39  import fr.paris.lutece.plugins.blog.business.BlogHome;
40  import fr.paris.lutece.plugins.blog.business.BlogSearchFilter;
41  import fr.paris.lutece.plugins.blog.business.DocContentHome;
42  import fr.paris.lutece.plugins.blog.business.Tag;
43  import fr.paris.lutece.plugins.blog.business.TagHome;
44  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublication;
45  import fr.paris.lutece.plugins.blog.business.portlet.BlogPublicationHome;
46  import fr.paris.lutece.plugins.blog.service.BlogService;
47  import fr.paris.lutece.plugins.blog.service.BlogServiceSession;
48  import fr.paris.lutece.plugins.blog.service.BlogSessionListner;
49  import fr.paris.lutece.plugins.blog.service.docsearch.BlogSearchService;
50  import fr.paris.lutece.plugins.blog.utils.BlogLock;
51  import fr.paris.lutece.portal.service.message.AdminMessage;
52  import fr.paris.lutece.portal.service.message.AdminMessageService;
53  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
54  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
55  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
56  import fr.paris.lutece.portal.web.resource.ExtendableResourcePluginActionManager;
57  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
58  import fr.paris.lutece.portal.web.util.LocalizedPaginator;
59  import fr.paris.lutece.util.date.DateUtil;
60  import fr.paris.lutece.util.html.Paginator;
61  import fr.paris.lutece.util.json.JsonResponse;
62  import fr.paris.lutece.util.json.JsonUtil;
63  import fr.paris.lutece.util.sort.AttributeComparator;
64  import fr.paris.lutece.util.url.UrlItem;
65  import fr.paris.lutece.util.ReferenceList;
66  import fr.paris.lutece.portal.service.rbac.RBACService;
67  import fr.paris.lutece.portal.service.resource.ExtendableResourceRemovalListenerService;
68  import fr.paris.lutece.portal.service.util.AppLogService;
69  import fr.paris.lutece.portal.service.util.AppPathService;
70  import fr.paris.lutece.portal.service.util.AppPropertiesService;
71  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
72  import fr.paris.lutece.portal.service.admin.AdminUserService;
73  import fr.paris.lutece.portal.service.datastore.DatastoreService;
74  import fr.paris.lutece.portal.business.rbac.RBAC;
75  import fr.paris.lutece.portal.business.user.AdminUser;
76  
77  import java.sql.Timestamp;
78  import java.util.ArrayList;
79  import java.util.Base64;
80  import java.util.Collections;
81  import java.util.HashMap;
82  import java.util.List;
83  import java.util.Locale;
84  import java.util.Map;
85  import java.util.stream.Collectors;
86  import java.io.ByteArrayInputStream;
87  import java.io.IOException;
88  import java.io.InputStream;
89  import java.io.StringWriter;
90  import java.net.URLConnection;
91  
92  import javax.servlet.http.HttpServletRequest;
93  import javax.servlet.http.HttpSession;
94  import javax.xml.transform.OutputKeys;
95  import javax.xml.transform.TransformerFactory;
96  import javax.xml.transform.sax.SAXTransformerFactory;
97  import javax.xml.transform.sax.TransformerHandler;
98  import javax.xml.transform.stream.StreamResult;
99  
100 import org.outerj.daisy.diff.HtmlCleaner;
101 import org.outerj.daisy.diff.html.HTMLDiffer;
102 import org.outerj.daisy.diff.html.HtmlSaxDiffOutput;
103 import org.outerj.daisy.diff.html.TextNodeComparator;
104 import org.outerj.daisy.diff.html.dom.DomTreeBuilder;
105 import org.xml.sax.InputSource;
106 import org.apache.commons.fileupload.FileItem;
107 import org.apache.commons.lang.ArrayUtils;
108 import org.apache.commons.lang.StringUtils;
109 
110 /**
111  * This class provides the user interface to manage Blog features ( manage, create, modify, remove )
112  */
113 @Controller( controllerJsp = "ManageBlogs.jsp", controllerPath = "jsp/admin/plugins/blog/", right = "BLOG_MANAGEMENT" )
114 public class BlogJspBean extends ManageBlogJspBean
115 {
116     // Templates
117     private static final String TEMPLATE_MANAGE_BLOGS = "/admin/plugins/blog/manage_blogs.html";
118     private static final String TEMPLATE_CREATE_BLOG = "/admin/plugins/blog/create_blog.html";
119     private static final String TEMPLATE_MODIFY_BLOG = "/admin/plugins/blog/modify_blog.html";
120     private static final String TEMPLATE_HISTORY_BLOG = "admin/plugins/blog/history_blog.html";
121     private static final String TEMPLATE_PREVIEW_BLOG = "admin/plugins/blog/preview_blog.html";
122     private static final String TEMPLATE_DIFF_BLOG = "admin/plugins/blog/diff_blog.html";
123 
124     // Parameters
125     protected static final String PARAMETER_ID_BLOG = "id";
126     protected static final String PARAMETER_VERSION_BLOG = "blog_version";
127     protected static final String PARAMETER_VERSION_BLOG2 = "blog_version2";
128     protected static final String PARAMETER_CONTENT_LABEL = "content_label";
129     protected static final String PARAMETER_HTML_CONTENT = "html_content";
130     protected static final String PARAMETER_EDIT_COMMENT = "edit_comment";
131     protected static final String PARAMETER_DESCRIPTION = "description";
132     protected static final String PARAMETER_FILE_NAME = "fileName";
133     protected static final String PARAMETER_VIEW = "view";
134     protected static final String PARAMETER_BUTTON_SEARCH = "button_search";
135     protected static final String PARAMETER_BUTTON_RESET = "button_reset";
136 
137     protected static final String PARAMETER_SEARCH_TEXT = "search_text";
138     protected static final String PARAMETER_UPDATE_ATTACHMENT = "update_attachment";
139     protected static final String PARAMETER_TAG = "tag_doc";
140     protected static final String PARAMETER_TAG_NAME = "tag_name";
141     protected static final String PARAMETER_URL = "url";
142     protected static final String PARAMETER_UNPUBLISHED = "unpublished";
143     protected static final String PARAMETER_DATE_UPDATE_BLOG_AFTER = "dateUpdateBlogAfter";
144     protected static final String PARAMETER_DATE_UPDATE_BLOG_BEFOR = "dateUpdateBlogBefor";
145 
146     protected static final String PARAMETER_TAG_TO_REMOVE = "tag_remove";
147     protected static final String PARAMETER_SHAREABLE = "shareable";
148     protected static final String PARAMETER_PRIORITY = "tag_priority";
149     protected static final String PARAMETER_TAG_ACTION = "tagAction";
150     protected static final String PARAMETER_ACTION_BUTTON = "button";
151     protected static final String PARAMETER_APPLY = "apply";
152     protected static final String PARAMETER_TYPE_ID = "idType";
153     protected static final String PARAMETER_CONTENT_ID = "idContent";
154     protected static final String PARAMETER_CONTENT_ACTION = "contentAction";
155 
156     // Properties for page titles
157     private static final String PROPERTY_PAGE_TITLE_MANAGE_BLOG = "blog.manage_blog.pageTitle";
158     private static final String PROPERTY_PAGE_TITLE_MODIFY_BLOG = "blog.modify_blog.pageTitle";
159     private static final String PROPERTY_PAGE_TITLE_CREATE_BLOG = "blog.create_blog.pageTitle";
160     private static final String PROPERTY_PAGE_TITLE_HISTORY_BLOG = "blog.history_blog.pageTitle";
161     private static final String PROPERTY_PAGE_TITLE_PREVIEW_BLOG = "blog.preview_blog.pageTitle";
162     private static final String PROPERTY_PAGE_TITLE_DIFF_BLOG = "blog.diff_blog.pageTitle";
163     protected static final String PROPERTY_USE_UPLOAD_IMAGE_PLUGIN = "use_upload_image_plugin";
164 
165     // Properties
166     private static final String PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE = "blog.listItems.itemsPerPage";
167 
168     // Markers
169     protected static final String MARK_BLOG_LIST = "blog_list";
170     protected static final String MARK_BLOG_VERSION_LIST = "blog_version_list";
171     protected static final String MARK_BLOG = "blog";
172     protected static final String MARK_WEBAPP_URL = "webapp_url";
173     protected static final String MARK_IS_CHECKED = "is_checked";
174     protected static final String MARK_CURRENT_USER = "current_user";
175     protected static final String MARK_ID_BLOG = "id";
176     protected static final String MARK_SEARCH_TEXT = "search_text";
177     protected static final String MARK_DIFF = "blog_diff";
178     protected static final String MARK_BLOG2 = "blog2";
179     protected static final String MARK_LIST_TAG = "list_tag";
180     protected static final String MARK_LIST_IMAGE_TYPE = "image_type";
181     protected static final String MARK_SORTED_ATTRIBUTE = "sorted_attribute_name";
182     protected static final String MARK_TAG = "tags";
183     protected static final String MARK_USE_UPLOAD_IMAGE_PLUGIN = "is_crop_image";
184     protected static final String MARK_PERMISSION_CREATE_BLOG = "permission_manage_create_blog";
185     protected static final String MARK_PERMISSION_MODIFY_BLOG = "permission_manage_modify_blog";
186     protected static final String MARK_PERMISSION_PUBLISH_BLOG = "permission_manage_publish_blog";
187     protected static final String MARK_PERMISSION_DELETE_BLOG = "permission_manage_delete_blog";
188 
189     private static final String JSP_MANAGE_BLOGS = "jsp/admin/plugins/blog/ManageBlogs.jsp";
190 
191     // Properties
192     private static final String MESSAGE_CONFIRM_REMOVE_BLOG = "blog.message.confirmRemoveBlog";
193     private static final String MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED = "blog.message.errorDocumentIsPublished";
194 
195     // Validations
196     private static final String VALIDATION_ATTRIBUTES_PREFIX = "blog.model.entity.blog.attribute.";
197 
198     // Views
199     protected static final String VIEW_MANAGE_BLOGS = "manageBlogs";
200     private static final String VIEW_CREATE_BLOG = "createBlog";
201     private static final String VIEW_MODIFY_BLOG = "modifyBlog";
202     private static final String VIEW_HISTORY_BLOG = "historyBlog";
203     private static final String VIEW_PREVIEW_BLOG = "previewBlog";
204     private static final String VIEW_DIFF_BLOG = "diffBlog";
205 
206     // Actions
207     private static final String ACTION_CREATE_BLOG = "createBlog";
208     private static final String ACTION_MODIFY_BLOG = "modifyBlog";
209     private static final String ACTION_REMOVE_BLOG = "removeBlog";
210     private static final String ACTION_CONFIRM_REMOVE_BLOG = "confirmRemoveBlog";
211     private static final String ACTION_ADD_TAG = "addTag";
212     private static final String ACTION_REMOVE_TAG = "removeTag";
213     private static final String ACTION_UPDATE_PRIORITY_TAG = "updatePriorityTag";
214     private static final String ACTION_ADD_FILE_CONTENT = "addContent";
215     private static final String ACTION_REMOVE_FILE_CONTENT = "deleteContent";
216     private static final String ACTION_UPDATE_PRIORITY_FILE_CONTENT = "updatePriorityContent";
217     private static final String ACTION_UPDATE_CONTENT_TYPE = "updateContentType";
218     private static final String ACTION_DUPLICATE_BLOG = "duplicateBlog";
219 
220     // Infos
221     private static final String INFO_BLOG_CREATED = "blog.info.blog.created";
222     private static final String INFO_BLOG_UPDATED = "blog.info.blog.updated";
223     private static final String INFO_BLOG_REMOVED = "blog.info.blog.removed";
224     private static final String BLOG_LOCKED = "blog.message.blogLocked";
225 
226     // Filter Marks
227     protected static final String MARK_BLOG_FILTER_LIST = "blog_filter_list";
228     protected static final String MARK_BLOG_FILTER_NAME = "Nom";
229     protected static final String MARK_BLOG_FILTER_DATE = "Date";
230     protected static final String MARK_BLOG_FILTER_USER = "Utilisateur";
231     protected static final String MARK_PAGINATOR = "paginator";
232     protected static final String MARK_NB_ITEMS_PER_PAGE = "nb_items_per_page";
233     protected static final String MARK_ASC_SORT = "asc_sort";
234     protected static final String MARK_DATE_UPDATE_BLOG_AFTER = "dateUpdateBlogAfter";
235     protected static final String MARK_DATE_UPDATE_BLOG_BEFOR = "dateUpdateBlogBefor";
236     protected static final String MARK_UNPUBLISHED = "unpublished";
237 
238     public static final String CONSTANT_DUPLICATE_BLOG_NAME = "Copie de ";
239 
240     private static final String RESPONSE_BLOG_LOCKED = "BLOG_LOCKED";
241     private static final String RESPONSE_SUCCESS = "SUCCESS";
242     private static final String RESPONSE_FAILURE = "FAILURE";
243 
244     // Session variable to store working values
245     private static Map<Integer, BlogLock> _mapLockBlog = new HashMap<>( );
246     protected Blog _blog;
247     protected boolean _bIsChecked = false;
248     protected String _strSearchText;
249     protected boolean _bIsUnpulished = false;
250     protected String _dateUpdateBlogAfter;
251     protected String _dateUpdateBlogBefor;
252     protected String _strCurrentPageIndex;
253     protected int _nItemsPerPage;
254     protected int _nDefaultItemsPerPage;
255     protected boolean _bIsSorted = false;
256     protected String _strSortedAttributeName;
257     protected Boolean _bIsAscSort;
258     protected String [ ] _strTag;
259 
260     // Session variable to store working values
261     private final BlogServiceSession _blogServiceSession = BlogServiceSession.getInstance( );
262 
263     /**
264      * Build the Manage View
265      *
266      * @param request
267      *            The HTTP request
268      * @return The page
269      */
270     @View( value = VIEW_MANAGE_BLOGS, defaultView = true )
271     public String getManageBlogs( HttpServletRequest request )
272     {
273         _blog = null;
274         _strCurrentPageIndex = Paginator.getPageIndex( request, Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex );
275         _nDefaultItemsPerPage = AppPropertiesService.getPropertyInt( PROPERTY_DEFAULT_LIST_ITEM_PER_PAGE, 50 );
276         _nItemsPerPage = Paginator.getItemsPerPage( request, Paginator.PARAMETER_ITEMS_PER_PAGE, _nItemsPerPage, _nDefaultItemsPerPage );
277 
278         // SORT
279         String strSortedAttributeName = request.getParameter( MARK_SORTED_ATTRIBUTE );
280         String strAscSort;
281 
282         AdminUser user = AdminUserService.getAdminUser( request );
283         List<Integer> listBlogsId = new ArrayList<>( );
284         String strButtonSearch = request.getParameter( PARAMETER_BUTTON_SEARCH );
285         String strButtonReset = request.getParameter( PARAMETER_BUTTON_RESET );
286 
287         if ( strButtonSearch != null )
288         {
289             // CURRENT USER
290             _bIsChecked = request.getParameter( MARK_CURRENT_USER ) != null;
291             _strSearchText = request.getParameter( PARAMETER_SEARCH_TEXT );
292             _strTag = request.getParameterValues( PARAMETER_TAG );
293             _bIsUnpulished = request.getParameter( PARAMETER_UNPUBLISHED ) != null;
294             _dateUpdateBlogAfter = request.getParameter( PARAMETER_DATE_UPDATE_BLOG_AFTER );
295             _dateUpdateBlogBefor = request.getParameter( PARAMETER_DATE_UPDATE_BLOG_BEFOR );
296 
297         }
298         else
299             if ( strButtonReset != null )
300             {
301                 _bIsChecked = false;
302                 _strSearchText = null;
303                 _strTag = null;
304                 _bIsUnpulished = false;
305                 _dateUpdateBlogAfter = null;
306                 _dateUpdateBlogBefor = null;
307 
308             }
309 
310         if ( StringUtils.isNotBlank( _strSearchText ) || ( _strTag != null && _strTag.length > 0 ) || _bIsChecked || _bIsUnpulished
311                 || _dateUpdateBlogAfter != null || _dateUpdateBlogBefor != null )
312         {
313             BlogSearchFilteriness/BlogSearchFilter.html#BlogSearchFilter">BlogSearchFilter filter = new BlogSearchFilter( );
314             if ( StringUtils.isNotBlank( _strSearchText ) )
315                 filter.setKeywords( _strSearchText );
316             if ( _strTag != null && ( _strTag.length > 0 ) )
317                 filter.setTag( _strTag );
318             if ( _bIsChecked )
319                 filter.setUser( user.getAccessCode( ) );
320             if ( _bIsUnpulished )
321                 filter.setIsUnpulished( _bIsUnpulished );
322             if ( _dateUpdateBlogAfter != null )
323                 filter.setUpdateDateAfter( DateUtil.formatDate( _dateUpdateBlogAfter, request.getLocale( ) ) );
324             if ( _dateUpdateBlogBefor != null )
325                 filter.setUpdateDateBefor( DateUtil.formatDate( _dateUpdateBlogBefor, request.getLocale( ) ) );
326 
327             BlogSearchService.getInstance( ).getSearchResults( filter, listBlogsId );
328 
329         }
330         else
331         {
332             listBlogsId = BlogHome.getIdBlogsList( );
333         }
334 
335         LocalizedPaginator<Integer> paginator = new LocalizedPaginator<>( (List<Integer>) listBlogsId, _nItemsPerPage, getHomeUrl( request ),
336                 Paginator.PARAMETER_PAGE_INDEX, _strCurrentPageIndex, getLocale( ) );
337 
338         List<Blog> listDocuments = new ArrayList<>( );
339 
340         for ( Integer documentId : paginator.getPageItems( ) )
341         {
342             Blog document = BlogService.getInstance( ).findByPrimaryKeyWithoutBinaries( documentId );
343 
344             if ( document != null )
345             {
346                 if ( _mapLockBlog.containsKey( document.getId( ) )
347                         && !_mapLockBlog.get( document.getId( ) ).getSessionId( ).equals( request.getSession( ).getId( ) ) )
348                 {
349 
350                     document.setLocked( true );
351                 }
352                 listDocuments.add( document );
353             }
354         }
355 
356         if ( strSortedAttributeName != null || _bIsSorted )
357         {
358             if ( strSortedAttributeName == null )
359             {
360                 strSortedAttributeName = _strSortedAttributeName;
361             }
362             strAscSort = request.getParameter( MARK_ASC_SORT );
363 
364             boolean bIsAscSort = Boolean.parseBoolean( strAscSort );
365             if ( strAscSort == null )
366             {
367                 bIsAscSort = _bIsAscSort;
368             }
369 
370             Collections.sort( listDocuments, new AttributeComparator( strSortedAttributeName, bIsAscSort ) );
371 
372             _bIsSorted = true;
373 
374             _strSortedAttributeName = strSortedAttributeName;
375             _bIsAscSort = bIsAscSort;
376         }
377         boolean bPermissionCreate = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_CREATE, getUser( ) );
378         boolean bPermissionModify = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_MODIFY, getUser( ) );
379         boolean bPermissionDelete = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_DELETE, getUser( ) );
380         boolean bPermissionPublish = RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_PUBLISH, getUser( ) );
381 
382         Map<String, Object> model = new HashMap<>( );
383         model.put( MARK_BLOG_LIST, listDocuments );
384         model.put( MARK_PAGINATOR, paginator );
385         model.put( MARK_BLOG_FILTER_LIST, getBlogFilterList( ) );
386         model.put( MARK_LIST_TAG, TagHome.getTagsReferenceList( ) );
387         model.put( MARK_WEBAPP_URL, AppPathService.getBaseUrl( request ) );
388         model.put( MARK_IS_CHECKED, _bIsChecked );
389         model.put( MARK_SEARCH_TEXT, _strSearchText );
390         model.put( MARK_NB_ITEMS_PER_PAGE, "" + _nItemsPerPage );
391         model.put( MARK_TAG, _strTag );
392         model.put( MARK_DATE_UPDATE_BLOG_AFTER, _dateUpdateBlogAfter );
393         model.put( MARK_DATE_UPDATE_BLOG_BEFOR, _dateUpdateBlogBefor );
394         model.put( MARK_UNPUBLISHED, _bIsUnpulished );
395 
396         model.put( MARK_PERMISSION_CREATE_BLOG, bPermissionCreate );
397         model.put( MARK_PERMISSION_MODIFY_BLOG, bPermissionModify );
398         model.put( MARK_PERMISSION_DELETE_BLOG, bPermissionDelete );
399         model.put( MARK_PERMISSION_PUBLISH_BLOG, bPermissionPublish );
400 
401         return getPage( PROPERTY_PAGE_TITLE_MANAGE_BLOG, TEMPLATE_MANAGE_BLOGS, model );
402     }
403 
404     /**
405      * Return View history page
406      *
407      * @param request
408      *            The request
409      * @return the hostory page
410      */
411     @View( value = VIEW_HISTORY_BLOG )
412     public String getHistoryBlog( HttpServletRequest request )
413     {
414         _blog = null;
415         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
416         List<Blog> listBlogsVersions = BlogHome.getBlogsVersionsList( nId );
417 
418         UrlItem urlHistory = new UrlItem( JSP_MANAGE_BLOGS );
419         urlHistory.addParameter( PARAMETER_VIEW, VIEW_HISTORY_BLOG );
420         urlHistory.addParameter( PARAMETER_ID_BLOG, nId );
421 
422         Map<String, Object> model = getPaginatedListModel( request, MARK_BLOG_LIST, listBlogsVersions, urlHistory.getUrl( ) );
423 
424         model.put( MARK_ID_BLOG, nId );
425 
426         return getPage( PROPERTY_PAGE_TITLE_HISTORY_BLOG, TEMPLATE_HISTORY_BLOG, model );
427     }
428 
429     /**
430      * Returns the form to create a blog
431      *
432      * @param request
433      *            The Http request
434      * @return the html code of the blog form
435      * @throws AccessDeniedException
436      */
437     @View( VIEW_CREATE_BLOG )
438     public String getCreateBlog( HttpServletRequest request ) throws AccessDeniedException
439     {
440 
441         if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_CREATE, getUser( ) ) )
442         {
443             throw new AccessDeniedException( UNAUTHORIZED );
444         }
445 
446         _blog = ( _blog != null && _blog.getId( ) == 0 ) ? _blog : new Blog( );
447         _blogServiceSession.saveBlogInSession( request.getSession( ), _blog );
448         _blog.getTag( ).sort( ( tg1, tg2 ) -> tg1.getPriority( ) - tg2.getPriority( ) );
449 
450         String useCropImage = DatastoreService.getDataValue( PROPERTY_USE_UPLOAD_IMAGE_PLUGIN, "false" );
451         Map<String, Object> model = getModel( );
452 
453         boolean bPermissionCreate = RBACService.isAuthorized( Tag.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Tag.PERMISSION_CREATE, getUser( ) );
454 
455         model.put( MARK_LIST_IMAGE_TYPE, DocContentHome.getListContentType( ) );
456         model.put( MARK_PERMISSION_CREATE_TAG, bPermissionCreate );
457         model.put( MARK_BLOG, _blog );
458         model.put( MARK_LIST_TAG, getTageList( ) );
459         model.put( MARK_WEBAPP_URL, AppPathService.getBaseUrl( request ) );
460         model.put( MARK_USE_UPLOAD_IMAGE_PLUGIN, Boolean.parseBoolean( useCropImage ) );
461 
462         return getPage( PROPERTY_PAGE_TITLE_CREATE_BLOG, TEMPLATE_CREATE_BLOG, model );
463     }
464 
465     /**
466      * Process the data capture form of a new blog
467      *
468      * @param request
469      *            The Http Request
470      * @return The Jsp URL of the process result
471      */
472     @Action( ACTION_CREATE_BLOG )
473     public String doCreateBlog( HttpServletRequest request )
474     {
475 
476         if ( RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_CREATE, getUser( ) ) )
477         {
478             String strAction = request.getParameter( PARAMETER_ACTION_BUTTON );
479             _blog.setCreationDate( getSqlDate( ) );
480             _blog.setUpdateDate( getSqlDate( ) );
481             _blog.setUser( AdminUserService.getAdminUser( request ).getAccessCode( ) );
482             _blog.setUserCreator( AdminUserService.getAdminUser( request ).getAccessCode( ) );
483             _blog.setVersion( 1 );
484             _blog.setAttachedPortletId( 0 );
485             populate( _blog, request );
486 
487             // Check constraints
488             if ( !validateBean( _blog, VALIDATION_ATTRIBUTES_PREFIX ) )
489             {
490                 return redirectView( request, VIEW_CREATE_BLOG );
491             }
492 
493             BlogService.getInstance( ).createBlog( _blog, _blog.getDocContent( ) );
494             _blogServiceSession.removeBlogFromSession( request.getSession( ), _blog.getId( ) );
495 
496             if ( strAction != null && strAction.equals( PARAMETER_APPLY ) )
497             {
498 
499                 return redirect( request, VIEW_MODIFY_BLOG, PARAMETER_ID_BLOG, _blog.getId( ) );
500             }
501 
502             addInfo( INFO_BLOG_CREATED, getLocale( ) );
503         }
504         return redirectView( request, VIEW_MANAGE_BLOGS );
505     }
506 
507     /**
508      * Return Json if the tag is added
509      *
510      * @param request
511      *            The request
512      * @return Json The Json success or echec
513      */
514     @Action( ACTION_ADD_TAG )
515     public String doAddTag( HttpServletRequest request )
516     {
517         String strIdTag = request.getParameter( PARAMETER_TAG );
518         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
519         String nIdSession = request.getSession( ).getId( );
520         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
521         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
522         {
523 
524             lockBlog( nIdBlog, request.getSession( ).getId( ) );
525         }
526         else
527             if ( _blog.getId( ) != 0 )
528             {
529 
530                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
531             }
532 
533         if ( RBACService.isAuthorized( Tag.PROPERTY_RESOURCE_TYPE, strIdTag, Tag.PERMISSION_CREATE, getUser( ) ) )
534         {
535 
536             String strTagName = request.getParameter( PARAMETER_TAG_NAME );
537 
538             Tagplugins/blog/business/Tag.html#Tag">Tag tag = new Tag( Integer.parseInt( strIdTag ), _blog.getTag( ).size( ) + 1 );
539             tag.setName( strTagName );
540 
541             _blog.addTag( tag );
542 
543             return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_SUCCESS ) );
544         }
545         return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_FAILURE ) );
546 
547     }
548 
549     /**
550      * Return Json if the tag is removed
551      *
552      * @param request
553      * @return Json The Json success or echec
554      */
555     @Action( ACTION_REMOVE_TAG )
556     public String doRemoveTag( HttpServletRequest request )
557     {
558         String strIdTag = request.getParameter( PARAMETER_TAG );
559         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
560         String nIdSession = request.getSession( ).getId( );
561         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
562         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
563         {
564 
565             lockBlog( nIdBlog, request.getSession( ).getId( ) );
566         }
567         else
568             if ( _blog.getId( ) != 0 )
569             {
570 
571                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
572             }
573 
574         if ( RBACService.isAuthorized( Tag.PROPERTY_RESOURCE_TYPE, strIdTag, Tag.PERMISSION_DELETE, getUser( ) ) )
575         {
576             Tag tag = _blog.getTag( ).stream( ).filter( tg -> tg.getIdTag( ) == Integer.parseInt( strIdTag ) ).collect( Collectors.toList( ) ).get( 0 );
577             _blog.deleteTag( tag );
578 
579             List<Tag> listTag = _blog.getTag( ).stream( ).map( tg -> {
580                 if ( ( tg.getPriority( ) > tag.getPriority( ) ) )
581                 {
582                     tg.setPriority( tg.getPriority( ) - 1 );
583                 }
584                 return tg;
585             } ).collect( Collectors.toList( ) );
586 
587             _blog.setTag( listTag );
588             return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_SUCCESS ) );
589         }
590         return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_FAILURE ) );
591 
592     }
593 
594     /**
595      * Return Json if the tag is updated
596      *
597      * @param request
598      * @return Json The Json success or echec
599      */
600     @Action( ACTION_UPDATE_PRIORITY_TAG )
601     public String doUpdatePriorityTag( HttpServletRequest request )
602     {
603         Tag tg = null;
604         Tag tagMove = null;
605         int nPriorityToSet = 0;
606         int nPriority = 0;
607 
608         String strIdTag = request.getParameter( PARAMETER_TAG );
609         String strAction = request.getParameter( PARAMETER_TAG_ACTION );
610         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
611         String nIdSession = request.getSession( ).getId( );
612         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
613         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
614         {
615 
616             lockBlog( nIdBlog, request.getSession( ).getId( ) );
617         }
618         else
619             if ( _blog.getId( ) != 0 )
620             {
621 
622                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
623             }
624 
625         for ( Tag tag : _blog.getTag( ) )
626         {
627             if ( tag.getIdTag( ) == Integer.parseInt( strIdTag ) )
628             {
629                 tg = tag;
630                 nPriorityToSet = tag.getPriority( );
631                 nPriority = tag.getPriority( );
632             }
633         }
634         for ( Tag tag : _blog.getTag( ) )
635         {
636             if ( strAction.equals( "moveUp" ) && tag.getPriority( ) == nPriority - 1 )
637             {
638                 tagMove = tag;
639                 tagMove.setPriority( tagMove.getPriority( ) + 1 );
640                 nPriorityToSet = nPriority - 1;
641 
642             }
643             else
644                 if ( strAction.equals( "moveDown" ) && tag.getPriority( ) == nPriority + 1 )
645                 {
646                     tagMove = tag;
647                     tagMove.setPriority( tagMove.getPriority( ) - 1 );
648                     nPriorityToSet = nPriority + 1;
649 
650                 }
651         }
652         tg.setPriority( nPriorityToSet );
653 
654         if ( tagMove != null )
655         {
656 
657             return JsonUtil.buildJsonResponse( new JsonResponse( String.valueOf( tagMove.getIdTag( ) ) ) );
658 
659         }
660         return JsonUtil.buildJsonResponse( new JsonResponse( String.valueOf( tg.getIdTag( ) ) ) );
661 
662     }
663 
664     /**
665      * Manages the removal form of a blog whose identifier is in the http request
666      *
667      * @param request
668      *            The Http request
669      * @return the html code to confirm
670      * @throws AccessDeniedException
671      */
672     @Action( ACTION_CONFIRM_REMOVE_BLOG )
673     public String getConfirmRemoveBlog( HttpServletRequest request ) throws AccessDeniedException
674     {
675 
676         String strId = request.getParameter( PARAMETER_ID_BLOG );
677         int nId = Integer.parseInt( strId );
678         if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, strId, Blog.PERMISSION_DELETE, getUser( ) ) )
679         {
680             throw new AccessDeniedException( UNAUTHORIZED );
681         }
682         if ( checkLockBlog( nId, request.getSession( ).getId( ) ) )
683         {
684 
685             UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) );
686             String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP );
687             return redirect( request, strMessageUrl );
688 
689         }
690 
691         UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_BLOG ) );
692         url.addParameter( PARAMETER_ID_BLOG, nId );
693 
694         String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_BLOG, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
695 
696         return redirect( request, strMessageUrl );
697     }
698 
699     /**
700      * Handles the removal form of a blog
701      *
702      * @param request
703      *            The Http request
704      * @return the jsp URL to display the form to manage blog
705      */
706     @Action( ACTION_REMOVE_BLOG )
707     public String doRemoveBlog( HttpServletRequest request )
708     {
709         String strId = request.getParameter( PARAMETER_ID_BLOG );
710 
711         int nId = Integer.parseInt( strId );
712 
713         if ( RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, strId, Blog.PERMISSION_DELETE, getUser( ) ) )
714         {
715 
716             if ( checkLockBlog( nId, request.getSession( ).getId( ) ) )
717             {
718 
719                 UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) );
720                 String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP );
721                 return redirect( request, strMessageUrl );
722 
723             }
724 
725             List<BlogPublication> docPublication = BlogPublicationHome.getDocPublicationByIdDoc( nId );
726 
727             if ( docPublication.size( ) > 0 )
728             {
729                 String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_ERROR_DOCUMENT_IS_PUBLISHED, AdminMessage.TYPE_STOP );
730 
731                 return redirect( request, strMessageUrl );
732             }
733             BlogService.getInstance( ).deleteBlog( nId );
734             _blogServiceSession.removeBlogFromSession( request.getSession( ), nId );
735             unLockBlog( nId );
736 
737             ExtendableResourceRemovalListenerService.doRemoveResourceExtentions( Blog.PROPERTY_RESOURCE_TYPE, String.valueOf( nId ) );
738 
739             addInfo( INFO_BLOG_REMOVED, getLocale( ) );
740         }
741         return redirectView( request, VIEW_MANAGE_BLOGS );
742     }
743 
744     @Action( ACTION_DUPLICATE_BLOG )
745     public String doDuplicateBlog( HttpServletRequest request ) throws AccessDeniedException
746     {
747 
748         if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Blog.PERMISSION_CREATE, getUser( ) ) )
749         {
750             throw new AccessDeniedException( UNAUTHORIZED );
751         }
752 
753         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
754         _blog = BlogService.getInstance( ).loadBlog( nIdBlog );
755 
756         Timestamp sqlDate = getSqlDate( );
757 
758         _blog.setContentLabel( CONSTANT_DUPLICATE_BLOG_NAME + _blog.getContentLabel( ) );
759         _blog.setCreationDate( sqlDate );
760         _blog.setUpdateDate( sqlDate );
761         _blog.setUser( AdminUserService.getAdminUser( request ).getAccessCode( ) );
762         _blog.setUserCreator( AdminUserService.getAdminUser( request ).getAccessCode( ) );
763         _blog.setVersion( 1 );
764         _blog.setAttachedPortletId( 0 );
765 
766         BlogService.getInstance( ).createBlog( _blog, _blog.getDocContent( ) );
767 
768         return redirectView( request, VIEW_MANAGE_BLOGS );
769     }
770 
771     /**
772      * Returns the form to update info about a blog
773      *
774      * @param request
775      *            The Http request
776      * @return The HTML form to update info
777      * @throws AccessDeniedException
778      */
779     @View( VIEW_MODIFY_BLOG )
780     public String getModifyBlog( HttpServletRequest request ) throws AccessDeniedException
781     {
782         String strId = request.getParameter( PARAMETER_ID_BLOG );
783 
784         if ( !RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, strId, Blog.PERMISSION_MODIFY, getUser( ) ) )
785         {
786             throw new AccessDeniedException( UNAUTHORIZED );
787         }
788         int nId = Integer.parseInt( strId );
789         String strResetVersion = request.getParameter( PARAMETER_VERSION_BLOG );
790         String useCropImage = DatastoreService.getDataValue( PROPERTY_USE_UPLOAD_IMAGE_PLUGIN, "false" );
791         String sessionId = request.getSession( ).getId( );
792 
793         int nVersion = -1;
794         if ( strResetVersion != null )
795         {
796             nVersion = Integer.parseInt( strResetVersion );
797         }
798 
799         if ( strResetVersion != null )
800         {
801 
802             _blog = BlogHome.findVersion( nId, nVersion );
803             _blogServiceSession.saveBlogInSession( request.getSession( ), _blog );
804         }
805         else
806         {
807             _blog = BlogService.getInstance( ).loadBlog( nId );
808             _blogServiceSession.saveBlogInSession( request.getSession( ), _blog );
809 
810         }
811 
812         if ( checkLockBlog( nId, sessionId ) )
813         {
814 
815             UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) );
816             String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP );
817             return redirect( request, strMessageUrl );
818         }
819         for ( HttpSession httpSession : BlogSessionListner.getMapSession( ).values( ) )
820         {
821 
822             if ( !httpSession.getId( ).equals( sessionId ) )
823             {
824 
825                 _blogServiceSession.removeBlogFromSession( httpSession, nId );
826             }
827         }
828 
829         lockBlog( nId, sessionId );
830 
831         _blog.getTag( ).sort( ( tg1, tg2 ) -> tg1.getPriority( ) - tg2.getPriority( ) );
832         _blog.getDocContent( ).sort( ( dc1, dc2 ) -> dc1.getPriority( ) - dc2.getPriority( ) );
833         Map<String, Object> model = getModel( );
834 
835         boolean bPermissionCreate = RBACService.isAuthorized( Tag.PROPERTY_RESOURCE_TYPE, RBAC.WILDCARD_RESOURCES_ID, Tag.PERMISSION_CREATE, getUser( ) );
836 
837         model.put( MARK_LIST_IMAGE_TYPE, DocContentHome.getListContentType( ) );
838         model.put( MARK_PERMISSION_CREATE_TAG, bPermissionCreate );
839         model.put( MARK_BLOG, _blog );
840         model.put( MARK_LIST_TAG, getTageList( ) );
841         model.put( MARK_USE_UPLOAD_IMAGE_PLUGIN, Boolean.parseBoolean( useCropImage ) );
842         model.put( MARK_WEBAPP_URL, AppPathService.getBaseUrl( request ) );
843 
844         ExtendableResourcePluginActionManager.fillModel( request, getUser( ), model, String.valueOf( nId ), Blog.PROPERTY_RESOURCE_TYPE );
845 
846         return getPage( PROPERTY_PAGE_TITLE_MODIFY_BLOG, TEMPLATE_MODIFY_BLOG, model );
847     }
848 
849     /**
850      * Process the change form of a blog
851      *
852      * @param request
853      *            The Http request
854      * @return The Jsp URL of the process result
855      */
856     @Action( ACTION_MODIFY_BLOG )
857     public String doModifyBlog( HttpServletRequest request )
858     {
859 
860         String strId = request.getParameter( PARAMETER_ID_BLOG );
861         String strAction = request.getParameter( PARAMETER_ACTION_BUTTON );
862         int nId = Integer.parseInt( strId );
863         String strHtmlContent = request.getParameter( PARAMETER_HTML_CONTENT );
864         String strEditComment = request.getParameter( PARAMETER_EDIT_COMMENT );
865         String strContentLabel = request.getParameter( PARAMETER_CONTENT_LABEL );
866         String strDescription = request.getParameter( PARAMETER_DESCRIPTION );
867         String strShareable = request.getParameter( PARAMETER_SHAREABLE );
868         String strUrl = request.getParameter( PARAMETER_URL );
869 
870         if ( RBACService.isAuthorized( Blog.PROPERTY_RESOURCE_TYPE, strId, Blog.PERMISSION_MODIFY, getUser( ) ) )
871         {
872             _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nId );
873             if ( checkLockBlog( Integer.parseInt( strId ), request.getSession( ).getId( ) ) || _blog == null )
874             {
875 
876                 UrlItem url = new UrlItem( getActionUrl( VIEW_MANAGE_BLOGS ) );
877                 String strMessageUrl = AdminMessageService.getMessageUrl( request, BLOG_LOCKED, url.getUrl( ), AdminMessage.TYPE_STOP );
878                 return redirect( request, strMessageUrl );
879             }
880             Blog latestVersionBlog = BlogService.getInstance( ).loadBlog( nId );
881 
882             _blog.setContentLabel( strContentLabel );
883             _blog.setDescription( strDescription );
884             _blog.setShareable( Boolean.parseBoolean( strShareable ) );
885             _blog.setHtmlContent( strHtmlContent );
886             _blog.setEditComment( strEditComment );
887             _blog.setUpdateDate( getSqlDate( ) );
888             _blog.setUser( AdminUserService.getAdminUser( request ).getAccessCode( ) );
889             _blog.setUrl( strUrl );
890 
891             // Check constraints
892             if ( !validateBean( _blog, VALIDATION_ATTRIBUTES_PREFIX ) )
893             {
894                 return redirect( request, VIEW_MODIFY_BLOG, PARAMETER_ID_BLOG, _blog.getId( ) );
895             }
896 
897             if ( strAction != null && strAction.equals( PARAMETER_APPLY ) )
898             {
899                 BlogService.getInstance( ).updateBlogWithoutVersion( _blog, _blog.getDocContent( ) );
900                 _blogServiceSession.removeBlogFromSession( request.getSession( ), nId );
901                 unLockBlog( nId );
902 
903                 return redirect( request, VIEW_MODIFY_BLOG, PARAMETER_ID_BLOG, _blog.getId( ) );
904 
905             }
906             else
907             {
908                 _blog.setVersion( latestVersionBlog.getVersion( ) + 1 );
909                 BlogService.getInstance( ).updateBlog( _blog, _blog.getDocContent( ) );
910                 _blogServiceSession.removeBlogFromSession( request.getSession( ), nId );
911                 unLockBlog( nId );
912                 addInfo( INFO_BLOG_UPDATED, getLocale( ) );
913             }
914         }
915         return redirectView( request, VIEW_MANAGE_BLOGS );
916     }
917 
918     /**
919      * Returns the preview of an blog
920      *
921      * @param request
922      *            The Http request
923      * @return The HTML form to update info
924      */
925     @View( VIEW_PREVIEW_BLOG )
926     public String getPreviewBlog( HttpServletRequest request )
927     {
928         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
929         String strVersion = request.getParameter( PARAMETER_VERSION_BLOG );
930         int nVersion = -1;
931         if ( strVersion != null )
932         {
933             nVersion = Integer.parseInt( strVersion );
934         }
935 
936         Blog blog;
937         if ( strVersion != null )
938         {
939             blog = BlogHome.findVersion( nId, nVersion );
940         }
941         else
942         {
943             blog = BlogService.getInstance( ).loadBlog( nId );
944         }
945         blog.setBlogPublication( BlogPublicationHome.getDocPublicationByIdDoc( nId ) );
946 
947         Map<String, Object> model = getModel( );
948         model.put( MARK_LIST_TAG, TagHome.getTagsReferenceList( ) );
949 
950         model.put( MARK_BLOG, blog );
951 
952         ExtendableResourcePluginActionManager.fillModel( request, getUser( ), model, String.valueOf( nId ), Blog.PROPERTY_RESOURCE_TYPE );
953 
954         return getPage( PROPERTY_PAGE_TITLE_PREVIEW_BLOG, TEMPLATE_PREVIEW_BLOG, model );
955     }
956 
957     /**
958      * Returns the diff of two blog versions
959      *
960      * @param request
961      *            The Http request
962      * @return The HTML form to update info
963      */
964     @View( VIEW_DIFF_BLOG )
965     public String getDiffBlog( HttpServletRequest request )
966     {
967         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
968         String strVersion = request.getParameter( PARAMETER_VERSION_BLOG );
969         int nVersion = -1;
970         if ( strVersion != null )
971         {
972             nVersion = Integer.parseInt( strVersion );
973         }
974         String strVersion2 = request.getParameter( PARAMETER_VERSION_BLOG2 );
975 
976         Blog blog;
977         if ( strVersion != null )
978         {
979             blog = BlogHome.findVersion( nId, nVersion );
980         }
981         else
982         {
983             blog = BlogHome.findByPrimaryKey( nId );
984         }
985 
986         int nVersion2 = blog.getVersion( ) - 1;
987         if ( strVersion2 != null )
988         {
989             nVersion2 = Integer.parseInt( strVersion2 );
990         }
991 
992         Blog blog2 = BlogHome.findVersion( nId, nVersion2 );
993         if ( blog2 == null )
994         {
995             blog2 = BlogHome.findByPrimaryKey( nId );
996         }
997 
998         if ( blog2.getVersion( ) > blog.getVersion( ) )
999         {
1000             Blog tmp = blog2;
1001             blog2 = blog;
1002             blog = tmp;
1003         }
1004 
1005         String strDiff = null;
1006         HtmlCleaner cleaner = new HtmlCleaner( );
1007         try
1008         {
1009             SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance( );
1010             TransformerHandler result = tf.newTransformerHandler( );
1011             result.getTransformer( ).setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" );
1012             StringWriter resultWriter = new StringWriter( );
1013             result.setResult( new StreamResult( resultWriter ) );
1014             Locale locale = getLocale( );
1015 
1016             DomTreeBuilder oldHandler = new DomTreeBuilder( );
1017             cleaner.cleanAndParse( new InputSource( new ByteArrayInputStream( blog2.getHtmlContent( ).getBytes( "UTF-8" ) ) ), oldHandler );
1018             TextNodeComparator leftComparator = new TextNodeComparator( oldHandler, locale );
1019 
1020             DomTreeBuilder newHandler = new DomTreeBuilder( );
1021             cleaner.cleanAndParse( new InputSource( new ByteArrayInputStream( blog.getHtmlContent( ).getBytes( "UTF-8" ) ) ), newHandler );
1022             TextNodeComparator rightComparator = new TextNodeComparator( newHandler, locale );
1023 
1024             HtmlSaxDiffOutput output = new HtmlSaxDiffOutput( result, "" );
1025             HTMLDiffer differ = new HTMLDiffer( output );
1026             differ.diff( leftComparator, rightComparator );
1027 
1028             strDiff = resultWriter.toString( );
1029         }
1030         catch( Exception e )
1031         {
1032             AppLogService.error( "Error generating daisy diff for blog " + nId + ":" + blog.getContentLabel( ) + "; versions (" + blog.getVersion( ) + ","
1033                     + blog2.getVersion( ) + ")", e );
1034         }
1035 
1036         List<Blog> listBlogsVersions = BlogHome.getBlogsVersionsList( nId );
1037 
1038         Map<String, Object> model = getModel( );
1039         model.put( MARK_BLOG, blog );
1040         model.put( MARK_BLOG2, blog2 );
1041         model.put( MARK_DIFF, strDiff );
1042         model.put( MARK_BLOG_VERSION_LIST, listBlogsVersions );
1043 
1044         return getPage( PROPERTY_PAGE_TITLE_DIFF_BLOG, TEMPLATE_DIFF_BLOG, model );
1045     }
1046 
1047     /**
1048      * 
1049      * Added docContent to the htmlDoc content list
1050      * 
1051      * @param request
1052      *            The Http request
1053      * @return
1054      */
1055     @Action( ACTION_ADD_FILE_CONTENT )
1056     public String addContent( HttpServletRequest request )
1057     {
1058 
1059         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
1060         String nIdSession = request.getSession( ).getId( );
1061         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
1062 
1063         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
1064         {
1065 
1066             lockBlog( nIdBlog, request.getSession( ).getId( ) );
1067         }
1068         else
1069             if ( _blog.getId( ) != 0 )
1070             {
1071 
1072                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
1073             }
1074 
1075         /* Gestion du mimeType */
1076         String result = request.getParameter( "fileContent" );
1077         String firstDelimiter = "[;]";
1078         String secondDelimiter = "[:]";
1079         String thirdDelimiter = "[,]";
1080         String [ ] firstParts = result.split( firstDelimiter );
1081         String partAfterFirstDelimiter = firstParts [0];
1082         String [ ] secondParts = partAfterFirstDelimiter.split( secondDelimiter );
1083         // Le mimeType
1084         String mimeType = secondParts [1];
1085         // Le fichier en base64
1086         String base64FileString = StringUtils.EMPTY;
1087         // Gestion des fichiers vides
1088         if ( !result.endsWith( "," ) )
1089         {
1090             String thirdParts[] = result.split( thirdDelimiter );
1091             base64FileString = thirdParts [1];
1092         }
1093 
1094         byte [ ] fileByteArray = Base64.getDecoder( ).decode( base64FileString );
1095 
1096         String strFileName = request.getParameter( PARAMETER_FILE_NAME );
1097         String strFileType = request.getParameter( "fileType" );
1098 
1099         if ( StringUtils.isEmpty( mimeType ) || mimeType == null )
1100         {
1101 
1102             InputStream is = new ByteArrayInputStream( fileByteArray );
1103 
1104             // Trouver le type du fichier
1105             try
1106             {
1107                 mimeType = URLConnection.guessContentTypeFromStream( is );
1108             }
1109             catch( IOException ioException )
1110             {
1111                 AppLogService.error( ioException.getStackTrace( ), ioException );
1112             }
1113 
1114         }
1115 
1116         DocContentusiness/DocContent.html#DocContent">DocContent docContent = new DocContent( );
1117         docContent.setBinaryValue( fileByteArray );
1118         docContent.setValueContentType( mimeType );
1119         docContent.setTextValue( strFileName );
1120 
1121         if ( strFileType != null )
1122         {
1123 
1124             ContentTypebusiness/ContentType.html#ContentType">ContentType contType = new ContentType( );
1125             contType.setIdContentType( Integer.parseInt( strFileType ) );
1126             docContent.setContentType( contType );
1127         }
1128         docContent.setPriority( _blog.getDocContent( ).size( ) + 1 );
1129         _blog.addContent( docContent );
1130         DocContentHome.create( docContent );
1131         String [ ] results = {
1132                 strFileName, String.valueOf( docContent.getId( ) )
1133         };
1134 
1135         return JsonUtil.buildJsonResponse( new JsonResponse( results ) );
1136 
1137     }
1138 
1139     /**
1140      * delete docContent in the htmlDoc content list
1141      * 
1142      * @param request
1143      *            The Http request
1144      * @return
1145      */
1146     @Action( ACTION_REMOVE_FILE_CONTENT )
1147     public String removeContent( HttpServletRequest request )
1148     {
1149 
1150         int nIdDoc = Integer.parseInt( request.getParameter( PARAMETER_CONTENT_ID ) );
1151         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
1152         String nIdSession = request.getSession( ).getId( );
1153         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
1154 
1155         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
1156         {
1157 
1158             lockBlog( nIdBlog, request.getSession( ).getId( ) );
1159         }
1160         else
1161             if ( _blog.getId( ) != 0 )
1162             {
1163 
1164                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
1165             }
1166 
1167         DocContent docCont = _blog.getDocContent( ).stream( ).filter( dc -> dc.getId( ) == nIdDoc ).collect( Collectors.toList( ) ).get( 0 );
1168         List<DocContent> listDocs = _blog.getDocContent( ).stream( ).map( dc -> {
1169             if ( ( dc.getPriority( ) > docCont.getPriority( ) ) && ( docCont.getId( ) != dc.getId( ) ) )
1170             {
1171 
1172                 dc.setPriority( dc.getPriority( ) - 1 );
1173             }
1174             return dc;
1175         } ).collect( Collectors.toList( ) );
1176 
1177         _blog.setDocContent( listDocs );
1178         _blog.deleteDocContent( nIdDoc );
1179         DocContentHome.removeInBlogById( nIdDoc );
1180 
1181         return JsonUtil.buildJsonResponse( new JsonResponse( nIdDoc ) );
1182 
1183     }
1184 
1185     /**
1186      * Return Json if the the content is updated
1187      *
1188      * @param request
1189      * @return Json The Json success or echec
1190      */
1191     @Action( ACTION_UPDATE_PRIORITY_FILE_CONTENT )
1192     public String doUpdatePriorityContent( HttpServletRequest request )
1193     {
1194         DocContent docCont = null;
1195         DocContent docContMove = null;
1196         int nPriorityToSet = 0;
1197         int nPriority = 0;
1198 
1199         String strIdDocContent = request.getParameter( PARAMETER_CONTENT_ID );
1200         String strAction = request.getParameter( PARAMETER_CONTENT_ACTION );
1201         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
1202         String nIdSession = request.getSession( ).getId( );
1203         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
1204         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
1205         {
1206 
1207             lockBlog( nIdBlog, request.getSession( ).getId( ) );
1208         }
1209         else
1210             if ( _blog.getId( ) != 0 )
1211             {
1212 
1213                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
1214             }
1215 
1216         for ( DocContent dc : _blog.getDocContent( ) )
1217         {
1218             if ( dc.getId( ) == Integer.parseInt( strIdDocContent ) )
1219             {
1220                 docCont = dc;
1221                 nPriorityToSet = dc.getPriority( );
1222                 nPriority = dc.getPriority( );
1223             }
1224         }
1225         for ( DocContent dc : _blog.getDocContent( ) )
1226         {
1227             if ( strAction.equals( "moveUp" ) && dc.getPriority( ) == nPriority - 1 )
1228             {
1229                 docContMove = dc;
1230                 docContMove.setPriority( dc.getPriority( ) + 1 );
1231                 nPriorityToSet = nPriority - 1;
1232 
1233             }
1234             else
1235                 if ( strAction.equals( "moveDown" ) && dc.getPriority( ) == nPriority + 1 )
1236                 {
1237                     docContMove = dc;
1238                     docContMove.setPriority( docContMove.getPriority( ) - 1 );
1239                     nPriorityToSet = nPriority + 1;
1240 
1241                 }
1242         }
1243         docCont.setPriority( nPriorityToSet );
1244 
1245         if ( docContMove != null )
1246         {
1247 
1248             return JsonUtil.buildJsonResponse( new JsonResponse( String.valueOf( docContMove.getId( ) ) ) );
1249 
1250         }
1251         return JsonUtil.buildJsonResponse( new JsonResponse( String.valueOf( docCont.getId( ) ) ) );
1252 
1253     }
1254 
1255     /**
1256      * 
1257      * @param request
1258      * @return
1259      */
1260     @Action( ACTION_UPDATE_CONTENT_TYPE )
1261     public String updateContentType( HttpServletRequest request )
1262     {
1263 
1264         String strContentTypeId = request.getParameter( PARAMETER_TYPE_ID );
1265         String strContentId = request.getParameter( PARAMETER_CONTENT_ID );
1266         int nIdBlog = Integer.parseInt( request.getParameter( PARAMETER_ID_BLOG ) );
1267         String nIdSession = request.getSession( ).getId( );
1268         _blog = _blogServiceSession.getBlogFromSession( request.getSession( ), nIdBlog );
1269 
1270         if ( _mapLockBlog.get( nIdBlog ) != null && _mapLockBlog.get( nIdBlog ).getSessionId( ).equals( nIdSession ) )
1271         {
1272 
1273             lockBlog( nIdBlog, request.getSession( ).getId( ) );
1274         }
1275         else
1276             if ( _blog.getId( ) != 0 )
1277             {
1278 
1279                 return JsonUtil.buildJsonResponse( new JsonResponse( RESPONSE_BLOG_LOCKED ) );
1280             }
1281 
1282         for ( DocContent content : _blog.getDocContent( ) )
1283         {
1284 
1285             if ( strContentId != null && content.getId( ) == Integer.parseInt( strContentId ) )
1286             {
1287 
1288                 ContentTypebusiness/ContentType.html#ContentType">ContentType contType = new ContentType( );
1289                 contType.setIdContentType( Integer.parseInt( strContentTypeId ) );
1290 
1291                 content.setContentType( contType );
1292                 break;
1293             }
1294         }
1295 
1296         return JsonUtil.buildJsonResponse( new JsonResponse( "SUCCESS" ) );
1297     }
1298 
1299     /**
1300      * Set content of the blog
1301      * 
1302      * @param mRequest
1303      * @param locale
1304      * @return the content of the blog
1305      */
1306 
1307     public DocContent setContent( MultipartHttpServletRequest mRequest, Locale locale )
1308     {
1309 
1310         FileItem fileParameterBinaryValue = mRequest.getFile( "attachment" );
1311 
1312         if ( fileParameterBinaryValue != null ) // If the field is a file
1313         {
1314 
1315             String strContentType = fileParameterBinaryValue.getContentType( );
1316             byte [ ] bytes = fileParameterBinaryValue.get( );
1317             String strFileName = fileParameterBinaryValue.getName( );
1318 
1319             if ( !ArrayUtils.isEmpty( bytes ) )
1320             {
1321 
1322                 DocContentusiness/DocContent.html#DocContent">DocContent docContent = new DocContent( );
1323                 docContent.setBinaryValue( bytes );
1324                 docContent.setValueContentType( strContentType );
1325                 docContent.setTextValue( strFileName );
1326 
1327                 return docContent;
1328             }
1329 
1330         }
1331 
1332         return null;
1333     }
1334 
1335     /**
1336      * 
1337      * @return
1338      */
1339     private ReferenceList getBlogFilterList( )
1340     {
1341         ReferenceList list = new ReferenceList( );
1342         list.addItem( MARK_BLOG_FILTER_NAME, "Nom" );
1343         list.addItem( MARK_BLOG_FILTER_DATE, "Date" );
1344         list.addItem( MARK_BLOG_FILTER_USER, "Utilisateur" );
1345 
1346         return list;
1347     }
1348 
1349     /**
1350      * 
1351      * @return BlogList
1352      */
1353     private ReferenceList getTageList( )
1354     {
1355 
1356         ReferenceList BlogList = TagHome.getTagsReferenceList( );
1357 
1358         for ( Tag tg : _blog.getTag( ) )
1359         {
1360             BlogList.removeIf( item -> item.getCode( ).equals( String.valueOf( tg.getIdTag( ) ) ) );
1361 
1362         }
1363         return BlogList;
1364     }
1365 
1366     /**
1367      * Check if the blog is locked
1368      * 
1369      * @param nIdBlog
1370      *            The Id blog
1371      * @param strIdSession
1372      *            The Id session
1373      * @return return true if the blog is locked else false
1374      */
1375     private boolean checkLockBlog( int nIdBlog, String strIdSession )
1376     {
1377 
1378         if ( _mapLockBlog.get( nIdBlog ) != null && !_mapLockBlog.get( nIdBlog ).getSessionId( ).equals( strIdSession ) )
1379         {
1380 
1381             return true;
1382 
1383         }
1384         return false;
1385     }
1386 
1387     /**
1388      * Lock blog
1389      * 
1390      * @param nIdBlog
1391      *            The Id blog
1392      * @param strIdSession
1393      *            The Id session
1394      */
1395     private void lockBlog( int nIdBlog, String strIdSession )
1396     {
1397 
1398         _mapLockBlog.remove( nIdBlog );
1399         _mapLockBlog.put( nIdBlog, new BlogLock( strIdSession, System.currentTimeMillis( ) ) );
1400 
1401     }
1402 
1403     /**
1404      * Unlock Blog
1405      * 
1406      * @param nIdBlog
1407      *            The id Blog
1408      */
1409     private void unLockBlog( int nIdBlog )
1410     {
1411 
1412         _mapLockBlog.remove( nIdBlog );
1413 
1414     }
1415 
1416     /**
1417      * Unlock Blogs By Session Id
1418      * 
1419      * @param strIdSession
1420      *            The Id session
1421      */
1422     public static void unLockedBlogByIdSession( String strIdSession )
1423     {
1424 
1425         _mapLockBlog.values( ).removeIf( id -> id.getSessionId( ).equals( strIdSession ) );
1426     }
1427 
1428     /**
1429      * Unlock the blog if the lock clearance time has passed
1430      * 
1431      * @param nTime
1432      *            the clearance time
1433      */
1434     public static void unLockedBlogByTime( long nTime )
1435     {
1436 
1437         long currentTime = System.currentTimeMillis( );
1438         _mapLockBlog.values( ).removeIf( id -> id.getTime( ) + nTime < currentTime );
1439     }
1440 
1441     /**
1442      * Gets the current
1443      *
1444      * @return the current date in sql format
1445      */
1446     public java.sql.Timestamp getSqlDate( )
1447     {
1448         java.util.Date utilDate = new java.util.Date( );
1449         java.sql.Timestamp sqlDate = new java.sql.Timestamp( utilDate.getTime( ) );
1450 
1451         return ( sqlDate );
1452     }
1453 
1454 }