blob: c1bbd9ad88bfc9566e02f46e972cddb81e0ef5d4 [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.html.impl;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import org.eclipse.actf.model.internal.dom.html.util.UnsynchronizedHashtable;
import org.eclipse.actf.model.internal.dom.sgml.impl.ElementDefinition;
import org.eclipse.actf.model.internal.dom.sgml.impl.SGMLDocument;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.w3c.dom.html.HTMLCollection;
import org.w3c.dom.html.HTMLDocument;
import org.w3c.dom.html.HTMLElement;
import org.w3c.dom.html.HTMLTitleElement;
@SuppressWarnings("nls")
public class SHDocument extends SGMLDocument implements HTMLDocument {
private static final String NAME = "name";
private static final String ID = "id";
private static final long serialVersionUID = 3204066329029237578L;
public SHDocument() {
this((SHDOMImpl) SHDOMImpl.getDOMImplementation());
}
SHDocument(SHDOMImpl imple) {
super(imple);
}
/**
* @serial
*/
private String cookie;
public void close() { /* do not support */
}
HTMLCollection createCollection(final NodeList list) {
return new HTMLCollection() {
public int getLength() {
return list.getLength();
}
public Node item(int index) {
return list.item(index);
}
public Node namedItem(String name) {
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (!(node instanceof Element))
continue;
if (name
.equalsIgnoreCase(((Element) node).getAttribute(ID))) {
return node;
}
}
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (!(node instanceof Element))
continue;
if (name.equalsIgnoreCase(((Element) node)
.getAttribute(NAME))) {
ElementDefinition def = getDTD().getElementDefinition(
node.getNodeName());
if (def != null && def.getAttributeDef(NAME) != null) {
return node;
}
}
}
return null;
}
public String toString() {
return list.toString();
}
};
}
HTMLCollection createCollection(final Node nodes[], final int len) {
return new HTMLCollection() {
public int getLength() {
return len;
}
public Node item(int index) {
return 0 <= index && index < len ? nodes[index] : null;
}
public Node namedItem(String name) {
for (int i = 0; i < len; i++) {
Node node = nodes[i];
if (!(node instanceof Element))
continue;
if (name
.equalsIgnoreCase(((Element) node).getAttribute(ID))) {
return node;
}
}
for (int i = 0; i < len; i++) {
Node node = nodes[i];
if (!(node instanceof Element))
continue;
if (name.equalsIgnoreCase(((Element) node)
.getAttribute(NAME))) {
ElementDefinition def = getDTD().getElementDefinition(
node.getNodeName());
if (def != null && def.getAttributeDef(NAME) != null) {
return node;
}
}
}
return null;
}
};
}
private static UnsynchronizedHashtable constructors;
static {
constructors = new UnsynchronizedHashtable();
constructors.put("COL", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableColElement(tagName, doc);
}
});
constructors.put("COLGROUP", constructors.get("COL"));
constructors.put("THEAD", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableSectionElement(tagName, doc);
}
});
constructors.put("TFOOT", constructors.get("THEAD"));
constructors.put("CAPTION", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableCaptionElement(tagName, doc);
}
});
constructors.put("TH", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableCellElement(tagName, doc);
}
});
constructors.put("HTML", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHHtmlElement(tagName, doc);
}
});
constructors.put("BASE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHBaseElement(tagName, doc);
}
});
constructors.put("STYLE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHStyleElement(tagName, doc);
}
});
constructors.put("TITLE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTitleElement(tagName, doc);
}
});
constructors.put("BODY", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHBodyElement(tagName, doc);
}
});
constructors.put("H6", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHHeadingElement(tagName, doc);
}
});
constructors.put("HEAD", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHHeadElement(tagName, doc);
}
});
constructors.put("SCRIPT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHScriptElement(tagName, doc);
}
});
constructors.put("LINK", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHLinkElement(tagName, doc);
}
});
constructors.put("FRAMESET", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHFrameSetElement(tagName, doc);
}
});
constructors.put("BASEFONT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHBaseFontElement(tagName, doc);
}
});
constructors.put("INS", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHModElement(tagName, doc);
}
});
constructors.put("DEL", constructors.get("INS"));
constructors.put("IFRAME", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHIFrameElement(tagName, doc);
}
});
constructors.put("FIELDSET", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHFieldSetElement(tagName, doc);
}
});
constructors.put("DIR", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHDirectoryElement(tagName, doc);
}
});
constructors.put("META", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHMetaElement(tagName, doc);
}
});
constructors.put("HR", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHHRElement(tagName, doc);
}
});
constructors.put("MENU", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHMenuElement(tagName, doc);
}
});
constructors.put("OBJECT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHObjectElement(tagName, doc);
}
});
constructors.put("APPLET", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHAppletElement(tagName, doc);
}
});
constructors.put("PARAM", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHParamElement(tagName, doc);
}
});
constructors.put("MAP", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHMapElement(tagName, doc);
}
});
constructors.put("AREA", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHAreaElement(tagName, doc);
}
});
constructors.put("LEGEND", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHLegendElement(tagName, doc);
}
});
constructors.put("ISINDEX", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHIsIndexElement(tagName, doc);
}
});
constructors.put("OPTGROUP", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHOptGroupElement(tagName, doc);
}
});
constructors.put("TEXTAREA", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTextAreaElement(tagName, doc);
}
});
constructors.put("FORM", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHFormElement(tagName, doc);
}
});
constructors.put("SELECT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHSelectElement(tagName, doc);
}
});
constructors.put("LABEL", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHLabelElement(tagName, doc);
}
});
constructors.put("H5", constructors.get("H6"));
constructors.put("BUTTON", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHButtonElement(tagName, doc);
}
});
constructors.put("INPUT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHInputElement(tagName, doc);
}
});
constructors.put("OPTION", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHOptionElement(tagName, doc);
}
});
constructors.put("QUOTE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHQuoteElement(tagName, doc);
}
});
constructors.put("H4", constructors.get("H6"));
constructors.put("PRE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHPreElement(tagName, doc);
}
});
constructors.put("H3", constructors.get("H6"));
constructors.put("BR", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHBRElement(tagName, doc);
}
});
constructors.put("TABLE", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableElement(tagName, doc);
}
});
constructors.put("TBODY", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableSectionElement(tagName, doc);
}
});
constructors.put("DL", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHDListElement(tagName, doc);
}
});
constructors.put("H2", constructors.get("H6"));
constructors.put("UL", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHUListElement(tagName, doc);
}
});
constructors.put("OL", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHOListElement(tagName, doc);
}
});
constructors.put("TR", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHTableRowElement(tagName, doc);
}
});
constructors.put("LI", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHLIElement(tagName, doc);
}
});
constructors.put("IMG", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHImageElement(tagName, doc);
}
});
constructors.put("DIV", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHDivElement(tagName, doc);
}
});
constructors.put("H1", constructors.get("H6"));
constructors.put("P", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHParagraphElement(tagName, doc);
}
});
constructors.put("FONT", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHFontElement(tagName, doc);
}
});
constructors.put("A", new Constructor() {
public SHElement newInstance(String tagName, SHDocument doc) {
return new SHAnchorElement(tagName, doc);
}
});
constructors.put("TD", constructors.get("TH"));
}
public Element createElement(String tagName) {
Constructor constructor = constructors.get(tagName);
return constructor != null ? constructor.newInstance(tagName, this)
: new SHElement(tagName, this);
}
public HTMLCollection getLinks() {
int len = 0;
Node links[] = new Node[32];
Node tmp1, tmp2;
Node root = getDocumentElement();
tmp1 = root;
outer: while (tmp1 != null) {
if (tmp1 instanceof Element) {
String name = tmp1.getNodeName();
if (name.equalsIgnoreCase("AREA")
|| (name.equalsIgnoreCase("A") && ((Element) tmp1)
.getAttributeNode("href") != null)) {
if (len == links.length) {
Node buf[] = new Node[len * 2];
System.arraycopy(links, 0, buf, 0, len);
links = buf;
}
links[len++] = tmp1;
}
}
if ((tmp2 = tmp1.getFirstChild()) == null) {
if (tmp1 == root) {
break outer;
} else {
tmp2 = tmp1.getNextSibling();
}
}
while (tmp2 == null) {
tmp1 = tmp2 = tmp1.getParentNode();
if (tmp1 != root) {
tmp2 = tmp1.getNextSibling();
} else {
break outer;
}
}
tmp1 = tmp2;
}
return createCollection(links, len);
}
public HTMLCollection getApplets() {
return createCollection(getElementsByTagName("APPLET"));
}
public String getCookie() {
return cookie;
}
public String getDomain() {
return null;
}
/*
replaced for performance reason @2009/06/25 by dsato@jp.ibm.com
public Element getElementById(String elementId) {
Node tmp1, tmp2;
Node root = getDocumentElement();
tmp1 = root;
while (tmp1 != null) {
if (tmp1 instanceof Element
&& elementId.equals(((Element) tmp1).getAttribute(ID))) {
return (Element) tmp1;
}
if ((tmp2 = tmp1.getFirstChild()) == null) {
if (tmp1 == root) {
return null;
} else {
tmp2 = tmp1.getNextSibling();
}
}
while (tmp2 == null) {
tmp1 = tmp2 = tmp1.getParentNode();
if (tmp1 != root) {
tmp2 = tmp1.getNextSibling();
} else {
return null;
}
}
tmp1 = tmp2;
}
return null;
}*/
public NodeList getElementsByName(String elementName) {
if (elementName.equals("*")) {
return new NodeList() {
public int getLength() {
return 0;
}
public Node item(int index) {
return null;
}
};
} else {
return getElementsByTagName(elementName);
}
}
public HTMLCollection getForms() {
return createCollection(getElementsByName("FORM"));
}
public HTMLCollection getImages() {
return createCollection(getElementsByName("IMG"));
}
public HTMLCollection getAnchors() {
int len = 0;
Node links[] = new Node[32];
Node tmp1, tmp2;
Node root = getDocumentElement();
tmp1 = root;
outer: while (tmp1 != null) {
if (tmp1 instanceof Element) {
String name = tmp1.getNodeName();
if ((name.equalsIgnoreCase("A") && ((Element) tmp1)
.getAttributeNode(NAME) != null)) {
if (len == links.length) {
Node buf[] = new Node[len * 2];
System.arraycopy(links, 0, buf, 0, len);
links = buf;
}
links[len++] = tmp1;
}
}
if ((tmp2 = tmp1.getFirstChild()) == null) {
if (tmp1 == root) {
break outer;
} else {
tmp2 = tmp1.getNextSibling();
}
}
while (tmp2 == null) {
tmp1 = tmp2 = tmp1.getParentNode();
if (tmp1 != root) {
tmp2 = tmp1.getNextSibling();
} else {
break outer;
}
}
tmp1 = tmp2;
}
return createCollection(links, len);
}
public String getReferrer() {
return null;
}
public String getTitle() {
if (null == getDocumentElement())
return null;
NodeList titles = getElementsByTagName("TITLE");
if (titles.getLength() == 0)
return null;
HTMLTitleElement te = (HTMLTitleElement) titles.item(0);
Node title = te.getFirstChild();
if (title == null || !(title instanceof Text))
return null;
return title.getNodeValue();
}
private URL url;
public String getURL() {
return url != null ? url.toString() : null;
}
/**
* @param url
* URL of this document.
*/
public void setURL(URL url) {
this.url = url;
}
public void open() { /* do not support */
}
/**
* @return if this document does not have <code>BODY</code> or
* <code>FRAMESET
* </code>, null.
*/
public HTMLElement getBody() {
if (getDocumentElement() == null)
return null;
NodeList bodies = getElementsByTagName("FRAMESET");
if (bodies.getLength() == 0) {
bodies = getElementsByTagName("BODY");
}
if (bodies.getLength() == 0)
return null;
return (HTMLElement) bodies.item(0);
}
public void setBody(HTMLElement body) {
HTMLElement oldBody = getBody();
if (oldBody == null) {
getDocumentElement().insertBefore(body, null);
} else {
oldBody.getParentNode().replaceChild(body, oldBody);
}
}
public void setCookie(String cookie) {
this.cookie = cookie;
}
public void setTitle(String title) {
NodeList titles = getElementsByTagName("TITLE");
if (titles.getLength() == 0)
return;
HTMLTitleElement te = (HTMLTitleElement) titles.item(0);
te.setText(title);
}
public void write(String text) { /* do not support */
}
public void writeln(String text) { /* do not support */
}
/**
* Prints this document as XHTML format. At the beginning of the document
* this method generates is a DOCTYPE declaration. Its contents is
* determined as follows.
* <ul>
* <li>if this document's doctype is "-//W3C//DTD HTML 4.0 Frameset//EN",
* then "-//W3C//DTD XHTML 1.0 Frameset//EN"
* <li>else if "-//W3C//DTD HTML 4.0//EN" then "-//W3C//DTD XHTML 1.0
* Strict//EN"
* <li>Otherwise, "-//W3C//DTD XHTML 1.0 Transitional//EN"
* </ul>
*
* @param pw
* PrintWriter to write
* @param indent
* if <code>true</code>, indents
* @param enc
* encoding of output
*/
public void printAsXHTML(PrintWriter pw, boolean indent, String enc)
throws IOException {
String dtdID = getDTD().toString();
if (dtdID.equals("-//W3C//DTD HTML 4.0 Frameset//EN")) {
printAsXML("-//W3C//DTD XHTML 1.0 Frameset//EN", new URL(
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"), pw,
indent, enc);
} else if (dtdID.equals("-//W3C//DTD HTML 4.0//EN")) {
printAsXML("-//W3C//DTD XHTML 1.0 Strict//EN", new URL(
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"), pw,
indent, enc);
} else {
printAsXML("-//W3C//DTD XHTML 1.0 Transitional//EN", new URL(
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"),
pw, indent, enc);
}
}
}