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 }