/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* 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.
* !#
*/
package net.ontopia.topicmaps.xml;
import com.thaiopensource.datatype.DatatypeLibraryLoader;
import net.ontopia.utils.OntopiaRuntimeException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import com.thaiopensource.validate.Schema;
import com.thaiopensource.relaxng.SchemaFactory;
import com.thaiopensource.util.PropertyMapBuilder;
import com.thaiopensource.validate.ValidateProperty;
import com.thaiopensource.xml.sax.DraconianErrorHandler;
import com.thaiopensource.xml.sax.Jaxp11XMLReaderCreator;
/**
* INTERNAL: SAX2 content handler used for validating XTM documents
* using Jing.</p>
*/
public class XTMValidatingContentHandler implements ContentHandler {
static final String EL_TOPICMAP = "topicMap";
private ContentHandler child; // validated events are passed here
private ContentHandler validator; // validating handler
private Locator locator; // stored until we can pass on to validator
private XTMVersion xtm_version; // which XTM version to validate against
public static final String XTM_1_RNC = "xtm1.rnc";
public static final String XTM_2_RNC = "xtm2.rnc";
public XTMValidatingContentHandler(ContentHandler child) {
this(child, XTMVersion.XTM_1_0);
}
public XTMValidatingContentHandler(ContentHandler child, XTMVersion version) {
this.child = child;
this.xtm_version = version;
}
protected ContentHandler createValidator() {
String rnc;
if (xtm_version == XTMVersion.XTM_1_0)
rnc = XTM_1_RNC;
else if (xtm_version == XTMVersion.XTM_2_0 ||
xtm_version == XTMVersion.XTM_2_1)
rnc = XTM_2_RNC;
else
throw new OntopiaRuntimeException("Unknown XTM version: " + xtm_version);
InputSource src = new InputSource(XTMValidatingContentHandler.class.getResourceAsStream(rnc));
try {
SchemaFactory factory = new SchemaFactory();
factory.setXMLReaderCreator(new Jaxp11XMLReaderCreator());
factory.setErrorHandler(new DraconianErrorHandler());
factory.setDatatypeLibraryFactory(new DatatypeLibraryLoader());
Schema schema = factory.createSchema(src);
PropertyMapBuilder pmb = new PropertyMapBuilder();
pmb.put(ValidateProperty.ERROR_HANDLER, new DraconianErrorHandler());
return schema.createValidator(pmb.toPropertyMap()).getContentHandler();
} catch (Exception e) {
throw new OntopiaRuntimeException("INTERNAL ERROR: " + e, e);
}
}
public void startDocument () throws SAXException {
child.startDocument();
}
public void endDocument () throws SAXException {
child.endDocument();
}
public void startElement (String uri, String name, String qName, Attributes atts) throws SAXException {
// initialize validator
if (EL_TOPICMAP.equals(qName)) {
validator = createValidator();
if (locator != null) // if received already
validator.setDocumentLocator(locator);
validator.startDocument();
}
if (validator != null) validator.startElement(uri, name, qName, atts);
child.startElement(uri, name, qName, atts);
}
public void characters (char ch[], int start, int length) throws SAXException {
if (validator != null) validator.characters(ch, start, length);
child.characters(ch, start, length);
}
public void endElement (String uri, String name, String qName) throws SAXException {
if (validator != null) validator.endElement(uri, name, qName);
child.endElement(uri, name, qName);
// clear validator
if (EL_TOPICMAP.equals(qName)) {
validator.endDocument();
validator = null;
}
}
public void startPrefixMapping(java.lang.String prefix, java.lang.String uri) throws SAXException {
if (validator != null) validator.startPrefixMapping(prefix, uri);
}
public void endPrefixMapping(java.lang.String prefix) throws SAXException {
if (validator != null) validator.endPrefixMapping(prefix);
}
public void skippedEntity(String entityname) {
}
public void processingInstruction(String target, String data) {
}
public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
if (validator != null) validator.characters(ch, start, length);
child.characters(ch, start, length);
}
public void setDocumentLocator(Locator docloc) {
if (validator != null) validator.setDocumentLocator(docloc);
child.setDocumentLocator(docloc);
locator = docloc; // stored in case we receive it before we have validator
}
}