Home | History | Annotate | Download | only in adapter
      1 package com.android.exchange.adapter;
      2 
      3 import android.content.ContentProviderOperation;
      4 import android.content.ContentResolver;
      5 import android.content.Context;
      6 import android.content.OperationApplicationException;
      7 import android.os.RemoteException;
      8 
      9 import com.android.emailcommon.Logging;
     10 import com.android.emailcommon.provider.Account;
     11 import com.android.emailcommon.provider.EmailContent;
     12 import com.android.emailcommon.provider.Mailbox;
     13 import com.android.emailcommon.provider.EmailContent.Message;
     14 import com.android.emailcommon.utility.TextUtilities;
     15 import com.android.exchange.Eas;
     16 import com.android.mail.utils.LogUtils;
     17 
     18 import java.io.IOException;
     19 import java.io.InputStream;
     20 import java.util.ArrayList;
     21 
     22 /**
     23  * Parse the result of a Search command
     24  */
     25 public class SearchParser extends Parser {
     26     private static final String LOG_TAG = Logging.LOG_TAG;
     27     private final Context mContext;
     28     private final ContentResolver mContentResolver;
     29     private final Mailbox mMailbox;
     30     private final Account mAccount;
     31     private final String mQuery;
     32     private int mTotalResults;
     33 
     34     public SearchParser(final Context context, final ContentResolver resolver,
     35         final InputStream in, final Mailbox mailbox, final Account account,
     36         String query)
     37             throws IOException {
     38         super(in);
     39         mContext = context;
     40         mContentResolver = resolver;
     41         mMailbox = mailbox;
     42         mAccount = account;
     43         mQuery = query;
     44     }
     45 
     46     public int getTotalResults() {
     47         return mTotalResults;
     48     }
     49 
     50     @Override
     51     public boolean parse() throws IOException {
     52         boolean res = false;
     53         if (nextTag(START_DOCUMENT) != Tags.SEARCH_SEARCH) {
     54             throw new IOException();
     55         }
     56         while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
     57             if (tag == Tags.SEARCH_STATUS) {
     58                 String status = getValue();
     59                 if (Eas.USER_LOG) {
     60                     LogUtils.d(Logging.LOG_TAG, "Search status: " + status);
     61                 }
     62             } else if (tag == Tags.SEARCH_RESPONSE) {
     63                 parseResponse();
     64             } else {
     65                 skipTag();
     66             }
     67         }
     68         return res;
     69     }
     70 
     71     private boolean parseResponse() throws IOException {
     72         boolean res = false;
     73         while (nextTag(Tags.SEARCH_RESPONSE) != END) {
     74             if (tag == Tags.SEARCH_STORE) {
     75                 parseStore();
     76             } else {
     77                 skipTag();
     78             }
     79         }
     80         return res;
     81     }
     82 
     83     private boolean parseStore() throws IOException {
     84         EmailSyncParser parser = new EmailSyncParser(this, mContext, mContentResolver,
     85                 mMailbox, mAccount);
     86         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
     87         boolean res = false;
     88 
     89         while (nextTag(Tags.SEARCH_STORE) != END) {
     90             if (tag == Tags.SEARCH_STATUS) {
     91                 getValue();
     92             } else if (tag == Tags.SEARCH_TOTAL) {
     93                 mTotalResults = getValueInt();
     94             } else if (tag == Tags.SEARCH_RESULT) {
     95                 parseResult(parser, ops);
     96             } else {
     97                 skipTag();
     98             }
     99         }
    100 
    101         try {
    102             // FLAG: In EmailSyncParser.commit(), we have complicated logic to constrain the size
    103             // of the batch, and fall back to one op at a time if that fails. We don't have any
    104             // such logic here, but we probably should.
    105             mContentResolver.applyBatch(EmailContent.AUTHORITY, ops);
    106             LogUtils.d(Logging.LOG_TAG, "Saved %s search results", ops.size());
    107         } catch (RemoteException e) {
    108             LogUtils.d(Logging.LOG_TAG, "RemoteException while saving search results.");
    109         } catch (OperationApplicationException e) {
    110         }
    111 
    112         return res;
    113     }
    114 
    115     private boolean parseResult(EmailSyncParser parser,
    116             ArrayList<ContentProviderOperation> ops) throws IOException {
    117         boolean res = false;
    118         Message msg = new Message();
    119         while (nextTag(Tags.SEARCH_RESULT) != END) {
    120             if (tag == Tags.SYNC_CLASS) {
    121                 getValue();
    122             } else if (tag == Tags.SYNC_COLLECTION_ID) {
    123                 getValue();
    124             } else if (tag == Tags.SEARCH_LONG_ID) {
    125                 msg.mProtocolSearchInfo = getValue();
    126             } else if (tag == Tags.SEARCH_PROPERTIES) {
    127                 msg.mAccountKey = mAccount.mId;
    128                 msg.mMailboxKey = mMailbox.mId;
    129                 msg.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;
    130                 // Delegate parsing of the properties to the EmailSyncParser.
    131 
    132                 // We push a new <Properties> tag onto the EmailSyncParser. It will parse
    133                 // until it consumes the </Properties>
    134                 parser.pushTag(tag);
    135                 // Since the EmailSyncParser is responsible for consuming the </Properties>
    136                 // tag, we need to remove it from our stack or it will be double counted.
    137                 pop();
    138 
    139                 parser.addData(msg, tag);
    140                 if (msg.mHtml != null) {
    141                     msg.mHtml = TextUtilities.highlightTermsInHtml(msg.mHtml, mQuery);
    142                 }
    143                 msg.addSaveOps(ops);
    144             } else {
    145                 skipTag();
    146             }
    147         }
    148         return res;
    149     }
    150 }
    151