View Javadoc
1   /*
2    * Copyright (c) 2002-2017, 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.plugins.sitemap.service;
35  
36  import fr.paris.lutece.portal.business.page.Page;
37  import fr.paris.lutece.portal.business.page.PageHome;
38  import fr.paris.lutece.portal.service.util.AppPropertiesService;
39  import fr.paris.lutece.util.sql.DAOUtil;
40  import fr.paris.lutece.util.xml.XmlUtil;
41  
42  
43  /**
44   * Site Map Service
45   */
46  public final class SiteMapService
47  {
48      private static final String TAG_URL = "url";
49      private static final String TAG_LOC = "loc";
50      private static final String TAG_PRIORITY = "priority";
51      private static final String TAG_LAST_MOD = "lastmod";
52      private static final String TAG_CHANGE_FREQ = "changefreq";
53      private static final String DEFAULT_DATE = "2007-12-23";
54      private static final String PROPERTY_LUTECE_PROD_URL = "lutece.prod.url";
55      private static final String PROPERTY_CHANGE_FREQUENCY_PAGE = "sitemap.page.changefreq";
56      private static final String PROPERTY_CHANGE_FREQUENCY_DOCUMENT = "sitemap.document.changefreq";
57      private static final String SQL_FIND_DOCUMENTS = "SELECT document_published.id_document, core_portlet.id_portlet , core_portlet.date_update " +
58          " FROM core_portlet, document_published " +
59          " WHERE core_portlet.id_portlet_type = 'DOCUMENT_LIST_PORTLET' and core_portlet.id_portlet = document_published.id_portlet and core_portlet.id_page = ?";
60      private static final String SQL_FIND_PAGES = "select date_update from core_page where core_page.id_page = ?";
61  
62      /**
63       * Private constructor
64       */
65      private SiteMapService(  )
66      {
67      }
68  
69      /**
70       * Build the sitemap XML file
71       * @return The sitemap as a String
72       */
73      public static String getXmlSiteMap(  )
74      {
75          StringBuffer strXml = new StringBuffer(  );
76          strXml.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
77          strXml.append( 
78              "<urlset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n\t http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\"\n\t xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n" );
79          findPages( strXml, 1, 0 );
80          strXml.append( "</urlset>" );
81  
82          return strXml.toString(  );
83      }
84  
85      /**
86       * Recursive crawling of all pages
87       * @param strXml The XML document to fill
88       * @param nPageId The current page id
89       * @param nLevel The current level
90       */
91      private static void findPages( StringBuffer strXml, int nPageId, int nLevel )
92      {
93          Page page = PageHome.getPage( nPageId );
94          Double priority = new Double( 1 ) / ( nLevel + 1 );
95          String strChangeFrequency = AppPropertiesService.getProperty( PROPERTY_CHANGE_FREQUENCY_PAGE );
96          String strBaseUrl = AppPropertiesService.getProperty( PROPERTY_LUTECE_PROD_URL );
97  
98          if ( page.isVisible( null ) )
99          {
100             XmlUtil.beginElement( strXml, TAG_URL );
101             XmlUtil.addElement( strXml, TAG_LOC, strBaseUrl + "/jsp/site/Portal.jsp?page_id=" + page.getId(  ) );
102             XmlUtil.addElement( strXml, TAG_PRIORITY, priority.toString(  ) );
103             XmlUtil.addElement( strXml, TAG_LAST_MOD, pageModificationDate( nPageId ) );
104             XmlUtil.addElement( strXml, TAG_CHANGE_FREQ, strChangeFrequency );
105             XmlUtil.endElement( strXml, TAG_URL );
106 
107             findDocuments( strXml, page.getId(  ), priority );
108 
109             for ( Page pageChild : PageHome.getChildPages( nPageId ) )
110             {
111                 findPages( strXml, pageChild.getId(  ), nLevel + 1 );
112             }
113         }
114     }
115 
116     /**
117      * Gets a the last modification date of a given page
118      * @param nPageId The page ID
119      * @return The date as a String
120      */
121     private static String pageModificationDate( int nPageId )
122     {
123         String strModificationDate = DEFAULT_DATE;
124         DAOUtil daoUtil = new DAOUtil( SQL_FIND_PAGES );
125         daoUtil.setInt( 1, nPageId );
126         daoUtil.executeQuery(  );
127 
128         if ( daoUtil.next(  ) )
129         {
130             strModificationDate = daoUtil.getString( 1 ).substring( 0, 10 );
131         }
132 
133         daoUtil.free(  );
134 
135         return strModificationDate;
136     }
137 
138     /**
139      *
140      * @param strXml The XML document to String
141      * @param nPageId The current page ID
142      * @param priority The priority
143      */
144     private static void findDocuments( StringBuffer strXml, int nPageId, Double priority )
145     {
146         String strChangeFrequency = AppPropertiesService.getProperty( PROPERTY_CHANGE_FREQUENCY_DOCUMENT );
147         String strBaseUrl = AppPropertiesService.getProperty( PROPERTY_LUTECE_PROD_URL );
148         DAOUtil daoUtil = new DAOUtil( SQL_FIND_DOCUMENTS );
149         daoUtil.setInt( 1, nPageId );
150         daoUtil.executeQuery(  );
151 
152         while ( daoUtil.next(  ) )
153         {
154             XmlUtil.beginElement( strXml, TAG_URL );
155             XmlUtil.addElement( strXml, TAG_LOC,
156                 strBaseUrl + "/jsp/site/Portal.jsp?document_id=" + daoUtil.getInt( 1 ) + "&amp;portlet_id=" +
157                 daoUtil.getInt( 2 ) );
158             XmlUtil.addElement( strXml, TAG_PRIORITY, priority.toString(  ) );
159             XmlUtil.addElement( strXml, TAG_LAST_MOD, daoUtil.getString( 3 ).substring( 0, 10 ) );
160             XmlUtil.addElement( strXml, TAG_CHANGE_FREQ, strChangeFrequency );
161             XmlUtil.endElement( strXml, TAG_URL );
162         }
163 
164         daoUtil.free(  );
165     }
166 }