1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage android.support.v7.mms; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.util.Log; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport org.xmlpull.v1.XmlPullParser; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport org.xmlpull.v1.XmlPullParserException; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.IOException; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Base class for a parser of XML resources 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddabstract class MmsXmlResourceParser { 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Parse the content 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws IOException 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws XmlPullParserException 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected abstract void parseRecord() throws IOException, XmlPullParserException; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the root tag of the content 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return the text of root tag 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected abstract String getRootTag(); 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private final StringBuilder mLogStringBuilder = new StringBuilder(); 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected final XmlPullParser mInputParser; 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected MmsXmlResourceParser(XmlPullParser parser) { 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mInputParser = parser; 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd void parse() { 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Find the first element 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (advanceToNextEvent(XmlPullParser.START_TAG) != XmlPullParser.START_TAG) { 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new XmlPullParserException("ApnsXmlProcessor: expecting start tag @" 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + xmlParserDebugContext()); 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (!getRootTag().equals(mInputParser.getName())) { 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.w(MmsService.TAG, "Carrier config does not start with " + getRootTag()); 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We are at the start tag 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (;;) { 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int nextEvent; 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Skipping spaces 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd while ((nextEvent = mInputParser.next()) == XmlPullParser.TEXT); 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (nextEvent == XmlPullParser.START_TAG) { 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Parse one record 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd parseRecord(); 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (nextEvent == XmlPullParser.END_TAG) { 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd throw new XmlPullParserException("Expecting start or end tag @" 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + xmlParserDebugContext()); 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (IOException e) { 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.w(MmsService.TAG, "XmlResourceParser: I/O failure", e); 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (XmlPullParserException e) { 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.w(MmsService.TAG, "XmlResourceParser: parsing failure", e); 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Move XML parser forward to next event type or the end of doc 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param eventType 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return The final event type we meet 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws XmlPullParserException 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @throws IOException 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected int advanceToNextEvent(int eventType) throws XmlPullParserException, IOException { 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (;;) { 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int nextEvent = mInputParser.next(); 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (nextEvent == eventType 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || nextEvent == XmlPullParser.END_DOCUMENT) { 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return nextEvent; 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return The debugging information of the parser's current position 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected String xmlParserDebugContext() { 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mLogStringBuilder.setLength(0); 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (mInputParser != null) { 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd try { 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int eventType = mInputParser.getEventType(); 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mLogStringBuilder.append(xmlParserEventString(eventType)); 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (eventType == XmlPullParser.START_TAG 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || eventType == XmlPullParser.END_TAG 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd || eventType == XmlPullParser.TEXT) { 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mLogStringBuilder.append('<').append(mInputParser.getName()); 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (int i = 0; i < mInputParser.getAttributeCount(); i++) { 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mLogStringBuilder.append(' ') 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .append(mInputParser.getAttributeName(i)) 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .append('=') 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .append(mInputParser.getAttributeValue(i)); 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd mLogStringBuilder.append("/>"); 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return mLogStringBuilder.toString(); 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } catch (XmlPullParserException e) { 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Log.w(MmsService.TAG, "XmlResourceParser exception", e); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return "Unknown"; 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static String xmlParserEventString(int event) { 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (event) { 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case XmlPullParser.START_DOCUMENT: return "START_DOCUMENT"; 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case XmlPullParser.END_DOCUMENT: return "END_DOCUMENT"; 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case XmlPullParser.START_TAG: return "START_TAG"; 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case XmlPullParser.END_TAG: return "END_TAG"; 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case XmlPullParser.TEXT: return "TEXT"; 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return Integer.toString(event); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 144