FileDocCategorySizeDatePackage
HTMLDocumentImpl.javaAPI DocApache Xerces 3.0.128783Fri Sep 14 20:33:54 BST 2007org.apache.html.dom

HTMLDocumentImpl

public class HTMLDocumentImpl extends org.apache.xerces.dom.DocumentImpl implements HTMLDocument
Implements an HTML document. Provides access to the top level element in the document, its body and title.

Several methods create new nodes of all basic types (comment, text, element, etc.). These methods create new nodes but do not place them in the document tree. The nodes may be placed in the document tree using {@link org.w3c.dom.Node#appendChild} or {@link org.w3c.dom.Node#insertBefore}, or they may be placed in some other document tree.

Note: <FRAMESET> documents are not supported at the moment, neither are direct document writing ({@link #open}, {@link #write}) and HTTP attribute methods ({@link #getURL}, {@link #getCookie}).

xerces.internal
version
$Revision: 451609 $ $Date: 2006-09-30 12:20:57 -0400 (Sat, 30 Sep 2006) $
author
Assaf Arkin
see
org.w3c.dom.html.HTMLDocument

Fields Summary
private static final long
serialVersionUID
private HTMLCollectionImpl
_anchors
Holds HTMLCollectionImpl object with live collection of all anchors in document. This reference is on demand only once.
private HTMLCollectionImpl
_forms
Holds HTMLCollectionImpl object with live collection of all forms in document. This reference is on demand only once.
private HTMLCollectionImpl
_images
Holds HTMLCollectionImpl object with live collection of all images in document. This reference is on demand only once.
private HTMLCollectionImpl
_links
Holds HTMLCollectionImpl object with live collection of all links in document. This reference is on demand only once.
private HTMLCollectionImpl
_applets
Holds HTMLCollectionImpl object with live collection of all applets in document. This reference is on demand only once.
private StringWriter
_writer
Holds string writer used by direct manipulation operation ({@link #open}. {@link #write}, etc) to write new contents into the document and parse that text into a document tree.
private static Hashtable
_elementTypesHTML
Holds names and classes of HTML element types. When an element with a particular tag name is created, the matching {@link java.lang.Class} is used to create the element object. For example, <A> matches {@link HTMLAnchorElementImpl}. This static table is shared across all HTML documents.
private static final Class[]
_elemClassSigHTML
Signature used to locate constructor of HTML element classes. This static array is shared across all HTML documents.
Constructors Summary
public HTMLDocumentImpl()



         
     
    
        super();
        populateElementTypes();
    
Methods Summary
public org.w3c.dom.NodecloneNode(boolean deep)

        HTMLDocumentImpl newdoc = new HTMLDocumentImpl();
        callUserDataHandlers(this, newdoc, UserDataHandler.NODE_CLONED);
        cloneNode(newdoc, deep);
        return newdoc;
    
public voidclose()

        // ! NOT IMPLEMENTED, REQUIRES PARSER !
        if ( _writer != null )
        {
            _writer = null;
        }
    
public org.w3c.dom.AttrcreateAttribute(java.lang.String name)
Creates an Attribute having this Document as its OwnerDoc. Overrides {@link DocumentImpl#createAttribute} and returns and attribute whose name is lower case.

param
name The name of the attribute
return
An attribute whose name is all lower case
throws
DOMException(INVALID_NAME_ERR) if the attribute name is not acceptable

        return super.createAttribute( name.toLowerCase(Locale.ENGLISH) );
    
public org.w3c.dom.ElementcreateElement(java.lang.String tagName)

        Class        elemClass;
        Constructor    cnst;

        // First, make sure tag name is all upper case, next get the associated
        // element class. If no class is found, generate a generic HTML element.
        // Do so also if an unexpected exception occurs.
        tagName = tagName.toUpperCase(Locale.ENGLISH);
        elemClass = (Class) _elementTypesHTML.get( tagName );
        if ( elemClass != null )
        {
            // Get the constructor for the element. The signature specifies an
            // owner document and a tag name. Use the constructor to instantiate
            // a new object and return it.
            try
            {
                cnst = elemClass.getConstructor( _elemClassSigHTML );
                return (Element) cnst.newInstance( new Object[] { this, tagName } );
            }
            catch ( Exception except )
            {
                /*
                Throwable thrw;

                if ( except instanceof java.lang.reflect.InvocationTargetException )
                    thrw = ( (java.lang.reflect.InvocationTargetException) except ).getTargetException();
                else
                    thrw = except;
                System.out.println( "Exception " + thrw.getClass().getName() );
                System.out.println( thrw.getMessage() );
                */
                throw new IllegalStateException( "HTM15 Tag '" + tagName + "' associated with an Element class that failed to construct.\n" + tagName);
            }
        }
        return new HTMLElementImpl( this, tagName );
    
public org.w3c.dom.ElementcreateElementNS(java.lang.String namespaceURI, java.lang.String qualifiedName, java.lang.String localpart)
Xerces-specific constructor. "localName" is passed in, so we don't need to create a new String for it.

param
namespaceURI The namespace URI of the element to create.
param
qualifiedName The qualified name of the element type to instantiate.
param
localpart The local name of the element to instantiate.
return
Element A new Element object with the following attributes:
throws
DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an invalid character.

        return createElementNS(namespaceURI, qualifiedName);
    
public org.w3c.dom.ElementcreateElementNS(java.lang.String namespaceURI, java.lang.String qualifiedName)

        if ( namespaceURI == null || namespaceURI.length() == 0 ) {
            return createElement( qualifiedName );
        }
        return super.createElementNS( namespaceURI, qualifiedName );
    
public org.w3c.dom.html.HTMLCollectiongetAnchors()

        // For more information see HTMLCollection#collectionMatch
        if ( _anchors == null )
            _anchors = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.ANCHOR );
        return _anchors;
    
public org.w3c.dom.html.HTMLCollectiongetApplets()

        // For more information see HTMLCollection#collectionMatch
        if ( _applets == null )
            _applets = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.APPLET );
        return _applets;
    
public synchronized org.w3c.dom.html.HTMLElementgetBody()

        Node    html;
        Node    head;
        Node    body;
        Node    child;
        Node    next;

        // Call getDocumentElement() to get the HTML element that is also the
        // top-level element in the document. Get the first element in the
        // document that is called BODY. Work with that.
        html = getDocumentElement();
        head = getHead();
        synchronized ( html )
        {
            body = head.getNextSibling();
            while ( body != null && ! ( body instanceof HTMLBodyElement )
                    && ! ( body instanceof HTMLFrameSetElement ) )
                body = body.getNextSibling();

            // BODY/FRAMESET exists but might not be second element in HTML
            // (after HEAD): make sure it is and return it.
            if ( body != null )
            {
                synchronized ( body )
                {
                    child = head.getNextSibling();
                    while ( child != null && child != body )
                    {
                        next = child.getNextSibling();
                        body.insertBefore( child, body.getFirstChild() );
                        child = next;
                    }
                }
                return (HTMLElement) body;
            }

            // BODY does not exist, create a new one, place it in the HTML element
            // right after the HEAD and return it.
            body = new HTMLBodyElementImpl( this, "BODY" );
            html.appendChild( body );
        }
        return (HTMLElement) body;
    
public java.lang.StringgetCookie()

        // Information not available on server side.
        return null;
    
public synchronized org.w3c.dom.ElementgetDocumentElement()

        Node    html;
        Node    child;
        Node    next;

        // The document element is the top-level HTML element of the HTML
        // document. Only this element should exist at the top level.
        // If the HTML element is found, all other elements that might
        // precede it are placed inside the HTML element.
        html = getFirstChild();
        while ( html != null )
        {
            if ( html instanceof HTMLHtmlElement )
            {
                // REVISIT: [Q] Why is this code even here? In fact, the
                //          original code is in error because it will
                //          try to move ALL nodes to be children of the
                //          HTML tag. This is not the intended behavior
                //          for comments and processing instructions
                //          outside the root element; it will throw a
                //          hierarchy request error exception for doctype
                //          nodes; *and* this code shouldn't even be
                //          needed because the parser should never build
                //          a document that contains more than a single
                //          root element, anyway! -Ac
                /***
                synchronized ( html )
                {
                    child = getFirstChild();
                    while ( child != null && child != html )
                    {
                        next = child.getNextSibling();
                        html.appendChild( child );
                        child = next;
                    }
                }
                /***/
                return (HTMLElement) html;
            }
            html = html.getNextSibling();
        }

        // HTML element must exist. Create a new element and dump the
        // entire contents of the document into it in the same order as
        // they appear now.
        html = new HTMLHtmlElementImpl( this, "HTML" );
        child = getFirstChild();
        while ( child != null )
        {
            next = child.getNextSibling();
            html.appendChild( child );
            child = next;
        }
        appendChild( html );
        return (HTMLElement) html;
    
public java.lang.StringgetDomain()

        // Information not available on server side.
        return null;
    
private org.w3c.dom.ElementgetElementById(java.lang.String elementId, org.w3c.dom.Node node)
Recursive method retreives an element by its id attribute. Called by {@link #getElementById(String)}.

param
elementId The id value to look for
return
The node in which to look for

        Node    child;
        Element    result;

        child = node.getFirstChild();
        while ( child != null )
        {
            if ( child instanceof Element )
            {
                if ( elementId.equals( ( (Element) child ).getAttribute( "id" ) ) )
                    return (Element) child;
                result = getElementById( elementId, child );
                if ( result != null )
                    return result;
            }
            child = child.getNextSibling();
        }
        return null;
    
public synchronized org.w3c.dom.ElementgetElementById(java.lang.String elementId)

        Element idElement = super.getElementById(elementId);
        if (idElement != null) {
            return idElement;
        }
        return getElementById( elementId, this );
    
public org.w3c.dom.NodeListgetElementsByName(java.lang.String elementName)

        return new NameNodeListImpl( this, elementName );
    
public final org.w3c.dom.NodeListgetElementsByTagName(java.lang.String tagName)

        return super.getElementsByTagName( tagName.toUpperCase(Locale.ENGLISH) );
    
public final org.w3c.dom.NodeListgetElementsByTagNameNS(java.lang.String namespaceURI, java.lang.String localName)

        if ( namespaceURI != null && namespaceURI.length() > 0 ) {
            return super.getElementsByTagNameNS( namespaceURI, localName.toUpperCase(Locale.ENGLISH) );
        }
        return super.getElementsByTagName( localName.toUpperCase(Locale.ENGLISH) );
    
public org.w3c.dom.html.HTMLCollectiongetForms()

        // For more information see HTMLCollection#collectionMatch
        if ( _forms == null )
            _forms = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.FORM );
        return _forms;
    
public synchronized org.w3c.dom.html.HTMLElementgetHead()
Obtains the <HEAD> element in the document, creating one if does not exist before. The <HEAD> element is the first element in the <HTML> in the document. The <HTML> element is obtained by calling {@link #getDocumentElement}. If the element does not exist, one is created.

Called by {@link #getTitle}, {@link #setTitle}, {@link #getBody} and {@link #setBody} to assure the document has the <HEAD> element correctly placed.

return
The <HEAD> element

        Node    head;
        Node    html;
        Node    child;
        Node    next;

        // Call getDocumentElement() to get the HTML element that is also the
        // top-level element in the document. Get the first element in the
        // document that is called HEAD. Work with that.
        html = getDocumentElement();
        synchronized ( html )
        {
            head = html.getFirstChild();
            while ( head != null && ! ( head instanceof HTMLHeadElement ) )
                head = head.getNextSibling();
            // HEAD exists but might not be first element in HTML: make sure
            // it is and return it.
            if ( head != null )
            {
                synchronized ( head )
                {
                    child = html.getFirstChild();
                    while ( child != null && child != head )
                    {
                        next = child.getNextSibling();
                        head.insertBefore( child, head.getFirstChild() );
                        child = next;
                    }
                }
                return (HTMLElement) head;
            }

            // Head does not exist, create a new one, place it at the top of the
            // HTML element and return it.
            head = new HTMLHeadElementImpl( this, "HEAD" );
            html.insertBefore( head, html.getFirstChild() );
        }
        return (HTMLElement) head;
    
public org.w3c.dom.html.HTMLCollectiongetImages()

        // For more information see HTMLCollection#collectionMatch
        if ( _images == null )
            _images = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.IMAGE );
        return _images;
    
public org.w3c.dom.html.HTMLCollectiongetLinks()

        // For more information see HTMLCollection#collectionMatch
        if ( _links == null )
            _links = new HTMLCollectionImpl( getBody(), HTMLCollectionImpl.LINK );
        return _links;
    
public java.lang.StringgetReferrer()

        // Information not available on server side.
        return null;
    
public synchronized java.lang.StringgetTitle()

        HTMLElement head;
        NodeList    list;
        Node        title;

        // Get the HEAD element and look for the TITLE element within.
        // When found, make sure the TITLE is a direct child of HEAD,
        // and return the title's text (the Text node contained within).
        head = getHead();
        list = head.getElementsByTagName( "TITLE" );
        if ( list.getLength() > 0 ) {
            title = list.item( 0 );
            return ( (HTMLTitleElement) title ).getText();
        }
        // No TITLE found, return an empty string.
        return "";
    
public java.lang.StringgetURL()

        // Information not available on server side.
        return null;
    
public voidopen()

        // When called an in-memory is prepared. The document tree is still
        // accessible the old way, until this writer is closed.
        if ( _writer == null )
            _writer = new StringWriter();
    
private static voidpopulateElementType(java.lang.String tagName, java.lang.String className)

        try {
            _elementTypesHTML.put( tagName,
                ObjectFactory.findProviderClass("org.apache.html.dom." + className,
                    HTMLDocumentImpl.class.getClassLoader(), true) );
        } catch ( Exception except ) {
            new RuntimeException( "HTM019 OpenXML Error: Could not find or execute class " + className + " implementing HTML element " + tagName
                                  + "\n" + className + "\t" + tagName);
        }
    
private static synchronized voidpopulateElementTypes()
Called by the constructor to populate the element types list (see {@link #_elementTypesHTML}). Will be called multiple times but populate the list only the first time. Replacement for static constructor.

        // This class looks like it is due to some strange
        // (read: inconsistent) JVM bugs.
        // Initially all this code was placed in the static constructor,
        // but that caused some early JVMs (1.1) to go mad, and if a
        // class could not be found (as happened during development),
        // the JVM would die.
        // Bertrand Delacretaz <bdelacretaz@worldcom.ch> pointed out
        // several configurations where HTMLAnchorElementImpl.class
        // failed, forcing me to revert back to Class.forName().

        if ( _elementTypesHTML != null )
            return;
        _elementTypesHTML = new Hashtable( 63 );
        populateElementType( "A", "HTMLAnchorElementImpl" );
        populateElementType( "APPLET", "HTMLAppletElementImpl" );
        populateElementType( "AREA", "HTMLAreaElementImpl" );
        populateElementType( "BASE",  "HTMLBaseElementImpl" );
        populateElementType( "BASEFONT", "HTMLBaseFontElementImpl" );
        populateElementType( "BLOCKQUOTE", "HTMLQuoteElementImpl" );
        populateElementType( "BODY", "HTMLBodyElementImpl" );
        populateElementType( "BR", "HTMLBRElementImpl" );
        populateElementType( "BUTTON", "HTMLButtonElementImpl" );
        populateElementType( "DEL", "HTMLModElementImpl" );
        populateElementType( "DIR", "HTMLDirectoryElementImpl" );
        populateElementType( "DIV",  "HTMLDivElementImpl" );
        populateElementType( "DL", "HTMLDListElementImpl" );
        populateElementType( "FIELDSET", "HTMLFieldSetElementImpl" );
        populateElementType( "FONT", "HTMLFontElementImpl" );
        populateElementType( "FORM", "HTMLFormElementImpl" );
        populateElementType( "FRAME","HTMLFrameElementImpl" );
        populateElementType( "FRAMESET", "HTMLFrameSetElementImpl" );
        populateElementType( "HEAD", "HTMLHeadElementImpl" );
        populateElementType( "H1", "HTMLHeadingElementImpl" );
        populateElementType( "H2", "HTMLHeadingElementImpl" );
        populateElementType( "H3", "HTMLHeadingElementImpl" );
        populateElementType( "H4", "HTMLHeadingElementImpl" );
        populateElementType( "H5", "HTMLHeadingElementImpl" );
        populateElementType( "H6", "HTMLHeadingElementImpl" );
        populateElementType( "HR", "HTMLHRElementImpl" );
        populateElementType( "HTML", "HTMLHtmlElementImpl" );
        populateElementType( "IFRAME", "HTMLIFrameElementImpl" );
        populateElementType( "IMG", "HTMLImageElementImpl" );
        populateElementType( "INPUT", "HTMLInputElementImpl" );
        populateElementType( "INS", "HTMLModElementImpl" );
        populateElementType( "ISINDEX", "HTMLIsIndexElementImpl" );
        populateElementType( "LABEL", "HTMLLabelElementImpl" );
        populateElementType( "LEGEND", "HTMLLegendElementImpl" );
        populateElementType( "LI", "HTMLLIElementImpl" );
        populateElementType( "LINK", "HTMLLinkElementImpl" );
        populateElementType( "MAP", "HTMLMapElementImpl" );
        populateElementType( "MENU", "HTMLMenuElementImpl" );
        populateElementType( "META", "HTMLMetaElementImpl" );
        populateElementType( "OBJECT", "HTMLObjectElementImpl" );
        populateElementType( "OL", "HTMLOListElementImpl" );
        populateElementType( "OPTGROUP", "HTMLOptGroupElementImpl" );
        populateElementType( "OPTION", "HTMLOptionElementImpl" );
        populateElementType( "P", "HTMLParagraphElementImpl" );
        populateElementType( "PARAM", "HTMLParamElementImpl" );
        populateElementType( "PRE", "HTMLPreElementImpl" );
        populateElementType( "Q", "HTMLQuoteElementImpl" );
        populateElementType( "SCRIPT", "HTMLScriptElementImpl" );
        populateElementType( "SELECT", "HTMLSelectElementImpl" );
        populateElementType( "STYLE", "HTMLStyleElementImpl" );
        populateElementType( "TABLE", "HTMLTableElementImpl" );
        populateElementType( "CAPTION", "HTMLTableCaptionElementImpl" );
        populateElementType( "TD", "HTMLTableCellElementImpl" );
        populateElementType( "TH", "HTMLTableCellElementImpl" );
        populateElementType( "COL", "HTMLTableColElementImpl" );
        populateElementType( "COLGROUP", "HTMLTableColElementImpl" );
        populateElementType( "TR", "HTMLTableRowElementImpl" );
        populateElementType( "TBODY", "HTMLTableSectionElementImpl" );
        populateElementType( "THEAD", "HTMLTableSectionElementImpl" );
        populateElementType( "TFOOT", "HTMLTableSectionElementImpl" );
        populateElementType( "TEXTAREA", "HTMLTextAreaElementImpl" );
        populateElementType( "TITLE", "HTMLTitleElementImpl" );
        populateElementType( "UL", "HTMLUListElementImpl" );
    
public synchronized voidsetBody(org.w3c.dom.html.HTMLElement newBody)

        Node    html;
        Node    body;
        Node    head;
        Node    child;
        NodeList list;

        synchronized ( newBody )
        {
            // Call getDocumentElement() to get the HTML element that is also the
            // top-level element in the document. Get the first element in the
            // document that is called BODY. Work with that.
            html = getDocumentElement();
            head = getHead();
            synchronized ( html )
            {
                list = this.getElementsByTagName( "BODY" );
                if ( list.getLength() > 0 ) {
                    // BODY exists but might not follow HEAD in HTML. If not,
                    // make it so and replce it. Start with the HEAD and make
                    // sure the BODY is the first element after the HEAD.
                    body = list.item( 0 );
                    synchronized ( body )
                    {
                        child = head;
                        while ( child != null )
                        {
                            if ( child instanceof Element )
                            {
                                if ( child != body )
                                    html.insertBefore( newBody, child );
                                else
                                    html.replaceChild( newBody, body );
                                return;
                            }
                            child = child.getNextSibling();
                        }
                        html.appendChild( newBody );
                    }
                    return;
                }
                // BODY does not exist, place it in the HTML element
                // right after the HEAD.
                html.appendChild( newBody );
            }
        }
    
public voidsetCookie(java.lang.String cookie)

        // Information not available on server side.
    
public synchronized voidsetTitle(java.lang.String newTitle)

        HTMLElement head;
        NodeList    list;
        Node        title;

        // Get the HEAD element and look for the TITLE element within.
        // When found, make sure the TITLE is a direct child of HEAD,
        // and set the title's text (the Text node contained within).
        head = getHead();
        list = head.getElementsByTagName( "TITLE" );
        if ( list.getLength() > 0 ) {
            title = list.item( 0 );
            if ( title.getParentNode() != head )
                head.appendChild( title );
            ( (HTMLTitleElement) title ).setText( newTitle );
        }
        else
        {
            // No TITLE found, create a new element and place it at the end
            // of the HEAD element.
            title = new HTMLTitleElementImpl( this, "TITLE" );
            ( (HTMLTitleElement) title ).setText( newTitle );
            head.appendChild( title );
        }
    
public voidwrite(java.lang.String text)

        // Write a string into the in-memory writer.
        if ( _writer != null )
            _writer.write( text );
    
public voidwriteln(java.lang.String text)

        // Write a line into the in-memory writer.
        if ( _writer != null )
            _writer.write( text + "\n" );