package com.thaiopensource.validate.auto; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; import org.xml.sax.Locator; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import java.io.IOException; import java.util.Vector; import com.thaiopensource.validate.Schema; import com.thaiopensource.validate.IncorrectSchemaException; import com.thaiopensource.util.Localizer; import com.thaiopensource.util.PropertyMap; public class AutoSchemaReceiver implements SchemaReceiver { private final PropertyMap properties; private final Rewindable rewindable; private class Handler extends DefaultHandler implements SchemaFuture { private final XMLReader xr; private SchemaFuture sf = null; private Locator locator = null; private final Vector prefixMappings = new Vector(); private Handler(XMLReader xr) { this.xr = xr; } public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startPrefixMapping(String prefix, String uri) { prefixMappings.addElement(prefix); prefixMappings.addElement(uri); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { SchemaReceiverFactory srf = properties.get(SchemaReceiverFactory.PROPERTY); SchemaReceiver sr = srf.createSchemaReceiver(uri, properties); if (sr == null) { Localizer localizer = new Localizer(AutoSchemaReceiver.class); String detail = ("".equals(uri) ? localizer.message("no_namespace") : localizer.message("unknown_namespace", uri)); throw new SAXParseException(detail, locator); } sf = sr.installHandlers(xr); rewindable.willNotRewind(); ContentHandler contentHandler = xr.getContentHandler(); if (contentHandler == null) return; if (locator != null) { contentHandler.setDocumentLocator(locator); contentHandler = xr.getContentHandler(); } contentHandler.startDocument(); contentHandler = xr.getContentHandler(); for (int i = 0, len = prefixMappings.size(); i < len; i += 2) { contentHandler.startPrefixMapping((String)prefixMappings.elementAt(i), (String)prefixMappings.elementAt(i + 1)); contentHandler = xr.getContentHandler(); } contentHandler.startElement(uri, localName, qName, attributes); } public Schema getSchema() throws IncorrectSchemaException, SAXException, IOException { if (sf == null) throw new IncorrectSchemaException(); return sf.getSchema(); } public RuntimeException unwrapException(RuntimeException e) throws SAXException, IOException, IncorrectSchemaException { if (sf == null) return e; return sf.unwrapException(e); } } public AutoSchemaReceiver(PropertyMap properties, Rewindable rewindable) { this.properties = properties; this.rewindable = rewindable; } public SchemaFuture installHandlers(XMLReader xr) { Handler h = new Handler(xr); xr.setContentHandler(h); return h; } }