1 package net.sf.saxon.event; 2 3 import net.sf.saxon.AugmentedSource; 4 import net.sf.saxon.Configuration; 5 import net.sf.saxon.StandardErrorHandler; 6 import net.sf.saxon.om.ExternalObjectModel; 7 import net.sf.saxon.om.NamePool; 8 import net.sf.saxon.om.NodeInfo; 9 import net.sf.saxon.om.Validation; 10 import net.sf.saxon.pull.PullProvider; 11 import net.sf.saxon.pull.PullPushCopier; 12 import net.sf.saxon.pull.PullSource; 13 import net.sf.saxon.trans.DynamicError; 14 import net.sf.saxon.trans.XPathException; 15 import net.sf.saxon.type.Type; 16 import org.xml.sax.*; 17 18 import javax.xml.transform.Source ; 19 import javax.xml.transform.dom.DOMSource ; 20 import javax.xml.transform.sax.SAXSource ; 21 import javax.xml.transform.stream.StreamSource ; 22 import java.util.List ; 23 24 27 28 public class Sender { 29 30 PipelineConfiguration pipe; 31 public Sender (PipelineConfiguration pipe) { 32 this.pipe = pipe; 33 } 34 35 42 43 public void send(Source source, Receiver receiver) 44 throws XPathException { 45 send(source, receiver, false); 46 } 47 48 58 59 public void send(Source source, Receiver receiver, boolean isFinal) 60 throws XPathException { 61 Configuration config = pipe.getConfiguration(); 62 receiver.setPipelineConfiguration(pipe); 63 receiver.setSystemId(source.getSystemId()); 64 65 int validation = config.getSchemaValidationMode(); 66 if (isFinal) { 67 validation |= Validation.VALIDATE_OUTPUT; 69 } 70 71 XMLReader parser = null; 72 if (source instanceof AugmentedSource) { 73 int localValidate = ((AugmentedSource)source).getSchemaValidation(); 74 if (localValidate != Validation.DEFAULT) { 75 validation = localValidate; 76 } 77 parser = ((AugmentedSource)source).getXMLReader(); 78 79 List filters = ((AugmentedSource)source).getFilters(); 80 if (filters != null) { 81 for (int i=filters.size()-1; i>=0; i--) { 82 ProxyReceiver filter = (ProxyReceiver)filters.get(i); 83 filter.setPipelineConfiguration(pipe); 84 filter.setSystemId(source.getSystemId()); 85 filter.setUnderlyingReceiver(receiver); 86 receiver = filter; 87 } 88 } 89 90 source = ((AugmentedSource)source).getContainedSource(); 91 } 92 93 if (source instanceof NodeInfo) { 94 NodeInfo ns = (NodeInfo)source; 95 String baseURI = ns.getBaseURI(); 96 int val = validation & Validation.VALIDATION_MODE_MASK; 97 if (val != Validation.PRESERVE) { 98 receiver = config.getDocumentValidator(receiver, baseURI, config.getNamePool(), val, null); 99 } 100 101 int kind = ns.getNodeKind(); 102 if (kind != Type.DOCUMENT && kind != Type.ELEMENT) { 103 throw new IllegalArgumentException ("Sender can only handle document or element nodes"); 104 } 105 receiver.setSystemId(baseURI); 106 sendDocumentInfo(ns, receiver, pipe.getConfiguration().getNamePool()); 107 return; 108 109 } else if (source instanceof PullSource) { 110 sendPullSource((PullSource)source, receiver, validation); 111 return; 112 113 } else if (source instanceof SAXSource ) { 114 sendSAXSource((SAXSource )source, receiver, validation); 115 return; 116 117 } else if (source instanceof StreamSource ) { 118 StreamSource ss = (StreamSource )source; 119 String url = source.getSystemId(); 120 InputSource is = new InputSource(url); 121 is.setCharacterStream(ss.getReader()); 122 is.setByteStream(ss.getInputStream()); 123 boolean reuseParser = false; 124 if (parser == null) { 125 parser = config.getSourceParser(); 126 reuseParser = true; 127 } 128 SAXSource sax = new SAXSource (parser, is); 129 sax.setSystemId(source.getSystemId()); 130 sendSAXSource(sax, receiver, validation); 131 if (reuseParser) { 132 config.reuseSourceParser(parser); 133 } 134 return; 135 } else { 136 if ((validation & Validation.VALIDATION_MODE_MASK) != Validation.PRESERVE) { 137 receiver = config.getDocumentValidator(receiver, 139 source.getSystemId(), 140 config.getNamePool(), 141 validation, null); 142 } 143 144 Source newSource = config.getSourceResolver().resolveSource(source, config); 146 if (newSource instanceof StreamSource || 147 newSource instanceof SAXSource || 148 newSource instanceof NodeInfo || 149 newSource instanceof PullSource) { 150 send(newSource, receiver, isFinal); 151 } 152 153 155 List externalObjectModels = config.getExternalObjectModels(); 156 for (int m=0; m<externalObjectModels.size(); m++) { 157 ExternalObjectModel model = (ExternalObjectModel)externalObjectModels.get(m); 158 boolean done = model.sendSource(source, receiver, pipe); 159 if (done) { 160 return; 161 } 162 } 163 164 } 165 if (source instanceof DOMSource ) { 166 throw new DynamicError("DOMSource cannot be processed: check that saxon8-dom.jar is on the classpath"); 167 } 168 throw new DynamicError("A source of type " + source.getClass().getName() + 169 " is not supported in this environment"); 170 } 171 172 173 private void sendDocumentInfo(NodeInfo top, Receiver receiver, NamePool namePool) 174 throws XPathException { 175 if (top.getNamePool() != namePool) { 176 NamePoolConverter converter = new NamePoolConverter(top.getNamePool(), namePool); 178 converter.setUnderlyingReceiver(receiver); 179 receiver = converter; 180 } 181 DocumentSender sender = new DocumentSender(top); 182 sender.send(receiver); 183 } 184 185 209 private void sendSAXSource(SAXSource source, Receiver receiver, int validation) 210 throws XPathException { 211 XMLReader parser = source.getXMLReader(); 212 boolean reuseParser = false; 213 if (parser==null) { 214 SAXSource ss = new SAXSource (); 215 ss.setInputSource(source.getInputSource()); 216 ss.setSystemId(source.getSystemId()); 217 parser = pipe.getConfiguration().getSourceParser(); 218 ss.setXMLReader(parser); 219 source = ss; 220 reuseParser = true; 221 } 222 223 if (parser.getErrorHandler()==null) { 224 parser.setErrorHandler(new StandardErrorHandler(pipe.getErrorListener())); 225 } 226 227 try { 228 parser.setFeature("http://xml.org/sax/features/namespaces", true); 229 } catch (SAXNotSupportedException err) { throw new DynamicError( 231 "The SAX2 parser does not recognize the 'namespaces' feature"); 232 } catch (SAXNotRecognizedException err) { 233 throw new DynamicError( 234 "The SAX2 parser does not support setting the 'namespaces' feature to true"); 235 } 236 237 try { 238 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 239 } catch (SAXNotSupportedException err) { throw new DynamicError( 241 "The SAX2 parser does not recognize the 'namespace-prefixes' feature"); 242 } catch (SAXNotRecognizedException err) { 243 throw new DynamicError( 244 "The SAX2 parser does not support setting the 'namespace-prefixes' feature to false"); 245 } 246 247 if ((validation & Validation.VALIDATION_MODE_MASK) != Validation.PRESERVE) { 248 Configuration config = pipe.getConfiguration(); 250 receiver = config.getDocumentValidator(receiver, 251 source.getSystemId(), 252 config.getNamePool(), 253 validation, null); 254 } 255 256 ReceivingContentHandler ce = new ReceivingContentHandler(); 257 ce.setReceiver(receiver); 258 ce.setPipelineConfiguration(pipe); 259 parser.setContentHandler(ce); 260 parser.setDTDHandler(ce); 261 262 try { 263 parser.setProperty("http://xml.org/sax/properties/lexical-handler", ce); 264 } catch (SAXNotSupportedException err) { } catch (SAXNotRecognizedException err) { 266 } 267 268 try { 269 parser.parse(source.getInputSource()); 270 } catch (SAXException err) { 271 Exception nested = err.getException(); 272 if (nested instanceof XPathException) { 273 throw (XPathException)nested; 274 } else if (nested instanceof RuntimeException ) { 275 throw (RuntimeException )nested; 276 } else { 277 throw new DynamicError(err); 278 } 279 } catch (java.io.IOException err) { 280 throw new DynamicError(err); 281 } 282 if (reuseParser) { 283 pipe.getConfiguration().reuseSourceParser(parser); 284 } 285 } 286 287 private void sendPullSource(PullSource source, Receiver receiver, int validation) 288 throws XPathException { 289 if (validation != Validation.PRESERVE && validation != Validation.STRIP) { 290 throw new DynamicError("Validation is not currently supported with a PullSource"); 291 } 292 receiver.open(); 293 PullProvider provider = source.getPullProvider(); 294 provider.setPipelineConfiguration(pipe); 295 receiver.setPipelineConfiguration(pipe); 296 PullPushCopier copier = new PullPushCopier(provider, receiver); 297 copier.copy(); 298 receiver.close(); 299 } 300 301 } 302 303 | Popular Tags |