You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

606 lines
46 KiB

<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 &quot;License&quot;);
* 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 &quot;AS IS&quot; 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">&quot;https://mail.google.com/tasks/&quot;</span><span class="s1">;</span>
<span class="s2">private static final </span><span class="s1">String GTASK_GET_URL = </span><span class="s3">&quot;https://mail.google.com/tasks/ig&quot;</span><span class="s1">;</span>
<span class="s2">private static final </span><span class="s1">String GTASK_POST_URL = </span><span class="s3">&quot;https://mail.google.com/tasks/r/ig&quot;</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 &lt; 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">&amp;&amp; !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">&quot;already logged in&quot;</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">&quot;login google account failed&quot;</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">&quot;gmail.com&quot;</span><span class="s1">) || mAccount.name.toLowerCase()</span>
<span class="s1">.endsWith(</span><span class="s3">&quot;googlemail.com&quot;</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">&quot;a/&quot;</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">&quot;/&quot;</span><span class="s1">);</span>
<span class="s1">mGetUrl = url.toString() + </span><span class="s3">&quot;ig&quot;</span><span class="s1">;</span>
<span class="s1">mPostUrl = url.toString() + </span><span class="s3">&quot;r/ig&quot;</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">&quot;com.google&quot;</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">&quot;there is no available google account&quot;</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">&quot;unable to get an account with the same name in the settings&quot;</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&lt;Bundle&gt; accountManagerFuture = accountManager.getAuthToken(account,</span>
<span class="s3">&quot;goanna_mobile&quot;</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">&quot;com.google&quot;</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">&quot;get auth token failed&quot;</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">&quot;login google account failed&quot;</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">&quot;login gtask failed&quot;</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">&quot;?auth=&quot; </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&lt;Cookie&gt; 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">&quot;GTL&quot;</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">&quot;it seems that there is no auth cookie&quot;</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">&quot;_setup(&quot;</span><span class="s1">;</span>
<span class="s1">String jsEnd = </span><span class="s3">&quot;)}&lt;/script&gt;&quot;</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">&amp;&amp; end != -</span><span class="s4">1 </span><span class="s1">&amp;&amp; begin &lt; 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">&quot;v&quot;</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">&quot;httpget gtask_url failed&quot;</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">&quot;Content-Type&quot;</span><span class="s1">, </span><span class="s3">&quot;application/x-www-form-urlencoded;charset=utf-8&quot;</span><span class="s1">);</span>
<span class="s1">httpPost.setHeader(</span><span class="s3">&quot;AT&quot;</span><span class="s1">, </span><span class="s3">&quot;1&quot;</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">&quot;encoding: &quot; </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">&amp;&amp; contentEncoding.equalsIgnoreCase(</span><span class="s3">&quot;gzip&quot;</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">&amp;&amp; contentEncoding.equalsIgnoreCase(</span><span class="s3">&quot;deflate&quot;</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">&quot;please login first&quot;</span><span class="s1">);</span>
<span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">&quot;not logged in&quot;</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&lt;BasicNameValuePair&gt; list = </span><span class="s2">new </span><span class="s1">LinkedList&lt;BasicNameValuePair&gt;();</span>
<span class="s1">list.add(</span><span class="s2">new </span><span class="s1">BasicNameValuePair(</span><span class="s3">&quot;r&quot;</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">&quot;UTF-8&quot;</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">&quot;postRequest failed&quot;</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">&quot;postRequest failed&quot;</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">&quot;unable to convert response content to jsonobject&quot;</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">&quot;error occurs when posting request&quot;</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">&quot;create task: handing jsonobject failed&quot;</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">&quot;create tasklist: handing jsonobject failed&quot;</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">&quot;commit update: handing jsonobject failed&quot;</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">&amp;&amp; mUpdateArray.length() &gt; </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 &amp;&amp; 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">&quot;move task: handing jsonobject failed&quot;</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">&quot;delete node: handing jsonobject failed&quot;</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">&quot;please login first&quot;</span><span class="s1">);</span>
<span class="s2">throw new </span><span class="s1">ActionFailureException(</span><span class="s3">&quot;not logged in&quot;</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">&quot;_setup(&quot;</span><span class="s1">;</span>
<span class="s1">String jsEnd = </span><span class="s3">&quot;)}&lt;/script&gt;&quot;</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">&amp;&amp; end != -</span><span class="s4">1 </span><span class="s1">&amp;&amp; begin &lt; 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">&quot;t&quot;</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">&quot;gettasklists: httpget failed&quot;</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">&quot;gettasklists: httpget failed&quot;</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">&quot;get task lists: handing jasonobject failed&quot;</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">&quot;get task list: handing jsonobject failed&quot;</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>