View Javadoc
1   /*
2    * Copyright (c) 2002-2021, 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  package fr.paris.lutece.plugins.address.service;
35  
36  import com.fasterxml.jackson.databind.JsonNode;
37  import com.fasterxml.jackson.databind.ObjectMapper;
38  import com.fasterxml.jackson.databind.node.ArrayNode;
39  import fr.paris.lutece.plugins.address.business.jaxb.Adresse;
40  import fr.paris.lutece.portal.service.util.AppLogService;
41  import fr.paris.lutece.portal.service.util.AppPropertiesService;
42  import fr.paris.lutece.util.ReferenceItem;
43  import fr.paris.lutece.util.ReferenceList;
44  import fr.paris.lutece.util.httpaccess.HttpAccess;
45  import fr.paris.lutece.util.httpaccess.HttpAccessException;
46  import fr.paris.lutece.util.string.StringUtil;
47  
48  import java.io.IOException;
49  import java.io.UnsupportedEncodingException;
50  import java.net.URLEncoder;
51  import java.rmi.RemoteException;
52  import javassist.bytecode.stackmap.BasicBlock;
53  
54  import javax.servlet.http.HttpServletRequest;
55  
56  import org.apache.log4j.Logger;
57  
58  /**
59   *
60   */
61  public class RestAddressService implements IAddressService
62  {
63  
64      // Plugin properties
65      private static final String PROPERTY_URL_ADR_COMPLETION = "address.teleservice.url.adr.completion";
66      private static final String PROPERTY_URL_ADR_LOCATION = "address.teleservice.url.adr.location";
67  
68      // constants (for synchro)
69      private static final String CONSTANT_KEY_FEATURES = "Features";
70      private static final String CONSTANT_KEY_ADDRESS_ID = "Idadrposte";
71      private static final String CONSTANT_KEY_ADDRESS_TYPO = "Adressetypo";
72      private static final String CONSTANT_KEY_PROPERTIES = "properties";
73      private static final String CONSTANT_KEY_NUM_DISTRICT = "Nqu";
74      private static final String CONSTANT_KEY_GEOLOCATION_X = "X";
75      private static final String CONSTANT_KEY_GEOLOCATION_Y = "Y";
76  
77      // constants
78      private static final String SECURITY_LOGGER_NAME = "lutece.security.http";
79  
80      /**
81       * @param request
82       *            Request
83       * @param searchTerm
84       * @return the XML flux of all adress corresponding
85       *
86       */
87      @Override
88      public ReferenceList searchAddress( HttpServletRequest request, String searchTerm )
89      {
90          ReferenceList list = null;
91  
92          try
93          {
94              String strUri = AppPropertiesService.getProperty( PROPERTY_URL_ADR_COMPLETION );
95  
96              HttpAccess ha = new HttpAccess( );
97              if ( StringUtil.containsXssCharacters( searchTerm ) )
98              {
99                  Logger logger = Logger.getLogger( SECURITY_LOGGER_NAME );
100                 logger.warn( "SECURITY WARNING : XSS CHARACTERS DETECTED : " + searchTerm );
101                 return null;
102             }
103 
104             String url = strUri + URLEncoder.encode( searchTerm, "UTF-8" ).replaceAll( "\\+", "%20" );
105             String strJson = ha.doGet( url );
106 
107             if ( strJson == null )
108             {
109                 AppLogService.info( "Error while getting URI : " + strUri + URLEncoder.encode( searchTerm, "UTF-8" ) );
110                 return null;
111             }
112 
113             ObjectMapper mapper = new ObjectMapper( );
114             JsonNode jsonNode = null;
115 
116             try
117             {
118                 jsonNode = mapper.readTree( strJson );
119             }
120             catch( IOException e )
121             {
122                 AppLogService.info( "Error while reading json : " + strJson );
123                 return null;
124             }
125 
126             return jsonToAddressList( jsonNode );
127 
128         }
129         catch( HttpAccessException | UnsupportedEncodingException e )
130         {
131             AppLogService.info( e );
132             return null;
133         }
134     }
135 
136     /**
137      * Build address referenceList from json
138      * 
139      * @param jsonNode
140      * @return address list
141      */
142     private static ReferenceList jsonToAddressList( JsonNode jsonNode )
143     {
144 
145         ReferenceList list = new ReferenceList( );
146         ArrayNode adrList = (ArrayNode) jsonNode;
147 
148         if ( adrList != null )
149         {
150             for ( JsonNode adr : adrList )
151             {
152                 JsonNode jsonAdrId = adr.get( CONSTANT_KEY_ADDRESS_ID );
153                 JsonNode jsonAdrTypo = adr.get( CONSTANT_KEY_ADDRESS_TYPO );
154 
155                 ReferenceItem item = new ReferenceItem( );
156                 item.setCode( jsonAdrId.asText( ) );
157                 item.setName( jsonAdrTypo.asText( ) );
158 
159                 list.add( item );
160             }
161         }
162 
163         return list;
164     }
165 
166     /**
167      * @param request
168      *            Request
169      * @param term
170      * @param strArrondissement
171      *            Arrondissement
172      * @return the XML flux of all adress corresponding
173      *
174      */
175     @Override
176     public ReferenceList searchAddress( HttpServletRequest request, String term, String strArrondissement )
177     {
178 
179         return searchAddress( request, term );
180     }
181 
182     /**
183      * @param request
184      *            Request
185      * @param idAdr
186      *            the adress id
187      * @return the XML flux of an adress
188      *
189      */
190     public Adresse getGeolocalisation( HttpServletRequest request, String idAdr )
191     {
192 
193         if ( StringUtil.containsXssCharacters( idAdr ) )
194         {
195             Logger logger = Logger.getLogger( SECURITY_LOGGER_NAME );
196             logger.warn( "SECURITY WARNING : XSS CHARACTERS DETECTED : " + idAdr );
197             return null;
198         }
199 
200         try
201         {
202             long id = Long.parseLong( idAdr );
203             return getGeolocalisation( request, id, null, null, false );
204         }
205         catch( NumberFormatException e )
206         {
207             return null;
208         }
209     }
210 
211     /**
212      * @param request
213      *            Request
214      * @param idAdr
215      *            the adress id
216      * @param strAddress
217      * @param strDate
218      * @param bIsTest
219      *            if true test connect at web service, if false search an adress
220      * @return the XML flux of an adress
221      *
222      */
223     @Override
224     public Adresse getGeolocalisation( HttpServletRequest request, long idAdr, String strAddress, String strDate, boolean bIsTest )
225     {
226         try
227         {
228             String strUri = AppPropertiesService.getProperty( PROPERTY_URL_ADR_LOCATION );
229 
230             HttpAccess ha = new HttpAccess( );
231 
232             String strJson = ha.doGet( strUri + String.valueOf( idAdr ) );
233 
234             if ( strJson == null )
235             {
236                 AppLogService.info( "Error while getting URI : " + strUri + idAdr );
237                 return null;
238             }
239 
240             ObjectMapper mapper = new ObjectMapper( );
241             JsonNode jsonNode;
242 
243             try
244             {
245                 jsonNode = mapper.readTree( strJson );
246             }
247             catch( IOException e )
248             {
249                 AppLogService.info( "Error while reading json : " + strJson );
250                 return null;
251             }
252 
253             return jsonToGeoloc( jsonNode );
254         }
255         catch( HttpAccessException e )
256         {
257             AppLogService.error( e );
258             return null;
259         }
260     }
261 
262     /**
263      * get sector numre from json
264      * 
265      * @param jsonNode
266      * @return the sector
267      */
268     private static Adresse jsonToGeoloc( JsonNode jsonNode )
269     {
270 
271         // Parse json
272         ArrayNode features = (ArrayNode) jsonNode.get( CONSTANT_KEY_FEATURES );
273         if ( features != null )
274         {
275             for ( JsonNode json : features )
276             {
277                 JsonNode properties = json.get( CONSTANT_KEY_PROPERTIES );
278                 if ( properties != null )
279                 {
280                     JsonNode jsonGeolocX = properties.get( CONSTANT_KEY_GEOLOCATION_X );
281                     JsonNode jsonGeolocY = properties.get( CONSTANT_KEY_GEOLOCATION_Y );
282 
283                     if ( jsonGeolocX != null )
284                     {
285                         Adresse adresseReturn = new Adresse( );
286 
287                         adresseReturn.setGeoX( jsonGeolocX.asLong( ) );
288                         adresseReturn.setGeoY( jsonGeolocY.asLong( ) );
289                     }
290 
291                 }
292             }
293         }
294 
295         // default
296         return null;
297     }
298 
299     /**
300      * @param request
301      *            Request
302      * @param id
303      *            the adress id
304      * @param bIsTest
305      *            if true test connect at web service, if false search an adress
306      * @return the XML flux of an adress
307      *
308      */
309     public Adresse getAdresseInfo( HttpServletRequest request, long id, boolean bIsTest )
310     {
311 
312         Adresse adresseReturn = new Adresse( );
313 
314         return adresseReturn;
315     }
316 
317     @Override
318     public ReferenceList searchAddress( HttpServletRequest request, String labeladresse, String strSRID, String strArrondissement ) throws RemoteException
319     {
320         throw new UnsupportedOperationException( "Not supported yet." ); // To change body of generated methods, choose Tools | Templates.
321     }
322 
323     @Override
324     public Adresse getGeolocalisation( HttpServletRequest request, String addresse, String date, boolean bIsTest ) throws RemoteException
325     {
326         return getGeolocalisation( request, addresse, date, bIsTest );
327     }
328 
329 }