package org.opensextant.xlayer; import java.io.IOException; import java.io.StringWriter; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.opensextant.ConfigException; import org.opensextant.extraction.TextMatch; import org.restlet.Application; import org.restlet.data.CharacterSet; import org.restlet.data.MediaType; import org.restlet.data.Parameter; import org.restlet.ext.json.JsonRepresentation; import org.restlet.representation.Representation; import org.restlet.resource.ClientResource; import org.restlet.resource.ResourceException; import org.restlet.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class XlayerClient extends Application { protected URL serviceAddress = null; private URI serviceURI = null; protected Logger log = LoggerFactory.getLogger(getClass()); protected final Context serviceContext = new Context(); private static final int ONE_SEC = 1000; /** 1 minute */ public static final String SO_TIMEOUT_STRING = new Integer(60 * ONE_SEC).toString(); /** 1 minutes */ public static final String READ_TIMEOUT_STRING = new Integer(60 * ONE_SEC).toString(); /* 5 seconds */ public static final String CONN_TIMEOUT_STRING = new Integer(5 * ONE_SEC).toString(); public XlayerClient(URL serviceAddr) throws ConfigException { serviceAddress = serviceAddr; try { serviceURI = serviceAddr.toURI(); } catch (Exception err) { throw new ConfigException("Bad Service Address", err); } /* * Not-so-super convincing timeout settings documented here: * http://restlet.com/technical-resources/restlet-framework/javadocs/2.3 * /jse/engine/org/restlet/engine/connector/HttpClientHelper.html * * Hard to find complete info on timeouts for HTTP in restlet. */ serviceContext.getParameters().add(new Parameter("socketTimeout", SO_TIMEOUT_STRING)); serviceContext.getParameters().add(new Parameter("readTimeout", READ_TIMEOUT_STRING)); serviceContext.getParameters().add(new Parameter("socketConnectTimeoutMs", CONN_TIMEOUT_STRING)); } /** * * @param text * @return * @throws IOException * @throws JSONException */ public List<TextMatch> process(String docid, String text) throws IOException, JSONException { ClientResource client = new ClientResource(serviceContext, serviceURI); org.json.JSONObject content = new JSONObject(); content.put("text", text); content.put("docid", docid); content.put("features", "places,coordinates,countries,persons,orgs,reverse-geocode"); /* Coordinates mainly are XY locations; Reverse Geocode them to find what country the location resides */ StringWriter data = new StringWriter(); try { Representation repr = new JsonRepresentation(content.toString()); repr.setCharacterSet(CharacterSet.UTF_8); //log.debug("CLIENT {} {}", serviceAddress, client); // Process and read response fully. Representation response = client.post(repr, MediaType.APPLICATION_JSON); response.write(data); response.exhaust(); response.release(); JSONObject json = new JSONObject(data.toString()); log.debug("POST: response {}", json.toString(2)); JSONObject meta = json.getJSONObject("response"); JSONArray annots = json.getJSONArray("annotations"); List<TextMatch> matches = new ArrayList<TextMatch>(); for (int x = 0; x < annots.length(); ++x) { Object m = annots.get(x); matches.add(Transforms.parseAnnotation(m)); } return matches; } catch (ResourceException restErr) { if (restErr.getCause() instanceof IOException) { throw (IOException) restErr.getCause(); } else { throw restErr; } } catch (java.net.SocketException err) { throw err; // This never happens. Restlet wraps everything. } finally { client.release(); } } }