001 package com.thaiopensource.validate.auto;
002
003 import org.xml.sax.XMLReader;
004 import org.xml.sax.SAXException;
005 import org.xml.sax.Locator;
006 import org.xml.sax.Attributes;
007 import org.xml.sax.ContentHandler;
008 import org.xml.sax.SAXParseException;
009 import org.xml.sax.helpers.DefaultHandler;
010
011 import java.io.IOException;
012 import java.util.Vector;
013
014 import com.thaiopensource.validate.Schema;
015 import com.thaiopensource.validate.IncorrectSchemaException;
016 import com.thaiopensource.util.Localizer;
017 import com.thaiopensource.util.PropertyMap;
018
019 public class AutoSchemaReceiver implements SchemaReceiver {
020 private final PropertyMap properties;
021 private final Rewindable rewindable;
022
023 private class Handler extends DefaultHandler implements SchemaFuture {
024 private final XMLReader xr;
025 private SchemaFuture sf = null;
026 private Locator locator = null;
027 private final Vector prefixMappings = new Vector();
028
029 private Handler(XMLReader xr) {
030 this.xr = xr;
031 }
032
033 public void setDocumentLocator(Locator locator) {
034 this.locator = locator;
035 }
036
037 public void startPrefixMapping(String prefix, String uri) {
038 prefixMappings.addElement(prefix);
039 prefixMappings.addElement(uri);
040 }
041
042 public void startElement(String uri, String localName,
043 String qName, Attributes attributes)
044 throws SAXException {
045 SchemaReceiverFactory srf = SchemaReceiverFactory.PROPERTY.get(properties);
046 SchemaReceiver sr = srf.createSchemaReceiver(uri, properties);
047 if (sr == null) {
048 Localizer localizer = new Localizer(AutoSchemaReceiver.class);
049 String detail = ("".equals(uri)
050 ? localizer.message("no_namespace")
051 : localizer.message("unknown_namespace", uri));
052 throw new SAXParseException(detail, locator);
053 }
054 sf = sr.installHandlers(xr);
055 rewindable.willNotRewind();
056 ContentHandler contentHandler = xr.getContentHandler();
057 if (contentHandler == null)
058 return;
059 if (locator != null) {
060 contentHandler.setDocumentLocator(locator);
061 contentHandler = xr.getContentHandler();
062 }
063 contentHandler.startDocument();
064 contentHandler = xr.getContentHandler();
065 for (int i = 0, len = prefixMappings.size(); i < len; i += 2) {
066 contentHandler.startPrefixMapping((String)prefixMappings.elementAt(i),
067 (String)prefixMappings.elementAt(i + 1));
068 contentHandler = xr.getContentHandler();
069 }
070 contentHandler.startElement(uri, localName, qName, attributes);
071 }
072
073 public Schema getSchema() throws IncorrectSchemaException, SAXException, IOException {
074 if (sf == null)
075 throw new IncorrectSchemaException();
076 return sf.getSchema();
077 }
078
079 public RuntimeException unwrapException(RuntimeException e) throws SAXException, IOException, IncorrectSchemaException {
080 if (sf == null)
081 return e;
082 return sf.unwrapException(e);
083 }
084 }
085
086 public AutoSchemaReceiver(PropertyMap properties, Rewindable rewindable) {
087 this.properties = properties;
088 this.rewindable = rewindable;
089 }
090
091 public SchemaFuture installHandlers(XMLReader xr) {
092 Handler h = new Handler(xr);
093 xr.setContentHandler(h);
094 return h;
095 }
096 }