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.document.modules.solr.business;
35  
36  import fr.paris.lutece.plugins.document.business.Document;
37  import fr.paris.lutece.plugins.document.business.DocumentHome;
38  import fr.paris.lutece.plugins.document.business.DocumentType;
39  import fr.paris.lutece.plugins.document.business.DocumentTypeHome;
40  import fr.paris.lutece.plugins.document.business.portlet.DocumentListPortlet;
41  import fr.paris.lutece.plugins.document.business.portlet.DocumentListPortletHome;
42  import fr.paris.lutece.plugins.document.business.publication.DocumentPublication;
43  import fr.paris.lutece.plugins.document.modules.solr.indexer.SolrDocIndexer;
44  import fr.paris.lutece.plugins.document.service.publishing.PublishingService;
45  import fr.paris.lutece.plugins.document.utils.DocumentIndexerUtils;
46  import fr.paris.lutece.plugins.search.solr.business.SolrSearchEngine;
47  import fr.paris.lutece.plugins.search.solr.util.SolrConstants;
48  import fr.paris.lutece.portal.business.page.Page;
49  import fr.paris.lutece.portal.business.page.PageHome;
50  import fr.paris.lutece.portal.business.portlet.AliasPortlet;
51  import fr.paris.lutece.portal.business.portlet.AliasPortletHome;
52  import fr.paris.lutece.portal.business.portlet.Portlet;
53  import fr.paris.lutece.portal.business.portlet.PortletHome;
54  import fr.paris.lutece.portal.business.style.ModeHome;
55  import fr.paris.lutece.portal.service.content.ContentService;
56  import fr.paris.lutece.portal.service.content.PageData;
57  import fr.paris.lutece.portal.service.html.XmlTransformerService;
58  import fr.paris.lutece.portal.service.message.SiteMessageException;
59  import fr.paris.lutece.portal.service.portal.PortalService;
60  import fr.paris.lutece.portal.service.security.LuteceUser;
61  import fr.paris.lutece.portal.service.security.SecurityService;
62  import fr.paris.lutece.portal.service.security.UserNotSignedException;
63  import fr.paris.lutece.portal.service.spring.SpringContextService;
64  import fr.paris.lutece.portal.service.template.AppTemplateService;
65  import fr.paris.lutece.portal.service.util.AppPathService;
66  import fr.paris.lutece.portal.service.util.AppPropertiesService;
67  import fr.paris.lutece.portal.web.constants.Parameters;
68  import fr.paris.lutece.util.ReferenceList;
69  import fr.paris.lutece.util.UniqueIDGenerator;
70  import fr.paris.lutece.util.date.DateUtil;
71  import fr.paris.lutece.util.html.HtmlTemplate;
72  
73  import java.io.FileInputStream;
74  
75  import java.util.ArrayList;
76  import java.util.Enumeration;
77  import java.util.HashMap;
78  import java.util.Hashtable;
79  import java.util.List;
80  import java.util.Map;
81  import java.util.Properties;
82  
83  import javax.servlet.http.HttpServletRequest;
84  
85  import javax.xml.transform.Source;
86  import javax.xml.transform.stream.StreamSource;
87  
88  /**
89   *
90   */
91  public class SolrDocumentContentService extends ContentService
92  {
93      ///////////////////////////////////////////////////////////////////////////////////////////////////
94      // Constants
95      private static final String CONTENT_SERVICE_NAME = "SOLR Document Content Service";
96      private static final String SLASH = "/";
97      private static final String ACCEPT_SITE_COMMENTS = "1";
98      private static final int MODE_ADMIN = 1;
99      private static final String CONSTANT_DEFAULT_PORTLET_DOCUMENT_LIST_XSL = "WEB-INF/xsl/normal/portlet_document_list.xsl";
100 
101     // Parameters
102     private static final String PARAMETER_SOLR_DOCUMENT_ID = "solr_document_id";
103     private static final String PARAMETER_COMMENT_DOCUMENT = "comment";
104     private static final String PARAMETER_MANDATORY_FIELD = "mandatory";
105     private static final String PARAMETER_XSS_ERROR = "xsserror";
106     private static final String PARAMETER_CHECK_EMAIL = "checkemail";
107     private static final String PARAMETER_SITE_PATH = "site-path";
108     private static final String PARAMETER_PUBLICATION_DATE = "publication-date";
109     private static final String PARAMETER_TERMS = "terms";
110 
111     // Markers
112     private static final String MARK_PUBLICATION = "publication";
113     private static final String MARK_DOCUMENT = "document";
114     private static final String MARK_ACCEPT_COMMENT = "accept_comment";
115     private static final String MARK_PORTLET = "portlet";
116     private static final String MARK_CATEGORY = "categories";
117     private static final String MARK_DOCUMENT_ID = "document_id";
118     private static final String MARK_PORTLET_ID = "portlet_id";
119     private static final String MARK_PORTLET_ID_LIST = "portlet_id_list";
120     private static final String MARK_DOCUMENT_COMMENTS = "document_comments";
121     private static final String MARK_DOCUMENT_COMMENT_FORM = "document_comment_form";
122     private static final String MARK_DOCUMENT_COMMENTS_LIST = "document_comments_list";
123     private static final String MARK_DOCUMENT_CATEGORIES_LIST = "document_categories_list";
124     private static final String MARK_XSS_ERROR_MESSAGE = "xss_error_message";
125     private static final String MARK_CHECK_EMAIL_MESSAGE = "check_email_message";
126     private static final String MARK_MANDATORY_FIELD_MESSAGE = "mandatory_field_message";
127     private static final String MARK_MAILINGLIST = "mailinglist";
128     private static final String MARK_URL_LOGIN = "url_login";
129     private static final String MARK_LUTECE_USER_NAME = "lutece_user_name";
130     private static final String MARK_LUTECE_USER_MAIL = "lutece_user_email";
131     private static final String MARKER_TARGET = "target";
132 
133     // Templates
134     private static final String TEMPLATE_DOCUMENT_PAGE_DEFAULT = "/skin/plugins/document/document_content_service.html";
135     private static final String TEMPLATE_DOCUMENT_COMMENTS = "/skin/plugins/document/modules/comment/document_comments.html";
136     private static final String TEMPLATE_DOCUMENT_CATEGORIES = "/skin/plugins/document/document_categories.html";
137     private static final String TEMPLATE_ADD_DOCUMENT_COMMENT = "/skin/plugins/document/modules/comment/add_document_comment.html";
138 
139     // Properties
140     private static final String PROPERTY_DEFAULT_PORTLET_DOCUMENT_LIST_XSL = "document.contentService.defaultPortletDocumentListXSL";
141     private static final String PROPERTY_CACHE_ENABLED = "document.cache.enabled";
142     private static final String XSLSOURCE_STYLE_PREFIX_ID = UniqueIDGenerator.getNewId( );
143     private static final String TARGET_TOP = "target=_top";
144 
145     private XmlTransformerService _xmlTransformerService;
146     private boolean _bInit;
147 
148     /**
149      * Returns the document page for a given document and a given portlet. The page is built from XML data or retrieved from the cache if it's enable and the
150      * document in it.
151      *
152      * @param request
153      *            The HTTP request.
154      * @param nMode
155      *            The current mode.
156      * @return The HTML code of the page as a String.
157      * @throws UserNotSignedException
158      * @throws SiteMessageException
159      *             occurs when a site message need to be displayed
160      */
161     public String getPage( HttpServletRequest request, int nMode ) throws UserNotSignedException, SiteMessageException
162     {
163         if ( !_bInit )
164         {
165             init( );
166         }
167 
168         String strDocumentId = request.getParameter( PARAMETER_SOLR_DOCUMENT_ID );
169         String strPortletId = request.getParameter( Parameters.PORTLET_ID );
170         String strTerms = request.getParameter( PARAMETER_TERMS );
171         String strKey = getCacheKey( strDocumentId, strPortletId, strTerms, nMode );
172         String strPage = (String) getFromCache( strKey );
173 
174         if ( strPage == null )
175         {
176             strPage = buildPage( request, strDocumentId, strPortletId, strTerms, nMode );
177 
178             if ( strDocumentId != null )
179             {
180                 int nDocumentId = Integer.parseInt( strDocumentId );
181                 Document document = DocumentHome.findByPrimaryKeyWithoutBinaries( nDocumentId );
182 
183                 if ( document != null )
184                 {
185                     putInCache( strKey, strPage );
186                 }
187             }
188         }
189 
190         return strPage;
191     }
192 
193     /**
194      * Initializes the service
195      */
196     private void init( )
197     {
198         // Initialize the cache according property value.
199         // If the property isn't found the default is true
200         String strCache = AppPropertiesService.getProperty( PROPERTY_CACHE_ENABLED, "true" );
201 
202         if ( strCache.equalsIgnoreCase( "true" ) )
203         {
204             initCache( getName( ) );
205         }
206 
207         _xmlTransformerService = new XmlTransformerService( );
208 
209         _bInit = true;
210     }
211 
212     /**
213      * Build the cache key
214      * 
215      * @param strDocumentId
216      *            The document ID
217      * @param strPortletId
218      *            The portlet ID
219      * @param nMode
220      *            The current mode
221      * @return The key
222      */
223     private String getCacheKey( String strDocumentId, String strPortletId, String terms, int nMode )
224     {
225         return "D" + strDocumentId + "P" + strPortletId + "T" + terms + "M" + nMode;
226     }
227 
228     /**
229      * Build the document page
230      * 
231      * @param request
232      *            The HTTP Request
233      * @param strDocumentId
234      *            The document ID
235      * @param strPortletId
236      *            The portlet ID
237      * @param nMode
238      *            The current mode
239      * @return
240      * @throws fr.paris.lutece.portal.service.security.UserNotSignedException
241      * @throws fr.paris.lutece.portal.service.message.SiteMessageException
242      */
243     private String buildPage( HttpServletRequest request, String strDocumentId, String strPortletId, String terms, int nMode )
244             throws UserNotSignedException, SiteMessageException
245     {
246         int nPortletId;
247         int nDocumentId;
248         boolean bPortletExist = false;
249         HashMap<String, String> mapXslParams = new HashMap<String, String>( );
250 
251         try
252         {
253             nPortletId = Integer.parseInt( strPortletId );
254             nDocumentId = Integer.parseInt( strDocumentId );
255         }
256         catch( NumberFormatException nfe )
257         {
258             return PortalService.getDefaultPage( request, nMode );
259         }
260 
261         Document document = DocumentHome.findByPrimaryKeyWithoutBinaries( nDocumentId );
262 
263         if ( ( document == null ) || ( !document.isValid( ) ) )
264         {
265             return PortalService.getDefaultPage( request, nMode );
266         }
267 
268         DocumentType type = DocumentTypeHome.findByPrimaryKey( document.getCodeDocumentType( ) );
269         DocumentPublication documentPublication = PublishingService.getInstance( ).getDocumentPublication( nPortletId, nDocumentId );
270 
271         Map<String, Object> model = new HashMap<String, Object>( );
272 
273         if ( documentPublication != null )
274         {
275             // Check if portlet is an alias portlet
276             boolean bIsAlias = DocumentListPortletHome.checkIsAliasPortlet( documentPublication.getPortletId( ) );
277 
278             if ( bIsAlias && ( documentPublication.getPortletId( ) != nPortletId ) )
279             {
280                 AliasPortlet alias = (AliasPortlet) AliasPortletHome.findByPrimaryKey( nPortletId );
281                 nPortletId = alias.getAliasId( );
282                 strPortletId = Integer.toString( nPortletId );
283             }
284 
285             if ( ( documentPublication.getPortletId( ) == nPortletId ) && ( documentPublication.getStatus( ) == DocumentPublication.STATUS_PUBLISHED ) )
286             {
287                 bPortletExist = true;
288             }
289 
290             // The publication informations are available in Xsl (only publication date) and in template (full DocumentPublication object)
291             mapXslParams.put( PARAMETER_PUBLICATION_DATE, DateUtil.getDateString( documentPublication.getDatePublishing( ), request.getLocale( ) ) );
292             model.put( MARK_PUBLICATION, documentPublication );
293         }
294 
295         if ( bPortletExist )
296         {
297             // Fill a PageData structure for those elements
298             PageData data = new PageData( );
299             data.setName( document.getTitle( ) );
300             data.setPagePath( PortalService.getXPagePathContent( document.getTitle( ), 0, request ) );
301 
302             Portlet portlet = PortletHome.findByPrimaryKey( nPortletId );
303             Page page = PageHome.getPage( portlet.getPageId( ) );
304             String strRole = page.getRole( );
305 
306             if ( !strRole.equals( Page.ROLE_NONE ) && SecurityService.isAuthenticationEnable( ) )
307             {
308                 LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
309 
310                 if ( ( user == null ) && ( !SecurityService.getInstance( ).isExternalAuthentication( ) ) )
311                 {
312                     // The user is not registered and identify itself with the Portal authentication
313                     String strAccessControledTemplate = SecurityService.getInstance( ).getAccessControledTemplate( );
314                     HashMap<String, Object> modelAccessControledTemplate = new HashMap<String, Object>( );
315                     String strLoginUrl = SecurityService.getInstance( ).getLoginPageUrl( );
316                     modelAccessControledTemplate.put( MARK_URL_LOGIN, strLoginUrl );
317 
318                     HtmlTemplate tAccessControled = AppTemplateService.getTemplate( strAccessControledTemplate, request.getLocale( ),
319                             modelAccessControledTemplate );
320                     data.setContent( tAccessControled.getHtml( ) );
321 
322                     return PortalService.buildPageContent( data, nMode, request );
323                 }
324 
325                 if ( !SecurityService.getInstance( ).isUserInRole( request, strRole ) )
326                 {
327                     // The user doesn't have the correct role
328                     String strAccessDeniedTemplate = SecurityService.getInstance( ).getAccessDeniedTemplate( );
329                     HtmlTemplate tAccessDenied = AppTemplateService.getTemplate( strAccessDeniedTemplate, request.getLocale( ) );
330                     data.setContent( tAccessDenied.getHtml( ) );
331 
332                     return PortalService.buildPageContent( data, nMode, request );
333                 }
334             }
335 
336             SolrDocIndexer solrDocIndexer = SpringContextService.getBean( SolrDocIndexer.BEAN_NAME );
337             String xmlContent = SolrSearchEngine.getInstance( )
338                     .getDocumentHighLighting( solrDocIndexer.getResourceUid( strDocumentId, DocumentIndexerUtils.CONSTANT_TYPE_RESOURCE ), terms );
339 
340             if ( xmlContent == null )
341             {
342                 xmlContent = document.getXmlValidatedContent( );
343             }
344 
345             String strDocument = _xmlTransformerService.transformBySourceWithXslCache( xmlContent, type.getContentServiceXslSource( ),
346                     XSLSOURCE_STYLE_PREFIX_ID + type.getCode( ), null, null );
347 
348             model.put( MARK_DOCUMENT, strDocument );
349             model.put( MARK_PORTLET, getPortlet( request, strPortletId, nMode ) );
350             model.put( MARK_CATEGORY, getRelatedDocumentsPortlet( request, document, nPortletId, nMode ) );
351             model.put( MARK_DOCUMENT_ID, strDocumentId );
352             model.put( MARK_PORTLET_ID, strPortletId );
353 
354             HtmlTemplate template = AppTemplateService.getTemplate( getTemplatePage( document ), request.getLocale( ), model );
355 
356             data.setContent( template.getHtml( ) );
357 
358             return PortalService.buildPageContent( data, nMode, request );
359         }
360         else // portlet does not exists
361         {
362             // TODO : view access denied page
363             return PortalService.getDefaultPage( request, nMode );
364         }
365     }
366 
367     /**
368      * Analyzes request parameters to see if the request should be handled by the current Content Service
369      *
370      * @param request
371      *            The HTTP request
372      * @return true if this ContentService should handle this request
373      */
374     public boolean isInvoked( HttpServletRequest request )
375     {
376         String strDocumentId = request.getParameter( PARAMETER_SOLR_DOCUMENT_ID );
377         String strIdPortlet = request.getParameter( Parameters.PORTLET_ID );
378         String strTerms = request.getParameter( PARAMETER_TERMS );
379 
380         if ( ( strDocumentId != null ) && ( strDocumentId.length( ) > 0 ) && ( strIdPortlet != null ) && ( strIdPortlet.length( ) > 0 ) && ( strTerms != null )
381                 && ( !"".equals( strTerms ) ) )
382         {
383             return true;
384         }
385 
386         return false;
387     }
388 
389     /**
390      * Returns the Content Service name
391      *
392      * @return The name as a String
393      */
394     public String getName( )
395     {
396         return CONTENT_SERVICE_NAME;
397     }
398 
399     private String getTemplatePage( Document document )
400     {
401         if ( document.getPageTemplateDocumentId( ) != 0 )
402         {
403             String strPageTemplateDocument = DocumentHome.getPageTemplateDocumentPath( document.getPageTemplateDocumentId( ) );
404 
405             return strPageTemplateDocument;
406         }
407         else
408         {
409             return TEMPLATE_DOCUMENT_PAGE_DEFAULT;
410         }
411     }
412 
413     ///////////////////////////////////////////////////////////////////////////////////////////////////////////
414     // Comments implementation
415     /**
416      * Gets the documents list portlet containing the document
417      *
418      * @param strPortletId
419      *            The ID of the documents list portlet where the document has been published.
420      * @param nMode
421      *            The current mode.
422      * @param request
423      *            The Http request
424      * @return The HTML code of the documents list portlet as a String
425      */
426     private synchronized String getPortlet( HttpServletRequest request, String strPortletId, int nMode ) throws SiteMessageException
427     {
428         try
429         {
430             int nPortletId = Integer.parseInt( strPortletId );
431 
432             Portlet portlet = (DocumentListPortlet) PortletHome.findByPrimaryKey( nPortletId );
433             String strXml = portlet.getXmlDocument( request );
434 
435             // Selection of the XSL stylesheet
436             // byte[] baXslSource = portlet.getXslSource( nMode );
437 
438             // FIXME Temporary solution (see LUTECE-824)
439             String strFilePath = AppPropertiesService.getProperty( PROPERTY_DEFAULT_PORTLET_DOCUMENT_LIST_XSL, CONSTANT_DEFAULT_PORTLET_DOCUMENT_LIST_XSL );
440 
441             if ( strFilePath == null )
442             {
443                 return SolrConstants.CONSTANT_EMPTY_STRING;
444             }
445 
446             if ( !strFilePath.startsWith( SLASH ) )
447             {
448                 strFilePath = SLASH + strFilePath;
449             }
450 
451             String strFileName = strFilePath.substring( strFilePath.lastIndexOf( SLASH ) + 1 );
452             strFilePath = strFilePath.substring( 0, strFilePath.lastIndexOf( SLASH ) + 1 );
453 
454             FileInputStream fis = AppPathService.getResourceAsStream( strFilePath, strFileName );
455             Source xslSource = new StreamSource( fis );
456 
457             // Get request paramaters and store them in a map
458             Enumeration enumParam = request.getParameterNames( );
459             HashMap<String, String> htParamRequest = new HashMap<>( );
460             String paramName = "";
461 
462             while ( enumParam.hasMoreElements( ) )
463             {
464                 paramName = (String) enumParam.nextElement( );
465                 htParamRequest.put( paramName, request.getParameter( paramName ) );
466             }
467 
468             Properties outputProperties = ModeHome.getOuputXslProperties( nMode );
469 
470             // Add a path param for choose url to use in admin or normal mode
471             if ( nMode != MODE_ADMIN )
472             {
473                 htParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getPortalUrl( ) );
474             }
475             else
476             {
477                 htParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getAdminPortalUrl( ) );
478                 htParamRequest.put( MARKER_TARGET, TARGET_TOP );
479             }
480 
481             return _xmlTransformerService.transformBySourceWithXslCache( strXml, xslSource, XSLSOURCE_STYLE_PREFIX_ID + strPortletId + "-" + nMode,
482                     htParamRequest, outputProperties );
483         }
484         catch( NumberFormatException e )
485         {
486             return null;
487         }
488     }
489 
490     /**
491      * Gets the category list portlet linked with the document
492      *
493      * @param request
494      *            The Http request
495      * @param document
496      *            The document
497      * @param nPortletId
498      *            The ID of the documents list portlet where the document has been published.
499      * @param nMode
500      *            The current mode.
501      * @return The HTML code of the categories list portlet as a String
502      */
503     private static synchronized String getRelatedDocumentsPortlet( HttpServletRequest request, Document document, int nPortletId, int nMode )
504     {
505         if ( ( nMode != MODE_ADMIN ) && ( document.getCategories( ) != null ) && ( document.getCategories( ).size( ) > 0 ) )
506         {
507             Map<String, Object> model = new HashMap<String, Object>( );
508             List<Document> listRelatedDocument = DocumentHome.findByRelatedCategories( document, request.getLocale( ) );
509 
510             List<Document> listDocument = new ArrayList<Document>( );
511             ReferenceList listDocumentPortlet = new ReferenceList( );
512 
513             // Create list of related documents from the specified categories of input document
514             for ( Document relatedDocument : listRelatedDocument )
515             {
516                 // Get list of portlets for each document
517                 for ( Portlet portlet : PublishingService.getInstance( ).getPortletsByDocumentId( Integer.toString( relatedDocument.getId( ) ) ) )
518                 {
519                     // Check if document and portlet are published and document is not the input document
520                     if ( ( PublishingService.getInstance( ).isPublished( relatedDocument.getId( ), portlet.getId( ) ) )
521                             && ( portlet.getStatus( ) == Portlet.STATUS_PUBLISHED ) && ( relatedDocument.isValid( ) )
522                             && ( relatedDocument.getId( ) != document.getId( ) ) )
523                     {
524                         listDocumentPortlet.addItem( Integer.toString( relatedDocument.getId( ) ), Integer.toString( portlet.getId( ) ) );
525                         listDocument.add( relatedDocument );
526 
527                         break;
528                     }
529                 }
530             }
531 
532             model.put( MARK_DOCUMENT_CATEGORIES_LIST, listDocument );
533             model.put( MARK_PORTLET_ID_LIST, listDocumentPortlet );
534 
535             HtmlTemplate templateComments = AppTemplateService.getTemplate( TEMPLATE_DOCUMENT_CATEGORIES, request.getLocale( ), model );
536 
537             return templateComments.getHtml( );
538         }
539         else
540         {
541             return SolrConstants.CONSTANT_EMPTY_STRING;
542         }
543     }
544 
545     /**
546      * Return the comment creation form
547      * 
548      * @param strDocumentId
549      *            the identifier of the document
550      * @param strPortletId
551      *            the identifier of the portlet
552      * @return the HTML code of the form
553      */
554     private static String getAddCommentForm( HttpServletRequest request, String strDocumentId, String strPortletId, String strMailingListId, String strXssError,
555             String strCheckEmail, String strMandatoryField )
556     {
557         Map<String, Object> model = new HashMap<String, Object>( );
558 
559         try
560         {
561             if ( SecurityService.isAuthenticationEnable( ) )
562             {
563                 // Authentication is enabled
564                 LuteceUser luteceUser = SecurityService.getInstance( ).getRemoteUser( request );
565 
566                 if ( luteceUser != null )
567                 {
568                     // User is authenticated => we display its id and its email
569                     model.put( MARK_LUTECE_USER_NAME, luteceUser.getName( ) );
570                     model.put( MARK_LUTECE_USER_MAIL, luteceUser.getUserInfo( LuteceUser.BUSINESS_INFO_ONLINE_EMAIL ) );
571                 }
572             }
573         }
574         catch( UserNotSignedException e )
575         {
576             /*
577              * Authentication is not enabled or User is not authenticated => we do not display id and email
578              */
579         }
580 
581         model.put( MARK_DOCUMENT_ID, strDocumentId );
582         model.put( MARK_PORTLET_ID, strPortletId );
583         model.put( MARK_MAILINGLIST, strMailingListId );
584         model.put( MARK_XSS_ERROR_MESSAGE, strXssError );
585         model.put( MARK_CHECK_EMAIL_MESSAGE, strCheckEmail );
586         model.put( MARK_MANDATORY_FIELD_MESSAGE, strMandatoryField );
587 
588         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADD_DOCUMENT_COMMENT, request.getLocale( ), model );
589 
590         return template.getHtml( );
591     }
592 }