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 public 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