SiteMapApp.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.web.xpages;
- import fr.paris.lutece.portal.business.XmlContent;
- import fr.paris.lutece.portal.business.page.Page;
- import fr.paris.lutece.portal.business.page.PageHome;
- import fr.paris.lutece.portal.business.portalcomponent.PortalComponentHome;
- import fr.paris.lutece.portal.business.style.ModeHome;
- import fr.paris.lutece.portal.business.stylesheet.StyleSheet;
- import fr.paris.lutece.portal.service.html.XmlTransformerService;
- import fr.paris.lutece.portal.service.i18n.I18nService;
- import fr.paris.lutece.portal.service.plugin.Plugin;
- import fr.paris.lutece.portal.service.portal.PortalService;
- import fr.paris.lutece.portal.service.security.LuteceUser;
- import fr.paris.lutece.portal.service.security.SecurityService;
- import fr.paris.lutece.portal.service.util.AppLogService;
- import fr.paris.lutece.portal.service.util.AppPathService;
- import fr.paris.lutece.portal.web.admin.AdminPageJspBean;
- import fr.paris.lutece.util.xml.XmlUtil;
- import org.apache.commons.lang3.StringUtils;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Properties;
- import java.util.Set;
- import javax.servlet.http.HttpServletRequest;
- /**
- * This class provides the map of the pages on the site
- */
- public class SiteMapApp implements XPageApplication
- {
- /**
- * Serial version UID
- */
- private static final long serialVersionUID = 1799476496018552101L;
- private static final int PORTAL_COMPONENT_SITE_MAP_ID = 6;
- private static final int MODE_NORMAL = 0;
- private static final int MODE_ADMIN = 1;
- private static final String PARAMETER_SITE_PATH = "site-path";
- private static final String MARKER_TARGET = "target";
- private static final String TARGET_TOP = "target='_top'";
- private static final String PROPERTY_SERVICE_NAME = "portal.site.serviceName.siteMapService";
- private static final String PROPERTY_PATH_LABEL = "portal.site.site_map.pathLabel";
- private static final String PROPERTY_PAGE_TITLE = "portal.site.site_map.pageTitle";
- /**
- * Creates a new SiteMapPage object
- */
- public SiteMapApp( )
- {
- // Ctor
- }
- /**
- * Returns the localized service name
- *
- * @param locale
- * The locale
- * @return The localized service name
- */
- public String getName( Locale locale )
- {
- return I18nService.getLocalizedString( PROPERTY_SERVICE_NAME, locale );
- }
- /**
- * Build or get in the cache the page which contains the site map depending on the mode
- *
- * @param request
- * The Http request
- * @param nMode
- * The selected mode
- * @param plugin
- * The plugin
- * @return The content of the site map
- */
- @Override
- public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin )
- {
- XPage page = new XPage( );
- String strKey = getKey( nMode, request );
- Locale locale = request.getLocale( );
- SiteMapCacheService siteMapCacheService = SiteMapCacheService.getInstance( );
- // Check the key in the cache
- String strCachedPage = siteMapCacheService.isCacheEnable( ) ? (String) siteMapCacheService.getFromCache( strKey ) : null;
- if ( strCachedPage == null )
- {
- // Build the HTML document
- String strPage = buildPageContent( nMode, request );
- // Add it to the cache
- if ( siteMapCacheService.isCacheEnable( ) )
- {
- synchronized( strKey )
- {
- siteMapCacheService.putInCache( strKey, strPage );
- }
- }
- page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATH_LABEL, locale ) );
- page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE, locale ) );
- page.setContent( strPage );
- return page;
- }
- // The document exist in the cache
- page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATH_LABEL, locale ) );
- page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE, locale ) );
- page.setContent( strCachedPage );
- return page;
- }
- /**
- * Gets the cache key
- *
- * @param nMode
- * The mode
- * @param request
- * The HTTP request
- * @return The key
- */
- private String getKey( int nMode, HttpServletRequest request )
- {
- String strRoles = "-";
- if ( SecurityService.isAuthenticationEnable( ) )
- {
- LuteceUser user = SecurityService.getInstance( ).getRegisteredUser( request );
- if ( ( user != null ) && ( user.getRoles( ) != null ) )
- {
- String [ ] roles = user.getRoles( );
- Arrays.sort( roles );
- strRoles = StringUtils.join( roles, ',' );
- }
- }
- return "[m:" + nMode + "][roles:" + strRoles + "]";
- }
- /**
- * Build an XML document containing the arborescence of the site pages and transform it with the stylesheet combined with the mode
- *
- * @param nMode
- * The selected mode
- * @param request
- * The HttpServletRequest
- * @return The content of the site map
- */
- private String buildPageContent( int nMode, HttpServletRequest request )
- {
- StringBuffer strArborescenceXml = new StringBuffer( );
- strArborescenceXml.append( XmlUtil.getXmlHeader( ) );
- int nLevel = 0;
- findPages( strArborescenceXml, PortalService.getRootPageId( ), nLevel, new HashSet<>( ), request );
- // Added in v1.3
- // Use the same stylesheet for normal or admin mode
- StyleSheet xslSource;
- switch( nMode )
- {
- case MODE_NORMAL:
- case MODE_ADMIN:
- xslSource = PortalComponentHome.getXsl( PORTAL_COMPONENT_SITE_MAP_ID, MODE_NORMAL );
- break;
- default:
- xslSource = PortalComponentHome.getXsl( PORTAL_COMPONENT_SITE_MAP_ID, nMode );
- break;
- }
- // Added in v1.3
- // Add a path param for choose url to use in admin or normal mode
- Map<String, String> mapParamRequest = new HashMap<>( );
- if ( nMode != MODE_ADMIN )
- {
- mapParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getPortalUrl( ) );
- }
- else
- {
- mapParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getAdminPortalUrl( ) );
- mapParamRequest.put( MARKER_TARGET, TARGET_TOP );
- }
- Properties outputProperties = ModeHome.getOuputXslProperties( nMode );
- XmlTransformerService xmlTransformerService = new XmlTransformerService( );
- return xmlTransformerService.transformBySourceWithXslCache( strArborescenceXml.toString( ), xslSource, mapParamRequest, outputProperties );
- }
- /**
- * Build recursively the XML document containing the arborescence of the site pages
- *
- * @param strXmlArborescence
- * The buffer in which adding the current page of the arborescence
- * @param nPageId
- * The current page of the recursive course
- * @param nLevel
- * The depth level of the page in the arborescence
- * @param request
- * The HttpServletRequest
- */
- private void findPages( StringBuffer strXmlArborescence, int nPageId, int nLevel, Set<Integer> seenPages, HttpServletRequest request )
- {
- if ( !seenPages.add( nPageId ) )
- {
- AppLogService.error( "SiteMapApp : A cycle exists in pages; page id {} was already processed", nPageId );
- return;
- }
- Page page = PageHome.getPage( nPageId );
- if ( page.isVisible( request ) )
- {
- XmlUtil.beginElement( strXmlArborescence, XmlContent.TAG_PAGE );
- XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_ID, page.getId( ) );
- XmlUtil.addElementHtml( strXmlArborescence, XmlContent.TAG_PAGE_NAME, page.getName( ) );
- XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_DESCRIPTION, page.getDescription( ) );
- XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_LEVEL, nLevel );
- AdminPageJspBean adminPage = new AdminPageJspBean( );
- if ( page.getImageContent( ) != null )
- {
- int nImageLength = page.getImageContent( ).length;
- if ( nImageLength >= 1 )
- {
- String strPageId = Integer.toString( page.getId( ) );
- XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_IMAGE, adminPage.getResourceImagePage( page, strPageId ) );
- }
- }
- XmlUtil.beginElement( strXmlArborescence, XmlContent.TAG_CHILD_PAGES_LIST );
- for ( Page pageChild : PageHome.getChildPagesMinimalData( nPageId ) )
- {
- findPages( strXmlArborescence, pageChild.getId( ), nLevel + 1, seenPages, request );
- }
- XmlUtil.endElement( strXmlArborescence, XmlContent.TAG_CHILD_PAGES_LIST );
- XmlUtil.endElement( strXmlArborescence, XmlContent.TAG_PAGE );
- }
- }
- }