View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de 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.portal.web.xpages;
35  
36  import fr.paris.lutece.portal.business.XmlContent;
37  import fr.paris.lutece.portal.business.page.Page;
38  import fr.paris.lutece.portal.business.page.PageHome;
39  import fr.paris.lutece.portal.business.portalcomponent.PortalComponentHome;
40  import fr.paris.lutece.portal.business.style.ModeHome;
41  import fr.paris.lutece.portal.business.stylesheet.StyleSheet;
42  import fr.paris.lutece.portal.service.html.XmlTransformerService;
43  import fr.paris.lutece.portal.service.i18n.I18nService;
44  import fr.paris.lutece.portal.service.plugin.Plugin;
45  import fr.paris.lutece.portal.service.portal.PortalService;
46  import fr.paris.lutece.portal.service.security.LuteceUser;
47  import fr.paris.lutece.portal.service.security.SecurityService;
48  import fr.paris.lutece.portal.service.util.AppPathService;
49  import fr.paris.lutece.portal.web.admin.AdminPageJspBean;
50  import fr.paris.lutece.util.xml.XmlUtil;
51  
52  import org.apache.commons.lang.StringUtils;
53  
54  import java.util.Arrays;
55  import java.util.HashMap;
56  import java.util.Locale;
57  import java.util.Map;
58  import java.util.Properties;
59  
60  import javax.servlet.http.HttpServletRequest;
61  
62  
63  /**
64   * This class provides the map of the pages on the site
65   */
66  public class SiteMapApp implements XPageApplication
67  {
68      /**
69       * Serial version UID
70       */
71      private static final long serialVersionUID = 1799476496018552101L;
72      private static final int PORTAL_COMPONENT_SITE_MAP_ID = 6;
73      private static final int MODE_NORMAL = 0;
74      private static final int MODE_ADMIN = 1;
75      private static final String PARAMETER_SITE_PATH = "site-path";
76      private static final String MARKER_TARGET = "target";
77      private static final String TARGET_TOP = "target='_top'";
78      private static final String PROPERTY_SERVICE_NAME = "portal.site.serviceName.siteMapService";
79      private static final String PROPERTY_PATH_LABEL = "portal.site.site_map.pathLabel";
80      private static final String PROPERTY_PAGE_TITLE = "portal.site.site_map.pageTitle";
81  
82      /**
83       * Creates a new SiteMapPage object
84       */
85      public SiteMapApp(  )
86      {
87      }
88  
89      /**
90       * Returns the localized service name
91       * @param locale The locale
92       * @return The localized service name
93       */
94      public String getName( Locale locale )
95      {
96          return I18nService.getLocalizedString( PROPERTY_SERVICE_NAME, locale );
97      }
98  
99      /**
100      * Build or get in the cache the page which contains the site map depending
101      * on the mode
102      *
103      * @param request The Http request
104      * @param nMode The selected mode
105      * @param plugin The plugin
106      * @return The content of the site map
107      */
108     @Override
109     public XPage getPage( HttpServletRequest request, int nMode, Plugin plugin )
110     {
111         XPage page = new XPage(  );
112         String strKey = getKey( nMode, request );
113 
114         Locale locale = request.getLocale(  );
115 
116         SiteMapCacheService siteMapCacheService = SiteMapCacheService.getInstance(  );
117 
118         // Check the key in the cache
119         String strCachedPage = siteMapCacheService.isCacheEnable(  )
120             ? (String) siteMapCacheService.getFromCache( strKey ) : null;
121 
122         if ( strCachedPage == null )
123         {
124             // Build the HTML document
125             String strPage = buildPageContent( nMode, request );
126 
127             // Add it to the cache
128             if ( siteMapCacheService.isCacheEnable(  ) )
129             {
130                 synchronized ( strKey )
131                 {
132                     siteMapCacheService.putInCache( strKey, strPage );
133                 }
134             }
135 
136             page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATH_LABEL, locale ) );
137             page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE, locale ) );
138             page.setContent( strPage );
139 
140             return page;
141         }
142 
143         // The document exist in the cache
144         page.setPathLabel( I18nService.getLocalizedString( PROPERTY_PATH_LABEL, locale ) );
145         page.setTitle( I18nService.getLocalizedString( PROPERTY_PAGE_TITLE, locale ) );
146         page.setContent( strCachedPage );
147 
148         return page;
149     }
150 
151     /**
152      * Gets the cache key
153      * @param nMode The mode
154      * @param request The HTTP request
155      * @return The key
156      */
157     private String getKey( int nMode, HttpServletRequest request )
158     {
159         String strRoles = "-";
160 
161         if ( SecurityService.isAuthenticationEnable(  ) )
162         {
163             LuteceUser user = SecurityService.getInstance(  ).getRegisteredUser( request );
164 
165             if ( ( user != null ) && ( user.getRoles(  ) != null ) )
166             {
167                 String[] roles = user.getRoles(  );
168                 Arrays.sort( roles );
169                 strRoles = StringUtils.join( roles, ',' );
170             }
171         }
172 
173         return "[m:" + nMode + "][roles:" + strRoles + "]";
174     }
175 
176     /**
177      * Build an XML document containing the arborescence of the site pages and
178      * transform it with the stylesheet
179      * combined with the mode
180      * @param nMode The selected mode
181      * @param request The HttpServletRequest
182      * @return The content of the site map
183      */
184     private String buildPageContent( int nMode, HttpServletRequest request )
185     {
186         StringBuffer strArborescenceXml = new StringBuffer(  );
187         strArborescenceXml.append( XmlUtil.getXmlHeader(  ) );
188 
189         int nLevel = 0;
190         findPages( strArborescenceXml, PortalService.getRootPageId(  ), nLevel, request );
191 
192         // Added in v1.3
193         // Use the same stylesheet for normal or admin mode
194         StyleSheet xslSource;
195 
196         switch ( nMode )
197         {
198             case MODE_NORMAL:
199             case MODE_ADMIN:
200                 xslSource = PortalComponentHome.getXsl( PORTAL_COMPONENT_SITE_MAP_ID, MODE_NORMAL );
201 
202                 break;
203 
204             default:
205                 xslSource = PortalComponentHome.getXsl( PORTAL_COMPONENT_SITE_MAP_ID, nMode );
206 
207                 break;
208         }
209 
210         // Added in v1.3
211         // Add a path param for choose url to use in admin or normal mode
212         Map<String, String> mapParamRequest = new HashMap<String, String>(  );
213 
214         if ( nMode != MODE_ADMIN )
215         {
216             mapParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getPortalUrl(  ) );
217         }
218         else
219         {
220             mapParamRequest.put( PARAMETER_SITE_PATH, AppPathService.getAdminPortalUrl(  ) );
221             mapParamRequest.put( MARKER_TARGET, TARGET_TOP );
222         }
223 
224         Properties outputProperties = ModeHome.getOuputXslProperties( nMode );
225 
226         XmlTransformerService xmlTransformerService = new XmlTransformerService(  );
227 
228         return xmlTransformerService.transformBySourceWithXslCache( strArborescenceXml.toString(  ), xslSource,
229             mapParamRequest, outputProperties );
230     }
231 
232     /**
233      * Build recursively the XML document containing the arborescence of the
234      * site pages
235      * @param strXmlArborescence The buffer in which adding the current page of
236      *            the arborescence
237      * @param nPageId The current page of the recursive course
238      * @param nLevel The depth level of the page in the arborescence
239      * @param request The HttpServletRequest
240      */
241     private void findPages( StringBuffer strXmlArborescence, int nPageId, int nLevel, HttpServletRequest request )
242     {
243         Page page = PageHome.getPage( nPageId );
244 
245         if ( page.isVisible( request ) )
246         {
247             XmlUtil.beginElement( strXmlArborescence, XmlContent.TAG_PAGE );
248             XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_ID, page.getId(  ) );
249             XmlUtil.addElementHtml( strXmlArborescence, XmlContent.TAG_PAGE_NAME, page.getName(  ) );
250             XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_DESCRIPTION, page.getDescription(  ) );
251             XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_LEVEL, nLevel );
252 
253             AdminPageJspBean adminPage = new AdminPageJspBean(  );
254 
255             if ( page.getImageContent(  ) != null )
256             {
257                 int nImageLength = page.getImageContent(  ).length;
258 
259                 if ( nImageLength >= 1 )
260                 {
261                     String strPageId = Integer.toString( page.getId(  ) );
262                     XmlUtil.addElement( strXmlArborescence, XmlContent.TAG_PAGE_IMAGE,
263                         adminPage.getResourceImagePage( page, strPageId ) );
264                 }
265             }
266 
267             XmlUtil.beginElement( strXmlArborescence, XmlContent.TAG_CHILD_PAGES_LIST );
268 
269             for ( Page pageChild : PageHome.getChildPagesMinimalData( nPageId ) )
270             {
271                 findPages( strXmlArborescence, pageChild.getId(  ), nLevel + 1, request );
272             }
273 
274             XmlUtil.endElement( strXmlArborescence, XmlContent.TAG_CHILD_PAGES_LIST );
275             XmlUtil.endElement( strXmlArborescence, XmlContent.TAG_PAGE );
276         }
277     }
278 }