1d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank/* 2d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Copyright (C) 2011 The Android Open Source Project 3d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * 4d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 5d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * you may not use this file except in compliance with the License. 6d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * You may obtain a copy of the License at 7d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * 8d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * http://www.apache.org/licenses/LICENSE-2.0 9d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * 10d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Unless required by applicable law or agreed to in writing, software 11d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * distributed under the License is distributed on an "AS IS" BASIS, 12d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * See the License for the specific language governing permissions and 14d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * limitations under the License. 15d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank */ 16d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 17d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankpackage com.android.exchange.adapter; 18d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 19d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.ContentProviderOperation; 20d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.ContentValues; 21d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.Context; 22d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.content.OperationApplicationException; 23d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.os.RemoteException; 24d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport android.util.Log; 25d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 26d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.Logging; 27d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.provider.Account; 28d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.provider.EmailContent; 29d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.provider.EmailContent.Message; 30d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.provider.Mailbox; 31d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.service.EmailServiceStatus; 32d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.service.SearchParams; 33d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.emailcommon.utility.TextUtilities; 34d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.Eas; 35d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.EasResponse; 36d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.EasSyncService; 37d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.ExchangeService; 38d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.exchange.adapter.EmailSyncAdapter.EasEmailSyncParser; 39d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport com.android.mail.providers.UIProvider; 40d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 41d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport org.apache.http.HttpStatus; 42d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 43d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.io.IOException; 44d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.io.InputStream; 45d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankimport java.util.ArrayList; 46d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 47d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank/** 48d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Implementation of server-side search for EAS using the EmailService API 49d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank */ 50d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blankpublic class Search { 51d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // The shortest search query we'll accept 52d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // TODO Check with UX whether this is correct 53d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private static final int MIN_QUERY_LENGTH = 3; 54d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // The largest number of results we'll ask for per server request 55d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private static final int MAX_SEARCH_RESULTS = 100; 56d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 57d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank public static int searchMessages(Context context, long accountId, SearchParams searchParams, 58d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank long destMailboxId) { 59d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Sanity check for arguments 60d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank int offset = searchParams.mOffset; 61d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank int limit = searchParams.mLimit; 62d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank String filter = searchParams.mFilter; 63d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (limit < 0 || limit > MAX_SEARCH_RESULTS || offset < 0) return 0; 64d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // TODO Should this be checked in UI? Are there guidelines for minimums? 65d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (filter == null || filter.length() < MIN_QUERY_LENGTH) return 0; 66d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 67d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank int res = 0; 68d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Account account = Account.restoreAccountWithId(context, accountId); 69d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (account == null) return res; 70d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank EasSyncService svc = EasSyncService.setupServiceForAccount(context, account); 71d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (svc == null) return res; 72d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Mailbox searchMailbox = Mailbox.restoreMailboxWithId(context, destMailboxId); 73d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Sanity check; account might have been deleted? 74d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (searchMailbox == null) return res; 75d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank ContentValues statusValues = new ContentValues(); 76d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank try { 77d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Set the status of this mailbox to indicate query 78edb48993842d47edaf75975258b3b3bf5a8ea48aVikram Aggarwal statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.LIVE_QUERY); 79d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank searchMailbox.update(context, statusValues); 80d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 81d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank svc.mMailbox = searchMailbox; 82d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank svc.mAccount = account; 83d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Serializer s = new Serializer(); 84d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.start(Tags.SEARCH_SEARCH).start(Tags.SEARCH_STORE); 85d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.SEARCH_NAME, "Mailbox"); 86d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.start(Tags.SEARCH_QUERY).start(Tags.SEARCH_AND); 87d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.SYNC_CLASS, "Email"); 88d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 89d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // If this isn't an inbox search, then include the collection id 90d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Mailbox inbox = Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_INBOX); 91d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (inbox == null) return 0; 92d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (searchParams.mMailboxId != inbox.mId) { 93d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.SYNC_COLLECTION_ID, inbox.mServerId); 94d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 95d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 96d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.SEARCH_FREE_TEXT, filter); 97d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.end().end(); // SEARCH_AND, SEARCH_QUERY 98d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.start(Tags.SEARCH_OPTIONS); 99d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (offset == 0) { 100d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.tag(Tags.SEARCH_REBUILD_RESULTS); 101d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 102d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (searchParams.mIncludeChildren) { 103d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.tag(Tags.SEARCH_DEEP_TRAVERSAL); 104d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 105d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Range is sent in the form first-last (e.g. 0-9) 106d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.SEARCH_RANGE, offset + "-" + (offset + limit - 1)); 107d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.start(Tags.BASE_BODY_PREFERENCE); 108d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.BASE_TYPE, Eas.BODY_PREFERENCE_HTML); 109d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.data(Tags.BASE_TRUNCATION_SIZE, "20000"); 110d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.end(); // BASE_BODY_PREFERENCE 111d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank s.end().end().end().done(); // SEARCH_OPTIONS, SEARCH_STORE, SEARCH_SEARCH 112d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank EasResponse resp = svc.sendHttpClientPost("Search", s.toByteArray()); 113d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank try { 114d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank int code = resp.getStatus(); 115d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (code == HttpStatus.SC_OK) { 116d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank InputStream is = resp.getInputStream(); 117d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank try { 118d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank SearchParser sp = new SearchParser(is, svc, filter); 119d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank sp.parse(); 120d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank res = sp.getTotalResults(); 121d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } finally { 122d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank is.close(); 123d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 124d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else { 125d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank svc.userLog("Search returned " + code); 126d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 127d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } finally { 128d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank resp.close(); 129d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 130d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } catch (IOException e) { 131d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank svc.userLog("Search exception " + e); 132d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } finally { 133d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank try { 134d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // TODO: Handle error states 135d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Set the status of this mailbox to indicate query over 136d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank statusValues.put(Mailbox.UI_SYNC_STATUS, UIProvider.SyncStatus.NO_SYNC); 137d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank searchMailbox.update(context, statusValues); 138d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank ExchangeService.callback().syncMailboxStatus(destMailboxId, 139d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank EmailServiceStatus.SUCCESS, 100); 140d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } catch (RemoteException e) { 141d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 142d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 143d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Return the total count 144d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return res; 145d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 146d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 147d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank /** 148d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank * Parse the result of a Search command 149d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank */ 150d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank static class SearchParser extends Parser { 151d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private final EasSyncService mService; 152d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private final String mQuery; 153d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private int mTotalResults; 154d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 155d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private SearchParser(InputStream in, EasSyncService service, String query) 156d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank throws IOException { 157d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank super(in); 158d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank mService = service; 159d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank mQuery = query; 160d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 161d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 162d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank protected int getTotalResults() { 163d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return mTotalResults; 164d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 165d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 166d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank @Override 167d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank public boolean parse() throws IOException { 168d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank boolean res = false; 169d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (nextTag(START_DOCUMENT) != Tags.SEARCH_SEARCH) { 170d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank throw new IOException(); 171d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 172d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank while (nextTag(START_DOCUMENT) != END_DOCUMENT) { 173d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (tag == Tags.SEARCH_STATUS) { 174d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank String status = getValue(); 175d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (Eas.USER_LOG) { 176d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Log.d(Logging.LOG_TAG, "Search status: " + status); 177d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 178d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SEARCH_RESPONSE) { 179d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank parseResponse(); 180d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else { 181d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank skipTag(); 182d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 183d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 184d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return res; 185d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 186d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 187d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private boolean parseResponse() throws IOException { 188d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank boolean res = false; 189d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank while (nextTag(Tags.SEARCH_RESPONSE) != END) { 190d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (tag == Tags.SEARCH_STORE) { 191d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank parseStore(); 192d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else { 193d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank skipTag(); 194d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 195d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 196d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return res; 197d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 198d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 199d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private boolean parseStore() throws IOException { 200d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank EmailSyncAdapter adapter = new EmailSyncAdapter(mService); 201d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank EasEmailSyncParser parser = adapter.new EasEmailSyncParser(this, adapter); 202d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 203d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank boolean res = false; 204d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 205d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank while (nextTag(Tags.SEARCH_STORE) != END) { 206d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (tag == Tags.SEARCH_STATUS) { 207b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook String status = getValue(); 208d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SEARCH_TOTAL) { 209d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank mTotalResults = getValueInt(); 210d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SEARCH_RESULT) { 211d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank parseResult(parser, ops); 212d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else { 213d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank skipTag(); 214d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 215d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 216d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 217d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank try { 218d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank adapter.mContentResolver.applyBatch(EmailContent.AUTHORITY, ops); 219d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (Eas.USER_LOG) { 220d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank mService.userLog("Saved " + ops.size() + " search results"); 221d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 222d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } catch (RemoteException e) { 223d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Log.d(Logging.LOG_TAG, "RemoteException while saving search results."); 224d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } catch (OperationApplicationException e) { 225d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 226d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 227d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return res; 228d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 229d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank 230d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank private boolean parseResult(EasEmailSyncParser parser, 231d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank ArrayList<ContentProviderOperation> ops) throws IOException { 232d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank // Get an email sync parser for our incoming message data 233d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank boolean res = false; 234d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank Message msg = new Message(); 235d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank while (nextTag(Tags.SEARCH_RESULT) != END) { 236d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (tag == Tags.SYNC_CLASS) { 237d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank getValue(); 238d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SYNC_COLLECTION_ID) { 239d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank getValue(); 240d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SEARCH_LONG_ID) { 241d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.mProtocolSearchInfo = getValue(); 242d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else if (tag == Tags.SEARCH_PROPERTIES) { 243d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.mAccountKey = mService.mAccount.mId; 244d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.mMailboxKey = mService.mMailbox.mId; 245d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE; 246d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank parser.pushTag(tag); 247d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank parser.addData(msg, tag); 248d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank if (msg.mHtml != null) { 249d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.mHtml = TextUtilities.highlightTermsInHtml(msg.mHtml, mQuery); 250d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 251d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank msg.addSaveOps(ops); 252d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } else { 253d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank skipTag(); 254d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 255d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 256d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank return res; 257d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 258d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank } 259d2e4d4675d04e78591ebd38fd084fc2cdbe144a0Marc Blank} 260