1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
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
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
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
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
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
150
151
152
153
154
155
156
157
158
159
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
195
196 private void init( )
197 {
198
199
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
214
215
216
217
218
219
220
221
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
230
231
232
233
234
235
236
237
238
239
240
241
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
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
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
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
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
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
361 {
362
363 return PortalService.getDefaultPage( request, nMode );
364 }
365 }
366
367
368
369
370
371
372
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
391
392
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
415
416
417
418
419
420
421
422
423
424
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
436
437
438
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
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
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
492
493
494
495
496
497
498
499
500
501
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
514 for ( Document relatedDocument : listRelatedDocument )
515 {
516
517 for ( Portlet portlet : PublishingService.getInstance( ).getPortletsByDocumentId( Integer.toString( relatedDocument.getId( ) ) ) )
518 {
519
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
547
548
549
550
551
552
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
564 LuteceUser luteceUser = SecurityService.getInstance( ).getRemoteUser( request );
565
566 if ( luteceUser != null )
567 {
568
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
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 }