1 28 29 package org.jibx.extras; 30 31 import java.io.IOException ; 32 import java.util.ArrayList ; 33 34 import javax.xml.parsers.DocumentBuilderFactory ; 35 import javax.xml.parsers.ParserConfigurationException ; 36 37 import org.jibx.runtime.JiBXException; 38 import org.jibx.runtime.impl.UnmarshallingContext; 39 import org.w3c.dom.Attr ; 40 import org.w3c.dom.Document ; 41 import org.w3c.dom.Element ; 42 import org.w3c.dom.NamedNodeMap ; 43 import org.w3c.dom.Node ; 44 import org.w3c.dom.NodeList ; 45 46 54 55 public class DomMapperBase extends DocumentModelMapperBase 56 { 57 58 protected Document m_document; 59 60 61 protected String m_defaultNamespaceURI; 62 63 64 protected int m_defaultNamespaceIndex; 65 66 72 73 protected DomMapperBase() throws JiBXException { 74 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 75 dbf.setNamespaceAware(true); 76 try { 77 m_document = dbf.newDocumentBuilder().newDocument(); 78 } catch (ParserConfigurationException e) { 79 throw new JiBXException("Unable to create DOM document", e); 80 } 81 } 82 83 91 92 private int findNamespaceIndex(String prefix, String uri) { 93 if ((prefix == null || "".equals(prefix)) && 94 (uri == null || "".equals(uri))) { 95 return 0; 96 } else if ("xml".equals(prefix) && XML_NAMESPACE.equals(uri)) { 97 return 1; 98 } else { 99 if (prefix == null) { 100 if (m_defaultNamespaceURI == null) { 101 int index = m_xmlWriter.getPrefixIndex(""); 102 if (index >= 0) { 103 m_defaultNamespaceURI = getNamespaceUri(index); 104 m_defaultNamespaceIndex = index; 105 if (m_defaultNamespaceURI.equals(uri)) { 106 return index; 107 } else { 108 return -1; 109 } 110 } else { 111 return -1; 112 } 113 } else { 114 return m_defaultNamespaceURI.equals(uri) ? 115 m_defaultNamespaceIndex : -1; 116 } 117 } else { 118 int index = m_xmlWriter.getPrefixIndex(prefix); 119 if (index >= 0) { 120 return getNamespaceUri(index).equals(uri) ? 121 index : -1; 122 } else { 123 return -1; 124 } 125 } 126 } 127 } 128 129 136 137 protected void marshalNode(Node node) throws JiBXException, IOException { 138 switch (node.getNodeType()) { 139 140 case Node.CDATA_SECTION_NODE: 141 m_xmlWriter.writeCData(node.getNodeValue()); 142 break; 143 144 case Node.COMMENT_NODE: 145 m_xmlWriter.writeComment(node.getNodeValue()); 146 break; 147 148 case Node.ELEMENT_NODE: 149 marshalElement((Element )node); 150 break; 151 152 case Node.ENTITY_REFERENCE_NODE: 153 m_xmlWriter.writeEntityRef(node.getNodeName()); 154 break; 155 156 case Node.PROCESSING_INSTRUCTION_NODE: 157 m_xmlWriter.writePI(node.getNodeName(), 158 node.getNodeValue()); 159 break; 160 161 case Node.TEXT_NODE: 162 m_xmlWriter.writeTextContent(node.getNodeValue()); 163 break; 164 165 default: 166 break; 167 } 168 } 169 170 177 178 protected void marshalContent(NodeList content) 179 throws JiBXException, IOException { 180 int size = content.getLength(); 181 for (int i = 0; i < size; i++) { 182 marshalNode(content.item(i)); 183 } 184 } 185 186 193 194 protected void marshalElement(Element element) 195 throws JiBXException, IOException { 196 197 String prefix = element.getPrefix(); 199 String uri = element.getNamespaceURI(); 200 int nsi = findNamespaceIndex(prefix, uri); 201 ArrayList nss = null; 202 int defind = -1; 203 String defuri = null; 204 NamedNodeMap attrs = element.getAttributes(); 205 int size = attrs.getLength(); 206 for (int i = 0; i < size; i++) { 207 Attr attr = (Attr )attrs.item(i); 208 if (XMLNS_NAMESPACE.equals(attr.getNamespaceURI())) { 209 210 String declpref = attr.getLocalName(); 212 if ("xmlns".equals(declpref)) { 213 declpref = null; 214 } 215 String decluri = attr.getValue(); 216 if (findNamespaceIndex(declpref, decluri) < 0) { 217 if (nss == null) { 218 nss = new ArrayList (); 219 } 220 nss.add(declpref == null ? "" : declpref); 221 nss.add(decluri == null ? "" : decluri); 222 if (declpref == null) { 223 defind = (nss.size() / 2) - 1; 224 defuri = decluri; 225 } 226 if (uri == decluri) { 227 nsi = defind; 228 } 229 } 230 } 231 } 232 233 String [] uris = null; 235 if (nss == null) { 236 m_xmlWriter.startTagOpen(nsi, element.getLocalName()); 237 } else { 238 int base = getNextNamespaceIndex(); 239 if (defind >= 0) { 240 m_defaultNamespaceIndex = base + defind; 241 m_defaultNamespaceURI = defuri; 242 } 243 int length = nss.size() / 2; 244 uris = new String [length]; 245 int[] nums = new int[length]; 246 String [] prefs = new String [length]; 247 for (int i = 0; i < length; i++) { 248 prefs[i] = (String )nss.get(i*2); 249 uris[i] = (String )nss.get(i*2+1); 250 nums[i] = base + i; 251 if (nsi < 0 && uri.equals(uris[i])) { 252 if ((prefix == null && prefs[i] == "") || 253 (prefix != null && prefix.equals(prefs[i]))) { 254 nsi = base + i; 255 } 256 } 257 } 258 m_xmlWriter.pushExtensionNamespaces(uris); 259 m_xmlWriter.startTagNamespaces(nsi, element.getLocalName(), 260 nums, prefs); 261 if (defind >= 0) { 262 m_defaultNamespaceIndex = defind; 263 m_defaultNamespaceURI = defuri; 264 } 265 } 266 267 for (int i = 0; i < size; i++) { 269 Attr attr = (Attr )attrs.item(i); 270 if (!XMLNS_NAMESPACE.equals(attr.getNamespaceURI())) { 271 int index = 0; 272 String apref = attr.getPrefix(); 273 if (apref != null) { 274 index = findNamespaceIndex(apref, attr.getNamespaceURI()); 275 } 276 m_xmlWriter.addAttribute(index, attr.getLocalName(), 277 attr.getValue()); 278 } 279 } 280 281 NodeList nodes = element.getChildNodes(); 283 size = nodes.getLength(); 284 if (size > 0) { 285 m_xmlWriter.closeStartTag(); 286 marshalContent(element.getChildNodes()); 287 m_xmlWriter.endTag(nsi, element.getLocalName()); 288 } else { 289 m_xmlWriter.closeEmptyTag(); 290 } 291 292 if (nss != null) { 294 m_xmlWriter.popExtensionNamespaces(); 295 if (defind >= 0) { 296 m_defaultNamespaceURI = null; 297 } 298 } 299 } 300 301 309 310 protected Node unmarshalNode() throws JiBXException, IOException { 311 while (true) { 312 int cev = m_unmarshalContext.currentEvent(); 313 switch (cev) { 314 315 case UnmarshallingContext.CDSECT: 316 { 317 String text = m_unmarshalContext.getText(); 318 m_unmarshalContext.nextToken(); 319 return m_document.createCDATASection(text); 320 } 321 322 case UnmarshallingContext.COMMENT: 323 { 324 String text = m_unmarshalContext.getText(); 325 m_unmarshalContext.nextToken(); 326 return m_document.createComment(text); 327 } 328 329 case UnmarshallingContext.END_TAG: 330 return null; 331 332 case UnmarshallingContext.ENTITY_REF: 333 if (m_unmarshalContext.getText() == null) { 334 String name = m_unmarshalContext.getName(); 335 m_unmarshalContext.nextToken(); 336 return m_document.createEntityReference(name); 337 } else { 338 String text = accumulateText(); 339 return m_document.createTextNode(text); 340 } 341 342 case UnmarshallingContext.PROCESSING_INSTRUCTION: 343 { 344 String text = m_unmarshalContext.getText(); 345 m_unmarshalContext.nextToken(); 346 int index = 0; 347 while (++index < text.length() && 348 !isWhitespace(text.charAt(index))); 349 if (index < text.length()) { 350 String target = text.substring(0, index); 351 while (++index < text.length() && 352 isWhitespace(text.charAt(index))); 353 String data = text.substring(index); 354 return m_document. 355 createProcessingInstruction(target, data); 356 } else { 357 return m_document. 358 createProcessingInstruction(text, ""); 359 } 360 } 361 362 case UnmarshallingContext.START_TAG: 363 return unmarshalElement(); 364 365 case UnmarshallingContext.TEXT: 366 return m_document.createTextNode(accumulateText()); 367 368 default: 369 m_unmarshalContext.nextToken(); 370 371 } 372 } 373 } 374 375 384 385 protected void unmarshalContent(Node parent) 386 throws JiBXException, IOException { 387 Node node; 388 while ((node = unmarshalNode()) != null) { 389 parent.appendChild(node); 390 } 391 } 392 393 401 402 protected Element unmarshalElement() throws JiBXException, IOException { 403 404 String uri = m_unmarshalContext.getNamespace(); 406 String prefix = m_unmarshalContext.getPrefix(); 407 String name = m_unmarshalContext.getName(); 408 if (prefix != null) { 409 name = prefix + ':' + name; 410 } 411 Element element = m_document.createElementNS(uri, name); 412 413 int ncount = m_unmarshalContext.getNamespaceCount(); 415 for (int i = 0; i < ncount; i++) { 416 prefix = m_unmarshalContext.getNamespacePrefix(i); 417 uri = m_unmarshalContext.getNamespaceUri(i); 418 if (prefix == null) { 419 element.setAttributeNS(XMLNS_NAMESPACE, "xmlns", uri); 420 } else { 421 element.setAttributeNS(XMLNS_NAMESPACE, "xmlns:" + prefix, uri); 422 } 423 } 424 425 int acount = m_unmarshalContext.getAttributeCount(); 427 for (int i = 0; i < acount; i++) { 428 prefix = m_unmarshalContext.getAttributePrefix(i); 429 uri = m_unmarshalContext.getAttributeNamespace(i); 430 name = m_unmarshalContext.getAttributeName(i); 431 if (prefix != null) { 432 name = prefix + ':' + name; 433 } 434 String value = m_unmarshalContext.getAttributeValue(i); 435 element.setAttributeNS(uri, name, value); 436 } 437 438 int event = m_unmarshalContext.nextToken(); 440 if (event != UnmarshallingContext.END_TAG) { 441 unmarshalContent(element); 442 } 443 m_unmarshalContext.nextToken(); 444 return element; 445 } 446 } | Popular Tags |