blob: 5395c5eef5397e6093fd41aff17bb0234634a1ed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2008 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Goh KONDOH - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.model.internal.dom.sgml.impl;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.HashMap;
import java.util.Hashtable;
import org.eclipse.actf.model.internal.dom.sgml.ISGMLDocument;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
/**
* Root node is a instance of this class.
*/
@SuppressWarnings("nls")
public class SGMLDocument extends SGMLParentNode implements ISGMLDocument {
/**
*
*/
private static final long serialVersionUID = -9052104600001817404L;
/**
* @serial
*/
public Element documentElement = null;
/**
* @serial
*/
public DocumentType doctype = null;
private transient DOMImplementation domImpl;
/**
* @see SGMLDOMImpl#createDocument(java.lang.String,java.lang.String,org.w3c.dom.DocumentType)
*/
public SGMLDocument() {
this(SGMLDOMImpl.getDOMImplementation());
}
protected SGMLDocument(DOMImplementation imple) {
super(null);
this.domImpl = imple;
}
void check(Node node) throws DOMException {
if (node.getOwnerDocument() != this && !(node instanceof SGMLDocType)) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, node
+ " created from " + node.getOwnerDocument() + " this.") {
/**
*
*/
private static final long serialVersionUID = -6949628537817157229L;
};
}
switch (node.getNodeType()) {
case ELEMENT_NODE:
if (documentElement == null) {
documentElement = (Element) node;
} else {
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
" document cannot have roots.") {
/**
*
*/
private static final long serialVersionUID = -8867384684522317782L;
};
}
break;
case PROCESSING_INSTRUCTION_NODE:
case COMMENT_NODE:
break;
case DOCUMENT_TYPE_NODE:
doctype = (DocumentType) node;
((SGMLNode) node).ownerDocument = this;
break;
default:
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, node
+ " is not allowed as a child of " + this) {
/**
*
*/
private static final long serialVersionUID = 7083250644035192730L;
};
}
}
public Node cloneNode(boolean deep) {
SGMLDocument ret = (SGMLDocument) super.cloneNode(true);
setOwnerDocument(ret, ret);
for (Node child = ret.firstChild; child != null; child = child
.getNextSibling()) {
if (child instanceof Element) {
ret.documentElement = (Element) child;
} else if (child instanceof DocumentType) {
ret.doctype = (DocumentType) child;
}
}
return ret;
}
private void setOwnerDocument(SGMLNode ret, Document doc) {
ret.ownerDocument = doc;
if (ret instanceof SGMLElement) {
((SGMLElement)ret).processNodeForOptimization((Element) ret);
}
for (SGMLNode child = (SGMLNode) ret.getFirstChild(); child != null; child = (SGMLNode) child
.getNextSibling()) {
setOwnerDocument(child, doc);
}
}
public Attr createAttribute(String name) {
return new SGMLAttribute(name, name, this);
}
public CDATASection createCDATASection(String c) {
return new SGMLCDATASection(c, this);
}
public Comment createComment(String data) {
return new SGMLComment(data, this);
}
public DocumentFragment createDocumentFragment() {
return new SGMLDocumentFragment(this);
}
public Element createElement(String tagName) {
return new SGMLElement(tagName, this);
}
public EntityReference createEntityReference(String a) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
"cannot create Entity Ref.") {
/**
*
*/
private static final long serialVersionUID = -4581301359508117945L;
};
}
public ProcessingInstruction createProcessingInstruction(String target,
String data) {
return new SGMLPI(target, data, this);
}
public Text createTextNode(String data) {
return new SGMLText(data, this);
}
public DocumentType getDoctype() {
return doctype;
}
public Element getDocumentElement() {
return documentElement;
}
// implementation of Document interface;
public Node getDocumentType() {
return doctype;
}
public NodeList getElementsByTagName(String tagname) {
// replaced for performance reason @2009/06/25 by dsato@jp.ibm.com
return documentElement.getElementsByTagName(tagname);
}
/* very slow
public NodeList getElementsByTagName(String tagname) {
final boolean all = tagname.equals("*");
final String targetName = tagname;
return new NodeList() {
public int getLength() {
int ret = 0;
Node tmp1, tmp2;
tmp1 = documentElement;
outer: while (tmp1 != null) {
if (tmp1 instanceof Element
&& (all || targetName.equalsIgnoreCase(tmp1
.getNodeName()))) {
ret++;
}
if ((tmp2 = tmp1.getFirstChild()) == null) {
if (tmp1 == documentElement) {
break outer;
} else {
tmp2 = tmp1.getNextSibling();
}
}
while (tmp2 == null && tmp1 != null) {
tmp1 = tmp2 = tmp1.getParentNode();
if (tmp1 != documentElement) {
tmp2 = tmp1.getNextSibling();
} else {
break outer;
}
}
tmp1 = tmp2;
}
return ret;
}
public Node item(int index) {
Node tmp1, tmp2;
tmp1 = documentElement;
outer: while (tmp1 != null) {
if (tmp1 instanceof Element
&& (all || targetName.equalsIgnoreCase(tmp1
.getNodeName()))) {
if (index == 0) {
return tmp1;
} else {
index--;
}
}
if ((tmp2 = tmp1.getFirstChild()) == null) {
if (tmp1 == documentElement) {
break outer;
} else {
tmp2 = tmp1.getNextSibling();
}
}
while (tmp2 == null && tmp1 != null) {
tmp1 = tmp2 = tmp1.getParentNode();
if (tmp1 != documentElement) {
tmp2 = tmp1.getNextSibling();
} else {
break outer;
}
}
tmp1 = tmp2;
}
return null;
}
};
}
*/
public DOMImplementation getImplementation() {
return this.domImpl;
}
public Node getNextSibling() {
return null;
}
public String getNodeName() {
return "#document";
}
// implementation of Node interface
public short getNodeType() {
return DOCUMENT_NODE;
}
public String getNodeValue() {
return null;
}
public Document getOwnerDocument() {
return null;
}
public Node getParentNode() {
return null;
}
/**
* A Document object is the root node. So this have no siblings.
*/
public Node getPreviousSibling() {
return null;
}
/**
* This method was created in VisualAge.
*
* @return org.w3c.dom.Node
* @param oldChild
* org.w3c.dom.Node
* @exception org.w3c.dom.DOMException
* The exception description.
*/
public Node removeChild(Node oldChild) throws DOMException {
if (oldChild == documentElement) {
documentElement = null;
} else if (oldChild == doctype) {
doctype = null;
}
return super.removeChild(oldChild);
}
public void setNodeValue(String nodeValue) throws DOMException {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"#document is always null") {
/**
*
*/
private static final long serialVersionUID = 6689389325290139309L;
};
}
public void printAsXML(String publicID, URL location, PrintWriter pw,
boolean indent) throws IOException {
printAsXML(publicID, location, pw, indent, null);
}
/**
* Print Document as XML
*
* @param public
* ID
* @param DTD's
* location
* @param pw
* stream to write this document.
* @param indent
* indent if true. Otherwise, not indent.
* @param enc
*/
public void printAsXML(String publicID, URL location, PrintWriter pw,
boolean indent, String enc) throws IOException {
if (enc == null) {
pw.println("<?xml version=\"1.0\"?>");
} else {
pw.println("<?xml version=\"1.0\" encoding=\"" + enc + "\"?>");
}
if (publicID != null) {
pw.print("<!DOCTYPE " + documentElement.getTagName() + " PUBLIC \""
+ publicID + '"');
if (location != null) {
pw.println(" \"" + location + "\">");
} else {
pw.println('>');
}
}
((SGMLElement) documentElement).printAsXML(pw, 0, indent);
pw.println();
pw.flush();
// charEntities4Xml = null;
}
public void printAsXML(PrintWriter pw, boolean indent, String enc)
throws IOException {
printAsXML(null, null, pw, indent, enc);
}
/**
* Print Document as SGML. starttag's string in this document are from the
* original document (see {@link SGMLElement#toString()}. Even if
* attributes in elements are modified, starttag's string does not change.
*
* @param DTD's
* location
* @param pw
* stream to write this document.
*/
public void printAsSGML(PrintWriter pw, boolean indent) throws IOException {
if (doctype != null) {
pw.println(doctype.toString());
}
if (documentElement != null)
((SGMLElement) documentElement).printAsSGML(pw, 0, indent);
pw.println();
pw.flush();
}
/**
* @serial
*/
// private Hashtable charEntities4Xml;
//
// String getEntityOrigin4Xml(String entity) {
// return (String) charEntities4Xml.get(entity);
// }
private transient SGMLDocTypeDef dtd;
public SGMLDocTypeDef getDTD() {
return dtd;
}
public void setDTD(SGMLDocTypeDef dtd) {
this.dtd = dtd;
}
String getEntityOrigin(Character Ch) {
return charNumEntities.get(Ch);
}
/**
* @serial
*/
private Hashtable<Character, String> charNumEntities = new Hashtable<Character, String>();
void putCharNumEntity(Character C, String ent) {
charNumEntities.put(C, ent);
}
String getCharNumEntity(Character C) {
return charNumEntities.get(C);
}
// DOM Level 2
public Node importNode(Node importedNode, boolean deep) throws DOMException {
Node ret;
switch (importedNode.getNodeType()) {
case Node.ELEMENT_NODE:
ret = createElement(importedNode.getNodeName());
NamedNodeMap attributes = importedNode.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Attr importedAttr = (Attr) attributes.item(i);
if (importedAttr.getSpecified()) {
Attr attr = createAttribute(importedAttr.getNodeName());
attr.setValue(importedAttr.getValue());
((Element) ret).setAttributeNode(attr);
}
}
break;
case Node.ATTRIBUTE_NODE:
ret = createAttribute(importedNode.getNodeName());
((Attr) ret).setValue(importedNode.getNodeValue());
break;
case Node.TEXT_NODE:
ret = createTextNode(importedNode.getNodeValue());
break;
case Node.CDATA_SECTION_NODE:
ret = createCDATASection(importedNode.getNodeValue());
break;
case Node.COMMENT_NODE:
ret = createComment(importedNode.getNodeValue());
break;
case Node.PROCESSING_INSTRUCTION_NODE:
ProcessingInstruction pi = (ProcessingInstruction) importedNode;
ret = createProcessingInstruction(pi.getTarget(), pi.getData());
break;
case Node.ENTITY_REFERENCE_NODE:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
"ENTITY_REFERENCE: " + importedNode) {
/**
*
*/
private static final long serialVersionUID = 1578579363722608207L;
};
case Node.ENTITY_NODE:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "ENTITY: "
+ importedNode) {
/**
*
*/
private static final long serialVersionUID = -450181572985174561L;
};
case Node.DOCUMENT_NODE:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "DOCUMENT: "
+ importedNode) {
/**
*
*/
private static final long serialVersionUID = 8785157203267073381L;
};
case Node.DOCUMENT_TYPE_NODE:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
"DOCUMENT_TYPE: " + importedNode) {
/**
*
*/
private static final long serialVersionUID = 5629745929750604049L;
};
case Node.DOCUMENT_FRAGMENT_NODE:
ret = createDocumentFragment();
break;
case Node.NOTATION_NODE:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "NOTATION: "
+ importedNode) {
/**
*
*/
private static final long serialVersionUID = 1787799543281735366L;
};
default:
throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
"Unknown node type: " + importedNode.getNodeType()) {
/**
*
*/
private static final long serialVersionUID = -9119985548894040858L;
};
}
if (deep) {
for (Node importedChild = importedNode.getFirstChild(); importedChild != null; importedChild = importedChild
.getNextSibling()) {
ret.appendChild(importNode(importedChild, true));
}
}
return ret;
}
/**
* @param namespaceURI
* always ignored.
* @return same as <code>createElement(qualifiedName)</code>
*/
public Element createElementNS(String namespaceURI, String qualifiedName)
throws DOMException {
return createElement(qualifiedName);
}
/**
* @param namespaceURI
* always ignored.
* @return same as <code>createAttribute(qualifiedName)</code>
*/
public Attr createAttributeNS(String namespaceURI, String qualifiedName)
throws DOMException {
return createAttribute(qualifiedName);
}
/**
* @param namespaceURI
* always ignored.
* @return same as <code>getElementsByTagName(localName)</code>
*/
public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
return getElementsByTagName(localName);
}
/**
* Returns the <code>Element</code> whose <code>ID</code> is given by
* <code>elementId</code>. If more than one element has this
* <code>ID</code> The first element in the depth-first and pre-order
* traversal is returned.
*/
public Element getElementById(String elementID) {
// replaced for performance reason @2009/06/25 by dsato@jp.ibm.com
if (documentElement instanceof SGMLElement) {
HashMap<String, Element> map = SGMLParentNode.getIdMap(this);
return map.get(elementID);
}
return null;
// very slow
// return getElementById(documentElement, elementID);
}
/*
private Element getElementById(Element el, String elementID) {
if (el.getAttribute("id").equals(elementID)) {
return el;
} else {
for (Node child = el.getFirstChild(); child != null; child = child
.getNextSibling()) {
if (child instanceof Element) {
Element ret = getElementById((Element) child, elementID);
if (ret != null) {
return ret;
}
}
}
return null;
}
}
*/
/**
* DOM Level 3
*/
public Node adoptNode(Node source) throws DOMException {
// TODO Auto-generated method stub
return null;
}
public String getDocumentURI() {
// TODO Auto-generated method stub
return null;
}
public DOMConfiguration getDomConfig() {
// TODO Auto-generated method stub
return null;
}
public String getInputEncoding() {
// TODO Auto-generated method stub
return null;
}
public boolean getStrictErrorChecking() {
// TODO Auto-generated method stub
return false;
}
public String getXmlEncoding() {
// TODO Auto-generated method stub
return null;
}
public boolean getXmlStandalone() {
// TODO Auto-generated method stub
return false;
}
public String getXmlVersion() {
// TODO Auto-generated method stub
return null;
}
public void normalizeDocument() {
// TODO Auto-generated method stub
}
public Node renameNode(Node n, String namespaceURI, String qualifiedName)
throws DOMException {
// TODO Auto-generated method stub
return null;
}
public void setDocumentURI(String documentURI) {
// TODO Auto-generated method stub
}
public void setStrictErrorChecking(boolean strictErrorChecking) {
// TODO Auto-generated method stub
}
public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
// TODO Auto-generated method stub
}
public void setXmlVersion(String xmlVersion) throws DOMException {
// TODO Auto-generated method stub
}
}