PageService.java
- /*
- * Copyright (c) 2002-2022, City of Paris
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice
- * and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice
- * and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * License 1.0
- */
- package fr.paris.lutece.portal.service.page;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Optional;
- import java.util.Properties;
- import javax.inject.Inject;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.lang3.BooleanUtils;
- import fr.paris.lutece.portal.business.page.Page;
- import fr.paris.lutece.portal.business.page.PageHome;
- import fr.paris.lutece.portal.business.page.PageRoleRemovalListener;
- import fr.paris.lutece.portal.business.portlet.Portlet;
- import fr.paris.lutece.portal.business.portlet.PortletRoleRemovalListener;
- import fr.paris.lutece.portal.business.portlet.PortletType;
- import fr.paris.lutece.portal.business.style.ModeHome;
- import fr.paris.lutece.portal.business.user.AdminUser;
- import fr.paris.lutece.portal.service.admin.AdminUserService;
- import fr.paris.lutece.portal.service.cache.ICacheKeyService;
- import fr.paris.lutece.portal.service.content.PageData;
- import fr.paris.lutece.portal.service.html.XmlTransformerService;
- import fr.paris.lutece.portal.service.i18n.I18nService;
- import fr.paris.lutece.portal.service.image.ImageResource;
- import fr.paris.lutece.portal.service.image.ImageResourceManager;
- import fr.paris.lutece.portal.service.image.ImageResourceProvider;
- import fr.paris.lutece.portal.service.includes.PageInclude;
- import fr.paris.lutece.portal.service.includes.PageIncludeService;
- import fr.paris.lutece.portal.service.message.SiteMessageException;
- import fr.paris.lutece.portal.service.portal.PortalService;
- import fr.paris.lutece.portal.service.portal.ThemesService;
- import fr.paris.lutece.portal.service.portlet.PortletEvent;
- import fr.paris.lutece.portal.service.portlet.PortletEventListener;
- import fr.paris.lutece.portal.service.portlet.PortletResourceIdService;
- import fr.paris.lutece.portal.service.rbac.RBACService;
- import fr.paris.lutece.portal.service.security.LuteceUser;
- import fr.paris.lutece.portal.service.security.SecurityService;
- import fr.paris.lutece.portal.service.template.AppTemplateService;
- import fr.paris.lutece.portal.service.util.AppException;
- import fr.paris.lutece.portal.service.util.AppLogService;
- import fr.paris.lutece.portal.service.util.AppPathService;
- import fr.paris.lutece.portal.service.util.AppPropertiesService;
- import fr.paris.lutece.portal.service.util.RemovalListenerService;
- import fr.paris.lutece.portal.web.LocalVariables;
- import fr.paris.lutece.portal.web.constants.Parameters;
- import fr.paris.lutece.portal.web.l10n.LocaleService;
- import fr.paris.lutece.util.html.HtmlTemplate;
- import fr.paris.lutece.util.url.UrlItem;
- /**
- * This class delivers pages to web componants. It handles XML tranformation to HTML and provides a cache feature in order to reduce the number of
- * tranformations.
- */
- public class PageService implements IPageService, ImageResourceProvider, PageEventListener, PortletEventListener
- {
- // //////////////////////////////////////////////////////////////////////////
- // Variables
- /**
- * Key for redirections
- */
- public static final String REDIRECTION_KEY = "redirect:";
- // Templates
- /** Access denied template */
- public static final String TEMPLATE_PAGE_ACCESS_DENIED = "/skin/site/page_access_denied.html";
- /** Access Controlled template */
- public static final String TEMPLATE_PAGE_ACCESS_CONTROLED = "/skin/site/page_access_controled.html";
- private static final String TEMPLATE_ADMIN_BUTTONS = "/admin/admin_buttons.html";
- private static final String TEMPLATE_COLUMN_OUTLINE = "/admin/column_outline.html";
- // Markers
- private static final String MARK_PORTLET = "portlet";
- private static final String MARK_STATUS_PUBLISHED = "portlet_status_published";
- private static final String MARK_STATUS_UNPUBLISHED = "portlet_status_unpublished";
- private static final String MARK_CUSTOM_ACTIONS = "custom_action_list";
- private static final String MARK_URL_LOGIN = "url_login";
- private static final String MARKER_TARGET = "target";
- private static final String MARKER_IS_USER_AUTHENTICATED = "is-user-authenticated";
- private static final String MARK_COLUMN_CONTENT = "column_content";
- private static final String MARK_COLUMN_ID = "column_id";
- private static final String MARK_MAX_ORDER = "order_max";
- // Parameters
- private static final String PARAMETER_SITE_PATH = "site-path";
- private static final String PARAMETER_USER_SELECTED_LOCALE = "user-selected-language";
- private static final String PARAMETER_PLUGIN_NAME = "plugin-name";
- private static final String PARAMETER_PORTLET = "portlet";
- // Properties
- private static final String PROPERTY_MESSAGE_PAGE_ACCESS_DENIED = "portal.site.message.pageAccessDenied";
- private static final String CONTENT_SERVICE_NAME = "PageService";
- private static final String PROPERTY_COLUMN_MAX = "nb.columns";
- private static final int DEFAULT_COLUMN_MAX = 5;
- private static final int DEFAULT_PORTLET_ORDER_MAX = 15;
- private static final String KEY_THEME = "theme";
- private static final String TARGET_TOP = "target='_top'";
- private static final String WELCOME_PAGE_ID = "1";
- private static final String WELCOME_PAGE_CACHE_KEY = "mode0";
- private static final int MODE_ADMIN = 1;
- private static final String VALUE_TRUE = "1";
- private static final String VALUE_FALSE = "0";
- private static final String XSL_UNIQUE_PREFIX = "page-";
- private static final String ATTRIBUTE_CORE_CAN_PAGE_BE_CACHED = "core.canPageBeCached";
- private static final String DEFAULT_OPEN_TAG_PREFIX = "<div class=\"lutece-admin-portlet\" draggable=\"true\">";
- private static final String DEFAULT_CLOSE_TAG_PREFIX = "</div>";
- private static final String ADMIN_PORTLET_OPEN_TAG = AppPropertiesService.getProperty( "lutece.portlet.open.tag", DEFAULT_OPEN_TAG_PREFIX );
- private static final String ADMIN_PORTLET_CLOSE_TAG = AppPropertiesService.getProperty( "lutece.portlet.close.tag", DEFAULT_CLOSE_TAG_PREFIX );
- private static final int PORTLET_MAX_ORDER = AppPropertiesService.getPropertyInt( "lutece.list.order.max", DEFAULT_PORTLET_ORDER_MAX );
- // Specific for plugin-document
- private static final String DOCUMENT_LIST_PORTLET = "DOCUMENT_LIST_PORTLET";
- private static final String DOCUMENT_PORTLET = "DOCUMENT_PORTLET";
- private static final String DOCUMENT_ACTION_URL = "jsp/admin/plugins/document/ManagePublishing.jsp";
- private static final String DOCUMENT_IMAGE_URL = "images/admin/skin/actions/publish.png";
- private static final String DOCUMENT_TITLE = "portal.site.portletPreview.buttonManage";
- private static final int MAX_COLUMNS = AppPropertiesService.getPropertyInt( PROPERTY_COLUMN_MAX, DEFAULT_COLUMN_MAX );
- private static List<PageEventListener> _listEventListeners = new ArrayList<>( );
- private ICacheKeyService _cksPage;
- private ICacheKeyService _cksPortlet;
- private PageCacheService _cachePages;
- private PortletCacheService _cachePortlets;
- /**
- * Creates a new PageService object.
- *
- * @param pageCacheService
- * the page cache service
- * @param portletCacheService
- * the portlet cache service
- */
- @Inject
- public PageService( PageCacheService pageCacheService, PortletCacheService portletCacheService )
- {
- _cachePages = pageCacheService;
- _cachePortlets = portletCacheService;
- init( );
- }
- /**
- * Initializes the service
- */
- private void init( )
- {
- _cachePages.initCache( );
- _cachePortlets.initCache( );
- ImageResourceManager.registerProvider( this );
- addPageEventListener( this );
- }
- /**
- * Returns the Content Service name
- *
- * @return The name as a String
- */
- public String getName( )
- {
- return CONTENT_SERVICE_NAME;
- }
- /**
- * Returns the page for a given ID. The page is built using XML data of each portlet or retrieved from the cache if it's enable.
- *
- * @param request
- * The page ID
- * @param nMode
- * The current mode.
- * @return The HTML code of the page as a String.
- * @throws SiteMessageException
- * If a message shouldbe displayed
- */
- @Override
- public String getPage( HttpServletRequest request, int nMode ) throws SiteMessageException
- {
- String strPageId = request.getParameter( Parameters.PAGE_ID );
- return getPage( strPageId, nMode, request );
- }
- /**
- * Returns the page for a given ID. The page is built using XML data of each portlet or retrieved from the cache if it's enable.
- *
- * @param strIdPage
- * The page ID
- * @param nMode
- * The current mode.
- * @param request
- * The HttpRequest
- * @return The HTML code of the page as a String.
- * @throws SiteMessageException
- * occurs when a site message need to be displayed
- */
- @Override
- public String getPage( String strIdPage, int nMode, HttpServletRequest request ) throws SiteMessageException
- {
- try
- {
- String strPage;
- // The cache is enable !
- if ( _cachePages.isCacheEnable( ) )
- {
- strPage = getCachedPage( strIdPage, nMode, request );
- // redirection handling
- strPage = redirect( strPage );
- }
- else
- {
- strPage = buildPageContent( strIdPage, nMode, request );
- }
- return strPage;
- }
- catch( NumberFormatException nfe )
- {
- AppLogService.error( "PageService.getPage() : {}", nfe.getLocalizedMessage( ), nfe );
- throw new PageNotFoundException( );
- }
- }
- private String redirect( String strPage )
- {
- if ( strPage.startsWith( REDIRECTION_KEY ) )
- {
- strPage = strPage.replaceFirst( REDIRECTION_KEY, "" );
- try
- {
- LocalVariables.getResponse( ).sendRedirect( strPage );
- }
- catch( IOException e )
- {
- AppLogService.error( "Error on sendRedirect for {}", strPage );
- }
- }
- return strPage;
- }
- private String getCachedPage( String strIdPage, int nMode, HttpServletRequest request ) throws SiteMessageException
- {
- // Get request paramaters and store them in a HashMap
- Map<String, String> htParamRequest = readRequestParams( request, strIdPage );
- LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
- // we add the key in the memory key only if cache is enable
- String strKey = getKey( htParamRequest, nMode, user );
- // get page from cache
- String strPage = (String) _cachePages.getFromCache( strKey );
- if ( strPage == null )
- {
- // only one thread can evaluate the page
- synchronized( strKey )
- {
- // can be useful if an other thread had evaluate the
- // page
- strPage = (String) _cachePages.getFromCache( strKey );
- // ignore checkstyle, this double verification is useful
- // when page cache has been created when thread is
- // blocked on synchronized
- if ( strPage == null )
- {
- boolean bCanBeCached = true;
- AppLogService.debug( "Page generation {}", strKey );
- RedirectionResponseWrapper response = new RedirectionResponseWrapper( LocalVariables.getResponse( ) );
- LocalVariables.setLocal( LocalVariables.getConfig( ), LocalVariables.getRequest( ), response );
- request.setAttribute( ATTRIBUTE_CORE_CAN_PAGE_BE_CACHED, null );
- // The key is not in the cache, so we have to build
- // the page
- strPage = buildPageContent( strIdPage, nMode, request );
- // We check if the page contains portlets that can not be cached.
- if ( Boolean.FALSE.equals( request.getAttribute( ATTRIBUTE_CORE_CAN_PAGE_BE_CACHED ) ) )
- {
- bCanBeCached = false;
- }
- if ( response.getRedirectLocation( ) != null )
- {
- AppLogService.debug( "Redirection found {}", response.getRedirectLocation( ) );
- strPage = REDIRECTION_KEY + response.getRedirectLocation( );
- }
- // Add the page to the cache if the page can be
- // cached
- if ( bCanBeCached && ( nMode != MODE_ADMIN ) )
- {
- _cachePages.putInCache( strKey, strPage );
- }
- }
- else
- {
- AppLogService.debug( "Page read from cache after synchronisation {}", strKey );
- }
- }
- }
- else
- {
- AppLogService.debug( "Page read from cache {}", strKey );
- }
- return strPage;
- }
- private Map<String, String> readRequestParams( HttpServletRequest request, String strIdPage )
- {
- Enumeration<?> enumParam = request.getParameterNames( );
- Map<String, String> htParamRequest = new HashMap<>( );
- while ( enumParam.hasMoreElements( ) )
- {
- String paramName = (String) enumParam.nextElement( );
- htParamRequest.put( paramName, request.getParameter( paramName ) );
- }
- if ( !htParamRequest.containsKey( Parameters.PAGE_ID ) )
- {
- htParamRequest.put( Parameters.PAGE_ID, strIdPage );
- }
- if ( !htParamRequest.containsKey( Parameters.BASE_URL ) )
- {
- htParamRequest.put( Parameters.BASE_URL, AppPathService.getBaseUrl( request ) );
- }
- String strUserTheme = ThemesService.getUserTheme( request );
- if ( strUserTheme != null )
- {
- htParamRequest.put( KEY_THEME, strUserTheme );
- }
- return htParamRequest;
- }
- /**
- * Build the page content.
- *
- * @param strIdPage
- * The page ID
- * @param nMode
- * The current mode.
- * @param request
- * The HttpRequest
- * @return The HTML code of the page as a String.
- * @throws SiteMessageException
- * occurs when a site message need to be displayed
- */
- public String buildPageContent( String strIdPage, int nMode, HttpServletRequest request ) throws SiteMessageException
- {
- int nIdPage;
- Page page;
- nIdPage = Integer.parseInt( strIdPage );
- boolean bPageExist = PageHome.checkPageExist( nIdPage );
- if ( bPageExist )
- {
- page = PageHome.getPage( nIdPage );
- }
- else
- {
- // If there is a problem finding the page, returns the home page
- nIdPage = PortalService.getRootPageId( );
- page = PageHome.getPage( nIdPage );
- }
- PageData data = new PageData( );
- data.setName( page.getName( ) );
- data.setPagePath( PortalService.getPagePathContent( nIdPage, nMode, request ) );
- data.setTheme( page.getCodeTheme( ) );
- data.setMetaKeywords( page.getMetaKeywords( ) );
- data.setMetaDescription( page.getMetaDescription( ) );
- data.setDisplayDateUpdate( page.getDisplayDateUpdate( ) );
- data.setDateUpdate( page.getDateUpdate( ) );
- // Checks the page role (v1.1)
- String strRole = page.getRole( );
- if ( !strRole.equals( Page.ROLE_NONE ) && ( SecurityService.isAuthenticationEnable( ) ) && ( nMode != MODE_ADMIN ) )
- {
- LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
- if ( ( user == null ) && ( !SecurityService.getInstance( ).isExternalAuthentication( ) ) )
- {
- // The user is not registered and identify itself with the
- // Portal authentication
- String strAccessControledTemplate = SecurityService.getInstance( ).getAccessControledTemplate( );
- HashMap<String, Object> model = new HashMap<>( );
- String strLoginUrl = SecurityService.getInstance( ).getLoginPageUrl( );
- model.put( MARK_URL_LOGIN, strLoginUrl );
- HtmlTemplate tAccessControled = AppTemplateService.getTemplate( strAccessControledTemplate, request.getLocale( ), model );
- data.setContent( tAccessControled.getHtml( ) );
- return PortalService.buildPageContent( nIdPage, data, nMode, request );
- }
- if ( !SecurityService.getInstance( ).isUserInRole( request, strRole ) )
- {
- // The user doesn't have the correct role
- String strAccessDeniedTemplate = SecurityService.getInstance( ).getAccessDeniedTemplate( );
- HtmlTemplate tAccessDenied = AppTemplateService.getTemplate( strAccessDeniedTemplate, request.getLocale( ) );
- data.setContent( tAccessDenied.getHtml( ) );
- return PortalService.buildPageContent( nIdPage, data, nMode, request );
- }
- }
- // Added in v2.0
- // Add the page authorization
- if ( nMode == MODE_ADMIN )
- {
- AdminUser user = AdminUserService.getAdminUser( request );
- if ( isAuthorizedAdminPage( nIdPage, PageResourceIdService.PERMISSION_VIEW, user ) )
- {
- // Fill a PageData structure for those elements
- data.setContent( getPageContent( nIdPage, nMode, request ) );
- }
- else
- {
- data.setContent( I18nService.getLocalizedString( PROPERTY_MESSAGE_PAGE_ACCESS_DENIED, user.getLocale( ) ) );
- }
- }
- else
- {
- data.setContent( getPageContent( nIdPage, nMode, request ) );
- }
- if ( nIdPage == PortalService.getRootPageId( ) )
- {
- // This page is the home page.
- data.setHomePage( true );
- }
- return PortalService.buildPageContent( nIdPage, data, nMode, request );
- }
- /**
- * Build the page content.
- *
- * @param nIdPage
- * The page ID
- * @param nMode
- * The current mode.
- * @param request
- * The HttpRequest
- * @return The HTML code of the page as a String.
- * @throws SiteMessageException
- * occurs when a site message need to be displayed
- */
- @Override
- public String getPageContent( int nIdPage, int nMode, HttpServletRequest request ) throws SiteMessageException
- {
- Locale locale = Optional.ofNullable( request ).map( HttpServletRequest::getLocale ).orElse( LocaleService.getDefault( ) );
- String [ ] arrayContent = new String [ MAX_COLUMNS];
- for ( int i = 0; i < MAX_COLUMNS; i++ )
- {
- arrayContent [i] = "";
- }
- Page page = PageHome.findByPrimaryKey( nIdPage );
- Map<String, String> mapParams = getParams( request, nMode );
- boolean bCanPageBeCached = Boolean.TRUE;
- LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
- for ( Portlet portlet : page.getPortlets( ) )
- {
- int nCol = portlet.getColumn( ) - 1;
- if ( nCol < MAX_COLUMNS )
- {
- arrayContent [nCol] += getPortletContent( request, portlet, mapParams, nMode );
- }
- // We check if the portlet can be cached
- if ( ( user != null ) ? ( !portlet.canBeCachedForConnectedUsers( ) ) : ( !portlet.canBeCachedForAnonymousUsers( ) ) )
- {
- bCanPageBeCached = false;
- }
- }
- // Add columns outline in admin mode
- if ( nMode == MODE_ADMIN )
- {
- for ( int i = 0; i < MAX_COLUMNS; i++ )
- {
- arrayContent [i] = addColumnOutline( i + 1, arrayContent [i], locale );
- }
- }
- // We save that the page that is generating can not be cached
- if ( !bCanPageBeCached && request != null )
- {
- request.setAttribute( ATTRIBUTE_CORE_CAN_PAGE_BE_CACHED, false );
- }
- Map<String, Object> rootModel = new HashMap<>( );
- for ( int j = 0; j < MAX_COLUMNS; j++ )
- {
- rootModel.put( "page_content_col" + ( j + 1 ), arrayContent [j] );
- }
- List<PageInclude> listIncludes = PageIncludeService.getIncludes( );
- PageData data = new PageData( );
- for ( PageInclude pic : listIncludes )
- {
- pic.fillTemplate( rootModel, data, nMode, request );
- }
- HtmlTemplate t = AppTemplateService.getTemplate( page.getTemplate( ), locale, rootModel );
- return t.getHtml( );
- }
- /**
- * Add the HTML code to display column outlines
- *
- * @param columnId
- * the column id
- * @param content
- * the column content
- * @param locale
- * the locale
- * @return The column code
- */
- private String addColumnOutline( int columnId, String content, Locale locale )
- {
- Map<String, Object> model = new HashMap<>( 2 );
- model.put( MARK_COLUMN_CONTENT, content );
- model.put( MARK_COLUMN_ID, columnId );
- HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_COLUMN_OUTLINE, locale, model );
- return template.getHtml( );
- }
- /**
- * Get the portlet content
- *
- * @param request
- * The HTTP request
- * @param portlet
- * The portlet
- * @param mapRequestParams
- * request parameters
- * @param nMode
- * The mode
- * @return The content
- * @throws SiteMessageException
- * If an error occurs
- */
- private String getPortletContent( HttpServletRequest request, Portlet portlet, Map<String, String> mapRequestParams, int nMode ) throws SiteMessageException
- {
- if ( ( request != null ) && !isPortletVisible( request, portlet, nMode ) )
- {
- return StringUtils.EMPTY;
- }
- if ( request != null )
- {
- String strPluginName = portlet.getPluginName( );
- request.setAttribute( PARAMETER_PLUGIN_NAME, strPluginName );
- }
- String strPortletContent = StringUtils.EMPTY;
- // Add the admin buttons for portlet management on admin mode
- if ( nMode == MODE_ADMIN )
- {
- strPortletContent = ADMIN_PORTLET_OPEN_TAG + addAdminButtons( request, portlet );
- }
- String strKey = StringUtils.EMPTY;
- LuteceUser user = null;
- if ( SecurityService.isAuthenticationEnable( ) )
- {
- user = SecurityService.getInstance( ).getRegisteredUser( request );
- }
- boolean isCacheEnabled = nMode != MODE_ADMIN && _cachePortlets.isCacheEnable( );
- boolean bCanBeCached = user != null ? portlet.canBeCachedForConnectedUsers( ) : portlet.canBeCachedForAnonymousUsers( );
- if ( portlet.isContentGeneratedByXmlAndXsl( ) )
- {
- Map<String, String> mapParams = mapRequestParams;
- Map<String, String> mapXslParams = portlet.getXslParams( );
- if ( mapParams != null )
- {
- if ( mapXslParams != null )
- {
- mapParams.putAll( mapXslParams );
- }
- }
- else
- {
- mapParams = mapXslParams;
- }
- if ( isCacheEnabled && bCanBeCached )
- {
- mapParams.put( PARAMETER_PORTLET, String.valueOf( portlet.getId( ) ) );
- strKey = _cksPortlet.getKey( mapParams, nMode, user );
- String strPortlet = (String) _cachePortlets.getFromCache( strKey );
- if ( strPortlet != null )
- {
- return strPortlet;
- }
- }
- Properties outputProperties = ModeHome.getOuputXslProperties( nMode );
- String strXslUniqueId = XSL_UNIQUE_PREFIX + String.valueOf( portlet.getStyleId( ) );
- XmlTransformerService xmlTransformerService = new XmlTransformerService( );
- String strPortletXmlContent = portlet.getXml( request );
- strPortletContent += xmlTransformerService.transformBySourceWithXslCache( strPortletXmlContent, portlet.getXslSource( nMode ), strXslUniqueId, mapParams, outputProperties );
- }
- else
- {
- if ( isCacheEnabled && bCanBeCached )
- {
- mapRequestParams.put( PARAMETER_PORTLET, String.valueOf( portlet.getId( ) ) );
- strKey = _cksPortlet.getKey( mapRequestParams, nMode, user );
- String strPortlet = (String) _cachePortlets.getFromCache( strKey );
- if ( strPortlet != null )
- {
- return strPortlet;
- }
- }
- strPortletContent += portlet.getHtmlContent( request );
- }
- if ( isCacheEnabled && StringUtils.isNotEmpty( strKey ) )
- {
- _cachePortlets.putInCache( strKey, strPortletContent );
- }
-
- if ( nMode == MODE_ADMIN )
- {
- strPortletContent += ADMIN_PORTLET_CLOSE_TAG;
- }
-
- return strPortletContent;
- }
- private boolean isPortletVisible( HttpServletRequest request, Portlet portlet, int nMode )
- {
- if ( ( nMode != MODE_ADMIN ) && ( portlet.getStatus( ) == Portlet.STATUS_UNPUBLISHED ) )
- {
- return false;
- }
- String strRole = portlet.getRole( );
- boolean bUserInRole = SecurityService.isAuthenticationEnable( ) ? SecurityService.getInstance( ).isUserInRole( request, strRole ) : true;
- boolean [ ] conditions = new boolean [ ] {
- strRole.equals( Page.ROLE_NONE ), // No role is required so the portlet is visible for anyone
- !SecurityService.isAuthenticationEnable( ), // No authentication
- nMode == MODE_ADMIN, // We are in Admin mode, so all the portlet should be visible
- bUserInRole // The authentication is ON and the user get the role
- };
- return BooleanUtils.or( conditions );
- }
- /**
- * Build the Cache HashMap key for pages Goal is to be able to have a synchronized on the key but a synchronize only work with strict reference. So we
- * manage an hashmap of string reference for cache keys to be able to get them back.
- *
- * @param mapParams
- * The Map params
- * @param nMode
- * The current mode.
- * @param user
- * Current Lutece user
- * @return The HashMap key for articles pages as a String.
- */
- private String getKey( Map<String, String> mapParams, int nMode, LuteceUser user )
- {
- String strKey = _cksPage.getKey( mapParams, nMode, user );
- return _cachePages.getKey( strKey );
- }
- /**
- * Remove a page from the cache
- *
- * @param nIdPage
- * The page ID
- */
- private void invalidatePage( int nIdPage )
- {
- String strIdPage = String.valueOf( nIdPage );
- invalidatePage( strIdPage );
- }
- /**
- * @param cacheKeyService
- * the _cacheKeyService to set
- */
- public void setPageCacheKeyService( ICacheKeyService cacheKeyService )
- {
- _cksPage = cacheKeyService;
- }
- /**
- * @param cacheKeyService
- * the _cacheKeyService to set
- */
- public void setPortletCacheKeyService( ICacheKeyService cacheKeyService )
- {
- _cksPortlet = cacheKeyService;
- }
- /**
- * @param removalService
- * the removal listener service
- */
- public void setRoleRemovalService( RemovalListenerService removalService )
- {
- removalService.registerListener( new PageRoleRemovalListener( ) );
- removalService.registerListener( new PortletRoleRemovalListener( ) );
- }
- /**
- * Remove a page from the cache
- *
- * @param strIdPage
- * The page ID
- */
- private void invalidatePage( String strIdPage )
- {
- if ( _cachePages.isCacheEnable( ) )
- {
- String strKey = "[" + Parameters.PAGE_ID + ":" + strIdPage + "]";
- for ( String strKeyTemp : (List<String>) _cachePages.getCache( ).getKeys( ) )
- {
- if ( ( strKeyTemp.contains( strKey ) ) || ( WELCOME_PAGE_ID.equals( strIdPage ) && WELCOME_PAGE_CACHE_KEY.equals( strKeyTemp ) ) )
- {
- _cachePages.getCache( ).remove( strKeyTemp );
- if ( AppLogService.isDebugEnabled( ) )
- {
- AppLogService.debug( "Page (cache key : " + strKeyTemp + ") removed from the cache." );
- }
- }
- }
- }
- }
- // ///////////////////////////////////////////////////////////////////////////
- // Events Listeners management
- /**
- * Add a new page event listener
- *
- * @param listener
- * An event listener to add
- */
- public static void addPageEventListener( PageEventListener listener )
- {
- _listEventListeners.add( listener );
- AppLogService.info( "New Page Event Listener registered : {}", listener.getClass( ).getName( ) );
- }
- /**
- * Notify an event to all listeners
- *
- * @param event
- * A page Event
- */
- private void notifyListeners( PageEvent event )
- {
- for ( PageEventListener listener : _listEventListeners )
- {
- listener.processPageEvent( event );
- }
- }
- /**
- * Returns the resource type Id
- *
- * @return The resource type Id
- */
- @Override
- public String getResourceTypeId( )
- {
- return Page.IMAGE_RESOURCE_TYPE_ID;
- }
- /**
- * Gets the image resource for a given resource
- *
- * @param nIdResource
- * The Resource id
- * @return The image resource
- */
- @Override
- public ImageResource getImageResource( int nIdResource )
- {
- return PageHome.getImageResource( nIdResource );
- }
- /**
- * Create a page
- *
- * @param page
- * The page to create
- */
- @Override
- public void createPage( Page page )
- {
- PageHome.create( page );
- PageEvent event = new PageEvent( page, PageEvent.PAGE_CREATED );
- notifyListeners( event );
- }
- /**
- * Update a given page
- *
- * @param page
- * The page to update
- */
- @Override
- public void updatePage( Page page )
- {
- PageHome.update( page );
- PageEvent event = new PageEvent( page, PageEvent.PAGE_CONTENT_MODIFIED );
- notifyListeners( event );
- }
- /**
- * Remove a given page
- *
- * @param nPageId
- * The page Id
- */
- @Override
- public void removePage( int nPageId )
- {
- Page page = PageHome.findByPrimaryKey( nPageId );
- PageEvent event = new PageEvent( page, PageEvent.PAGE_DELETED );
- PageHome.remove( nPageId );
- notifyListeners( event );
- }
- /**
- * Process a page event
- *
- * @param event
- * The event to process
- */
- @Override
- public void processPageEvent( PageEvent event )
- {
- Page page = event.getPage( );
- invalidatePage( page.getId( ) );
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public void processPortletEvent( PortletEvent event )
- {
- invalidateContent( event.getPageId( ) );
- }
- /**
- * Invalidate Page Content
- *
- * @param nPageId
- * The Page ID
- */
- @Override
- public void invalidateContent( int nPageId )
- {
- Page page = PageHome.findByPrimaryKey( nPageId );
- PageEvent event = new PageEvent( page, PageEvent.PAGE_CONTENT_MODIFIED );
- notifyListeners( event );
- }
- /**
- * Check that a given user is allowed to access a page for a given permission
- *
- * @param nIdPage
- * the id of the page to check
- * @param strPermission
- * the permission needed
- * @param user
- * The current user
- * @return true if authorized, otherwise false
- */
- @Override
- public boolean isAuthorizedAdminPage( int nIdPage, String strPermission, AdminUser user )
- {
- Page page = PageHome.findByPrimaryKey( nIdPage );
- if ( page.getIdAuthorizationNode( ) != null )
- {
- String strAuthorizationNode = Integer.toString( page.getIdAuthorizationNode( ) );
- return ( RBACService.isAuthorized( Page.RESOURCE_TYPE, strAuthorizationNode, strPermission, user ) );
- }
- return true;
- }
- /**
- * Add the HTML code to display admin buttons under each portlet
- *
- * @param request
- * The Http request
- * @param portlet
- * The portlet
- * @return The buttons code
- */
- private String addAdminButtons( HttpServletRequest request, Portlet portlet )
- {
- AdminUser user = AdminUserService.getAdminUser( request );
- if ( RBACService.isAuthorized( PortletType.RESOURCE_TYPE, portlet.getPortletTypeId( ), PortletResourceIdService.PERMISSION_MANAGE, user ) )
- {
- Locale locale = user.getLocale( );
- Collection<PortletCustomAdminAction> listCustomActions = new ArrayList<>( );
- // TODO : listCustomActions should be provided by PortletType
- // FIXME : Delete plugin-document specifics
- if ( portlet.getPortletTypeId( ).equals( DOCUMENT_LIST_PORTLET ) || portlet.getPortletTypeId( ).equals( DOCUMENT_PORTLET ) )
- {
- PortletCustomAdminAction customAction = new PortletCustomAdminAction( );
- customAction.setActionUrl( DOCUMENT_ACTION_URL );
- customAction.setImageUrl( DOCUMENT_IMAGE_URL );
- customAction.setTitle( DOCUMENT_TITLE );
- listCustomActions.add( customAction );
- }
- Map<String, Object> model = new HashMap<>( );
- model.put( MARK_PORTLET, portlet );
- model.put( MARK_STATUS_PUBLISHED, Portlet.STATUS_PUBLISHED );
- model.put( MARK_MAX_ORDER, PORTLET_MAX_ORDER );
- model.put( MARK_STATUS_UNPUBLISHED, Portlet.STATUS_UNPUBLISHED );
- model.put( MARK_CUSTOM_ACTIONS, listCustomActions );
- HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_ADMIN_BUTTONS, locale, model );
- return template.getHtml( );
- }
- return StringUtils.EMPTY;
- }
- /**
- * Gets the params map
- *
- * @param request
- * The HTTP request
- * @param nMode
- * The mode
- * @return the map
- */
- private Map<String, String> getParams( HttpServletRequest request, int nMode )
- {
- Map<String, String> mapModifyParam = new HashMap<>( );
- String strParamName;
- // Get request paramaters and store them in a HashMap
- if ( request != null )
- {
- Enumeration<?> enumParam = request.getParameterNames( );
- while ( enumParam.hasMoreElements( ) )
- {
- strParamName = (String) enumParam.nextElement( );
- mapModifyParam.put( strParamName, request.getParameter( strParamName ) );
- }
- // Add selected locale
- mapModifyParam.put( PARAMETER_USER_SELECTED_LOCALE, LocaleService.getUserSelectedLocale( request ).getLanguage( ) );
- }
- // Added in v1.3
- // Add a path param for choose url to use in admin or normal mode
- if ( nMode != MODE_ADMIN )
- {
- mapModifyParam.put( PARAMETER_SITE_PATH, AppPathService.getPortalUrl( ) );
- if ( SecurityService.isAuthenticationEnable( ) )
- {
- mapModifyParam.put( MARKER_IS_USER_AUTHENTICATED,
- ( SecurityService.getInstance( ).getRegisteredUser( request ) != null ) ? VALUE_TRUE : VALUE_FALSE );
- }
- }
- else
- {
- mapModifyParam.put( PARAMETER_SITE_PATH, AppPathService.getAdminPortalUrl( ) );
- mapModifyParam.put( MARKER_TARGET, TARGET_TOP );
- }
- if ( !mapModifyParam.containsKey( Parameters.PAGE_ID ) )
- {
- mapModifyParam.put( Parameters.PAGE_ID, Integer.toString( PortalService.getRootPageId( ) ) );
- }
- return mapModifyParam;
- }
- /**
- * Management of the image associated to the page
- *
- * @param strPageId
- * The page identifier
- * @return The url
- */
- public String getResourceImagePage( String strPageId )
- {
- String strResourceType = getResourceTypeId( );
- UrlItem url = new UrlItem( Parameters.IMAGE_SERVLET );
- url.addParameter( Parameters.RESOURCE_TYPE, strResourceType );
- url.addParameter( Parameters.RESOURCE_ID, strPageId );
- return url.getUrlWithEntity( );
- }
- /**
- * Gets the page cache service.
- *
- * @return the page cache service
- */
- public PageCacheService getPageCacheService( )
- {
- return _cachePages;
- }
- /**
- * Sets the cache page service
- *
- * @param pageCacheService
- * the page cache service
- */
- public void setPageCacheService( PageCacheService pageCacheService )
- {
- _cachePages = pageCacheService;
- }
- /**
- * Gets the portlet cache service
- *
- * @return the porlet cache service
- */
- public PortletCacheService getPortletCacheService( )
- {
- return _cachePortlets;
- }
- /**
- * Gets the portlet cache service
- *
- * @param portletCacheService
- * the portlet cache service
- */
- public void setPortletCacheService( PortletCacheService portletCacheService )
- {
- _cachePortlets = portletCacheService;
- }
- /**
- * update authorization node of children page
- *
- * @param nIdParentPage
- * id of the parent page
- * @param nIdNewAuthorizationNode
- * the new authorization id
- */
- public static void updateChildrenAuthorizationNode( int nIdParentPage, Integer nIdNewAuthorizationNode )
- {
- List<Integer> listPagesChildren = PageHome.getPagesWhichMustChangeAuthorizationNode( nIdParentPage );
- if ( listPagesChildren != null )
- {
- for ( Integer idPage : listPagesChildren )
- {
- PageHome.updateAuthorizationNode( idPage, nIdNewAuthorizationNode );
- updateChildrenAuthorizationNode( idPage, nIdNewAuthorizationNode );
- }
- }
- }
- }