1 23 24 package org.enhydra.xml.xmlc.parsers; 25 26 import java.util.ArrayList ; 27 28 import org.enhydra.xml.xmlc.XMLCError; 29 import org.enhydra.xml.xmlc.XMLCException; 30 import org.enhydra.xml.xmlc.dom.XMLCDocument; 31 import org.enhydra.xml.xmlc.dom.XMLCDomFactory; 32 import org.w3c.dom.Document ; 33 import org.w3c.dom.Element ; 34 import org.w3c.dom.EntityReference ; 35 import org.w3c.dom.Node ; 36 37 45 public class DocBuilder { 46 49 private static final String DEFAULT_XML_ENCODING = "UTF-8"; 50 51 54 private XMLCDomFactory fDomFactory; 55 56 59 private XMLCDocument fXmlcDoc; 60 61 64 private Document fDocument; 65 66 69 private String fDocTypeName; private String fPublicId; 71 private String fSystemId; 72 73 76 private String fInternalSubsetStr; 77 78 82 protected Node fCurrentNode; 83 84 89 private ArrayList fPendingPreDocument; 90 91 96 public DocBuilder(XMLCDomFactory domFactory) throws XMLCException { 97 fDomFactory = domFactory; 98 fXmlcDoc = new XMLCDocument(domFactory); 99 } 100 101 105 private void checkIfAlreadyCreated() { 106 if (fDocument != null) { 107 throw new XMLCError("XMLC bug: attempt to add document type data after DocumentType object has been created"); 108 } 109 } 110 111 116 public void setXMLVersion(String xmlVersion) { 117 fXmlcDoc.setXMLVersion(xmlVersion); 118 } 119 120 125 public void setEncoding(String encoding) { 126 fXmlcDoc.setEncoding(encoding); 127 } 128 129 134 public void setDocumentTypeName(String docTypeName) { 135 checkIfAlreadyCreated(); 136 fDocTypeName = docTypeName; 137 } 138 139 144 public void setPublicId(String publicId) { 145 checkIfAlreadyCreated(); 146 fPublicId = publicId; 147 } 148 149 154 public void setSystemId(String systemId) { 155 checkIfAlreadyCreated(); 156 fSystemId = systemId; 157 } 158 159 162 public void setInternalSubset(String subsetStr) { 163 checkIfAlreadyCreated(); 164 fInternalSubsetStr = subsetStr; 165 } 166 167 170 public void addPCDataContentElement(String elementName) { 171 checkIfAlreadyCreated(); 172 fXmlcDoc.addPCDataContentElement(elementName); 173 } 174 175 178 public void addIdAttribute(String elementName, 179 String attributeName) { 180 checkIfAlreadyCreated(); 181 fXmlcDoc.addIdAttribute(elementName, attributeName); 182 } 183 184 188 private void docNotCreatedError() { 189 throw new XMLCError("Bug: parser event on document contents occured before document is created"); 190 } 191 192 195 private void holdComment(String data) { 196 if (fPendingPreDocument == null) { 197 fPendingPreDocument = new ArrayList (); 198 } 199 fPendingPreDocument.add(data); 200 } 201 202 205 private void holdProcessingInstruction(String target, 206 String data) { 207 if (fPendingPreDocument == null) { 208 fPendingPreDocument = new ArrayList (); 209 } 210 fPendingPreDocument.add(new String []{target, data}); 211 } 212 213 217 private void addPendingPreDocument() { 218 Node first = fDocument.getFirstChild(); 220 for (int idx = 0; idx < fPendingPreDocument.size(); idx++) { 221 Object entry = fPendingPreDocument.get(idx); 222 if (entry instanceof String ) { 223 fDocument.insertBefore(fDocument.createComment((String )entry), 224 first); 225 } else { 226 String [] pi = (String [])entry; 227 fDocument.insertBefore(fDocument.createProcessingInstruction(pi[0], pi[1]), 228 first); 229 } 230 } 231 } 232 233 239 private void createDocument(String namespaceURI, 240 String rootTagName) { 241 if ((fPublicId != null) || (fSystemId != null) || (fInternalSubsetStr != null)) { 242 fXmlcDoc.createDocumentType(fDocTypeName, fPublicId, fSystemId, 243 fInternalSubsetStr); 244 } 245 fDocument = fXmlcDoc.createDocument(namespaceURI, rootTagName); 246 247 fCurrentNode = fDocument.getDocumentElement(); 248 if (fPendingPreDocument != null) { 249 addPendingPreDocument(); 250 } 251 } 252 253 256 public XMLCDocument getDocument() { 257 if (fDocument == null) { 258 throw new XMLCError("XMLC bug: Attempt to get document that hasn;t been created"); 259 } 260 return fXmlcDoc; 261 } 262 263 267 public Node getCurrentNode() { 268 return fCurrentNode; 269 } 270 271 277 public void popCurrentNode() { 278 fCurrentNode = fCurrentNode.getParentNode(); 279 } 280 281 284 public void startElement(String namespaceURI, 285 String tagName) { 286 if (fDocument == null) { 287 createDocument(namespaceURI, tagName); 289 } else { 290 Element element; 292 if (namespaceURI != null) { 293 element = fDocument.createElementNS(namespaceURI, tagName); 294 } else { 295 element = fDocument.createElement(tagName); 296 } 297 fCurrentNode.appendChild(element); 298 fCurrentNode = element; 299 } 300 } 301 302 306 public void addAttribute(String namespaceURI, 308 String name, 309 String value) { 310 if ((namespaceURI == null) || (namespaceURI.length() == 0)) { 314 int prefixIdx = name.indexOf(':'); 315 String prefix = (prefixIdx < 0) ? null : name.substring(0, prefixIdx); 316 if ((prefix != null) && (prefix.equals("xmlns")) 317 || (name.equals("xmlns"))) { 318 namespaceURI = "http://www.w3.org/2000/xmlns/"; 319 } 320 } 321 if (namespaceURI != null) { 322 ((Element )fCurrentNode).setAttributeNS(namespaceURI, name, value); 323 } else { 324 ((Element )fCurrentNode).setAttribute(name, value); 325 } 326 } 327 328 331 public void finishElement() { 332 if (fCurrentNode == null) { 333 throw new XMLCError("node stack underflow; malformed document"); 334 } 335 if (!(fCurrentNode instanceof Element )) { 336 throw new XMLCError("DOM node top of stack not a element for end tag"); 337 } 338 fCurrentNode = fCurrentNode.getParentNode(); 339 } 340 341 344 public void startEntityReference(String entityName) { 345 if (fDocument == null) { 346 docNotCreatedError(); 347 } 348 349 EntityReference entityRef = fDocument.createEntityReference(entityName); 350 fCurrentNode.appendChild(entityRef); 351 fCurrentNode = entityRef; 352 } 353 354 357 public void endEntityReference() { 358 if (fCurrentNode == null) { 359 throw new XMLCError("node stack underflow; malformed document"); 360 } 361 if (!(fCurrentNode instanceof EntityReference )) { 362 throw new XMLCError("DOM node top of stack not a EntityReference for end tag"); 363 } 364 fCurrentNode = fCurrentNode.getParentNode(); 365 } 366 367 368 371 public void addTextNode(String data) { 372 if (fDocument == null) { 373 docNotCreatedError(); 374 } 375 fCurrentNode.appendChild(fDocument.createTextNode(data)); 376 } 377 378 381 public void addComment(String data) { 382 if (fDocument == null) { 383 holdComment(data); } else { 385 fCurrentNode.appendChild(fDocument.createComment(data)); 386 } 387 } 388 389 392 public void addCDATASection(String data) { 393 if (fDocument == null) { 394 docNotCreatedError(); 395 } 396 fCurrentNode.appendChild(fDocument.createCDATASection(data)); 397 } 398 399 402 public void addProcessingInstruction(String target, 403 String data) { 404 if (fDocument == null) { 405 holdProcessingInstruction(target, data); 406 } else { 407 fCurrentNode.appendChild(fDocument.createProcessingInstruction(target, data)); 408 } 409 } 410 411 414 public void addEntityReference(String name) { 415 if (fDocument == null) { 416 docNotCreatedError(); 417 } 418 fCurrentNode.appendChild(fDocument.createEntityReference(name)); 419 } 420 421 425 public void finish() { 426 if (fXmlcDoc.getEncoding() == null) { 427 fXmlcDoc.setEncoding(DEFAULT_XML_ENCODING); 428 } 429 } 430 } 431 | Popular Tags |