/* * =| ADAPTIVE RUNTIME PLATFORM |======================================================================================= * * (C) Copyright 2013-2014 Carlos Lozano Diez t/a Adaptive.me <http://adaptive.me>. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * * Original author: * * * Carlos Lozano Diez * <http://github.com/carloslozano> * <http://twitter.com/adaptivecoder> * <mailto:carlos@adaptive.me> * * Contributors: * * * Francisco Javier Martin Bueno * <https://github.com/kechis> * <mailto:kechis@gmail.com> * * ===================================================================================================================== */ package me.adaptive.arp.common.parser.plist; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import me.adaptive.arp.api.AppRegistryBridge; import me.adaptive.arp.api.ILogging; import me.adaptive.arp.api.ILoggingLogLevel; public class PListParser { private final static String PLIST_TAG = "plist"; private final static String DICT_TAG = "dict"; private final static String KEY_TAG = "key"; private final static String VALUE_TAG = "string"; // logger private static final String LOG_TAG = "PListParser"; private static ILogging logger; private static final Pattern ESCAPE_XML_CHARS = Pattern.compile("[\"&'<>]"); private static PListParser instance = null; protected PListParser() { // Exists only to defeat instantiation. logger = AppRegistryBridge.getInstance().getLoggingBridge(); } public static PListParser getInstance() { if(instance == null) { instance = new PListParser(); } return instance; } public static PList parse(InputStream is) { PList plist = new PList(); try { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); factory.setValidating(false); factory.setFeature(Xml.FEATURE_RELAXED, true); XmlPullParser parser = factory.newPullParser(); parser.setInput(is, "UTF-8"); int event = parser.next(); while (event != XmlPullParser.END_DOCUMENT) { String name; switch (event) { case XmlPullParser.START_TAG: name = parser.getName(); if (PLIST_TAG.equals(name)) { // root node, do nothing } else if (DICT_TAG.equals(name)) { // dictionary node plist.setValues(parseDictionary(parser)); } else { throw new XmlPullParserException( "Unexpected element found [" + event + "," + name + "]"); } break; case XmlPullParser.END_TAG: name = parser.getName(); if (PLIST_TAG.equals(name)) { // root node, do nothing } else { throw new XmlPullParserException( "Unexpected element found [" + event + "," + name + "]"); } break; } event = parser.next(); } } catch (Exception ex) { plist = null; logger.log(ILoggingLogLevel.Error,LOG_TAG, "Parse Error: " + ex.getLocalizedMessage()); } if (plist != null) { logger.log(ILoggingLogLevel.Debug,LOG_TAG, "Parse Result is: " + plist.toString()); } else { logger.log(ILoggingLogLevel.Debug,LOG_TAG, "Parse Result is null"); } return plist; } private static Map<String, String> parseDictionary(XmlPullParser parser) throws IOException, XmlPullParserException { Map<String, String> map = new HashMap<String, String>(); String key = null; String value = null; int event = parser.next(); while ((event != XmlPullParser.END_TAG) || !DICT_TAG.equals(parser.getName())) { switch (event) { case XmlPullParser.START_TAG: String name = parser.getName(); if (KEY_TAG.equals(name)) { key = getText(parser, KEY_TAG); } else if (VALUE_TAG.equals(name)) { value = getText(parser, VALUE_TAG); map.put(key, value); } break; } event = parser.next(); } return map; } private static String getText(XmlPullParser parser, String tag) throws IOException, XmlPullParserException { int event = parser.getEventType(); if ((event != XmlPullParser.START_TAG) || !tag.equals(parser.getName())) { throw new XmlPullParserException("Unexpected element found [" + event + "," + parser.getName() + "]"); } StringBuilder sb = new StringBuilder(); event = parser.next(); while (event == XmlPullParser.TEXT) { sb.append(parser.getText()); event = parser.next(); } String text = sb.toString(); if ((event != XmlPullParser.END_TAG) || !tag.equals(parser.getName())) { throw new XmlPullParserException("Unexpected element found [" + event + "," + parser.getName() + "]"); } return text; } public static String escapeXml2(String s) { Matcher m = ESCAPE_XML_CHARS.matcher(s); StringBuffer buf = new StringBuffer(); while (m.find()) { switch (m.group().codePointAt(0)) { case '"': m.appendReplacement(buf, """); break; case '&': m.appendReplacement(buf, "&"); break; case '\'': m.appendReplacement(buf, "'"); break; case '<': m.appendReplacement(buf, "<"); break; case '>': m.appendReplacement(buf, ">"); break; } } m.appendTail(buf); return buf.toString(); } }