1 package net.sf.saxon.dom; 2 import net.sf.saxon.event.PipelineConfiguration; 3 import net.sf.saxon.event.Receiver; 4 import net.sf.saxon.event.SaxonLocator; 5 import net.sf.saxon.om.Name; 6 import net.sf.saxon.om.NamePool; 7 import net.sf.saxon.style.StandardNames; 8 import net.sf.saxon.trans.DynamicError; 9 import net.sf.saxon.trans.XPathException; 10 import org.w3c.dom.*; 11 import org.xml.sax.helpers.AttributesImpl ; 12 import org.xml.sax.helpers.NamespaceSupport ; 13 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 17 23 24 public class DOMSender implements SaxonLocator { 25 private Receiver receiver; 26 private PipelineConfiguration pipe; 27 28 private NamespaceSupport nsSupport = new NamespaceSupport (); 29 private AttributesImpl attlist = new AttributesImpl (); 30 private String [] parts = new String [3]; 31 private String [] elparts = new String [3]; 32 private HashMap nsDeclarations = new HashMap (10); 33 protected Node root = null; 34 protected String systemId; 35 36 39 40 public void setPipelineConfiguration(PipelineConfiguration pipe) { 41 this.pipe = pipe; 42 } 43 44 48 49 public void setReceiver (Receiver receiver) { 50 this.receiver = receiver; 51 } 52 53 56 57 public void setStartNode(Node start) { 58 root = start; 59 } 60 61 65 66 public void setSystemId(String systemId) { 67 this.systemId = systemId; 68 } 69 70 74 75 public void send() throws XPathException { 76 if (root==null) { 77 throw new DynamicError("DOMSender: no start node defined"); 78 } 79 if (receiver==null) { 80 throw new DynamicError("DOMSender: no receiver defined"); 81 } 82 83 receiver.setSystemId(systemId); 84 pipe.setLocationProvider(this); 85 receiver.setPipelineConfiguration(pipe); 86 87 receiver.open(); 88 if (root.getNodeType() == Node.ELEMENT_NODE) { 89 sendElement((Element)root); 90 } else { 91 receiver.startDocument(0); 93 walkNode(root); 94 receiver.endDocument(); 95 } 96 receiver.close(); 97 } 98 99 104 105 private void sendElement(Element startNode) throws XPathException { 106 Element node = startNode; 107 NamedNodeMap topAtts = gatherNamespaces(node, false); 108 while (true) { 109 gatherNamespaces(node, true); 110 Node parent = node.getParentNode(); 111 if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) { 112 node = (Element)parent; 113 } else { 114 break; 115 } 116 } 117 outputElement(startNode, topAtts); 118 } 119 120 126 127 private void walkNode (Node node) throws XPathException { 128 if (node.hasChildNodes()) { 129 NodeList nit = node.getChildNodes(); 130 for (int i=0; i<nit.getLength(); i++) { 131 Node child = nit.item(i); 132 switch (child.getNodeType()) { 133 case Node.DOCUMENT_NODE: 134 break; case Node.ELEMENT_NODE: 136 Element element = (Element)child; 137 NamedNodeMap atts = gatherNamespaces(element, false); 138 139 outputElement(element, atts); 140 141 nsSupport.popContext(); 142 break; 143 case Node.ATTRIBUTE_NODE: break; 145 case Node.PROCESSING_INSTRUCTION_NODE: 146 receiver.processingInstruction( 147 ((ProcessingInstruction)child).getTarget(), 148 ((ProcessingInstruction)child).getData(), 149 0, 0); 150 break; 151 case Node.COMMENT_NODE: { 152 String text = ((Comment)child).getData(); 153 if (text!=null) { 154 receiver.comment(text, 0, 0); 155 } 156 break; 157 } 158 case Node.TEXT_NODE: 159 case Node.CDATA_SECTION_NODE: { 160 String text = ((CharacterData)child).getData(); 161 if (text!=null) { 162 receiver.characters(text, 0, 0); 163 } 164 break; 165 } 166 case Node.ENTITY_REFERENCE_NODE: 167 walkNode(child); 168 break; 169 default: 170 break; } 172 } 173 } 174 175 } 176 177 private void outputElement(Element element, NamedNodeMap atts) throws XPathException { 178 String [] elparts2 = nsSupport.processName(element.getTagName(), elparts, false); 179 if (elparts2==null) { 180 throw new DynamicError("Undeclared namespace in " + element.getTagName()); 181 } 182 String uri = elparts2[0]; 183 String local = elparts2[1]; 184 String prefix = Name.getPrefix(elparts2[2]); 185 186 NamePool namePool = pipe.getConfiguration().getNamePool(); 187 int nameCode = namePool.allocate(prefix, uri, local); 188 189 receiver.startElement(nameCode, StandardNames.XDT_UNTYPED, 0, 0); 190 for (Iterator iter = nsDeclarations.keySet().iterator(); iter.hasNext();) { 191 String nsprefix = (String )iter.next(); 192 String nsuri = (String )nsDeclarations.get(nsprefix); 193 receiver.namespace(namePool.allocateNamespaceCode(nsprefix, nsuri), 0); 194 } 195 196 if (atts != null) { 197 for (int a2=0; a2<atts.getLength(); a2++) { 198 Attr att = (Attr)atts.item(a2); 199 String attname = att.getName(); 200 if (!attname.equals("xmlns") && !attname.startsWith("xmlns:")) { 201 String [] parts2 = nsSupport.processName(attname, parts, true); 203 if (parts2==null) { 204 throw new DynamicError("Undeclared namespace in " + attname); 205 } 206 String atturi = parts2[0]; 207 String attlocal = parts2[1]; 208 String attprefix = Name.getPrefix(parts2[2]); 209 210 int attCode = namePool.allocate(attprefix, atturi, attlocal); 211 212 receiver.attribute(attCode, StandardNames.XDT_UNTYPED_ATOMIC, att.getValue(), 0, 0); 213 } 214 } 215 } 216 receiver.startContent(); 217 218 walkNode(element); 219 220 receiver.endElement(); 221 } 222 223 229 230 private NamedNodeMap gatherNamespaces(Element element, boolean cumulative) { 231 if (!cumulative) { 232 nsSupport.pushContext(); 233 attlist.clear(); 234 nsDeclarations.clear(); 235 } 236 237 242 try { 243 String prefix = element.getPrefix(); 244 String uri = element.getNamespaceURI(); 245 if (prefix==null) prefix=""; 246 if (uri==null) uri=""; 247 if (nsDeclarations.get(prefix)==null) { 249 nsSupport.declarePrefix(prefix, uri); 250 nsDeclarations.put(prefix, uri); 251 } 252 } catch (Throwable err) { 253 } 255 256 NamedNodeMap atts = element.getAttributes(); 257 258 if (atts == null) { 260 return null; 261 } 262 for (int a1=0; a1<atts.getLength(); a1++) { 263 Attr att = (Attr)atts.item(a1); 264 String attname = att.getName(); 265 if (attname.equals("xmlns")) { 266 if (nsDeclarations.get("")==null) { 268 String uri = att.getValue(); 269 nsSupport.declarePrefix("", uri); 270 nsDeclarations.put("", uri); 271 } 272 } else if (attname.startsWith("xmlns:")) { 273 String prefix = attname.substring(6); 275 if (nsDeclarations.get(prefix)==null) { 276 String uri = att.getValue(); 277 nsSupport.declarePrefix(prefix, uri); 278 nsDeclarations.put(prefix, uri); 279 } 280 } else if (attname.indexOf(':')>=0) { 281 try { 282 String prefix = att.getPrefix(); 283 String uri = att.getNamespaceURI(); 284 if (nsDeclarations.get(prefix)==null) { 286 nsSupport.declarePrefix(prefix, uri); 287 nsDeclarations.put(prefix, uri); 289 } 290 } catch (Throwable err) { 291 } 293 } 294 } 295 return atts; 296 } 297 298 302 public int getColumnNumber() { 303 return -1; 304 } 305 306 public int getLineNumber() { 307 return -1; 308 } 309 310 public String getPublicId() { 311 return null; 312 } 313 314 public String getSystemId() { 315 return systemId; 316 } 317 318 public String getSystemId(int locationId) { 319 return getSystemId(); 320 } 321 322 public int getLineNumber(int locationId) { 323 return getLineNumber(); 324 } 325 326 337 } 338 | Popular Tags |