/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.jena.rdfxml.xmlinput.impl; import java.util.HashSet; import java.util.Set; import org.apache.jena.rdfxml.xmlinput.ARPErrorNumbers ; import org.apache.jena.rdfxml.xmlinput.states.Frame ; import org.xml.sax.SAXParseException; abstract public class QNameLexer implements Names, ARPErrorNumbers { final int bad; final int select; final Frame frame; public QNameLexer(Frame f, int good, int bad) { bad &= ~good; this.bad = bad; this.select = good|bad; this.frame = f; } private int xml(String wanted, int fl) { return (fl &select)== fl && wanted.equals(getLocalName()) && getUri().equals(xmlns) ? fl : 0; } abstract boolean isInRdfns(Taint taintMe) throws SAXParseException; abstract void error(Taint taintMe,int rslt) throws SAXParseException; abstract void deprecatedAttribute(Taint me,int rslt) throws SAXParseException; abstract String getLocalName(); abstract String getUri(); abstract String getQName(); private int rdf(Taint taintMe,String wanted, int fl) throws SAXParseException { if ((fl &select)== fl && wanted.equals(getLocalName())) { if (isInRdfns(taintMe)) return fl; if (getQName().toLowerCase().startsWith("rdf:")) frame.warning(taintMe,WARN_NOT_RDF_NAMESPACE,getQName() + " is not special. " + "The namespace binding of the RDF namespace is incorrect. It should be <"+rdfns+"> not <"+getUri()+">"); } return 0; } int lookup(Taint taintMe) throws SAXParseException { int rslt = lookupNoMsg(taintMe); if ((rslt&bad)!=0) { switch (rslt){ case A_DEPRECATED: deprecatedAttribute(taintMe,rslt); break; case A_BAGID: bagIDAttribute(taintMe,rslt); break; default: error(taintMe,rslt); } } return rslt; } abstract void bagIDAttribute(Taint taintMe, int rslt) throws SAXParseException; private int lookupNoMsg(Taint taintMe) throws SAXParseException { char firstChar; try { firstChar = getLocalName().charAt(0); } catch (StringIndexOutOfBoundsException e) { // Yes this really happens with the DOM one. // How disgusting. // When xmlns="eg:a" // xmlns is the prefix ... // System.err.println(getUri()); if (this.getUri().equals(xmlnsns)) return A_XMLNS; throw e; } switch (firstChar) { case 'b': /* base bagID */ switch (getLocalName().length()) { case 4: return xml("base",A_XMLBASE); case 5: return rdf(taintMe,"bagID",A_BAGID); } break; case 'l': /* lang li */ switch (getLocalName().length()) { case 2: return rdf(taintMe,"li",E_LI); case 4: return xml("lang",A_XMLLANG); } break; case 's': /* space */ return xml("space",A_XML_OTHER); case 'i': /* space */ return xml("id",A_XML_OTHER); case 'I': /* ID */ return rdf(taintMe,"ID",A_ID); case 'n': /* nodeID */ return rdf(taintMe,"nodeID",A_NODEID); case 'a': /* about aboutEach aboutEachPrefix */ switch (getLocalName().length()) { case 5: return rdf(taintMe,"about",A_ABOUT); case 9: return rdf(taintMe,"aboutEach",A_DEPRECATED); case 15: return rdf(taintMe,"aboutEachPrefix",A_DEPRECATED); } break; case 'r': /* resource */ return rdf(taintMe,"resource",A_RESOURCE); case 'R': /* resource */ return rdf(taintMe,"RDF",E_RDF); case 'd': /* datatype */ return rdf(taintMe,"datatype",A_DATATYPE); case 't': /* type */ return rdf(taintMe,"type",A_TYPE); case 'p': /* parseType */ return rdf(taintMe,"parseType",A_PARSETYPE); case 'D': /* Description */ return rdf(taintMe,"Description",E_DESCRIPTION); } return 0; } // static final Set rdfnames = new HashSet(); // static { // rdfnames.add("Description"); // rdfnames.add("RDF"); // rdfnames.add("li"); // } static final Set<String> knownRDFProperties = new HashSet<>(); static final Set<String> knownRDFTypes = knownRDFProperties; static { knownRDFTypes.add("Bag"); knownRDFTypes.add("Seq"); knownRDFTypes.add("Alt"); knownRDFTypes.add("List"); knownRDFTypes.add("XMLLiteral"); knownRDFTypes.add("Property"); knownRDFProperties.add("type"); knownRDFTypes.add("Statement"); knownRDFProperties.add("subject"); knownRDFProperties.add("predicate"); knownRDFProperties.add("object"); knownRDFProperties.add("value"); knownRDFProperties.add("first"); knownRDFProperties.add("rest"); // not strictly true. knownRDFProperties.add("nil"); } // static final Set knownBadRDFNames = new HashSet(); // static { // knownBadRDFNames.add("ID"); // knownBadRDFNames.add("about"); // knownBadRDFNames.add("aboutEach"); // knownBadRDFNames.add("aboutEachPrefix"); // knownBadRDFNames.add("resource"); // knownBadRDFNames.add("bagID"); // knownBadRDFNames.add("parseType"); // knownBadRDFNames.add("datatype"); // knownBadRDFNames.add("li"); // knownBadRDFNames.add("type"); // knownBadRDFNames.add("Description"); // knownBadRDFNames.add("nodeID"); // } protected static boolean isMemberProperty(String name) { if (name.startsWith("_")) { String number = name.substring(1); if (number.startsWith("-") || number.startsWith("0")) return false; try { Integer.parseInt(number); return true; } catch (NumberFormatException e) { try { // It might be > Integer.MAX_VALUE new java.math.BigInteger(number); return true; } catch (NumberFormatException ee) { return false; } } } return false; } static public boolean isKnownRDFProperty(String name) { return knownRDFProperties.contains(name) || isMemberProperty(name); } static public boolean isKnownNonMemberRDFProperty(String name) { return knownRDFProperties.contains(name); } }