001 package com.oxygenxml.validate.isoschematron;
002
003 import com.thaiopensource.util.PropertyMap;
004 import com.thaiopensource.validate.ValidateProperty;
005 import com.thaiopensource.validate.Validator;
006 import com.thaiopensource.xml.sax.DelegatingContentHandler;
007 import org.xml.sax.ContentHandler;
008 import org.xml.sax.DTDHandler;
009 import org.xml.sax.ErrorHandler;
010 import org.xml.sax.InputSource;
011 import org.xml.sax.Locator;
012 import org.xml.sax.SAXException;
013
014 import javax.xml.transform.Templates;
015 import javax.xml.transform.Transformer;
016 import javax.xml.transform.TransformerConfigurationException;
017 import javax.xml.transform.TransformerException;
018 import javax.xml.transform.sax.SAXResult;
019 import javax.xml.transform.sax.SAXSource;
020
021 class ValidatorImpl extends DelegatingContentHandler implements Validator {
022 private final Transformer transformer;
023 private Locator locator;
024 private TransformerException transformerException;
025
026 private final Object contentHandlerMonitor = new Object();
027 private final Object parseMonitor = new Object();
028 private final Object transformMonitor = new Object();
029 private Thread transformThread;
030 private final ContentHandler outputHandler;
031
032 class BlockingReader extends XMLReaderImpl {
033 public void parse(InputSource in) throws SAXException {
034 synchronized (parseMonitor) {
035 synchronized (contentHandlerMonitor) {
036 contentHandlerMonitor.notify();
037 }
038 try {
039 parseMonitor.wait();
040 }
041 catch (InterruptedException e) {
042 throw new SAXException(e);
043 }
044 }
045 }
046
047 public void setContentHandler(ContentHandler handler) {
048 setDelegate(handler);
049 }
050
051 public ContentHandler getContentHandler() {
052 return getDelegate();
053 }
054
055 }
056
057 ValidatorImpl(Templates templates, PropertyMap properties) {
058 ErrorHandler eh = ValidateProperty.ERROR_HANDLER.get(properties);
059 outputHandler = new OutputHandler(eh);
060 try {
061 transformer = templates.newTransformer();
062 // XXX set up transformer with a resolver that uses the resolver
063 // XXX and XMLReaderCreator from properties
064 // XXX set up transformer with an ErrorListener that just throws
065 }
066 catch (TransformerConfigurationException e) {
067 throw new RuntimeException("could not create transformer");
068 }
069 }
070
071 public ContentHandler getContentHandler() {
072 return this;
073 }
074
075 public DTDHandler getDTDHandler() {
076 return null;
077 }
078
079 public void reset() {
080 if (transformThread != null) {
081 synchronized (transformMonitor) {
082 transformThread.interrupt();
083 try {
084 transformMonitor.wait();
085 }
086 catch (InterruptedException e) { }
087 transformThread = null;
088 }
089 }
090 transformerException = null;
091 locator = null;
092 }
093
094 public void setDocumentLocator(Locator locator) {
095 this.locator = locator;
096 }
097
098 public void startDocument()
099 throws SAXException {
100 final SAXSource source = new SAXSource(new BlockingReader(),
101 new InputSource(""));
102 transformThread = new Thread(new Runnable() {
103 public void run() {
104 try {
105 transformer.transform(source, new SAXResult(outputHandler));
106 }
107 catch (TransformerException e) {
108 transformerException = e;
109 }
110 finally {
111 synchronized (transformMonitor) {
112 transformMonitor.notify();
113 }
114 }
115 }
116 }, "Transform");
117 synchronized (contentHandlerMonitor) {
118 transformThread.start();
119 try {
120 contentHandlerMonitor.wait();
121 }
122 catch (InterruptedException e) {
123 throw new SAXException(e);
124 }
125 }
126 if (locator != null)
127 super.setDocumentLocator(locator);
128 super.startDocument();
129 }
130
131 public void endDocument()
132 throws SAXException {
133 super.endDocument();
134 synchronized (transformMonitor) {
135 synchronized (parseMonitor) {
136 parseMonitor.notify();
137 }
138 try {
139 transformMonitor.wait();
140 }
141 catch (InterruptedException e) {
142 throw new SAXException(e);
143 }
144 finally {
145 transformThread = null;
146 }
147 }
148 if (transformerException != null)
149 throw toSAXException(transformerException);
150 }
151
152 static SAXException toSAXException(TransformerException transformerException) {
153 // Unwrap where possible
154 Throwable wrapped = transformerException.getException();
155 if (wrapped instanceof SAXException)
156 return (SAXException)wrapped;
157 if (wrapped instanceof RuntimeException)
158 throw (RuntimeException)wrapped;
159 if (wrapped instanceof Exception)
160 return new SAXException((Exception)wrapped);
161 return new SAXException(transformerException);
162 }
163 }