Home | History | Annotate | Download | only in adapter
      1 /* Copyright (C) 2010 The Android Open Source Project.
      2  *
      3  * Licensed under the Apache License, Version 2.0 (the "License");
      4  * you may not use this file except in compliance with the License.
      5  * You may obtain a copy of the License at
      6  *
      7  *      http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software
     10  * distributed under the License is distributed on an "AS IS" BASIS,
     11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12  * See the License for the specific language governing permissions and
     13  * limitations under the License.
     14  */
     15 
     16 package com.android.exchange.adapter;
     17 
     18 import com.android.exchange.Eas;
     19 import com.android.mail.utils.LogUtils;
     20 
     21 import java.io.IOException;
     22 import java.io.InputStream;
     23 
     24 /**
     25  * Parse the result of a MoveItems command.
     26  */
     27 public class MoveItemsParser extends Parser {
     28     private static final String TAG = Eas.LOG_TAG;
     29     private int mStatusCode = 0;
     30     private String mNewServerId;
     31     private String mSourceServerId;
     32 
     33     // These are the EAS status codes for MoveItems
     34     private static final int STATUS_NO_SOURCE_FOLDER = 1;
     35     private static final int STATUS_NO_DESTINATION_FOLDER = 2;
     36     private static final int STATUS_SUCCESS = 3;
     37     private static final int STATUS_SOURCE_DESTINATION_SAME = 4;
     38     private static final int STATUS_INTERNAL_ERROR = 5;
     39     private static final int STATUS_ALREADY_EXISTS = 6;
     40     private static final int STATUS_LOCKED = 7;
     41 
     42     // These are the status values we return to callers
     43     public static final int STATUS_CODE_SUCCESS = 1;
     44     public static final int STATUS_CODE_REVERT = 2;
     45     public static final int STATUS_CODE_RETRY = 3;
     46 
     47     public MoveItemsParser(InputStream in) throws IOException {
     48         super(in);
     49     }
     50 
     51     public int getStatusCode() {
     52         if (mStatusCode == 0) {
     53             LogUtils.e(TAG, "Trying to get status for MoveItems, but no status was set");
     54             // TODO: We currently treat empty responses as retry, so for now we'll do the same for
     55             // partially empty responses.
     56             return STATUS_CODE_RETRY;
     57         }
     58         return mStatusCode;
     59     }
     60 
     61     public String getNewServerId() {
     62         return mNewServerId;
     63     }
     64 
     65     public String getSourceServerId() {
     66         return mSourceServerId;
     67     }
     68 
     69     private void parseResponse() throws IOException {
     70         while (nextTag(Tags.MOVE_RESPONSE) != END) {
     71             if (tag == Tags.MOVE_STATUS) {
     72                 int status = getValueInt();
     73                 // Convert the EAS status code with our external codes
     74                 switch(status) {
     75                     case STATUS_SUCCESS:
     76                     case STATUS_SOURCE_DESTINATION_SAME:
     77                     case STATUS_ALREADY_EXISTS:
     78                         // Same destination and already exists are ok with us; we'll continue as
     79                         // if the move succeeded
     80                         mStatusCode = STATUS_CODE_SUCCESS;
     81                         break;
     82                     case STATUS_LOCKED:
     83                         // This sounds like a transient error, so we can safely retry
     84                         mStatusCode = STATUS_CODE_RETRY;
     85                         break;
     86                     case STATUS_NO_SOURCE_FOLDER:
     87                     case STATUS_NO_DESTINATION_FOLDER:
     88                     case STATUS_INTERNAL_ERROR:
     89                     default:
     90                         // These are non-recoverable, so we'll revert the message to its original
     91                         // mailbox.  If there's an unknown response, revert
     92                         mStatusCode = STATUS_CODE_REVERT;
     93                         break;
     94                 }
     95                 if (status != STATUS_SUCCESS) {
     96                     // There's not much to be done if this fails
     97                     LogUtils.w(TAG, "Error in MoveItems: %d", status);
     98                 }
     99             } else if (tag == Tags.MOVE_DSTMSGID) {
    100                 mNewServerId = getValue();
    101                 LogUtils.d(TAG, "Moved message id is now: %s", mNewServerId);
    102             } else if (tag == Tags.MOVE_SRCMSGID) {
    103                 mSourceServerId = getValue();
    104                 LogUtils.d(TAG, "Source message id is: %s", mNewServerId);
    105             } else {
    106                 skipTag();
    107             }
    108         }
    109     }
    110 
    111     @Override
    112     public boolean parse() throws IOException {
    113         boolean res = false;
    114         if (nextTag(START_DOCUMENT) != Tags.MOVE_MOVE_ITEMS) {
    115             throw new IOException();
    116         }
    117         while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
    118             if (tag == Tags.MOVE_RESPONSE) {
    119                 parseResponse();
    120             } else {
    121                 skipTag();
    122             }
    123         }
    124         return res;
    125     }
    126 }
    127 
    128