Java tutorial
/******************************************************************************* * Copyright 2012 Crazywater * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.knufficast.flattr; import java.io.IOException; import java.net.URLEncoder; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.json.JSONException; import org.json.JSONObject; import android.net.Uri; import android.util.Base64; import de.knufficast.App; import de.knufficast.logic.FlattrConfiguration; import de.knufficast.logic.FlattrConfiguration.FlattrStatus; import de.knufficast.util.BooleanCallback; import de.knufficast.util.HttpUtil; /** * A class that communicates with Flattr via REST. * * @author crazywater * */ public class FlattrApi { private static final IFlattrConstants CONSTANTS = new FlattrConstants(); private static final String LOGIN_URL = "https://flattr.com/oauth/token"; private static final String LOOKUP_URL = "https://api.flattr.com/rest/v2/things/lookup/?url=%s"; private static final String FLATTR_URL = "https://api.flattr.com/rest/v2/flattr"; public static final String ERROR_AUTHORIZATION = "Not authorized"; public static final String ERROR_JSON = "JSON Error"; public static final String ERROR_NO_MEANS = "No means"; public static final String ERROR_CONNECTION = "Connection Error"; public static final String ERROR_NOT_FOUND = "Not found"; private final HttpUtil httpUtil = new HttpUtil(); private final FlattrConfiguration config = App.get().getConfiguration().getFlattrConfig(); private void login() { try { JSONObject json = new JSONObject(); json.put("code", config.getAuthCode()); json.put("grant_type", "authorization_code"); json.put("redirect_uri", "knufficastoauth://"); // the client ID and secret are used as username and password // encode username and password using base64 user:password (BASIC auth for // http) String userPassword = "Basic " + new String(Base64.encode( (CONSTANTS.getClientId() + ":" + CONSTANTS.getClientSecret()).getBytes(), Base64.NO_WRAP)); JSONObject response = postAuthorized(LOGIN_URL, json, userPassword); if (response.getString("access_token") != null) { config.setAccessToken(response.getString("access_token")); config.setFlattrStatus(FlattrStatus.AUTHENTICATED); } else { config.resetAuthentication(); } } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { config.resetAuthentication(); } } private JSONObject lookup(final String flattrUrl) throws JSONException, IOException { String authorization = getTokenAuthorization(); if (authorization == null) { return null; } String encodedUrl = URLEncoder.encode(flattrUrl); String requestUrl = String.format(LOOKUP_URL, encodedUrl); return getAuthorized(requestUrl, authorization); } /** * Flattrs a thing. */ public void flattr(final String flattrUrl, final BooleanCallback<String, String> callback) { runOnThread(new Runnable() { @Override public void run() { try { JSONObject request = new JSONObject(); request.put("url", flattrUrl); String authorization = getTokenAuthorization(); if (authorization == null) { callback.fail(ERROR_AUTHORIZATION); } JSONObject result = postAuthorized(FLATTR_URL, request, authorization); if (result.has("error")) { if (result.getString("error").equals("no_means")) { config.setFlattrStatus(FlattrStatus.NO_MEANS); callback.fail(ERROR_NO_MEANS); } else if (result.getString("error").equals("flattr_once")) { callback.success(flattrUrl); } else if (result.getString("error").equals("unauthorized")) { config.setFlattrStatus(FlattrStatus.NOT_AUTHENTICATED); callback.fail(ERROR_AUTHORIZATION); } else { callback.fail(ERROR_NOT_FOUND); } } if (!result.has("message")) { throw new JSONException("No message field"); } else { String str = result.getString("message"); if ("ok".equals(str)) { callback.success(flattrUrl); } else { throw new JSONException("Message field is not ok"); } } } catch (JSONException e) { callback.fail(ERROR_JSON); } catch (IOException e) { callback.fail(ERROR_CONNECTION); } } }); } /** * Inform this client of an OAuth response. * * @param data * the URI of the OAuth response */ public void setOauthResponse(final String data) { runOnThread(new Runnable() { @Override public void run() { Uri uri = Uri.parse(data); FlattrConfiguration config = App.get().getConfiguration().getFlattrConfig(); config.setFlattrStatus(FlattrStatus.AUTHENTICATING); if (uri.getQueryParameter("code") != null) { config.setAuthCode(uri.getQueryParameter("code")); login(); } else { config.setFlattrStatus(FlattrStatus.ERROR); } } }); } /** * Asks the flattr servers whether a thing has been flattred. */ public void isFlattred(final String flattrUrl, final BooleanCallback<Boolean, String> callback) { runOnThread(new Runnable() { @Override public void run() { try { JSONObject thing = lookup(flattrUrl); if (thing == null) { callback.fail(ERROR_CONNECTION); return; } if (thing.has("flattred")) { boolean result = thing.getBoolean("flattred"); callback.success(result); } else if (thing.has("message")) { if ("flattrable".equals(thing.getString("message"))) { // thing is flattrable but hasn't been flattred yet callback.success(false); } else { callback.fail(ERROR_JSON); } } else { callback.fail(ERROR_JSON); } } catch (JSONException e) { callback.fail(ERROR_JSON); } catch (IOException e) { callback.fail(ERROR_CONNECTION); } } }); } private void runOnThread(Runnable runnable) { Thread thread = new Thread(runnable); thread.start(); } private String getTokenAuthorization() { String accessToken = config.getAccessToken(); if (accessToken == null) { return null; } return "Bearer " + accessToken; } private JSONObject getAuthorized(String httpsUrl, String authorization) throws JSONException, IOException { HttpGet request = new HttpGet(httpsUrl); request.addHeader("Authorization", authorization); return httpUtil.getJson(request); } private JSONObject postAuthorized(String httpsUrl, JSONObject contents, String authorization) throws JSONException, IOException { HttpPost request = new HttpPost(httpsUrl); request.addHeader("Authorization", authorization); request.addHeader("content-type", "application/json"); if (contents != null) { StringEntity params = new StringEntity(contents.toString()); request.setEntity(params); } return httpUtil.getJson(request); } }