001/**
002 *
003 * Copyright 2019 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack.xml.xpp3;
018
019import java.io.Reader;
020import java.util.logging.Level;
021import java.util.logging.Logger;
022
023import org.jivesoftware.smack.xml.XmlPullParserException;
024import org.jivesoftware.smack.xml.XmlPullParserFactory;
025
026public class Xpp3XmlPullParserFactory implements XmlPullParserFactory {
027
028    private static final Logger LOGGER = Logger.getLogger(Xpp3XmlPullParserFactory.class.getName());
029
030    private static final org.xmlpull.v1.XmlPullParserFactory XPP3_XML_PULL_PARSER_FACTORY;
031
032    public static final String FEATURE_XML_ROUNDTRIP = "http://xmlpull.org/v1/doc/features.html#xml-roundtrip";
033
034    /**
035     * True if the XmlPullParser supports the XML_ROUNDTRIP feature.
036     */
037    public static final boolean XML_PULL_PARSER_SUPPORTS_ROUNDTRIP;
038
039    static {
040        org.xmlpull.v1.XmlPullParser xmlPullParser;
041        boolean roundtrip = false;
042        try {
043            XPP3_XML_PULL_PARSER_FACTORY = org.xmlpull.v1.XmlPullParserFactory.newInstance();
044            xmlPullParser = XPP3_XML_PULL_PARSER_FACTORY.newPullParser();
045            try {
046                xmlPullParser.setFeature(FEATURE_XML_ROUNDTRIP, true);
047                // We could successfully set the feature
048                roundtrip = true;
049            } catch (org.xmlpull.v1.XmlPullParserException e) {
050                // Doesn't matter if FEATURE_XML_ROUNDTRIP isn't available
051                LOGGER.log(Level.FINEST, "XmlPullParser does not support XML_ROUNDTRIP", e);
052            }
053        }
054        catch (org.xmlpull.v1.XmlPullParserException e) {
055            // Something really bad happened
056            throw new AssertionError(e);
057        }
058        XML_PULL_PARSER_SUPPORTS_ROUNDTRIP = roundtrip;
059    }
060
061    @Override
062    public Xpp3XmlPullParser newXmlPullParser(Reader reader) throws XmlPullParserException {
063        org.xmlpull.v1.XmlPullParser xpp3XmlPullParser;
064        try {
065            xpp3XmlPullParser = XPP3_XML_PULL_PARSER_FACTORY.newPullParser();
066            xpp3XmlPullParser.setFeature(org.xmlpull.v1.XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
067            xpp3XmlPullParser.setInput(reader);
068        } catch (org.xmlpull.v1.XmlPullParserException e) {
069            throw new XmlPullParserException(e);
070        }
071
072        if (XML_PULL_PARSER_SUPPORTS_ROUNDTRIP) {
073            try {
074                xpp3XmlPullParser.setFeature(FEATURE_XML_ROUNDTRIP, true);
075            }
076            catch (org.xmlpull.v1.XmlPullParserException e) {
077                LOGGER.log(Level.SEVERE,
078                                "XmlPullParser does not support XML_ROUNDTRIP, although it was first determined to be supported",
079                                e);
080            }
081        }
082
083        return new Xpp3XmlPullParser(xpp3XmlPullParser);
084    }
085
086}