View Javadoc
1   /*
2    * Copyright (c) 2002-2020, City of 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  /*
35   * To change this license header, choose License Headers in Project Properties.
36   * To change this template file, choose Tools | Templates
37   * and open the template in the editor.
38   */
39  package fr.paris.lutece.plugins.lutecetools.service;
40  
41  import java.io.ByteArrayInputStream;
42  import java.io.InputStream;
43  import java.util.ArrayList;
44  import java.util.HashSet;
45  import java.util.List;
46  import java.util.Set;
47  
48  import javax.xml.parsers.DocumentBuilder;
49  import javax.xml.parsers.DocumentBuilderFactory;
50  
51  import org.apache.commons.lang.StringUtils;
52  import org.w3c.dom.Document;
53  import org.w3c.dom.Element;
54  import org.w3c.dom.NodeList;
55  import org.xml.sax.InputSource;
56  
57  import fr.paris.lutece.plugins.lutecetools.business.Component;
58  import fr.paris.lutece.portal.service.util.AppLogService;
59  import fr.paris.lutece.util.httpaccess.HttpAccess;
60  import fr.paris.lutece.util.httpaccess.HttpAccessException;
61  
62  /**
63   *
64   * @author leridons
65   */
66  public final class SiteInfoService
67  {
68  
69      private static final String TAG_TITLE = "title";
70      private static final String TAG_META = "meta";
71      private static final String TAG_IMG = "img";
72      private static final String TAG_SUBSECTION = "subsection";
73  
74      private static final String ATTRIBUTE_NAME = "name";
75      private static final String ATTRIBUTE_CONTENT = "content";
76      private static final String ATTRIBUTE_SRC = "src";
77      private static final String ATTRIBUTE_KEYWORDS_VALUE = "keywords";
78      private static final String ATTRIBUTE_INTRODUCTION_VALUE = "Introduction";
79      private static final String ATTRIBUTE_CONFIGURATION_VALUE = "Configuration";
80      private static final String ATTRIBUTE_USAGE_VALUE = "Usage";
81  
82      private static final String EXCEPTION_MESSAGE = "LuteceTools - SiteInfoService : Error retrieving site index infos : ";
83  
84      private static SiteInfoService _singleton;
85  
86      /**
87       * Private constructor
88       */
89      private SiteInfoService( )
90      {
91      }
92  
93      /**
94       * Returns the unique instance
95       * 
96       * @return the unique instance
97       */
98      public static synchronized SiteInfoService instance( )
99      {
100         if ( _singleton == null )
101         {
102             _singleton = new SiteInfoService( );
103         }
104 
105         return _singleton;
106     }
107 
108     /**
109      * Retreive SITE infos for a given component
110      * 
111      * @param component           The component
112      * @param strXdocSiteIndexUrl The Xdoc Site Index URL
113      * @param strLang
114      * @param sbLogs              Logs
115      */
116     public void getSiteInfos( Component component, String strXdocSiteIndexUrl, String strLang, StringBuilder sbLogs )
117     {
118         try
119         {
120             HttpAccess httpAccess = new HttpAccess( );
121             String strSiteIndex = httpAccess.doGet( strXdocSiteIndexUrl );
122 
123             String strLANG = "_" + strLang;
124 
125             DocumentBuilderFactory documentBuilder = DocumentBuilderFactory.newInstance( );
126             InputStream is = new ByteArrayInputStream( strSiteIndex.getBytes( ) ); // use inputstream to ignore BOM when
127                                                                                    // parsing
128 
129             DocumentBuilder builder = documentBuilder.newDocumentBuilder( );
130             Document document = builder.parse( new InputSource( is ) );
131             Element root = document.getDocumentElement( );
132 
133             NodeList titleList = root.getElementsByTagName( TAG_TITLE );
134             for ( int i = 0; i < titleList.getLength( ); i++ )
135             {
136                 Element elmt = (Element) titleList.item( i );
137                 String title = elmt.getTextContent( );
138                 if ( title != null )
139                 {
140                     component.set( Component.SITE_TITLE + strLANG, title );
141                 }
142             }
143 
144             NodeList metaList = root.getElementsByTagName( TAG_META );
145             String strKeywords = null;
146             for ( int i = 0; i < metaList.getLength( ); i++ )
147             {
148                 Element elmt = (Element) metaList.item( i );
149                 if ( elmt.hasAttribute( ATTRIBUTE_NAME )
150                         && ATTRIBUTE_KEYWORDS_VALUE.equals( elmt.getAttribute( ATTRIBUTE_NAME ) ) )
151                 {
152                     strKeywords = elmt.getAttribute( ATTRIBUTE_CONTENT );
153                 }
154             }
155 
156             component.set( Component.HAS_KEYWORDS + strLANG,
157                     ( StringUtils.isBlank( strKeywords ) ? "false" : "true" ) );
158 
159             // split keywords
160             if ( strKeywords != null )
161             {
162                 String[] strTempKeywords = strKeywords.split( "," );
163                 Set<String> keywords = new HashSet<>( );
164                 for ( String keyword : strTempKeywords )
165                 {
166                     keywords.add( keyword.trim( ) );
167                 }
168 
169                 component.set( Component.SITE_KEYWORDS + strLANG, keywords );
170             }
171 
172             NodeList subSections = root.getElementsByTagName( TAG_SUBSECTION );
173             StringBuilder strIntroduction = new StringBuilder( );
174             StringBuilder strConfiguration = new StringBuilder( );
175             StringBuilder strUsage = new StringBuilder( );
176 
177             for ( int i = 0; i < subSections.getLength( ); i++ )
178             {
179                 Element elmt = (Element) subSections.item( i );
180 
181                 if ( elmt.hasAttribute( ATTRIBUTE_NAME )
182                         && ATTRIBUTE_INTRODUCTION_VALUE.equals( elmt.getAttribute( ATTRIBUTE_NAME ) ) )
183                 {
184                     strIntroduction.append( elmt.getTextContent( ) );
185                 }
186 
187                 if ( elmt.hasAttribute( ATTRIBUTE_NAME )
188                         && ATTRIBUTE_CONFIGURATION_VALUE.equals( elmt.getAttribute( ATTRIBUTE_NAME ) ) )
189                 {
190                     strConfiguration.append( elmt.getTextContent( ) );
191                 }
192 
193                 if ( elmt.hasAttribute( ATTRIBUTE_NAME )
194                         && ATTRIBUTE_USAGE_VALUE.equals( elmt.getAttribute( ATTRIBUTE_NAME ) ) )
195                 {
196                     strUsage.append( elmt.getTextContent( ) );
197                 }
198             }
199 
200             component.set( Component.SITE_INTRODUCTION + strLANG, strIntroduction.toString( ) );
201             component.set( Component.SITE_CONFIGURATION + strLANG, strConfiguration.toString( ) );
202             component.set( Component.SITE_USAGE + strLANG, strUsage.toString( ) );
203 
204             NodeList imgList = root.getElementsByTagName( TAG_IMG );
205             List<String> imagesSrcList = new ArrayList<>( );
206             for ( int i = 0; i < imgList.getLength( ); i++ )
207             {
208                 Element elmt = (Element) imgList.item( i );
209                 imagesSrcList.add( elmt.getAttribute( ATTRIBUTE_SRC ) );
210             }
211             component.set( Component.SITE_IMGS + strLANG, imagesSrcList );
212 
213         }
214         catch ( HttpAccessException e )
215         {
216             sbLogs.append( "\n*** ERROR *** Error reading site index for component :" )
217                     .append( component.getArtifactId( ) ).append( " [url : " + strXdocSiteIndexUrl + "]" )
218                     .append( EXCEPTION_MESSAGE );
219         }
220         catch ( Exception e )
221         {
222             AppLogService.error( EXCEPTION_MESSAGE + component.getArtifactId( ) + " : " + e.getMessage( ), e );
223         }
224     }
225 
226 }