1 package net.sf.saxon.dom; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.event.Receiver; 5 import net.sf.saxon.event.PipelineConfiguration; 6 import net.sf.saxon.expr.XPathContext; 7 import net.sf.saxon.om.*; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.trans.DynamicError; 10 import net.sf.saxon.value.SequenceExtent; 11 import net.sf.saxon.value.Value; 12 import org.w3c.dom.Document ; 13 import org.w3c.dom.Node ; 14 import org.w3c.dom.NodeList ; 15 16 import javax.xml.transform.Result ; 17 import javax.xml.transform.Source ; 18 import javax.xml.transform.dom.DOMResult ; 19 import javax.xml.transform.dom.DOMSource ; 20 import javax.xml.parsers.DocumentBuilderFactory ; 21 import javax.xml.parsers.DocumentBuilder ; 22 import javax.xml.parsers.ParserConfigurationException ; 23 import java.util.ArrayList ; 24 import java.util.List ; 25 import java.util.HashSet ; 26 import java.io.Serializable ; 27 28 33 34 public class DOMObjectModel implements ExternalObjectModel, Serializable { 35 36 public DOMObjectModel() {} 37 38 41 42 public boolean isRecognizedNode(Object object) { 43 return object instanceof Node ; 44 } 45 46 53 54 public boolean isRecognizedNodeClass(Class nodeClass) { 55 return Node .class.isAssignableFrom(nodeClass); 56 } 57 58 65 66 public boolean isRecognizedNodeListClass(Class nodeClass) { 67 return NodeList .class.isAssignableFrom(nodeClass); 68 } 69 70 75 76 public Receiver getDocumentBuilder(Result result) throws XPathException { 77 if (result instanceof DOMResult ) { 78 DOMEmitter emitter = new DOMEmitter(); 79 Node root = ((DOMResult )result).getNode(); 80 if (root == null) { 81 try { 82 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 83 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 84 Document out = docBuilder.newDocument(); 85 ((DOMResult )result).setNode(out); 86 emitter.setNode(out); 87 } catch (ParserConfigurationException e) { 88 throw new DynamicError(e); 89 } 90 } else { 91 emitter.setNode(root); 92 } 93 return emitter; 94 } 95 return null; 96 } 97 98 103 104 public boolean sendSource(Source source, Receiver receiver, PipelineConfiguration pipe) throws XPathException { 105 if (source instanceof DOMSource ) { 106 Node startNode = ((DOMSource )source).getNode(); 107 DOMSender driver = new DOMSender(); 108 driver.setStartNode(startNode); 109 driver.setReceiver(receiver); 110 driver.setPipelineConfiguration(pipe); 111 driver.setSystemId(source.getSystemId()); 112 driver.send(); 113 return true; 114 } 115 return false; 116 } 117 118 122 123 public NodeInfo unravel(Source source, Configuration config) { 124 125 if (source instanceof DOMSource ) { 126 NodeInfo start; 127 Node dsnode = ((DOMSource )source).getNode(); 128 if (dsnode instanceof NodeOverNodeInfo) { 129 start = ((NodeOverNodeInfo)dsnode).getUnderlyingNodeInfo(); 131 } else { 132 Document dom; 134 if (dsnode.getNodeType() == Node.DOCUMENT_NODE) { 135 dom = (Document )dsnode; 136 } else { 137 dom = dsnode.getOwnerDocument(); 138 } 139 DocumentWrapper docWrapper = new DocumentWrapper(dom, source.getSystemId(), config); 140 start = docWrapper.wrap(dsnode); 141 } 142 return start; 143 } 144 return null; 145 } 146 147 153 154 public Value convertObjectToXPathValue(Object object, Configuration config) throws XPathException { 155 if (object instanceof org.w3c.dom.NodeList ) { 156 NodeList list = ((NodeList )object); 157 NodeInfo[] nodes = new NodeInfo[list.getLength()]; 158 for (int i=0; i<list.getLength(); i++) { 159 if (list.item(i) instanceof NodeOverNodeInfo) { 160 nodes[i] = ((NodeOverNodeInfo)list.item(i)).getUnderlyingNodeInfo(); 161 } else { 162 DocumentInfo doc = wrapDocument(list.item(i), "", config); 163 NodeInfo node = wrapNode(doc, list.item(i)); 164 nodes[i] = node; 165 } 166 } 167 return new SequenceExtent(nodes); 168 169 } else if (object instanceof NodeOverNodeInfo) { 172 return Value.asValue(((NodeOverNodeInfo)object).getUnderlyingNodeInfo()); 173 } else { 174 return null; 175 } 176 } 177 178 187 188 public Object convertXPathValueToObject(Value value, Class target, XPathContext context) throws XPathException { 189 boolean requireDOM = 193 (Node .class.isAssignableFrom(target) || (target == NodeList .class) || 194 (target.isArray() && Node .class.isAssignableFrom(target.getComponentType()))); 195 196 199 boolean allowDOM = 200 (target == Object .class || target.isAssignableFrom(ArrayList .class) || 201 target.isAssignableFrom(HashSet .class) || 202 (target.isArray() && target.getComponentType() == Object .class)); 203 if (!(requireDOM || allowDOM)) { 204 return null; 205 } 206 List nodes = new ArrayList (20); 207 208 SequenceIterator iter = value.iterate(context); 209 while (true) { 210 Item item = iter.next(); 211 if (item == null) { 212 break; 213 } 214 if (item instanceof VirtualNode) { 215 Object o = ((VirtualNode)item).getUnderlyingNode(); 216 if (o instanceof Node ) { 217 nodes.add(o); 218 } else { 219 if (requireDOM) { 220 DynamicError err = new DynamicError("Extension function required class " + target.getName() + 221 "; supplied value of class " + item.getClass().getName() + 222 " could not be converted"); 223 throw err; 224 }; 225 } 226 } else if (requireDOM) { 227 if (item instanceof NodeInfo) { 228 nodes.add(NodeOverNodeInfo.wrap((NodeInfo)item)); 229 } else { 230 DynamicError err = new DynamicError("Extension function required class " + target.getName() + 231 "; supplied value of class " + item.getClass().getName() + 232 " could not be converted"); 233 throw err; 234 } 235 } else { 236 return null; } 238 } 239 240 if (nodes.size() == 0 && !requireDOM) { 241 return null; } 243 if (Node .class.isAssignableFrom(target)) { 244 if (nodes.size() != 1) { 245 DynamicError err = new DynamicError("Extension function requires a single DOM Node" + 246 "; supplied value contains " + nodes.size() + " nodes"); 247 throw err; 248 } 249 return nodes.get(0); 250 } else if (target == NodeList .class) { 252 return new DOMNodeList(nodes); 253 } else if (target.isArray() && target.getComponentType() == Node .class) { 254 Node [] array = new Node [nodes.size()]; 255 nodes.toArray(array); 256 return array; 257 } else if (target.isAssignableFrom(ArrayList .class)) { 258 return nodes; 259 } else if (target.isAssignableFrom(HashSet .class)) { 260 return new HashSet (nodes); 261 } else { 262 return null; 264 } 265 } 266 267 276 277 public DocumentInfo wrapDocument(Object node, String baseURI, Configuration config) { 278 if (node instanceof DocumentOverNodeInfo) { 279 return (DocumentInfo)((DocumentOverNodeInfo)node).getUnderlyingNodeInfo(); 280 } 281 if (node instanceof NodeOverNodeInfo) { 282 return ((NodeOverNodeInfo)node).getUnderlyingNodeInfo().getDocumentRoot(); 283 } 284 if (node instanceof org.w3c.dom.Node ) { 285 if (((Node )node).getNodeType() == Node.DOCUMENT_NODE) { 286 Document doc = (org.w3c.dom.Document )node; 287 return new DocumentWrapper(doc, baseURI, config); 288 } else { 289 Document doc = ((org.w3c.dom.Node )node).getOwnerDocument(); 290 return new DocumentWrapper(doc, baseURI, config); 291 } 292 } 293 throw new IllegalArgumentException ("Unknown node class " + node.getClass()); 294 } 295 296 304 305 public NodeInfo wrapNode(DocumentInfo document, Object node) { 306 return ((DocumentWrapper)document).wrap((Node )node); 307 } 308 309 316 317 public Object convertToNodeList(SequenceExtent extent) { 318 try { 319 NodeList nodeList = DOMNodeList.checkAndMake(extent); 320 return nodeList; 321 } catch (XPathException e) { 322 return null; 323 } 324 } 325 } 326 327 328 | Popular Tags |