Android: Unable to create instance of a class: IllegalArgumentException: http://www.w3.org/2001/XMLSchema
Asked Answered
R

0

0

I am developing an Android app that should convert a valid Alert string (i.e.: in XML string format) to CAP Alert object. To do so, I am using this Google-Cap-Library.

Here is my code:

import android.app.Activity;
import android.os.Bundle;

import com.google.publicalerts.cap.AlertOrBuilder;
import com.google.publicalerts.cap.CapException;
import com.google.publicalerts.cap.CapValidator;
import com.google.publicalerts.cap.CapXmlParser;

import org.xml.sax.SAXParseException;

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    createAlertFromValidXml(new CapXmlParser(true));
}

public AlertOrBuilder createAlertFromValidXml(CapXmlParser parser) {
    AlertOrBuilder alert = null;
    try {
        alert = parser.parseFrom(getValidAlertXmlString());
    } catch (CapException e) {
        e.printStackTrace();
    } catch (SAXParseException e) {
        e.printStackTrace();
    }

    return alert;
}


private String getValidAlertXmlString() {
    return "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
            + "<alert xmlns=\"" + CapValidator.CAP_LATEST_XMLNS + "\">\n"
            + "<identifier>43b080713727</identifier>\n"
            + "<sender>[email protected]</sender>\n"
            + "<sent>2003-04-02T14:39:01-05:00</sent>\n"
            + "<status>Actual</status>\n"
            + "<msgType>Alert</msgType>\n"
            + "<source>a source</source>\n"
            + "<scope>Private</scope>\n"
            + "<addresses>\"address 1\" address2</addresses>\n"
            + "<code>abcde</code>\n"
            + "<code>fghij</code>\n"
            + "<note>a note</note>\n"

            + "<references>a,b,2002-04-02T14:39:01-05:00 </references>\n"

            + "<info>\n"
            + "<category>Security</category>\n"
            + "<category>Safety</category>\n"
            + "<event>Homeland Security Advisory System Update</event>\n"
            + "<urgency>Unknown</urgency>\n"
            + "<severity>Unknown</severity>\n"
            + "<certainty>Unknown</certainty>\n"
            + "<senderName>Department of Homeland Security</senderName>\n"
            + "<headline>Homeland Security Sets Code ORANGE</headline>\n"
            + "<description>DHS has set the threat level to ORANGE.</description>\n"
            + "<instruction>Take Protective Measures.</instruction>\n"
            + "<web>http://www.dhs.gov/dhspublic/display?theme=29</web>\n"
            + "</info>\n"

            + "<info>\n"
            + "<language>fr-CA</language>\n"
            + "<category>Safety</category>\n"
            + "<event>Homeland Security Advisory System Update</event>\n"
            + "<responseType>Evacuate</responseType>\n"
            + "<responseType>Shelter</responseType>\n"
            + "<urgency>Unknown</urgency>\n"
            + "<severity>Unknown</severity>\n"
            + "<certainty>Unknown</certainty>\n"
            + "<audience>an audience</audience>\n"
            + "<eventCode><valueName>EC</valueName><value>v1</value></eventCode>\n"
            + "<eventCode><valueName>EC2</valueName><value>v2</value></eventCode>\n"
            + "<effective>2003-04-02T14:39:01-05:00</effective>\n"
            + "<onset>2003-04-02T15:39:01+05:00</onset>\n"
            + "<expires>2003-04-02T16:39:01-00:00</expires>\n"
            + "<senderName>Department of Homeland Security</senderName>\n"
            + "<contact>a contact</contact>\n"
            + "<parameter>\n"
            + "<valueName>HSAS</valueName>\n"
            + "<value>ORANGE</value>\n"
            + "</parameter>\n"
            + "<parameter>\n"
            + "<valueName>p2</valueName>\n"
            + "<value>v2</value>\n"
            + "</parameter>\n"
            + "</info>\n"
            + "</alert>";
}

public String getXmlValues() {
    return "Test";
    }
}

However, when I run the app, it crashes and the logcat on Android-Studio shows me the following output:

enter image description here

UPDATE: CapXmlParser.java

package com.google.publicalerts.cap;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.protobuf.ByteString;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor.Type;
import com.google.publicalerts.cap.Alert;
import com.google.publicalerts.cap.CachedSaxInputSource;
import com.google.publicalerts.cap.CapException;
import com.google.publicalerts.cap.CapUtil;
import com.google.publicalerts.cap.CapValidator;
import com.google.publicalerts.cap.Circle;
import com.google.publicalerts.cap.Group;
import com.google.publicalerts.cap.NotCapException;
import com.google.publicalerts.cap.Point;
import com.google.publicalerts.cap.Polygon;
import com.google.publicalerts.cap.Reason;
import com.google.publicalerts.cap.Reasons;
import com.google.publicalerts.cap.ValuePair;
import com.google.publicalerts.cap.XPath;
import com.google.publicalerts.cap.XmlUtil;
import com.google.publicalerts.cap.CapException.ReasonType;
import com.google.publicalerts.cap.Reason.Level;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
import java.util.Stack;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class CapXmlParser {
    private static final Map<String, Schema> EXTENDED_SCHEMA_MAP = initSchemaMap(new String[]{"cap10_extended.xsd", "cap11_extended.xsd", "cap12_extended.xsd"});
    private static final Map<String, Schema> STRICT_SCHEMA_MAP = initSchemaMap(new String[]{"cap10.xsd", "cap11.xsd", "cap12.xsd"});
    private final boolean validate;
    private final Map<String, Schema> schemaMap;

    private static Map<String, Schema> initSchemaMap(String[] xsds) {
        SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
        String[] xmlns = new String[]{"http://www.incident.com/cap/1.0", "urn:oasis:names:tc:emergency:cap:1.1", "urn:oasis:names:tc:emergency:cap:1.2"};
        Builder schemas = ImmutableMap.builder();

        for(int i = 0; i < xsds.length; ++i) {
            StreamSource cap = new StreamSource(CapXmlParser.class.getResourceAsStream("schema/" + xsds[i]));

            try {
                schemas.put(xmlns[i], schemaFactory.newSchema(new Source[]{cap}));
            } catch (SAXException var7) {
                throw new RuntimeException(var7);
            }
        }

        return schemas.build();
    }

    public CapXmlParser(boolean validate) {
        this(validate, false);
    }

    public CapXmlParser(boolean validate, boolean strictXsdValidation) {
        this.validate = validate;
        this.schemaMap = strictXsdValidation?STRICT_SCHEMA_MAP:EXTENDED_SCHEMA_MAP;
    }

    public static Circle toCircle(String str) {
        if(str == null) {
            return null;
        } else {
            String[] pointRadius = str.trim().split("\\s+");
            if(pointRadius.length == 0) {
                return null;
            } else if(pointRadius.length != 2) {
                return null;
            } else {
                Point point = toPoint(pointRadius[0]);
                if(point == null) {
                    return null;
                } else {
                    float radius;
                    try {
                        radius = Float.parseFloat(pointRadius[1]);
                    } catch (NumberFormatException var5) {
                        return null;
                    }

                    return Circle.newBuilder().setPoint(point).setRadius((double)radius).buildPartial();
                }
            }
        }
    }

    static Point toPoint(String point) {
        String[] latlng = point.split(",");
        if(latlng.length != 2) {
            return null;
        } else {
            double latitude;
            double longitude;
            try {
                latitude = Double.parseDouble(latlng[0]);
                longitude = Double.parseDouble(latlng[1]);
            } catch (NumberFormatException var7) {
                return null;
            }

            return Point.newBuilder().setLatitude(latitude).setLongitude(longitude).buildPartial();
        }
    }

    public static Polygon toPolygon(String str) {
        if(str == null) {
            return null;
        } else {
            String[] pointStrs = str.trim().split("\\s+");
            if(!CapUtil.isEmptyOrWhitespace(str) && pointStrs.length != 0) {
                com.google.publicalerts.cap.Polygon.Builder polygon = Polygon.newBuilder();
                String[] var3 = pointStrs;
                int var4 = pointStrs.length;

                for(int var5 = 0; var5 < var4; ++var5) {
                    String pointStr = var3[var5];
                    Point point = toPoint(pointStr);
                    if(point == null) {
                        return null;
                    }

                    polygon.addPoint(point);
                }

                return polygon.buildPartial();
            } else {
                return null;
            }
        }
    }

    public static Polygon toPolygonNullIfTooFew(String str) {
        Polygon polygon = toPolygon(str);
        return polygon != null && polygon.getPointCount() < 4?null:polygon;
    }

    public final Alert parseFrom(String str) throws CapException, NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(str));
    }

    public final Alert parseFrom(String str, com.google.publicalerts.cap.Reasons.Builder reasons) throws NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(str), reasons);
    }

    public final Alert parseFrom(Reader reader) throws CapException, NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(reader));
    }

    public final Alert parseFrom(Reader reader, com.google.publicalerts.cap.Reasons.Builder reasons) throws NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(reader), reasons);
    }

    public final Alert parseFrom(InputSource is) throws CapException, NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(is));
    }

    public final Alert parseFrom(InputSource is, com.google.publicalerts.cap.Reasons.Builder reasons) throws NotCapException, SAXParseException {
        return this.parseFromInternal(new CachedSaxInputSource(is), reasons);
    }

    private Alert parseFromInternal(CachedSaxInputSource is) throws CapException, NotCapException, SAXParseException {
        com.google.publicalerts.cap.Reasons.Builder reasonsBuilder = Reasons.newBuilder();
        Alert alert = this.parseFromInternal(is, reasonsBuilder);
        Reasons reasons = reasonsBuilder.build();
        if(this.validate && reasons.containsWithLevelOrHigher(Level.ERROR)) {
            throw new CapException(reasons);
        } else {
            return alert;
        }
    }

    protected Alert parseFromInternal(CachedSaxInputSource is, com.google.publicalerts.cap.Reasons.Builder reasons) throws NotCapException, SAXParseException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        CapXmlParser.CapXmlHandler handler = new CapXmlParser.CapXmlHandler();

        try {
            String alert = this.getXmlns(is);
            if(!this.schemaMap.containsKey(alert)) {
                throw new NotCapException("Unsupported xmlns:" + alert);
            }

            is.reset();
            factory.setSchema((Schema)this.schemaMap.get(alert));
            XMLReader reader = XmlUtil.getXMLReader(factory);
            reader.setContentHandler(handler);
            reader.setErrorHandler(handler);
            reader.parse(is);
        } catch (IOException var7) {
            throw new RuntimeException(var7);
        } catch (SAXException var8) {
            if(var8 instanceof SAXParseException) {
                throw (SAXParseException)var8;
            }

            throw new RuntimeException(var8);
        } catch (ParserConfigurationException var9) {
            throw new RuntimeException(var9);
        }

        reasons.addAll(handler.getReasons());
        Alert alert1 = handler.getAlert();
        if(this.schemaMap != STRICT_SCHEMA_MAP) {
            reasons.addAll((new CapValidator()).validateAlert(alert1));
        }

        return alert1;
    }

    private String getXmlns(CachedSaxInputSource is) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XMLReader reader = XmlUtil.getXMLReader(factory);
        reader.setContentHandler(new CapXmlParser.XmlnsHandler());

        try {
            reader.parse(is);
            return null;
        } catch (CapXmlParser.AbortXmlnsParseException var5) {
            return var5.xmlns;
        }
    }

    static class CapXmlHandler extends DefaultHandler {
        private final StringBuilder characters = new StringBuilder();
        private final Stack<com.google.protobuf.Message.Builder> builderStack = new Stack();
        private final Stack<String> builderNameStack = new Stack();
        private final com.google.publicalerts.cap.Reasons.Builder reasons = Reasons.newBuilder();
        private final XPath xPath = new XPath();
        private boolean inSignature;
        private com.google.publicalerts.cap.Alert.Builder alertBuilder;
        private Alert alert;
        private String localName;

        public CapXmlHandler() {
        }

        public Alert getAlert() {
            return this.alert;
        }

        public Reasons getReasons() {
            return this.reasons.build();
        }

        public void error(SAXParseException e) throws SAXException {
            this.reasons.add(new Reason(this.xPath.toString(), ReasonType.OTHER, new Object[]{e.getMessage(), this.localName, this.characters.toString()}));
        }

        public void fatalError(SAXParseException e) throws SAXException {
            this.error(e);
        }

        public void warning(SAXParseException e) throws SAXException {
            this.error(e);
        }

        public void startElement(String uri, String localName, String qName, Attributes attributes) {
            this.localName = localName;
            this.characters.setLength(0);
            if(!this.inSignature) {
                FieldDescriptor fd = this.getField(localName);
                if(this.builderStack.isEmpty()) {
                    if(!"alert".equals(localName) || !CapValidator.CAP_XML_NAMESPACES.contains(uri)) {
                        throw new NotCapException();
                    }

                    this.alertBuilder = Alert.newBuilder();
                    this.alertBuilder.setXmlns(uri);
                    this.builderStack.push(this.alertBuilder);
                    this.builderNameStack.push(localName);
                    this.xPath.push("alert");
                } else if("Signature".equals(localName)) {
                    this.inSignature = true;
                } else if(fd != null) {
                    if(fd.getType() == Type.MESSAGE) {
                        this.builderStack.push(((com.google.protobuf.Message.Builder)this.builderStack.peek()).newBuilderForField(fd));
                        this.builderNameStack.push(localName);
                    }

                    this.xPath.push(localName);
                }

            }
        }

        public void endElement(String uri, String localName, String qName) {
            this.localName = localName;
            if(this.inSignature) {
                if("Signature".equals(localName)) {
                    this.inSignature = false;
                }

            } else {
                FieldDescriptor fd = this.getField(localName);
                if(fd == null) {
                    if(localName.equals(this.builderNameStack.peek())) {
                        com.google.protobuf.Message.Builder finishedBuilder;
                        if(this.builderStack.size() == 1) {
                            this.builderNameStack.pop();
                            finishedBuilder = (com.google.protobuf.Message.Builder)this.builderStack.pop();
                            if(finishedBuilder != null) {
                                this.alert = (Alert)finishedBuilder.buildPartial();
                            }
                        } else {
                            this.builderNameStack.pop();
                            finishedBuilder = (com.google.protobuf.Message.Builder)this.builderStack.pop();
                            fd = this.getField(localName);
                            if(fd != null) {
                                this.setOrAdd(fd, this.getComplexValue(finishedBuilder, this.characters.toString()));
                                this.characters.setLength(0);
                                this.xPath.pop();
                            }
                        }
                    }

                } else {
                    this.setOrAdd(fd, this.getPrimitiveValue(fd, this.characters.toString()));
                    this.characters.setLength(0);
                    if(fd != null) {
                        this.xPath.pop();
                    }

                }
            }
        }

        public void characters(char[] ch, int start, int length) {
            this.characters.append(ch, start, length);
        }

        void setOrAdd(FieldDescriptor fd, Object value) {
            this.setOrAdd((com.google.protobuf.Message.Builder)this.builderStack.peek(), fd, value);
        }

        void setOrAdd(com.google.protobuf.Message.Builder builder, FieldDescriptor fd, Object value) {
            if(value != null) {
                if(fd.isRepeated()) {
                    builder.addRepeatedField(fd, value);
                } else if(!builder.hasField(fd)) {
                    builder.setField(fd, value);
                }

            }
        }

        private FieldDescriptor getField(String localName) {
            return this.builderStack.isEmpty()?null:CapUtil.findFieldByName((com.google.protobuf.Message.Builder)this.builderStack.peek(), localName);
        }

        Object getPrimitiveValue(FieldDescriptor fd, String val) {
            switch(null.$SwitchMap$com$google$protobuf$Descriptors$FieldDescriptor$Type[fd.getType().ordinal()]) {
            case 1:
            case 2:
            case 3:
                try {
                    return Integer.valueOf(Integer.parseInt(val));
                } catch (NumberFormatException var11) {
                    ;
                } catch (NullPointerException var12) {
                    ;
                }
                break;
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
                try {
                    return Long.valueOf(Long.parseLong(val));
                } catch (NumberFormatException var9) {
                    ;
                } catch (NullPointerException var10) {
                    ;
                }
                break;
            case 9:
                try {
                    return Double.valueOf(Double.parseDouble(val));
                } catch (NumberFormatException var7) {
                    ;
                } catch (NullPointerException var8) {
                    ;
                }
                break;
            case 10:
                return Boolean.valueOf(Boolean.parseBoolean(val));
            case 11:
                return val;
            case 12:
                try {
                    return Float.valueOf(Float.parseFloat(val));
                } catch (NumberFormatException var5) {
                    ;
                } catch (NullPointerException var6) {
                    ;
                }
                break;
            case 13:
                return ByteString.copyFromUtf8(val);
            case 14:
                if("Very Likely".equals(val)) {
                    val = "VERY_LIKELY";
                } else if(val != null) {
                    val = CapUtil.underscoreCase(val).toUpperCase();
                }

                EnumDescriptor enumType = fd.getEnumType();
                EnumValueDescriptor evd = enumType.findValueByName(val);
                if(evd == null) {
                    evd = enumType.findValueByName(val + "_" + enumType.getName().toUpperCase());
                }

                if(evd == null) {
                    return null;
                }

                return evd;
            case 15:
            case 16:
            case 17:
            case 18:
            default:
                throw new IllegalArgumentException(fd.getName() + " has unsupported type " + fd.getType());
            }

            return null;
        }

        MessageOrBuilder getComplexValue(com.google.protobuf.Message.Builder builder, String str) {
            Object message;
            if(builder instanceof com.google.publicalerts.cap.Polygon.Builder) {
                message = this.toPolygonWithErrors(str);
            } else if(builder instanceof com.google.publicalerts.cap.Circle.Builder) {
                message = CapXmlParser.toCircle(str);
            } else if(builder instanceof com.google.publicalerts.cap.Group.Builder) {
                message = this.toGroup(str);
            } else if(builder instanceof com.google.publicalerts.cap.ValuePair.Builder && "http://www.incident.com/cap/1.0".equals(this.alertBuilder.getXmlns())) {
                message = this.toCap10ValuePair(str);
            } else {
                message = builder.buildPartial();
            }

            return (MessageOrBuilder)message;
        }

        Polygon toPolygonWithErrors(String str) {
            Polygon polygon = CapXmlParser.toPolygon(str);
            if(polygon == null) {
                this.reasons.add(new Reason(this.xPath.toString(), ReasonType.INVALID_POLYGON, new Object[]{str.length() > 50?str.substring(0, 47) + "...":str}));
                return null;
            } else {
                if(polygon.getPointCount() < 4) {
                    this.reasons.add(new Reason(this.xPath.toString(), ReasonType.INVALID_POLYGON, new Object[]{str.length() > 50?str.substring(0, 47) + "...":str}));
                }

                return polygon;
            }
        }

        Group toGroup(String str) {
            com.google.publicalerts.cap.Group.Builder group = Group.newBuilder();
            boolean inQuotes = false;
            boolean lastWasEscape = false;
            char[] chars = str.toCharArray();
            StringBuilder sb = new StringBuilder();
            char[] var7 = chars;
            int var8 = chars.length;

            for(int var9 = 0; var9 < var8; ++var9) {
                char ch = var7[var9];
                boolean unescapedQuote = false;
                if(ch == 34 && !lastWasEscape) {
                    inQuotes = !inQuotes;
                    unescapedQuote = true;
                }

                if(!inQuotes && Character.isWhitespace(ch)) {
                    if(sb.length() > 0) {
                        group.addValue(sb.toString());
                        sb.setLength(0);
                    }
                } else if(!unescapedQuote) {
                    sb.append(ch);
                }

                lastWasEscape = ch == 47;
            }

            if(sb.length() > 0) {
                group.addValue(sb.toString());
            }

            if(group.getValueCount() == 0) {
                return null;
            } else {
                return group.buildPartial();
            }
        }

        ValuePair toCap10ValuePair(String str) {
            String[] nameValue = str.split("=");
            return nameValue.length != 2?null:ValuePair.newBuilder().setValueName(nameValue[0].trim()).setValue(nameValue[1].trim()).build();
        }
    }

    static class XmlnsHandler extends DefaultHandler {
        XmlnsHandler() {
        }

        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if("alert".equals(localName) && CapValidator.CAP_XML_NAMESPACES.contains(uri)) {
                throw new CapXmlParser.AbortXmlnsParseException(uri);
            } else {
                throw new NotCapException();
            }
        }
    }

    static class AbortXmlnsParseException extends RuntimeException {
        private static final long serialVersionUID = 6359526632284475695L;
        private final String xmlns;

        public AbortXmlnsParseException(String xmlns) {
            super(xmlns);
            this.xmlns = xmlns;
        }
    }
}
Robison answered 15/2, 2017 at 11:29 Comment(3)
Share CapXmlParser.java codeMcmurry
@Mcmurry : Please check the update. Here is CapXmlParser.java also from the GitHub (same file with more comments only): (github.com/google/cap-library/blob/master/java/src/com/google/…).Robison
Check this out : github.com/google/cap-library/issues/14 it may helps youMcmurry

© 2022 - 2024 — McMap. All rights reserved.