001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.google.services.impl;
016    
017    import java.io.BufferedReader;
018    import java.io.IOException;
019    import java.io.InputStreamReader;
020    import java.net.Proxy;
021    import java.net.URISyntaxException;
022    import java.net.URL;
023    import java.net.URLConnection;
024    import java.util.List;
025    import java.util.Locale;
026    
027    import org.chenillekit.google.services.GoogleGeoCoder;
028    import org.chenillekit.google.utils.GeoCodeLocation;
029    import org.chenillekit.google.utils.JSONException;
030    import org.chenillekit.google.utils.JSONObject;
031    import org.chenillekit.google.utils.geocode.GeoCodeResult;
032    import org.slf4j.Logger;
033    
034    /**
035     * This service let you ues some Google Maps services in your application.
036     *
037     * @version $Id: GoogleGeoCoderImpl.java 594 2009-12-05 15:17:26Z mlusetti $
038     */
039    public class GoogleGeoCoderImpl extends AbstractGoogleService implements GoogleGeoCoder
040    {
041        private final Logger logger;
042    
043        /**
044         * standard constructor.
045         *
046         * @param logger         system logger
047         */
048        public GoogleGeoCoderImpl(Logger logger, String googleKey, int timeout, String referer, String proxy)
049        {
050            super(logger, googleKey, timeout, referer, proxy);
051            this.logger = logger;
052        }
053    
054        /**
055         * get the geo code from google map service for address.
056         *
057         * @param geoCodeLocation location holder
058         */
059        public GeoCodeResult getGeoCode(GeoCodeLocation geoCodeLocation)
060        {
061            return getGeoCode(geoCodeLocation.getStreet(), geoCodeLocation.getCountry(),
062                              geoCodeLocation.getState(), geoCodeLocation.getZipCode(), geoCodeLocation.getCity());
063        }
064    
065        /**
066         * get the geo code from google map service for address.
067         *
068         * @param street  the street
069         * @param country the country
070         * @param state   the state
071         * @param zipCode the zip code
072         * @param city    the city
073         */
074        public GeoCodeResult getGeoCode(String street, String country, String state, String zipCode, String city)
075        {
076            return getGeoCode(null, street, country, state, zipCode, city);
077        }
078    
079        /**
080         * get the geo code from google map service for address.
081         *
082         * @param street  the street
083         * @param country the country
084         * @param state   the state
085         * @param zipCode the zip code
086         * @param city    the city
087         */
088        public GeoCodeResult getGeoCode(Locale locale, String street, String country, String state, String zipCode, String city)
089        {
090            GeoCodeResult geoCodeResult;
091    
092            if (locale == null)
093                locale = Locale.getDefault();
094    
095            try
096            {
097                String queryString = String.format("%shttp://maps.google.com/maps/geo?q=%s,%s,%s,%s,%s&key=%s&gl=%s&output=json",
098                                                   getProxy(),
099                                                   getEncodedString(street),
100                                                   getEncodedString(country),
101                                                   getEncodedString(state),
102                                                   getEncodedString(zipCode),
103                                                   getEncodedString(city),
104                                                   getKey(),
105                                                   locale.getLanguage());
106    
107                if (logger.isDebugEnabled())
108                    logger.debug(String.format("send query '%s' to google maps", queryString));
109    
110    
111                URL url = new URL(queryString);
112                List<Proxy> proxies = getProxySelector().select(url.toURI());
113                URLConnection connection = url.openConnection(proxies.get(0));
114                connection.setConnectTimeout(getTimeout());
115                connection.setUseCaches(false);
116                connection.addRequestProperty("Referer", getReferer());
117    
118                String line;
119                StringBuilder builder = new StringBuilder();
120                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
121                while ((line = reader.readLine()) != null)
122                    builder.append(line);
123    
124                JSONObject jsonObject = new JSONObject(builder.toString());
125    
126                if (logger.isDebugEnabled())
127                    logger.debug("JSON result: {}", jsonObject.toString(1));
128    
129                geoCodeResult = new GeoCodeResult(jsonObject);
130    
131                if (geoCodeResult.getStatus().getCode() != 200)
132                {
133                    if (logger.isWarnEnabled())
134                        logger.warn("GoogleMapService receives an error code '{}'", geoCodeResult.getStatus().getCode());
135                }
136    
137                return geoCodeResult;
138            }
139            catch (IOException e)
140            {
141                throw new RuntimeException(e);
142            }
143            catch (URISyntaxException e)
144            {
145                throw new RuntimeException(e);
146            }
147            catch (JSONException e)
148            {
149                throw new RuntimeException(e);
150            }
151        }
152    }