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