Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.android.authenticator.rest; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.auth.AuthenticationException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.params.ConnManagerParams; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.accounts.Account; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.util.Xml; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Provides utility methods for communicating with the server. */ final public class XWikiConnector { /** The tag used to log to adb console. */ private static final String TAG = "NetworkUtilities"; /** POST parameter name for the user's account name */ public static final String PARAM_USERNAME = "username"; /** POST parameter name for the user's password */ public static final String PARAM_PASSWORD = "password"; /** POST parameter name for the user's authentication token */ public static final String PARAM_AUTH_TOKEN = "authtoken"; /** POST parameter name for the client's last-known sync state */ public static final String PARAM_SYNC_STATE = "syncstate"; /** POST parameter name for the sending client-edited contact info */ public static final String PARAM_CONTACTS_DATA = "contacts"; /** Timeout (in ms) we specify for each http request */ public static final int HTTP_REQUEST_TIMEOUT_MS = 30 * 1000; /** Base URL for the v2 Sample Sync Service */ public static final String BASE_URL = "https://samplesyncadapter2.appspot.com"; /** URI for authentication service */ public static final String AUTH_URI = BASE_URL + "/auth"; /** URI for sync service */ public static final String SYNC_CONTACTS_URI = BASE_URL + "/sync"; private XWikiConnector() { } /** * Configures the httpClient to connect to the URL provided. */ public static HttpClient getHttpClient() { HttpClient httpClient = new DefaultHttpClient(); final HttpParams params = httpClient.getParams(); HttpConnectionParams.setConnectionTimeout(params, HTTP_REQUEST_TIMEOUT_MS); HttpConnectionParams.setSoTimeout(params, HTTP_REQUEST_TIMEOUT_MS); ConnManagerParams.setTimeout(params, HTTP_REQUEST_TIMEOUT_MS); return httpClient; } public static HttpGet createHtpGet(String url, String user, String pass) { HttpGet httpGet = new HttpGet(url); httpGet.addHeader("Authorization", "Basic " + Base64.encodeToString((user + ':' + pass).getBytes(), Base64.NO_WRAP)); HttpParams params = new BasicHttpParams(); params.setParameter("username", user); params.setParameter("password", pass); httpGet.setParams(params); httpGet.addHeader("Accept", "application/xml"); return httpGet; } public static HttpResponse executeGet(String url, String user, String pass) throws IOException { HttpClient httpClient = getHttpClient(); HttpGet httpGet = createHtpGet(url, user, pass); return httpClient.execute(httpGet); } public static XmlPullParser getXML(String url, String user, String pass) throws IOException, XmlPullParserException { HttpResponse response = executeGet(url, user, pass); int error = response.getStatusLine().getStatusCode(); if (error != HttpStatus.SC_OK) { throw new IOException("Error getting [" + url + "] with error code [" + error + ", " + response.getStatusLine() + "]"); } XmlPullParser parser = Xml.newPullParser(); parser.setInput(response.getEntity().getContent(), null); return parser; } public static String userSignIn(String server, String user, String pass, String authType) throws Exception { Log.d("xwiki", "userSignIn"); DefaultHttpClient httpClient = new DefaultHttpClient(); String url = server + "/rest/"; HttpGet httpGet = new HttpGet(url); httpGet.addHeader("Authorization", "Basic " + Base64.encodeToString((user + ':' + pass).getBytes(), Base64.NO_WRAP)); HttpParams params = new BasicHttpParams(); params.setParameter("username", user); params.setParameter("password", pass); httpGet.setParams(params); HttpResponse response = httpClient.execute(httpGet); int error = response.getStatusLine().getStatusCode(); if (error != 200) { throw new Exception("Error signing-in [" + url + "] with error code [" + error + "]"); } return null; } /** * Connects to the SampleSync test server, authenticates the provided * username and password. * * @param username The server account username * @param password The server account password * @return String The authentication token returned by the server (or null) */ public static String authenticate(String username, String password) { final HttpResponse resp; final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair(PARAM_USERNAME, username)); params.add(new BasicNameValuePair(PARAM_PASSWORD, password)); final HttpEntity entity; try { entity = new UrlEncodedFormEntity(params); } catch (final UnsupportedEncodingException e) { // this should never happen. throw new IllegalStateException(e); } Log.i(TAG, "Authenticating to: " + AUTH_URI); final HttpPost post = new HttpPost(AUTH_URI); post.addHeader(entity.getContentType()); post.setEntity(entity); try { resp = getHttpClient().execute(post); String authToken = null; if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { InputStream istream = (resp.getEntity() != null) ? resp.getEntity().getContent() : null; if (istream != null) { BufferedReader ireader = new BufferedReader(new InputStreamReader(istream)); authToken = ireader.readLine().trim(); } } if ((authToken != null) && (authToken.length() > 0)) { Log.v(TAG, "Successful authentication"); return authToken; } else { Log.e(TAG, "Error authenticating" + resp.getStatusLine()); return null; } } catch (final IOException e) { Log.e(TAG, "IOException when getting authtoken", e); return null; } finally { Log.v(TAG, "getAuthtoken completing"); } } /** * Download the avatar image from the server. * * @param avatarUrl the URL pointing to the avatar image * @return a byte array with the raw JPEG avatar image */ public static byte[] downloadAvatar(final String avatarUrl) { // If there is no avatar, we're done if (TextUtils.isEmpty(avatarUrl)) { return null; } try { Log.i(TAG, "Downloading avatar: " + avatarUrl); // Request the avatar image from the server, and create a bitmap // object from the stream we get back. URL url = new URL(avatarUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); try { final BitmapFactory.Options options = new BitmapFactory.Options(); final Bitmap avatar = BitmapFactory.decodeStream(connection.getInputStream(), null, options); // Take the image we received from the server, whatever format it // happens to be in, and convert it to a JPEG image. Note: we're // not resizing the avatar - we assume that the image we get from // the server is a reasonable size... Log.i(TAG, "Converting avatar to JPEG"); ByteArrayOutputStream convertStream = new ByteArrayOutputStream( avatar.getWidth() * avatar.getHeight() * 4); avatar.compress(Bitmap.CompressFormat.JPEG, 95, convertStream); convertStream.flush(); convertStream.close(); // On pre-Honeycomb systems, it's important to call recycle on bitmaps avatar.recycle(); return convertStream.toByteArray(); } finally { connection.disconnect(); } } catch (MalformedURLException muex) { // A bad URL - nothing we can really do about it here... Log.e(TAG, "Malformed avatar URL: " + avatarUrl); } catch (IOException ioex) { // If we're unable to download the avatar, it's a bummer but not the // end of the world. We'll try to get it next time we sync. Log.e(TAG, "Failed to download user avatar: " + avatarUrl); } return null; } }