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("fieldset", DomHTMLFieldSetElement.class);
  91:     map.put("font", DomHTMLFontElement.class);
  92:     map.put("form", DomHTMLFormElement.class);
  93:     map.put("frame", DomHTMLFrameElement.class);
  94:     map.put("frameset", DomHTMLFrameSetElement.class);
  95:     map.put("head", DomHTMLHeadElement.class);
  96:     map.put("h1", DomHTMLHeadingElement.class);
  97:     map.put("h2", DomHTMLHeadingElement.class);
  98:     map.put("h3", DomHTMLHeadingElement.class);
  99:     map.put("h4", DomHTMLHeadingElement.class);
 100:     map.put("h5", DomHTMLHeadingElement.class);
 101:     map.put("h6", DomHTMLHeadingElement.class);
 102:     map.put("html", DomHTMLHtmlElement.class);
 103:     map.put("iframe", DomHTMLIFrameElement.class);
 104:     map.put("img", DomHTMLImageElement.class);
 105:     map.put("input", DomHTMLInputElement.class);
 106:     map.put("isindex", DomHTMLIsIndexElement.class);
 107:     map.put("label", DomHTMLLabelElement.class);
 108:     map.put("legend", DomHTMLLegendElement.class);
 109:     map.put("li", DomHTMLLIElement.class);
 110:     map.put("link", DomHTMLLinkElement.class);
 111:     map.put("map", DomHTMLMapElement.class);
 112:     map.put("menu", DomHTMLMenuElement.class);
 113:     map.put("meta", DomHTMLMetaElement.class);
 114:     map.put("ins", DomHTMLModElement.class);
 115:     map.put("del", DomHTMLModElement.class);
 116:     map.put("object", DomHTMLObjectElement.class);
 117:     map.put("ol", DomHTMLOListElement.class);
 118:     map.put("optgroup", DomHTMLOptGroupElement.class);
 119:     map.put("option", DomHTMLOptionElement.class);
 120:     map.put("p", DomHTMLParagraphElement.class);
 121:     map.put("param", DomHTMLParamElement.class);
 122:     map.put("pre", DomHTMLPreElement.class);
 123:     map.put("q", DomHTMLQuoteElement.class);
 124:     map.put("blockquote", DomHTMLQuoteElement.class);
 125:     map.put("script", DomHTMLScriptElement.class);
 126:     map.put("select", DomHTMLSelectElement.class);
 127:     map.put("style", DomHTMLStyleElement.class);
 128:     map.put("caption", DomHTMLTableCaptionElement.class);
 129:     map.put("th", DomHTMLTableCellElement.class);
 130:     map.put("td", DomHTMLTableCellElement.class);
 131:     map.put("col", DomHTMLTableColElement.class);
 132:     map.put("colgroup", DomHTMLTableColElement.class);
 133:     map.put("table", DomHTMLTableElement.class);
 134:     map.put("tr", DomHTMLTableRowElement.class);
 135:     map.put("thead", DomHTMLTableSectionElement.class);
 136:     map.put("tfoot", DomHTMLTableSectionElement.class);
 137:     map.put("tbody", DomHTMLTableSectionElement.class);
 138:     map.put("textarea", DomHTMLTextAreaElement.class);
 139:     map.put("title", DomHTMLTitleElement.class);
 140:     map.put("ul", DomHTMLUListElement.class);
 141:     ELEMENT_CLASSES = Collections.unmodifiableMap(map);
 142:   }
 143: 
 144:   private static Set HTML_NS_URIS;
 145:   static
 146:   {
 147:     Set set = new HashSet();
 148:     set.add("http://www.w3.org/TR/html4/strict");
 149:     set.add("http://www.w3.org/TR/html4/loose");
 150:     set.add("http://www.w3.org/TR/html4/frameset");
 151:     set.add("http://www.w3.org/1999/xhtml");
 152:     set.add("http://www.w3.org/TR/xhtml1/strict");
 153:     set.add("http://www.w3.org/TR/xhtml1/loose");
 154:     set.add("http://www.w3.org/TR/xhtml1/frameset");
 155:     HTML_NS_URIS = Collections.unmodifiableSet(set);
 156:   }
 157: 
 158:   /**
 159:    * Convenience constructor.
 160:    */
 161:   public DomHTMLDocument()
 162:   {
 163:     this(new DomHTMLImpl());
 164:   }
 165: 
 166:   /**
 167:    * Constructor.
 168:    * This is called by the DOMImplementation.
 169:    */
 170:   public DomHTMLDocument(DomHTMLImpl impl)
 171:   {
 172:     super(impl);
 173:   }
 174: 
 175:   private Node getChildNodeByName(Node parent, String name)
 176:   {
 177:     for (Node ctx = parent.getFirstChild(); ctx != null;
 178:          ctx = ctx.getNextSibling())
 179:       {
 180:         if (name.equalsIgnoreCase(ctx.getNodeName()))
 181:           {
 182:             return ctx;
 183:           }
 184:       }
 185:     return null;
 186:   }
 187: 
 188:   public String getTitle()
 189:   {
 190:     Node html = getDocumentElement();
 191:     if (html != null)
 192:       {
 193:         Node head = getChildNodeByName(html, "head");
 194:         if (head != null)
 195:           {
 196:             Node title = getChildNodeByName(head, "title");
 197:             if (title != null)
 198:               {
 199:                 return title.getTextContent();
 200:               }
 201:           }
 202:       }
 203:     return null;
 204:   }
 205: 
 206:   public void setTitle(String title)
 207:   {
 208:     Node html = getDocumentElement();
 209:     if (html == null)
 210:       {
 211:         html = createElement("html");
 212:         appendChild(html);
 213:       }
 214:     Node head = getChildNodeByName(html, "head");
 215:     if (head == null)
 216:       {
 217:         head = createElement("head");
 218:         Node first = html.getFirstChild();
 219:         if (first != null)
 220:           {
 221:             html.insertBefore(first, head);
 222:           }
 223:         else
 224:           {
 225:             html.appendChild(head);
 226:           }
 227:       }
 228:     Node titleNode = getChildNodeByName(head, "title");
 229:     if (titleNode == null)
 230:       {
 231:         titleNode = createElement("title");
 232:         Node first = head.getFirstChild();
 233:         if (first != null)
 234:           {
 235:             head.insertBefore(first, titleNode);
 236:           }
 237:         else
 238:           {
 239:             head.appendChild(titleNode);
 240:           }
 241:       }
 242:     titleNode.setTextContent(title);
 243:   }
 244: 
 245:   public String getReferrer()
 246:   {
 247:     // TODO getReferrer
 248:     return null;
 249:   }
 250: 
 251:   public String getDomain()
 252:   {
 253:     try
 254:       {
 255:         URL url = new URL(getDocumentURI());
 256:         return url.getHost();
 257:       }
 258:     catch (MalformedURLException e)
 259:       {
 260:         return null;
 261:       }
 262:   }
 263: 
 264:   public String getURL()
 265:   {
 266:     return getDocumentURI();
 267:   }
 268: 
 269:   public HTMLElement getBody()
 270:   {
 271:     Node html = getDocumentElement();
 272:     if (html != null)
 273:       {
 274:         Node body = getChildNodeByName(html, "body");
 275:         if (body == null)
 276:           {
 277:             body = getChildNodeByName(html, "frameset");
 278:           }
 279:         return (HTMLElement) body;
 280:       }
 281:     return null;
 282:   }
 283: 
 284:   public void setBody(HTMLElement body)
 285:   {
 286:     Node html = getDocumentElement();
 287:     if (html == null)
 288:       {
 289:         html = createElement("html");
 290:         appendChild(html);
 291:       }
 292:     Node ref = getBody();
 293:     if (ref == null)
 294:       {
 295:         html.appendChild(body);
 296:       }
 297:     else
 298:       {
 299:         html.replaceChild(body, ref);
 300:       }
 301:   }
 302: 
 303:   public HTMLCollection getImages()
 304:   {
 305:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 306:     ret.addNodeName("img");
 307:     ret.evaluate();
 308:     return ret;
 309:   }
 310: 
 311:   public HTMLCollection getApplets()
 312:   {
 313:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 314:     ret.addNodeName("object");
 315:     ret.addNodeName("applet");
 316:     ret.evaluate();
 317:     return ret;
 318:   }
 319: 
 320:   public HTMLCollection getLinks()
 321:   {
 322:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 323:     ret.addNodeName("area");
 324:     ret.addNodeName("a");
 325:     ret.evaluate();
 326:     return ret;
 327:   }
 328: 
 329:   public HTMLCollection getForms()
 330:   {
 331:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 332:     ret.addNodeName("form");
 333:     ret.evaluate();
 334:     return ret;
 335:   }
 336: 
 337:   public HTMLCollection getAnchors()
 338:   {
 339:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 340:     ret.addNodeName("a");
 341:     ret.addAttributeName("name");
 342:     ret.evaluate();
 343:     return ret;
 344:   }
 345: 
 346:   public String getCookie()
 347:   {
 348:     // TODO getCookie
 349:     return null;
 350:   }
 351: 
 352:   public void setCookie(String cookie)
 353:   {
 354:     // TODO setCookie
 355:   }
 356: 
 357:   public void open()
 358:   {
 359:     // TODO open
 360:   }
 361: 
 362:   public void close()
 363:   {
 364:     // TODO close
 365:   }
 366: 
 367:   public void write(String text)
 368:   {
 369:     // TODO write
 370:   }
 371: 
 372:   public void writeln(String text)
 373:   {
 374:     // TODO write
 375:   }
 376: 
 377:   public NodeList getElementsByName(String name)
 378:   {
 379:     DomHTMLCollection ret = new DomHTMLCollection(this, this);
 380:     ret.addNodeName(name);
 381:     ret.evaluate();
 382:     return ret;
 383:     // TODO xhtml: return only form controls (?)
 384:   }
 385: 
 386:   public Element createElement(String tagName)
 387:   {
 388:     return createElementNS(null, tagName);
 389:   }
 390: 
 391:   public Element createElementNS(String uri, String qName)
 392:   {
 393:     /* If a non-HTML element, use the default implementation. */
 394:     if (uri != null && !HTML_NS_URIS.contains(uri))
 395:       {
 396:         return super.createElementNS(uri, qName);
 397:       }
 398:     String localName = qName.toLowerCase();
 399:     int ci = qName.indexOf(':');
 400:     if (ci != -1)
 401:       {
 402:         localName = qName.substring(ci + 1);
 403:       }
 404:     Class t = (Class) ELEMENT_CLASSES.get(localName);
 405:     /* If a non-HTML element, use the default implementation. */
 406:     if (t == null)
 407:       {
 408:         return super.createElementNS(uri, qName);
 409:       }
 410:     try
 411:       {
 412:         Constructor c = t.getDeclaredConstructor(ELEMENT_PT);
 413:         Object[] args = new Object[] { this, uri, qName };
 414:         return (Element) c.newInstance(args);
 415:       }
 416:     catch (Exception e)
 417:       {
 418:         DOMException e2 = new DomDOMException(DOMException.TYPE_MISMATCH_ERR);
 419:         e2.initCause(e);
 420:         throw e2;
 421:       }
 422:   }
 423: 
 424: }