Java tutorial
/* * Copyright 2009, Arjan Scherpenisse <arjan@scherpenisse.net> * See LICENSE for details. */ package net.anymeta; import java.io.DataInput; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.*; import org.apache.commons.codec.binary.Base64; import org.apache.http.NameValuePair; import org.apache.http.client.*; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.*; import org.apache.http.impl.client.*; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.CoreProtocolPNames; import org.json.*; import oauth.signpost.OAuthConsumer; import oauth.signpost.commonshttp.*; import oauth.signpost.exception.*; import oauth.signpost.signature.SignatureMethod;; /** * Main API access class. Implements synchronous access to an AnyMeta site. * * @author arjan */ public class AnyMetaAPI { public String entrypoint; private String ckey; private String csec; private String tkey; private String tsec; /** * Create a AnyMetaAPI instance by specifying the entry point and * OAuth credentials. It is often easier to use the "fromRegistry" * method to separate your code and your OAuth secrets. * * @param entrypoint * @param ckey * @param csec * @param tkey * @param tsec */ public AnyMetaAPI(String entrypoint, String ckey, String csec, String tkey, String tsec) { this.entrypoint = entrypoint; this.ckey = ckey; this.csec = csec; this.tkey = tkey; this.tsec = tsec; } /** * Load a AnyMetaAPI object from the registry. * * @param identifier The registry identifier. * @return A valid AnyMetaAPI object which can be used to access the site. * @throws AnyMetaRegistryException */ public static AnyMetaAPI fromRegistry(String identifier) throws AnyMetaRegistryException { AnyMetaRegistry reg = AnyMetaRegistry.getInstance(); Map<String, String> values = reg.get(identifier); String ckey = values.get("c_key"); String csec = values.get("c_sec"); String tkey = values.get("t_key"); String tsec = values.get("t_sec"); String entrypoint = values.get("entrypoint"); return new AnyMetaAPI(entrypoint, ckey, csec, tkey, tsec); } public String toString() { return "<AnyMetaAPI: " + this.entrypoint + ">"; } /** * Execute the given API call onto the anymeta instance. * * @param method The method. * @return A JSONObject with the response. * @throws AnyMetaException */ public Object doMethod(String method) throws AnyMetaException { return this.doMethod(method, new HashMap<String, Object>()); } /** * Execute the given API call onto the anymeta instance, with arguments. * * @param method The method, e.g. "anymeta.user.info" * @param args Arguments to give to the call. * @return A JSONObject or JSONArray with the response. * @throws AnyMetaException */ public Object doMethod(String method, Map<String, Object> args) throws AnyMetaException { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("method", method)); params.add(new BasicNameValuePair("format", "json")); convertParameters((Object) args, params, null); String url = this.entrypoint; OAuthConsumer consumer = new CommonsHttpOAuthConsumer(this.ckey, this.csec, SignatureMethod.PLAINTEXT); consumer.setTokenWithSecret(this.tkey, this.tsec); HttpPost request = new HttpPost(url); request.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false); // set up httppost try { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8"); request.setEntity(entity); } catch (UnsupportedEncodingException e) { throw new AnyMetaException(e.getMessage()); } try { consumer.sign(request); } catch (OAuthMessageSignerException e) { throw new AnyMetaException(e.getMessage()); } catch (OAuthExpectationFailedException e) { throw new AnyMetaException(e.getMessage()); } DefaultHttpClient client = new DefaultHttpClient(); ResponseHandler<String> handler = new BasicResponseHandler(); String response = ""; try { response = client.execute(request, handler); } catch (IOException e) { throw new AnyMetaException(e.getMessage()); } if (response.equalsIgnoreCase("null") || response.equalsIgnoreCase("false")) { return null; } if (!response.startsWith("[") && !response.startsWith("{")) { response = "{\"result\": " + response + "}"; } // System.out.println(response); Object o; try { o = new JSONObject(response); } catch (JSONException e) { try { o = new JSONArray(response); } catch (JSONException e2) { throw new AnyMetaException(e.getMessage() + ": response=" + response); } } if (o instanceof JSONObject && ((JSONObject) o).has("err")) { // handle error try { JSONObject err = ((JSONObject) o).getJSONObject("err").getJSONObject("-attrib-"); throw new AnyMetaException(err.getString("code") + ": " + err.getString("msg")); } catch (JSONException e) { throw new AnyMetaException("Unexpected response in API error: response=" + response); } } return o; } /** * Recursively descend the args structure to convert each to * form-encoded params. */ private void convertParameters(Object arg, List<NameValuePair> params, String prefix) throws AnyMetaException { if (arg instanceof String) { String value = (String) arg; if (value.charAt(0) == '@') { // try to do some file-magic try { File f = new File(value.substring(1)); if (f.exists() && f.canRead()) { byte[] buf = new byte[(int) f.length()]; FileInputStream fis = new FileInputStream(f); fis.read(buf); value = new String(Base64.encodeBase64(buf)); } } catch (IOException e) { throw new AnyMetaException(e.getMessage()); } } params.add(new BasicNameValuePair(prefix, value)); } else if (arg instanceof Map) { Map<String, Object> m = (Map<String, Object>) arg; for (String k : m.keySet()) { Object value = ((Map<String, Object>) arg).get(k); convertParameters(value, params, (prefix != null) ? prefix + "[" + k + "]" : k); } } else if (arg instanceof List) { if (prefix == null) { throw new AnyMetaException("Cannot use list as first level of API arguments"); } for (int i = 0; i < ((List) arg).size(); i++) { Object value = ((List) arg).get(i); convertParameters(value, params, prefix + "[" + i + "]"); } } else { throw new AnyMetaException("Unsupported argument type"); } } }