<html> <head> <title>GTaskClient.java</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <style type="text/css"> .s0 { color: #8c8c8c; font-style: italic;} .s1 { color: #080808;} .s2 { color: #0033b3;} .s3 { color: #067d17;} .s4 { color: #1750eb;} </style> </head> <body bgcolor="#ffffff"> <table CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#c0c0c0" > <tr><td><center> <font face="Arial, Helvetica" color="#000000"> GTaskClient.java</font> </center></td></tr></table> <pre><span class="s0">/* * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * * 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. */</span> <span class="s2">package </span><span class="s1">net.micode.notes.gtask.remote;</span> <span class="s2">import </span><span class="s1">android.accounts.Account;</span> <span class="s2">import </span><span class="s1">android.accounts.AccountManager;</span> <span class="s2">import </span><span class="s1">android.accounts.AccountManagerFuture;</span> <span class="s2">import </span><span class="s1">android.app.Activity;</span> <span class="s2">import </span><span class="s1">android.os.Bundle;</span> <span class="s2">import </span><span class="s1">android.text.TextUtils;</span> <span class="s2">import </span><span class="s1">android.util.Log;</span> <span class="s2">import </span><span class="s1">net.micode.notes.gtask.data.Node;</span> <span class="s2">import </span><span class="s1">net.micode.notes.gtask.data.Task;</span> <span class="s2">import </span><span class="s1">net.micode.notes.gtask.data.TaskList;</span> <span class="s2">import </span><span class="s1">net.micode.notes.gtask.exception.ActionFailureException;</span> <span class="s2">import </span><span class="s1">net.micode.notes.gtask.exception.NetworkFailureException;</span> <span class="s2">import </span><span class="s1">net.micode.notes.tool.GTaskStringUtils;</span> <span class="s2">import </span><span class="s1">net.micode.notes.ui.NotesPreferenceActivity;</span> <span class="s2">import </span><span class="s1">org.apache.http.HttpEntity;</span> <span class="s2">import </span><span class="s1">org.apache.http.HttpResponse;</span> <span class="s2">import </span><span class="s1">org.apache.http.client.ClientProtocolException;</span> <span class="s2">import </span><span class="s1">org.apache.http.client.entity.UrlEncodedFormEntity;</span> <span class="s2">import </span><span class="s1">org.apache.http.client.methods.HttpGet;</span> <span class="s2">import </span><span class="s1">org.apache.http.client.methods.HttpPost;</span> <span class="s2">import </span><span class="s1">org.apache.http.cookie.Cookie;</span> <span class="s2">import </span><span class="s1">org.apache.http.impl.client.BasicCookieStore;</span> <span class="s2">import </span><span class="s1">org.apache.http.impl.client.DefaultHttpClient;</span> <span class="s2">import </span><span class="s1">org.apache.http.message.BasicNameValuePair;</span> <span class="s2">import </span><span class="s1">org.apache.http.params.BasicHttpParams;</span> <span class="s2">import </span><span class="s1">org.apache.http.params.HttpConnectionParams;</span> <span class="s2">import </span><span class="s1">org.apache.http.params.HttpParams;</span> <span class="s2">import </span><span class="s1">org.apache.http.params.HttpProtocolParams;</span> <span class="s2">import </span><span class="s1">org.json.JSONArray;</span> <span class="s2">import </span><span class="s1">org.json.JSONException;</span> <span class="s2">import </span><span class="s1">org.json.JSONObject;</span> <span class="s2">import </span><span class="s1">java.io.BufferedReader;</span> <span class="s2">import </span><span class="s1">java.io.IOException;</span> <span class="s2">import </span><span class="s1">java.io.InputStream;</span> <span class="s2">import </span><span class="s1">java.io.InputStreamReader;</span> <span class="s2">import </span><span class="s1">java.util.LinkedList;</span> <span class="s2">import </span><span class="s1">java.util.List;</span> <span class="s2">import </span><span class="s1">java.util.zip.GZIPInputStream;</span> <span class="s2">import </span><span class="s1">java.util.zip.Inflater;</span> <span class="s2">import </span><span class="s1">java.util.zip.InflaterInputStream;</span> <span class="s2">public class </span><span class="s1">GTaskClient {</span> <span class="s2">private static final </span><span class="s1">String TAG = GTaskClient.</span><span class="s2">class</span><span class="s1">.getSimpleName();</span> <span class="s2">private static final </span><span class="s1">String GTASK_URL = </span><span class="s3">"https://mail.google.com/tasks/"</span><span class="s1">;</span> <span class="s2">private static final </span><span class="s1">String GTASK_GET_URL = </span><span class="s3">"https://mail.google.com/tasks/ig"</span><span class="s1">;</span> <span class="s2">private static final </span><span class="s1">String GTASK_POST_URL = </span><span class="s3">"https://mail.google.com/tasks/r/ig"</span><span class="s1">;</span> <span class="s2">private static </span><span class="s1">GTaskClient mInstance = </span><span class="s2">null</span><span class="s1">;</span> <span class="s2">private </span><span class="s1">DefaultHttpClient mHttpClient;</span> <span class="s2">private </span><span class="s1">String mGetUrl;</span> <span class="s2">private </span><span class="s1">String mPostUrl;</span> <span class="s2">private long </span><span class="s1">mClientVersion;</span> <span class="s2">private boolean </span><span class="s1">mLoggedin;</span> <span class="s2">private long </span><span class="s1">mLastLoginTime;</span> <span class="s2">private int </span><span class="s1">mActionId;</span> <span class="s2">private </span><span class="s1">Account mAccount;</span> <span class="s2">private </span><span class="s1">JSONArray mUpdateArray;</span> <span class="s2">private </span><span class="s1">GTaskClient() {</span> <span class="s1">mHttpClient = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">mGetUrl = GTASK_GET_URL;</span> <span class="s1">mPostUrl = GTASK_POST_URL;</span> <span class="s1">mClientVersion = -</span><span class="s4">1</span><span class="s1">;</span> <span class="s1">mLoggedin = </span><span class="s2">false</span><span class="s1">;</span> <span class="s1">mLastLoginTime = </span><span class="s4">0</span><span class="s1">;</span> <span class="s1">mActionId = </span><span class="s4">1</span><span class="s1">;</span> <span class="s1">mAccount = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">mUpdateArray = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">public static synchronized </span><span class="s1">GTaskClient getInstance() {</span> <span class="s2">if </span><span class="s1">(mInstance == </span><span class="s2">null</span><span class="s1">) {</span> <span class="s1">mInstance = </span><span class="s2">new </span><span class="s1">GTaskClient();</span> <span class="s1">}</span> <span class="s2">return </span><span class="s1">mInstance;</span> <span class="s1">}</span> <span class="s2">public boolean </span><span class="s1">login(Activity activity) {</span> <span class="s0">// we suppose that the cookie would expire after 5 minutes</span> <span class="s0">// then we need to re-login</span> <span class="s2">final long </span><span class="s1">interval = </span><span class="s4">1000 </span><span class="s1">* </span><span class="s4">60 </span><span class="s1">* </span><span class="s4">5</span><span class="s1">;</span> <span class="s2">if </span><span class="s1">(mLastLoginTime + interval < System.currentTimeMillis()) {</span> <span class="s1">mLoggedin = </span><span class="s2">false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s0">// need to re-login after account switch</span> <span class="s2">if </span><span class="s1">(mLoggedin</span> <span class="s1">&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity</span> <span class="s1">.getSyncAccountName(activity))) {</span> <span class="s1">mLoggedin = </span><span class="s2">false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">if </span><span class="s1">(mLoggedin) {</span> <span class="s1">Log.d(TAG, </span><span class="s3">"already logged in"</span><span class="s1">);</span> <span class="s2">return true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">mLastLoginTime = System.currentTimeMillis();</span> <span class="s1">String authToken = loginGoogleAccount(activity, </span><span class="s2">false</span><span class="s1">);</span> <span class="s2">if </span><span class="s1">(authToken == </span><span class="s2">null</span><span class="s1">) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"login google account failed"</span><span class="s1">);</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s0">// login with custom domain if necessary</span> <span class="s2">if </span><span class="s1">(!(mAccount.name.toLowerCase().endsWith(</span><span class="s3">"gmail.com"</span><span class="s1">) || mAccount.name.toLowerCase()</span> <span class="s1">.endsWith(</span><span class="s3">"googlemail.com"</span><span class="s1">))) {</span> <span class="s1">StringBuilder url = </span><span class="s2">new </span><span class="s1">StringBuilder(GTASK_URL).append(</span><span class="s3">"a/"</span><span class="s1">);</span> <span class="s2">int </span><span class="s1">index = mAccount.name.indexOf(</span><span class="s3">'@'</span><span class="s1">) + </span><span class="s4">1</span><span class="s1">;</span> <span class="s1">String suffix = mAccount.name.substring(index);</span> <span class="s1">url.append(suffix + </span><span class="s3">"/"</span><span class="s1">);</span> <span class="s1">mGetUrl = url.toString() + </span><span class="s3">"ig"</span><span class="s1">;</span> <span class="s1">mPostUrl = url.toString() + </span><span class="s3">"r/ig"</span><span class="s1">;</span> <span class="s2">if </span><span class="s1">(tryToLoginGtask(activity, authToken)) {</span> <span class="s1">mLoggedin = </span><span class="s2">true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s0">// try to login with google official url</span> <span class="s2">if </span><span class="s1">(!mLoggedin) {</span> <span class="s1">mGetUrl = GTASK_GET_URL;</span> <span class="s1">mPostUrl = GTASK_POST_URL;</span> <span class="s2">if </span><span class="s1">(!tryToLoginGtask(activity, authToken)) {</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s1">mLoggedin = </span><span class="s2">true</span><span class="s1">;</span> <span class="s2">return true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">private </span><span class="s1">String loginGoogleAccount(Activity activity, </span><span class="s2">boolean </span><span class="s1">invalidateToken) {</span> <span class="s1">String authToken;</span> <span class="s1">AccountManager accountManager = AccountManager.get(activity);</span> <span class="s1">Account[] accounts = accountManager.getAccountsByType(</span><span class="s3">"com.google"</span><span class="s1">);</span> <span class="s2">if </span><span class="s1">(accounts.length == </span><span class="s4">0</span><span class="s1">) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"there is no available google account"</span><span class="s1">);</span> <span class="s2">return null</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">String accountName = NotesPreferenceActivity.getSyncAccountName(activity);</span> <span class="s1">Account account = </span><span class="s2">null</span><span class="s1">;</span> <span class="s2">for </span><span class="s1">(Account a : accounts) {</span> <span class="s2">if </span><span class="s1">(a.name.equals(accountName)) {</span> <span class="s1">account = a;</span> <span class="s2">break</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">if </span><span class="s1">(account != </span><span class="s2">null</span><span class="s1">) {</span> <span class="s1">mAccount = account;</span> <span class="s1">} </span><span class="s2">else </span><span class="s1">{</span> <span class="s1">Log.e(TAG, </span><span class="s3">"unable to get an account with the same name in the settings"</span><span class="s1">);</span> <span class="s2">return null</span><span class="s1">;</span> <span class="s1">}</span> <span class="s0">// get the token now</span> <span class="s1">AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account,</span> <span class="s3">"goanna_mobile"</span><span class="s1">, </span><span class="s2">null</span><span class="s1">, activity, </span><span class="s2">null</span><span class="s1">, </span><span class="s2">null</span><span class="s1">);</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">Bundle authTokenBundle = accountManagerFuture.getResult();</span> <span class="s1">authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);</span> <span class="s2">if </span><span class="s1">(invalidateToken) {</span> <span class="s1">accountManager.invalidateAuthToken(</span><span class="s3">"com.google"</span><span class="s1">, authToken);</span> <span class="s1">loginGoogleAccount(activity, </span><span class="s2">false</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(Exception e) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"get auth token failed"</span><span class="s1">);</span> <span class="s1">authToken = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">return </span><span class="s1">authToken;</span> <span class="s1">}</span> <span class="s2">private boolean </span><span class="s1">tryToLoginGtask(Activity activity, String authToken) {</span> <span class="s2">if </span><span class="s1">(!loginGtask(authToken)) {</span> <span class="s0">// maybe the auth token is out of date, now let's invalidate the</span> <span class="s0">// token and try again</span> <span class="s1">authToken = loginGoogleAccount(activity, </span><span class="s2">true</span><span class="s1">);</span> <span class="s2">if </span><span class="s1">(authToken == </span><span class="s2">null</span><span class="s1">) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"login google account failed"</span><span class="s1">);</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">if </span><span class="s1">(!loginGtask(authToken)) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"login gtask failed"</span><span class="s1">);</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">return true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">private boolean </span><span class="s1">loginGtask(String authToken) {</span> <span class="s2">int </span><span class="s1">timeoutConnection = </span><span class="s4">10000</span><span class="s1">;</span> <span class="s2">int </span><span class="s1">timeoutSocket = </span><span class="s4">15000</span><span class="s1">;</span> <span class="s1">HttpParams httpParameters = </span><span class="s2">new </span><span class="s1">BasicHttpParams();</span> <span class="s1">HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);</span> <span class="s1">HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);</span> <span class="s1">mHttpClient = </span><span class="s2">new </span><span class="s1">DefaultHttpClient(httpParameters);</span> <span class="s1">BasicCookieStore localBasicCookieStore = </span><span class="s2">new </span><span class="s1">BasicCookieStore();</span> <span class="s1">mHttpClient.setCookieStore(localBasicCookieStore);</span> <span class="s1">HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), </span><span class="s2">false</span><span class="s1">);</span> <span class="s0">// login gtask</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">String loginUrl = mGetUrl + </span><span class="s3">"?auth=" </span><span class="s1">+ authToken;</span> <span class="s1">HttpGet httpGet = </span><span class="s2">new </span><span class="s1">HttpGet(loginUrl);</span> <span class="s1">HttpResponse response = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">response = mHttpClient.execute(httpGet);</span> <span class="s0">// get the cookie now</span> <span class="s1">List<Cookie> cookies = mHttpClient.getCookieStore().getCookies();</span> <span class="s2">boolean </span><span class="s1">hasAuthCookie = </span><span class="s2">false</span><span class="s1">;</span> <span class="s2">for </span><span class="s1">(Cookie cookie : cookies) {</span> <span class="s2">if </span><span class="s1">(cookie.getName().contains(</span><span class="s3">"GTL"</span><span class="s1">)) {</span> <span class="s1">hasAuthCookie = </span><span class="s2">true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">if </span><span class="s1">(!hasAuthCookie) {</span> <span class="s1">Log.w(TAG, </span><span class="s3">"it seems that there is no auth cookie"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s0">// get the client version</span> <span class="s1">String resString = getResponseContent(response.getEntity());</span> <span class="s1">String jsBegin = </span><span class="s3">"_setup("</span><span class="s1">;</span> <span class="s1">String jsEnd = </span><span class="s3">")}</script>"</span><span class="s1">;</span> <span class="s2">int </span><span class="s1">begin = resString.indexOf(jsBegin);</span> <span class="s2">int </span><span class="s1">end = resString.lastIndexOf(jsEnd);</span> <span class="s1">String jsString = </span><span class="s2">null</span><span class="s1">;</span> <span class="s2">if </span><span class="s1">(begin != -</span><span class="s4">1 </span><span class="s1">&& end != -</span><span class="s4">1 </span><span class="s1">&& begin < end) {</span> <span class="s1">jsString = resString.substring(begin + jsBegin.length(), end);</span> <span class="s1">}</span> <span class="s1">JSONObject js = </span><span class="s2">new </span><span class="s1">JSONObject(jsString);</span> <span class="s1">mClientVersion = js.getLong(</span><span class="s3">"v"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(Exception e) {</span> <span class="s0">// simply catch all exceptions</span> <span class="s1">Log.e(TAG, </span><span class="s3">"httpget gtask_url failed"</span><span class="s1">);</span> <span class="s2">return false</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">return true</span><span class="s1">;</span> <span class="s1">}</span> <span class="s2">private int </span><span class="s1">getActionId() {</span> <span class="s2">return </span><span class="s1">mActionId++;</span> <span class="s1">}</span> <span class="s2">private </span><span class="s1">HttpPost createHttpPost() {</span> <span class="s1">HttpPost httpPost = </span><span class="s2">new </span><span class="s1">HttpPost(mPostUrl);</span> <span class="s1">httpPost.setHeader(</span><span class="s3">"Content-Type"</span><span class="s1">, </span><span class="s3">"application/x-www-form-urlencoded;charset=utf-8"</span><span class="s1">);</span> <span class="s1">httpPost.setHeader(</span><span class="s3">"AT"</span><span class="s1">, </span><span class="s3">"1"</span><span class="s1">);</span> <span class="s2">return </span><span class="s1">httpPost;</span> <span class="s1">}</span> <span class="s2">private </span><span class="s1">String getResponseContent(HttpEntity entity) </span><span class="s2">throws </span><span class="s1">IOException {</span> <span class="s1">String contentEncoding = </span><span class="s2">null</span><span class="s1">;</span> <span class="s2">if </span><span class="s1">(entity.getContentEncoding() != </span><span class="s2">null</span><span class="s1">) {</span> <span class="s1">contentEncoding = entity.getContentEncoding().getValue();</span> <span class="s1">Log.d(TAG, </span><span class="s3">"encoding: " </span><span class="s1">+ contentEncoding);</span> <span class="s1">}</span> <span class="s1">InputStream input = entity.getContent();</span> <span class="s2">if </span><span class="s1">(contentEncoding != </span><span class="s2">null </span><span class="s1">&& contentEncoding.equalsIgnoreCase(</span><span class="s3">"gzip"</span><span class="s1">)) {</span> <span class="s1">input = </span><span class="s2">new </span><span class="s1">GZIPInputStream(entity.getContent());</span> <span class="s1">} </span><span class="s2">else if </span><span class="s1">(contentEncoding != </span><span class="s2">null </span><span class="s1">&& contentEncoding.equalsIgnoreCase(</span><span class="s3">"deflate"</span><span class="s1">)) {</span> <span class="s1">Inflater inflater = </span><span class="s2">new </span><span class="s1">Inflater(</span><span class="s2">true</span><span class="s1">);</span> <span class="s1">input = </span><span class="s2">new </span><span class="s1">InflaterInputStream(entity.getContent(), inflater);</span> <span class="s1">}</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">InputStreamReader isr = </span><span class="s2">new </span><span class="s1">InputStreamReader(input);</span> <span class="s1">BufferedReader br = </span><span class="s2">new </span><span class="s1">BufferedReader(isr);</span> <span class="s1">StringBuilder sb = </span><span class="s2">new </span><span class="s1">StringBuilder();</span> <span class="s2">while </span><span class="s1">(</span><span class="s2">true</span><span class="s1">) {</span> <span class="s1">String buff = br.readLine();</span> <span class="s2">if </span><span class="s1">(buff == </span><span class="s2">null</span><span class="s1">) {</span> <span class="s2">return </span><span class="s1">sb.toString();</span> <span class="s1">}</span> <span class="s1">sb = sb.append(buff);</span> <span class="s1">}</span> <span class="s1">} </span><span class="s2">finally </span><span class="s1">{</span> <span class="s1">input.close();</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">private </span><span class="s1">JSONObject postRequest(JSONObject js) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s2">if </span><span class="s1">(!mLoggedin) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"please login first"</span><span class="s1">);</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"not logged in"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">HttpPost httpPost = createHttpPost();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">LinkedList<BasicNameValuePair> list = </span><span class="s2">new </span><span class="s1">LinkedList<BasicNameValuePair>();</span> <span class="s1">list.add(</span><span class="s2">new </span><span class="s1">BasicNameValuePair(</span><span class="s3">"r"</span><span class="s1">, js.toString()));</span> <span class="s1">UrlEncodedFormEntity entity = </span><span class="s2">new </span><span class="s1">UrlEncodedFormEntity(list, </span><span class="s3">"UTF-8"</span><span class="s1">);</span> <span class="s1">httpPost.setEntity(entity);</span> <span class="s0">// execute the post</span> <span class="s1">HttpResponse response = mHttpClient.execute(httpPost);</span> <span class="s1">String jsString = getResponseContent(response.getEntity());</span> <span class="s2">return new </span><span class="s1">JSONObject(jsString);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(ClientProtocolException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">NetworkFailureException(</span><span class="s3">"postRequest failed"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(IOException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">NetworkFailureException(</span><span class="s3">"postRequest failed"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"unable to convert response content to jsonobject"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(Exception e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"error occurs when posting request"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">createTask(Task task) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s1">commitUpdate();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s1">JSONArray actionList = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s0">// action_list</span> <span class="s1">actionList.put(task.getCreateAction(getActionId()));</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);</span> <span class="s0">// client_version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s0">// post</span> <span class="s1">JSONObject jsResponse = postRequest(jsPost);</span> <span class="s1">JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(</span> <span class="s1">GTaskStringUtils.GTASK_JSON_RESULTS).get(</span><span class="s4">0</span><span class="s1">);</span> <span class="s1">task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"create task: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">createTaskList(TaskList tasklist) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s1">commitUpdate();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s1">JSONArray actionList = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s0">// action_list</span> <span class="s1">actionList.put(tasklist.getCreateAction(getActionId()));</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);</span> <span class="s0">// client version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s0">// post</span> <span class="s1">JSONObject jsResponse = postRequest(jsPost);</span> <span class="s1">JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(</span> <span class="s1">GTaskStringUtils.GTASK_JSON_RESULTS).get(</span><span class="s4">0</span><span class="s1">);</span> <span class="s1">tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"create tasklist: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">commitUpdate() </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s2">if </span><span class="s1">(mUpdateArray != </span><span class="s2">null</span><span class="s1">) {</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s0">// action_list</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray);</span> <span class="s0">// client_version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s1">postRequest(jsPost);</span> <span class="s1">mUpdateArray = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"commit update: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">addUpdateNode(Node node) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s2">if </span><span class="s1">(node != </span><span class="s2">null</span><span class="s1">) {</span> <span class="s0">// too many update items may result in an error</span> <span class="s0">// set max to 10 items</span> <span class="s2">if </span><span class="s1">(mUpdateArray != </span><span class="s2">null </span><span class="s1">&& mUpdateArray.length() > </span><span class="s4">10</span><span class="s1">) {</span> <span class="s1">commitUpdate();</span> <span class="s1">}</span> <span class="s2">if </span><span class="s1">(mUpdateArray == </span><span class="s2">null</span><span class="s1">)</span> <span class="s1">mUpdateArray = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s1">mUpdateArray.put(node.getUpdateAction(getActionId()));</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">moveTask(Task task, TaskList preParent, TaskList curParent)</span> <span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s1">commitUpdate();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s1">JSONArray actionList = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s1">JSONObject action = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s0">// action_list</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,</span> <span class="s1">GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE);</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid());</span> <span class="s2">if </span><span class="s1">(preParent == curParent && task.getPriorSibling() != </span><span class="s2">null</span><span class="s1">) {</span> <span class="s0">// put prioring_sibing_id only if moving within the tasklist and</span> <span class="s0">// it is not the first one</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());</span> <span class="s1">}</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid());</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid());</span> <span class="s2">if </span><span class="s1">(preParent != curParent) {</span> <span class="s0">// put the dest_list only if moving between tasklists</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid());</span> <span class="s1">}</span> <span class="s1">actionList.put(action);</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);</span> <span class="s0">// client_version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s1">postRequest(jsPost);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"move task: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">deleteNode(Node node) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s1">commitUpdate();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s1">JSONArray actionList = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s0">// action_list</span> <span class="s1">node.setDeleted(</span><span class="s2">true</span><span class="s1">);</span> <span class="s1">actionList.put(node.getUpdateAction(getActionId()));</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);</span> <span class="s0">// client_version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s1">postRequest(jsPost);</span> <span class="s1">mUpdateArray = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"delete node: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public </span><span class="s1">JSONArray getTaskLists() </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s2">if </span><span class="s1">(!mLoggedin) {</span> <span class="s1">Log.e(TAG, </span><span class="s3">"please login first"</span><span class="s1">);</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"not logged in"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">HttpGet httpGet = </span><span class="s2">new </span><span class="s1">HttpGet(mGetUrl);</span> <span class="s1">HttpResponse response = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">response = mHttpClient.execute(httpGet);</span> <span class="s0">// get the task list</span> <span class="s1">String resString = getResponseContent(response.getEntity());</span> <span class="s1">String jsBegin = </span><span class="s3">"_setup("</span><span class="s1">;</span> <span class="s1">String jsEnd = </span><span class="s3">")}</script>"</span><span class="s1">;</span> <span class="s2">int </span><span class="s1">begin = resString.indexOf(jsBegin);</span> <span class="s2">int </span><span class="s1">end = resString.lastIndexOf(jsEnd);</span> <span class="s1">String jsString = </span><span class="s2">null</span><span class="s1">;</span> <span class="s2">if </span><span class="s1">(begin != -</span><span class="s4">1 </span><span class="s1">&& end != -</span><span class="s4">1 </span><span class="s1">&& begin < end) {</span> <span class="s1">jsString = resString.substring(begin + jsBegin.length(), end);</span> <span class="s1">}</span> <span class="s1">JSONObject js = </span><span class="s2">new </span><span class="s1">JSONObject(jsString);</span> <span class="s2">return </span><span class="s1">js.getJSONObject(</span><span class="s3">"t"</span><span class="s1">).getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(ClientProtocolException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">NetworkFailureException(</span><span class="s3">"gettasklists: httpget failed"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(IOException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">NetworkFailureException(</span><span class="s3">"gettasklists: httpget failed"</span><span class="s1">);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"get task lists: handing jasonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public </span><span class="s1">JSONArray getTaskList(String listGid) </span><span class="s2">throws </span><span class="s1">NetworkFailureException {</span> <span class="s1">commitUpdate();</span> <span class="s2">try </span><span class="s1">{</span> <span class="s1">JSONObject jsPost = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s1">JSONArray actionList = </span><span class="s2">new </span><span class="s1">JSONArray();</span> <span class="s1">JSONObject action = </span><span class="s2">new </span><span class="s1">JSONObject();</span> <span class="s0">// action_list</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,</span> <span class="s1">GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL);</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid);</span> <span class="s1">action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, </span><span class="s2">false</span><span class="s1">);</span> <span class="s1">actionList.put(action);</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);</span> <span class="s0">// client_version</span> <span class="s1">jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);</span> <span class="s1">JSONObject jsResponse = postRequest(jsPost);</span> <span class="s2">return </span><span class="s1">jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS);</span> <span class="s1">} </span><span class="s2">catch </span><span class="s1">(JSONException e) {</span> <span class="s1">Log.e(TAG, e.toString());</span> <span class="s1">e.printStackTrace();</span> <span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">"get task list: handing jsonobject failed"</span><span class="s1">);</span> <span class="s1">}</span> <span class="s1">}</span> <span class="s2">public </span><span class="s1">Account getSyncAccount() {</span> <span class="s2">return </span><span class="s1">mAccount;</span> <span class="s1">}</span> <span class="s2">public void </span><span class="s1">resetUpdateArray() {</span> <span class="s1">mUpdateArray = </span><span class="s2">null</span><span class="s1">;</span> <span class="s1">}</span> <span class="s1">}</span> </pre> </body> </html>