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 }