All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enhydra.xml.dom.DOMOps Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: DOMOps.java,v 1.3 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.dom;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.enhydra.xml.lazydom.LazyDocument;
import org.enhydra.xml.xmlc.XMLObject;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Entity;
import org.w3c.dom.Node;
import org.w3c.dom.html.HTMLElement;

/**
 * Various static methods the do simple operations on the DOM.
 */
public final class DOMOps {
    
    /** Type constant for {@link #callByReflection(Object,String,String) */
    private static final Class[] ARGTYPES_STRING = { String.class };

    /** Type constant for {@link #callByReflection(Object,String,boolean) */
    private static final Class[] ARGTYPES_PRIM_BOOLEAN = { Boolean.TYPE };

    /** Type constant for {@link #adoptNode */
    private static final Class[] ARGTYPES_NODE = { Node.class };

    /** Type constant for {@link #getContentDocument */
    private static final Class[] ARGTYPES_HTMLELEMENT = { HTMLElement.class };

    /**
     * Prevent instantiation.
     */
    private DOMOps() {
    }

    /**
     * Get the owner document object for a node.  This gets the actual
     * document.  If a XMLC document class instance the contained document is
     * returned.
     */
    public static Document getDocument(Node node) {
        if (node instanceof XMLObject) {
            // Get real document from XMLC.
            return ((XMLObject)node).getDocument();
        } else if (node instanceof Document) {
            return (Document)node;
        } else {
            return node.getOwnerDocument();
        }
    }

    /**
     * Get the real DOM node, bypassing an XMLC-generated container. If a XMLC
     * document class instance the contained document is returned.  Otherwise
     * the node is returned.
     */
    public static Node getActualNode(Node node) {
        if (node instanceof XMLObject) {
            return ((XMLObject)node).getDocument();
        } else {
            return node;
        }
    }

    /**
     * Replace a node with one imported from another document.
     * @param srcNode The node to clone and insert 
     * @param destNode The node to be replaced
     * @return The new node that replaces the destination node.
     */
    public static Node replaceNode(Node srcNode, Node destNode) {
        Node node = destNode.getOwnerDocument().importNode(srcNode, true);
        Node parent = destNode.getParentNode(); 
        if (parent != null){
            parent.replaceChild(node, destNode);
        }
        return node;
    }

    /**
     * Count the number of children in a node has.
     */
    public static int countChildren(Node node) {
        int cnt = 0;
        for (Node child = node.getFirstChild(); child != null;
             child = child.getNextSibling()) {
            cnt++;
        }
        return cnt;
    }

    /**
     * Determine if a document is a LazyDOM instance document.  
     * @return true if its a LazyDOM instance, false if its a LazyDOM template
     *  or not a LazyDOM at all.
     */
    public static boolean isLazyDOMInstance(Document doc) {
        return ((doc instanceof LazyDocument) && !((LazyDocument)doc).isTemplateNode());
    }

    /** Calls a method using reflection.
     * If the desired method is not found, an {@link
     * UnsupportedOperationException} is thrown.
     * @param obj the object to call the method on
     * @param name the method name
     * @param argtypes the argument types. May be null
     * for a void method
     * @param args the arguments. Primitive types must be wrapped in
     * the corresponding class
     * @return whatever the called method returns
     * @throws UnsupportedOperationException if the method cannot be
     * found or cannot be called via reflection
     * @throws InvocationTargetException if the called method throws
     * a checked exception. Note that errors and runtime exceptions
     * thrown by the called method are automatically propagated.
     */
    private static Object callByReflection(Object obj, String name,
				    Class[] argtypes, Object[] args)
	    throws UnsupportedOperationException,
	           InvocationTargetException {
	Class cl = obj.getClass();
	try {
	    Method m = cl.getMethod(name, argtypes);
	    return m.invoke(obj, args);
	} catch (NoSuchMethodException e) {
	    throw new UnsupportedOperationException(e.toString());
	} catch (SecurityException e) {
	    throw new UnsupportedOperationException(e.toString());
	} catch (IllegalAccessException e) {
	    throw new UnsupportedOperationException(e.toString());
	} catch (IllegalArgumentException e) {
	    throw new UnsupportedOperationException(e.toString());
	} catch (InvocationTargetException e) {
	    Throwable cause = e.getTargetException();
	    if (cause instanceof Error) {
		throw (Error)cause;
	    } else if (cause instanceof RuntimeException) {
		throw (RuntimeException)cause;
	    } else {
		throw e;
	    }
	}
    }

    /** Calls a method using reflection. This is exactly the same
     * as calling callByReflection(obj, name,  new Class[] {String.class}, new Object[] { arg }).
     * @param obj the object to call the method on
     * @param name the method name
     * @param arg the single boolean argument to the method
     * for a void method
     * @return whatever the called method returns
     * @throws UnsupportedOperationException if the method cannot be
     * found or cannot be called via reflection
     * @throws InvocationTargetException if the called method throws
     * a checked exception. Note that errors and runtime exceptions
     * thrown by the called method are automatically propagated.
     */
    private static Object callByReflection(Object obj, String name,
					   boolean arg)
	    throws UnsupportedOperationException,
	           InvocationTargetException {

	return callByReflection(obj, name, ARGTYPES_PRIM_BOOLEAN,
	       		new Object[] { (arg?Boolean.TRUE:Boolean.FALSE) });
    }

    /** Calls a method using reflection. This is exactly the same
     * as calling callByReflection(obj, name,  new Class[] {Boolean.TYPE}, new Object[] { new Boolean(arg) }).
     * @param obj the object to call the method on
     * @param name the method name
     * @param arg the single string argument to the method
     * for a void method
     * @return whatever the called method returns
     * @throws UnsupportedOperationException if the method cannot be
     * found or cannot be called via reflection
     * @throws InvocationTargetException if the called method throws
     * a checked exception. Note that errors and runtime exceptions
     * thrown by the called method are automatically propagated.
     */
    private static Object callByReflection(Object obj, String name, String arg)
	    throws UnsupportedOperationException,
	           InvocationTargetException {

	return callByReflection(obj, name, 
				ARGTYPES_STRING, new Object[] { arg });
    }

    /** Call Document#getStandalone() on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.getStandalone() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @return true if the document is standalone,
     * false else
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static boolean getStandalone(Document doc) {
	try {
	    Boolean result =
		(Boolean)callByReflection(doc, "getStandalone", null, null);
	    return result.booleanValue();
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }

    /** Call Document#setStandalone(val) on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.setStandalone() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @param val the new value
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static void setStandalone(Document doc, boolean val) {
	try {
	    callByReflection(doc, "setStandalone", val);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     

    /** Call Document#getEncoding() on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.getEncoding() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @return the encoding
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static String getEncoding(Document doc) {
	try {
	    return (String)callByReflection(doc, "getEncoding", null, null);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     
    /** Call Document#setEncoding(enc) on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.setEncoding() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @param enc the encoding
     * @return the encoding
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static void setEncoding(Document doc, String enc) {
	try {
	    callByReflection(doc, "setEncoding", enc);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     
    /** Call Document#getStrictErrorChecking() on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.getStrictErrorChecking() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @return true if the document has strict error checking,
     * false else
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static boolean getStrictErrorChecking(Document doc) {
	try {
	    Boolean result =
		(Boolean)callByReflection(doc, "getStrictErrorChecking", 
					  null, null);
	    return result.booleanValue();
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }

    /** Call Document#setStrictErrorChecking(val) on
     * doc if supported.  By using reflection, this
     * method avoids problems when
     * Document.setStrictErrorChecking() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @param val the new value
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static void setStrictErrorChecking(Document doc, boolean val) {
	try {
	    callByReflection(doc, "setStrictErrorChecking", val);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     
    /** Call Document#getVersion() on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.getVersion() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @return the version
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static String getVersion(Document doc) {
	try {
	    return (String)callByReflection(doc, "getVersion", null, null);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }

    /** Call Document#setVersion(version) on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.setVersion() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @param version the version
     * @return the version
     * @throws UnsupportedOperationException if doc does
     * not support the method
     */
    public static void setVersion(Document doc, String version) {
	try {
	    callByReflection(doc, "setVersion", version);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }

    /** Call Document#adoptNode(node) on doc if
     * supported.
     * By using reflection, this method avoids problems when
     * Document.adoptNode() is not supported by the
     * given implementation of org.w3c.dom.Document
     * (e.g. the one provided by JDK 1.4).
     * @param doc the document
     * @param node the node
     * @return the adopted node, or null if this
     * operation fails, such as when the source node comes from a
     * different implementation.
     * @throws UnsupportedOperationException if doc does
     * not support the method
     * @throws DOMException NOT_SUPPORTED_ERR: Raised if the source
     * node is of type DOCUMENT,
     * DOCUMENT_TYPE. NO_MODIFICATION_ALLOWED_ERR: Raised when the
     * source node is readonly. 
     */
    public static Node adoptNode(Document doc, Node node) throws DOMException {
	try {
	    return (Node)callByReflection(doc, "adoptNode",
					    ARGTYPES_NODE,
					    new Object[] { node });
	} catch (InvocationTargetException e) {
	    Throwable cause = e.getTargetException();
	    if (cause instanceof DOMException) {
		throw (DOMException) cause;
	    } else {
		// Something went seriously wrong - we don't expect any
		// other checked exceptions here...
		throw new Error("Unexpected exception: " + cause);
	    }
	}
    }

    

    /** Call Entity#getEncoding on entity if
     * supported.
     * By using reflection, this method avoids problems when
     * Entity.getEncoding() is not supported by the
     * given implementation of org.w3c.dom.Entity
     * (e.g. the one provided by JDK 1.4).
     * @param entity the entity
     * @return the encoding
     * @throws UnsupportedOperationException if entity does
     * not support the method
     */
    public static String getEncoding(Entity entity) {
	try {
	    return (String)callByReflection(entity, "getEncoding", null, null);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     
    /** Call Entity#setEncoding(enc) on entity if
     * supported.
     * By using reflection, this method avoids problems when
     * Entity.setEncoding() is not supported by the
     * given implementation of org.w3c.dom.Entity
     * (e.g. the one provided by JDK 1.4).
     * @param entity the entity
     * @param enc the encoding
     * @return the encoding
     * @throws UnsupportedOperationException if entity does
     * not support the method
     */
    public static void setEncoding(Entity entity, String enc) {
	try {
	    callByReflection(entity, "setEncoding", enc);
	} catch (InvocationTargetException e) {
	    // Something went seriously wrong - we don't expect any
	    // checked exception here...
	    throw new Error("Unexpected exception: " + e.getTargetException());
	}
    }
     
    /** Call HTMLElement#getContentDocument(node) on elem if
     * supported.
     * By using reflection, this method avoids problems when
     * HTMLElement.getContentDocument() is not supported by the
     * given implementation of org.w3c.dom.HTMLElement
     * (e.g. the one provided by JDK 1.4).
     * @param elem the element
     * @return the adopted node, or null if this
     * operation fails, such as when the source node comes from a
     * different implementation.
     * @throws UnsupportedOperationException if elem does
     * not support the method
     */
    public static Document getContentDocument(HTMLElement elem) {
	try {
	    return (Document)callByReflection(elem, "getContentDocument",
					      ARGTYPES_HTMLELEMENT,
					      new Object[] { elem });
	} catch (InvocationTargetException e) {
	    Throwable cause = e.getTargetException();
	    if (cause instanceof DOMException) {
		throw (DOMException) cause;
	    } else {
		// Something went seriously wrong - we don't expect any
		// other checked exceptions here...
		throw new Error("Unexpected exception: " + cause);
	    }
	}
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy