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