/** * Copyright 2010-present Facebook * * 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 com.facebook.android; import android.app.AlertDialog.Builder; import android.content.Context; import android.os.Bundle; import com.facebook.internal.Utility; import org.json.JSONException; import org.json.JSONObject; import java.io.*; import java.net.*; /** * Utility class supporting the Facebook Object. * <p/> * THIS CLASS SHOULD BE CONSIDERED DEPRECATED. * <p/> * All public members of this class are intentionally deprecated. * New code should instead use * {@link com.facebook.Request} * <p/> * Adding @Deprecated to this class causes warnings in other deprecated classes * that reference this one. That is the only reason this entire class is not * deprecated. * * @devDocDeprecated */ public final class Util { private final static String UTF8 = "UTF-8"; /** * Generate the multi-part post body providing the parameters and boundary * string * * @param parameters the parameters need to be posted * @param boundary the random string as boundary * @return a string of the post body */ @Deprecated public static String encodePostBody(Bundle parameters, String boundary) { if (parameters == null) return ""; StringBuilder sb = new StringBuilder(); for (String key : parameters.keySet()) { Object parameter = parameters.get(key); if (!(parameter instanceof String)) { continue; } sb.append("Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n" + (String)parameter); sb.append("\r\n" + "--" + boundary + "\r\n"); } return sb.toString(); } @Deprecated public static String encodeUrl(Bundle parameters) { if (parameters == null) { return ""; } StringBuilder sb = new StringBuilder(); boolean first = true; for (String key : parameters.keySet()) { Object parameter = parameters.get(key); if (!(parameter instanceof String)) { continue; } if (first) first = false; else sb.append("&"); sb.append(URLEncoder.encode(key) + "=" + URLEncoder.encode(parameters.getString(key))); } return sb.toString(); } @Deprecated public static Bundle decodeUrl(String s) { Bundle params = new Bundle(); if (s != null) { String array[] = s.split("&"); for (String parameter : array) { String v[] = parameter.split("="); try { if (v.length == 2) { params.putString(URLDecoder.decode(v[0], UTF8), URLDecoder.decode(v[1], UTF8)); } else if (v.length == 1) { params.putString(URLDecoder.decode(v[0], UTF8), ""); } } catch (UnsupportedEncodingException e) { // shouldn't happen } } } return params; } /** * Parse a URL query and fragment parameters into a key-value bundle. * * @param url the URL to parse * @return a dictionary bundle of keys and values */ @Deprecated public static Bundle parseUrl(String url) { // hack to prevent MalformedURLException url = url.replace("fbconnect", "http"); try { URL u = new URL(url); Bundle b = decodeUrl(u.getQuery()); b.putAll(decodeUrl(u.getRef())); return b; } catch (MalformedURLException e) { return new Bundle(); } } /** * Connect to an HTTP URL and return the response as a string. * * Note that the HTTP method override is used on non-GET requests. (i.e. * requests are made as "POST" with method specified in the body). * * @param url - the resource to open: must be a welformed URL * @param method - the HTTP method to use ("GET", "POST", etc.) * @param params - the query parameter for the URL (e.g. access_token=foo) * @return the URL contents as a String * @throws MalformedURLException - if the URL format is invalid * @throws IOException - if a network problem occurs */ @Deprecated public static String openUrl(String url, String method, Bundle params) throws MalformedURLException, IOException { // random string as boundary for multi-part http post String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f"; String endLine = "\r\n"; OutputStream os; if (method.equals("GET")) { url = url + "?" + encodeUrl(params); } Utility.logd("Facebook-Util", method + " URL: " + url); HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestProperty("User-Agent", System.getProperties(). getProperty("http.agent") + " FacebookAndroidSDK"); if (!method.equals("GET")) { Bundle dataparams = new Bundle(); for (String key : params.keySet()) { Object parameter = params.get(key); if (parameter instanceof byte[]) { dataparams.putByteArray(key, (byte[])parameter); } } // use method override if (!params.containsKey("method")) { params.putString("method", method); } if (params.containsKey("access_token")) { String decoded_token = URLDecoder.decode(params.getString("access_token")); params.putString("access_token", decoded_token); } conn.setRequestMethod("POST"); conn.setRequestProperty( "Content-Type", "multipart/form-data;boundary="+strBoundary); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestProperty("Connection", "Keep-Alive"); conn.connect(); os = new BufferedOutputStream(conn.getOutputStream()); os.write(("--" + strBoundary +endLine).getBytes()); os.write((encodePostBody(params, strBoundary)).getBytes()); os.write((endLine + "--" + strBoundary + endLine).getBytes()); if (!dataparams.isEmpty()) { for (String key: dataparams.keySet()){ os.write(("Content-Disposition: form-data; filename=\"" + key + "\"" + endLine).getBytes()); os.write(("Content-Type: content/unknown" + endLine + endLine).getBytes()); os.write(dataparams.getByteArray(key)); os.write((endLine + "--" + strBoundary + endLine).getBytes()); } } os.flush(); } String response = ""; try { response = read(conn.getInputStream()); } catch (FileNotFoundException e) { // Error Stream contains JSON that we can parse to a FB error response = read(conn.getErrorStream()); } return response; } @Deprecated private static String read(InputStream in) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000); for (String line = r.readLine(); line != null; line = r.readLine()) { sb.append(line); } in.close(); return sb.toString(); } /** * Parse a server response into a JSON Object. This is a basic * implementation using org.json.JSONObject representation. More * sophisticated applications may wish to do their own parsing. * * The parsed JSON is checked for a variety of error fields and * a FacebookException is thrown if an error condition is set, * populated with the error message and error type or code if * available. * * @param response - string representation of the response * @return the response as a JSON Object * @throws JSONException - if the response is not valid JSON * @throws FacebookError - if an error condition is set */ @Deprecated public static JSONObject parseJson(String response) throws JSONException, FacebookError { // Edge case: when sending a POST request to /[post_id]/likes // the return value is 'true' or 'false'. Unfortunately // these values cause the JSONObject constructor to throw // an exception. if (response.equals("false")) { throw new FacebookError("request failed"); } if (response.equals("true")) { response = "{value : true}"; } JSONObject json = new JSONObject(response); // errors set by the server are not consistent // they depend on the method and endpoint if (json.has("error")) { JSONObject error = json.getJSONObject("error"); throw new FacebookError( error.getString("message"), error.getString("type"), 0); } if (json.has("error_code") && json.has("error_msg")) { throw new FacebookError(json.getString("error_msg"), "", Integer.parseInt(json.getString("error_code"))); } if (json.has("error_code")) { throw new FacebookError("request failed", "", Integer.parseInt(json.getString("error_code"))); } if (json.has("error_msg")) { throw new FacebookError(json.getString("error_msg")); } if (json.has("error_reason")) { throw new FacebookError(json.getString("error_reason")); } return json; } /** * Display a simple alert dialog with the given text and title. * * @param context * Android context in which the dialog should be displayed * @param title * Alert dialog title * @param text * Alert dialog message */ @Deprecated public static void showAlert(Context context, String title, String text) { Builder alertBuilder = new Builder(context); alertBuilder.setTitle(title); alertBuilder.setMessage(text); alertBuilder.create().show(); } }