package org.limewire.geocode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.limewire.http.httpclient.LimeHttpClient;
import com.google.inject.Inject;
import com.google.inject.Provider;
final class GeocoderImpl implements Geocoder {
// private static final Log LOG = LogFactory.getLog(GeocoderImpl.class);
private final Provider<String> geoCodeURL;
private final Provider<LimeHttpClient> httpClient;
private GeocodeInformation info;
private boolean failed;
@Inject
public GeocoderImpl(@GeocodeUrl Provider<String> geoCodeURL,
Provider<LimeHttpClient> client) {
this.geoCodeURL = geoCodeURL;
this.httpClient = client;
}
public void initialize() {
String url = geoCodeURL.get();
if(url == null || url.equals("")) {
failed = true;
return;
}
HttpGet get = new HttpGet(url);
LimeHttpClient client = httpClient.get();
HttpResponse response = null;
try {
//System.out.println("GeocodeImpl.initialize: calling client.execute");
// TODO: The following call seems to hang on some systems.
response = client.execute(get);
//System.out.println("GeocodeImpl.initialize: response = " + response);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
if(entity != null) {
String charset = EntityUtils.getContentCharSet(entity);
setGeocodeInformation(entity.getContent(), charset != null ? charset : HTTP.DEFAULT_CONTENT_CHARSET);
return;
}
}
failed = true;
} catch (IOException e) {
failed = true;
} finally {
client.releaseConnection(response);
}
}
public GeocodeInformation getGeocodeInformation() {
return info;
}
public boolean isReady() {
return hasFailed() || info != null;
}
public boolean hasFailed() {
return failed;
}
public void clear() {
info = null;
}
/**
* Read the lines and set the fields appropriately. The fields will be
* name/value pairs separated by tabs (i.e. <code>\t</code>). The name
* correspond to the set method on {@link GeocodeInformationImpl}.
* <p>
* For example: <code>countryName United States</code> would cause a call
* to <code>g.setCountryName("United States").
*
* @param is input lines of the form
* <blockquote>
* <first line ignored><br>
* ( String[<em>Name</em>] <tab> String[<em>Value</em>] <newline> )<br>
* [ repeat name/value pairs ]
* </blockquote>
* @param charset
* @throws java.io.IOException
*/
protected void setGeocodeInformation(InputStream is, String charset) throws IOException {
GeocodeInformation res = new GeocodeInformation();
String separator = "\t";
BufferedReader in = new BufferedReader(new InputStreamReader(is, charset));
in.readLine(); // ignore the first line
String line;
while ((line = in.readLine()) != null) {
if (line.equals("") || line.startsWith("#")) {
continue;
}
String[] parts = line.split(separator);
if (parts.length < 2) {
continue;
}
String name = parts[0];
String value = parts[1];
res.setProperty(name, value);
}
this.info = res;
}
}