Created
February 19, 2012 05:52
-
-
Save zaneli/1862190 to your computer and use it in GitHub Desktop.
「remember the milk API 用 Java クライアントを作る(1)」ブログ用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm.model.util; | |
import java.util.HashMap; | |
import java.util.Map; | |
import com.zaneli.rtm.RtmException; | |
public class AuthUtil { | |
private static final String URL = "http://www.rememberthemilk.com/services/auth/"; | |
public static String createAuthUrl( | |
String apikey, String sharedSecret, Perms perms, String frob) throws RtmException { | |
Map<String, String> params = new HashMap<String, String>(); | |
params.put("api_key", apikey); | |
params.put("perms", perms.getValue()); | |
params.put("frob", frob); | |
params.put("api_sig", RtmUtil.createApiSig(sharedSecret, params)); | |
return RtmUtil.createQueryUrl(URL, params); | |
} | |
public enum Perms { | |
READ("read"), READ_WRITE("write"), ALL("delete"); | |
private final String value; | |
private Perms(String value) { | |
this.value = value; | |
} | |
public String getValue() { | |
return value; | |
} | |
} | |
private AuthUtil() {}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm.model; | |
public class GetFrobResult extends Result { | |
public String getFrob() { | |
return (String) getRsp().get("frob"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm.model; | |
import java.util.Map; | |
public class GetTokenResult extends Result { | |
public String getToken() { | |
return (String) getAuth().get("token"); | |
} | |
public String getPerms() { | |
return (String) getAuth().get("perms"); | |
} | |
public int getUserId() { | |
return ((Integer) getUser().get("id")).intValue(); | |
} | |
public int getUserName() { | |
return ((Integer) getUser().get("username")).intValue(); | |
} | |
public int getFullName() { | |
return ((Integer) getUser().get("fullname")).intValue(); | |
} | |
@SuppressWarnings("unchecked") | |
private Map<String, Object> getAuth() { | |
return (Map<String, Object>) getRsp().get("auth"); | |
} | |
@SuppressWarnings("unchecked") | |
private Map<String, Object> getUser() { | |
return (Map<String, Object>) getAuth().get("user"); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm.model; | |
import java.util.Map; | |
import org.apache.commons.lang3.builder.EqualsBuilder; | |
import org.apache.commons.lang3.builder.HashCodeBuilder; | |
import org.apache.commons.lang3.builder.ToStringBuilder; | |
import com.zaneli.rtm.RtmException; | |
public abstract class Result { | |
private Map<String, Object> rsp; | |
public String getStat() { | |
return (String) getRsp().get("stat"); | |
} | |
@SuppressWarnings("unchecked") | |
public RtmException getErr() { | |
return new RtmException((Map<String, Object>) rsp.get("err")); | |
} | |
public void setRsp(Map<String, Object> rsp) { | |
this.rsp = rsp; | |
} | |
protected Map<String, Object> getRsp() { | |
return rsp; | |
} | |
@Override | |
public String toString() { | |
return ToStringBuilder.reflectionToString(this); | |
} | |
@Override | |
public boolean equals(Object obj) { | |
return EqualsBuilder.reflectionEquals(this, obj); | |
} | |
@Override | |
public int hashCode() { | |
return HashCodeBuilder.reflectionHashCode(this); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.UnsupportedEncodingException; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import net.arnx.jsonic.JSON; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.NameValuePair; | |
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.entity.UrlEncodedFormEntity; | |
import org.apache.http.client.methods.HttpPost; | |
import org.apache.http.client.methods.HttpRequestBase; | |
import org.apache.http.impl.client.DefaultHttpClient; | |
import org.apache.http.message.BasicNameValuePair; | |
import org.apache.http.protocol.HTTP; | |
import com.zaneli.rtm.model.GetFrobResult; | |
import com.zaneli.rtm.model.GetTokenResult; | |
import com.zaneli.rtm.model.Result; | |
import com.zaneli.rtm.model.util.RtmUtil; | |
public class RtmClient { | |
private static final String URL = "https://api.rememberthemilk.com/services/rest/"; | |
private final String apikey; | |
private final String sharedSecret; | |
public RtmClient(String apikey, String sharedSecret) { | |
this.apikey = apikey; | |
this.sharedSecret = sharedSecret; | |
} | |
public GetFrobResult getFrob() throws RtmException, IOException { | |
Map<String, String> params = new HashMap<String, String>(); | |
params.put("method", "rtm.auth.getFrob"); | |
params.put("api_key", apikey); | |
params.put("format", "json"); | |
params.put("api_sig", RtmUtil.createApiSig(sharedSecret, params)); | |
HttpPost request = new HttpPost(URL); | |
request.setEntity(createEntity(params)); | |
return execute(request, GetFrobResult.class); | |
} | |
public GetTokenResult getToken(String frob) throws RtmException, IOException { | |
Map<String, String> params = new HashMap<String, String>(); | |
params.put("method", "rtm.auth.getToken"); | |
params.put("api_key", apikey); | |
params.put("frob", frob); | |
params.put("format", "json"); | |
params.put("api_sig", RtmUtil.createApiSig(sharedSecret, params)); | |
HttpPost request = new HttpPost(URL); | |
request.setEntity(createEntity(params)); | |
return execute(request, GetTokenResult.class); | |
} | |
private <T extends Result> T execute( | |
HttpRequestBase request, | |
Class<? extends T> resultClass) throws IOException, RtmException { | |
HttpClient httpClient = new DefaultHttpClient(); | |
HttpResponse response = httpClient.execute(request); | |
InputStream in = null; | |
try { | |
in = response.getEntity().getContent(); | |
T result = JSON.decode(in, resultClass); | |
String stat = result.getStat(); | |
if ("ok".equals(stat)) { | |
return result; | |
} else if ("fail".equals(stat)) { | |
throw result.getErr(); | |
} else { | |
throw new IllegalStateException("stat=" + stat); | |
} | |
} finally { | |
if (in != null) in.close(); | |
} | |
} | |
private UrlEncodedFormEntity createEntity(Map<String, String> params) throws RtmException { | |
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); | |
for (Entry<String, String> entry : params.entrySet()) { | |
nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); | |
} | |
try { | |
return new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8); | |
} catch (UnsupportedEncodingException e) { | |
throw new RtmException(e); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm; | |
import java.util.Map; | |
@SuppressWarnings("serial") | |
public class RtmException extends Exception { | |
public RtmException(Map<String, Object> errMap) { | |
super("code=" + errMap.get("code") + ", msg=" + errMap.get("msg")); | |
} | |
public RtmException(Throwable cause) { | |
super(cause); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.zaneli.rtm.model.util; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import java.util.TreeMap; | |
import com.zaneli.rtm.RtmException; | |
public class RtmUtil { | |
public static String createQueryUrl(String url, Map<String, String> queryParams) { | |
StringBuilder sb = new StringBuilder(url); | |
sb.append('?'); | |
for (Entry<String, String> entry : queryParams.entrySet()) { | |
sb.append(entry.getKey()).append('=').append(entry.getValue()).append('&'); | |
} | |
return sb.substring(0, sb.length() - 1).toString(); | |
} | |
public static String createApiSig(String sharedSecret, Map<String, String> params) throws RtmException { | |
Map<String, String> sortedParams = new TreeMap<String, String>(params); | |
StringBuilder sb = new StringBuilder(sharedSecret); | |
for (Entry<String, String> entry : sortedParams.entrySet()) { | |
sb.append(entry.getKey()); | |
sb.append(entry.getValue()); | |
} | |
try { | |
return digest(sb.toString()); | |
} catch (NoSuchAlgorithmException e) { | |
throw new RtmException(e); | |
} | |
} | |
private static String digest(String value) throws NoSuchAlgorithmException { | |
MessageDigest md = MessageDigest.getInstance("MD5"); | |
md.update(value.getBytes()); | |
return toHexString(md.digest()); | |
} | |
private static String toHexString(byte[] byteArray) { | |
StringBuilder sb = new StringBuilder(); | |
for (byte b : byteArray) { | |
String hexStr = Integer.toHexString(b & 0xff); | |
if (hexStr.length() == 1) { | |
sb.append("0"); | |
} | |
sb.append(hexStr); | |
} | |
return sb.toString(); | |
} | |
private RtmUtil() {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment