Source for gnu.xml.dom.html2.DomHTMLDocument

   1: /* DomHTMLDocument.java --
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.xml.dom.html2;
  39: 
  40: import gnu.xml.dom.DomDocument;
  41: import gnu.xml.dom.DomDOMException;
  42: import java.lang.reflect.Constructor;
  43: import java.net.MalformedURLException;
  44: import java.net.URL;
  45: import java.util.Collections;
  46: import java.util.HashMap;
  47: import java.util.HashSet;
  48: import java.util.Map;
  49: import java.util.Set;
  50: import org.w3c.dom.DOMException;
  51: import org.w3c.dom.Element;
  52: import org.w3c.dom.Node;
  53: import org.w3c.dom.NodeList;
  54: import org.w3c.dom.html2.HTMLCollection;
  55: import org.w3c.dom.html2.HTMLDocument;
  56: import org.w3c.dom.html2.HTMLElement;
  57: 
  58: /**
  59:  * An HTML document.
  60:  * This is the factory object used to create HTML elements.
  61:  *
  62:  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  63:  */
  64: public class DomHTMLDocument
  65:   extends DomDocument
  66:   implements HTMLDocument
  67: {
  68: 
  69:   private static final Class[] ELEMENT_PT = new Class[] {
  70:     DomHTMLDocument.class,
  71:     String.class,
  72:     String.class
  73:   };
  74: 
  75:   private static Map ELEMENT_CLASSES;
  76:   static
  77:   {
  78:     Map map = new HashMap();
  79:     map.put("a", DomHTMLAnchorElement.class);
  80:     map.put("applet", DomHTMLAppletElement.class);
  81:     map.put("area", DomHTMLAreaElement.class);
  82:     map.put("base", DomHTMLBaseElement.class);
  83:     map.put("basefont", DomHTMLBaseFontElement.class);
  84:     map.put("body", DomHTMLBodyElement.class);
  85:     map.put("br", DomHTMLBRElement.class);
  86:     map.put("button", DomHTMLButtonElement.class);
  87:     map.put("dir", DomHTMLDirectoryElement.class);
  88:     map.put("div", DomHTMLDivElement.class);
  89:     map.put("dlist", DomHTMLDListElement.class);
  90:     map.put("embed", DomHTMLEmbedElement.class);
  91:     map.put("fieldset", DomHTMLFieldSetElement.class);
  92:     map.put("font", DomHTMLFontElement.class);
  93:     map.put("form", DomHTMLFormElement.class);
  94:     map.put("frame", DomHTMLFrameElement.class);
  95:     map.put("frameset", DomHTMLFrameSetElement.class);
  96:     map.put("head", DomHTMLHeadElement.class);
  97:     map.put("h1", DomHTMLHeadingElement.class);
  98:     map.put("h2", DomHTMLHeadingElement.class);
  99:     map.put("h3", DomHTMLHeadingElement.class);
 100:     map.put("h4", DomHTMLHeadingElement.class);
 101:     map.put("h5", DomHTMLHeadingElement.class);
 102:     map.put("h6", DomHTMLHeadingElement.class);
 103:     map.put("html", DomHTMLHtmlElement.class);
 104:     map.put("iframe", DomHTMLIFrameElement.class);
 105:     map.put("img", DomHTMLImageElement.class);
 106:     map.put("input", DomHTMLInputElement.class);
 107:     map.put("isindex", DomHTMLIsIndexElement.class);
 108:     map.put("label", DomHTMLLabelElement.class);
 109:     map.put("legend", DomHTMLLegendElement.class);
 110:     map.put("li", DomHTMLLIElement.class);
 111:     map.put("link", DomHTMLLinkElement.class);
 112:     map.put("map", DomHTMLMapElement.class);
 113:     map.put("menu", DomHTMLMenuElement.class);
 114:     map.put("meta", DomHTMLMetaElement.class);
 115:     map.put("ins", DomHTMLModElement.class);
 116:     map.put("del", DomHTMLModElement.class);
 117:     map.put("object", DomHTMLObjectElement.class);
 118:     map.put("ol", DomHTMLOListElement.class);
 119:     map.put("optgroup", DomHTMLOptGroupElement.class);
 120:     map.put("option", DomHTMLOptionElement.class);
 121:     map.put("p", DomHTMLParagraphElement.class);
 122:     map.put("param", DomHTMLParamElement.class);
 123:     map.put("pre", DomHTMLPreElement.class);
 124:     map.put("q", DomHTMLQuoteElement.class);
 125:     map.put("blockquote", DomHTMLQuoteElement.class);
 126:     map.put("script", DomHTMLScriptElement.class);
 127:     map.put("select", DomHTMLSelectElement.class);
 128:     map.put("style", DomHTMLStyleElement.class);
 129:     map.put("caption", DomHTMLTableCaptionElement.class);
 130:     map.put("th", DomHTMLTableCellElement.class);
 131:     map.put("td", DomHTMLTableCellElement.class);
 132:     map.put("col", DomHTMLTableColElement.class);
 133:     map.put("colgroup", DomHTMLTableColElement.class);
 134:     map.put("table", DomHTMLTableElement.class);
 135:     map.put("tr", DomHTMLTableRowElement.class);
 136:     map.put("thead", DomHTMLTableSectionElement.class);
 137:     map.put("tfoot", DomHTMLTableSectionElement.class);
 138:     map.put("tbody", DomHTMLTableSectionElement.class);
 139:     map.put("textarea", DomHTMLTextAreaElement.class);
 140:     map.put("title", DomHTMLTitleElement.class);
 141:     map.put("ul", DomHTMLUListElement.class);
 142:     ELEMENT_CLASSES = Collections.unmodifiableMap(map);
 143:   }
 144: 
 145:   private static Set HTML_NS_URIS;
 146:   static
 147:   {
 148:     Set set = new HashSet();
 149:     set.add("http://www.w3.org/TR/html4/strict");
 150:     set.add("http://www.w3.org/TR/html4/loose");
 151:     set.add("http://www.w3.org/TR/html4/frameset");
 152:     set.add("http://www.w3.org/1999/xhtml");
 153:     set.add("http://www.w3.org/TR/xhtml1/strict");
 154:     set.add("http://www.w3.org/TR/xhtml1/loose");
 155:     set.add("http://www.w3.org/TR/xhtml1/frameset");
 156:     HTML_NS_URIS = Collections.unmodifiableSet(set);
 157:   }
 158: 
 159:   /**
 160:    * Convenience constructor.
 161:    */
 162:   public DomHTMLDocument()
 163:   {
 164:     this(new DomHTMLImpl());
 165:   }
 166: 
 167:   /**
 168:    * Constructor.
 169:    * This is called by the DOMImplementation.
 170:    */
 171:   public DomHTMLDocument(DomHTMLImpl impl)
 172:   {
 173:     super(impl);
 174:   }
 175: 
 176:   private Node getChildNodeByName(Node parent, String name)
 177:   {
 178:     for (Node ctx = parent.getFirstChild(); ctx != null;
 179:          ctx = ctx.getNextSibling())
 180:       {
 181:         if (name.equalsIgnoreCase(ctx.getNodeName()))
 182:           {
 183:             return ctx;
 184:           }
 185:       }
 186:     return null;
 187:   }
 188: 
 189:   public String getTitle()
 190:   {
 191:     Node html = getDocumentElement();
 192:     if (html != null)
 193:       {
 194:         Node head = getChildNodeByName(html, "head");
 195:         if (head != null)
 196:           {
 197:             Node title = getChildNodeByName(head, "title");
 198:             if (title != null)
 199:               {
 200:                 return title.getTextContent();
 201:               }
 202:           }
 203:       }
 204:     return null;
 205:   }
 206: 
 207:   public void setTitle(String title)
 208:   {
 209:     Node html = getDocumentElement();
 210:     if (html == null)
 211:       {
 212:         html = createElement("html");
 213:         appendChild(html);
 214:       }
 215:     Node head = getChildNodeByName(html, "head");
 216:     if (head == null)
 217:       {
 218:         head = createElement("head");
 219:         Node first = html.getFirstChild();
 220:         if (first != null)
 221:           {
 222:             html.insertBefore(first, head);
 223:           }
 224:         else
 225:           {
 226:             html.appendChild(head);
 227:           }
 228:       }
 229:     Node titleNode = getChildNodeByName(head, "title");
 230:     if (titleNode == null)
 231:       {
 232:         titleNode = createElement("title");
 233:         Node first = head.getFirstChild();
 234:         if (first != null)
 235:           {
 236:             head.insertBefore(first, titleNode);
 237:           }
 238:         else
 239:           {
 240:             head.appendChild(titleNode);
 241:           }
 242:       }
 243:     titleNode.setTextContent(title);
 244:   }
 245: 
 246:   public String getReferrer()
 247:   {
 248:     // TODO getReferrer
 249:     return null;
 250:   }
 251: 
 252:   public String getDomain()
 253:   {
 254:     try
 255:       {
 256:         URL url = new URL(getDocumentURI());
 257:         return url.getHost();
 258:       }
 259:     catch (MalformedURLException e)
 260:       {
 261:         return null;
 262:       }
 263:   }
 264: 
 265:   public String getURL()
 266:   {
 267:     return getDocumentURI();
 268:   }
 269: 
 270:   public HTMLElement getBody()
 271:   {
 272:     Node html = getDocumentElement();
 273:     if (html != null)
 274:       {
 275:         Node body = getChildNodeByName(html, "body");
 276:         if (body == null)
 277:           {
 278:             body = getChildNodeByName(html, "frameset");
 279:           }
 280:         return (HTMLElement) body;
 281:       }
 282:     return null;
 283:   }
 284: 
 285:   public void setBody(HTMLElement body)
 286:   {
 287:     Node html = getDocumentElement();
 288:     if (html == null)
 289:       {
 290:         html = createElement("html");
 291:         appendChild(html);
 292:       }
 293:     Node ref = getBody();
 294:     if (ref == null)
 295:       {
 296:         html.appendChild(body);
 297:       }
 298:     else
 299:       {
 300:         html.replaceChild(body, ref);
 301:       }
 302:   }
 303: 
 304:   public HTMLCollection getImages()
 305:   {
 306:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 307:     ret.addNodeName("img");
 308:     ret.evaluate();
 309:     return ret;
 310:   }
 311: 
 312:   public HTMLCollection getApplets()
 313:   {
 314:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 315:     ret.addNodeName("embed");
 316:     ret.addNodeName("object");
 317:     ret.addNodeName("applet");
 318:     ret.evaluate();
 319:     return ret;
 320:   }
 321: 
 322:   public HTMLCollection getLinks()
 323:   {
 324:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 325:     ret.addNodeName("area");
 326:     ret.addNodeName("a");
 327:     ret.evaluate();
 328:     return ret;
 329:   }
 330: 
 331:   public HTMLCollection getForms()
 332:   {
 333:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 334:     ret.addNodeName("form");
 335:     ret.evaluate();
 336:     return ret;
 337:   }
 338: 
 339:   public HTMLCollection getAnchors()
 340:   {
 341:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 342:     ret.addNodeName("a");
 343:     ret.addAttributeName("name");
 344:     ret.evaluate();
 345:     return ret;
 346:   }
 347: 
 348:   public String getCookie()
 349:   {
 350:     // TODO getCookie
 351:     return null;
 352:   }
 353: 
 354:   public void setCookie(String cookie)
 355:   {
 356:     // TODO setCookie
 357:   }
 358: 
 359:   public void open()
 360:   {
 361:     // TODO open
 362:   }
 363: 
 364:   public void close()
 365:   {
 366:     // TODO close
 367:   }
 368: 
 369:   public void write(String text)
 370:   {
 371:     // TODO write
 372:   }
 373: 
 374:   public void writeln(String text)
 375:   {
 376:     // TODO write
 377:   }
 378: 
 379:   public NodeList getElementsByName(String name)
 380:   {
 381:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 382:     ret.addNodeName(name);
 383:     ret.evaluate();
 384:     return ret;
 385:     // TODO xhtml: return only form controls (?)
 386:   }
 387: 
 388:   public Element createElement(String tagName)
 389:   {
 390:     return createElementNS(null, tagName);
 391:   }
 392: 
 393:   public Element createElementNS(String uri, String qName)
 394:   {
 395:     /* If a non-HTML element, use the default implementation. */
 396:     if (uri != null && !HTML_NS_URIS.contains(uri))
 397:       {
 398:         return super.createElementNS(uri, qName);
 399:       }
 400:     String localName = qName.toLowerCase();
 401:     int ci = qName.indexOf(':');
 402:     if (ci != -1)
 403:       {
 404:         localName = qName.substring(ci + 1);
 405:       }
 406:     Class t = (Class) ELEMENT_CLASSES.get(localName);
 407:     /* If a non-HTML element, use the default implementation. */
 408:     if (t == null)
 409:       {
 410:         return super.createElementNS(uri, qName);
 411:       }
 412:     try
 413:       {
 414:         Constructor c = t.getDeclaredConstructor(ELEMENT_PT);
 415:         Object[] args = new Object[] { this, uri, qName };
 416:         return (Element) c.newInstance(args);
 417:       }
 418:     catch (Exception e)
 419:       {
 420:         DOMException e2 = new DomDOMException(DOMException.TYPE_MISMATCH_ERR);
 421:         e2.initCause(e);
 422:         throw e2;
 423:       }
 424:   }
 425: 
 426: }