mkwan 2003/01/22 08:08:12
Added: java/src/org/apache/xml/utils DOM2Helper.java DOMHelper.java
DOMOrder.java Constants.java
ThreadControllerWrapper.java
Log:
DTM Separation - new files in org.apache.xml.utils
Move the classes DOMOrder, DOMHelper and DOM2Helper from XPath to xml.utils.
Add a new Constants class to hold the constants used by XPath.
The ThreadControllerWrapper class is a container for the nested class
ThreadController which was originally in
org.apache.xalan.transformer.TransformerImpl.
Revision Changes Path
1.1 xml-xalan/java/src/org/apache/xml/utils/DOM2Helper.java
Index: DOM2Helper.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
import java.io.IOException;
import java.util.StringTokenizer;
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.Attr;
import org.xml.sax.InputSource;
import org.xml.sax.Parser;
import javax.xml.parsers.*;
import javax.xml.transform.TransformerException;
/**
* @deprecated Since the introduction of the DTM, this class will be removed.
* This class provides a DOM level 2 "helper", which provides services
currently
* not provided be the DOM standard.
*/
public class DOM2Helper extends DOMHelper
{
/**
* Construct an instance.
*/
public DOM2Helper(){}
/**
* <meta name="usage" content="internal"/>
* Check node to see if it was created by a DOM implementation
* that this helper is intended to support. This is currently
* disabled, and assumes all nodes are acceptable rather than checking
* that they implement org.apache.xerces.dom.NodeImpl.
*
* @param node The node to be tested.
*
* @throws TransformerException if the node is not one which this
* DOM2Helper can support. If we return without throwing the exception,
* the node is compatable.
*/
public void checkNode(Node node) throws TransformerException
{
// if(!(node instanceof org.apache.xerces.dom.NodeImpl))
// throw new
TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XERCES_CANNOT_HANDLE_NODES,
new Object[]{((Object)node).getClass()})); //"DOM2Helper can not handle nodes
of type"
//+((Object)node).getClass());
}
/**
* Returns true if the DOM implementation handled by this helper
* supports the SAX ContentHandler interface.
*
* @return true (since Xerces does).
*/
public boolean supportsSAX()
{
return true;
}
/** Field m_doc: Document Node for the document this helper is currently
* accessing or building
* @see #setDocument
* @see #getDocument
* */
private Document m_doc;
/**
* Specify which document this helper is currently operating on.
*
* @param doc The DOM Document node for this document.
* @see #getDocument
*/
public void setDocument(Document doc)
{
m_doc = doc;
}
/**
* Query which document this helper is currently operating on.
*
* @return The DOM Document node for this document.
* @see #setDocument
*/
public Document getDocument()
{
return m_doc;
}
/**
* <meta name="usage" content="internal"/>
* Parse an XML document.
*
* <p>Right now the Xerces DOMParser class is used. This needs
* fixing, either via jaxp, or via some other, standard method.</p>
*
* <p>The application can use this method to instruct the SAX parser
* to begin parsing an XML document from any valid input
* source (a character stream, a byte stream, or a URI).</p>
*
* <p>Applications may not invoke this method while a parse is in
* progress (they should create a new Parser instead for each
* additional XML document). Once a parse is complete, an
* application may reuse the same Parser object, possibly with a
* different input source.</p>
*
* @param source The input source for the top-level of the
* XML document.
*
* @throws TransformerException if any checked exception is thrown.
*/
public void parse(InputSource source) throws TransformerException
{
try
{
// I guess I should use JAXP factory here... when it's legal.
// org.apache.xerces.parsers.DOMParser parser
// = new org.apache.xerces.parsers.DOMParser();
DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
builderFactory.setValidating(true);
DocumentBuilder parser = builderFactory.newDocumentBuilder();
/*
//
domParser.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes",
getShouldExpandEntityRefs()? false : true);
if(m_useDOM2getNamespaceURI)
{
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
true);
parser.setFeature("http://xml.org/sax/features/namespaces", true);
}
else
{
parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",
false);
}
parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
*/
parser.setErrorHandler(
new org.apache.xml.utils.DefaultErrorHandler());
// if(null != m_entityResolver)
// {
// System.out.println("Setting the entity resolver.");
// parser.setEntityResolver(m_entityResolver);
// }
setDocument(parser.parse(source));
}
catch (org.xml.sax.SAXException se)
{
throw new TransformerException(se);
}
catch (ParserConfigurationException pce)
{
throw new TransformerException(pce);
}
catch (IOException ioe)
{
throw new TransformerException(ioe);
}
//
setDocument(((org.apache.xerces.parsers.DOMParser)parser).getDocument());
}
/**
* Given an XML ID, return the element. This requires assistance from the
* DOM and parser, and is meaningful only in the context of a DTD
* or schema which declares attributes as being of type ID. This
* information may or may not be available in all parsers, may or
* may not be available for specific documents, and may or may not
* be available when validation is not turned on.
*
* @param id The ID to search for, as a String.
* @param doc The document to search within, as a DOM Document node.
* @return DOM Element node with an attribute of type ID whose value
* uniquely matches the requested id string, or null if there isn't
* such an element or if the DOM can't answer the question for other
* reasons.
*/
public Element getElementByID(String id, Document doc)
{
return doc.getElementById(id);
}
/**
* Figure out whether node2 should be considered as being later
* in the document than node1, in Document Order as defined
* by the XPath model. This may not agree with the ordering defined
* by other XML applications.
* <p>
* There are some cases where ordering isn't defined, and neither are
* the results of this function -- though we'll generally return true.
* <p>
* TODO: Make sure this does the right thing with attribute nodes!!!
*
* @param node1 DOM Node to perform position comparison on.
* @param node2 DOM Node to perform position comparison on .
*
* @return false if node2 comes before node1, otherwise return true.
* You can think of this as
* <code>(node1.documentOrderPosition <=
node2.documentOrderPosition)</code>.
*/
public static boolean isNodeAfter(Node node1, Node node2)
{
// Assume first that the nodes are DTM nodes, since discovering node
// order is massivly faster for the DTM.
if(node1 instanceof DOMOrder && node2 instanceof DOMOrder)
{
int index1 = ((DOMOrder) node1).getUid();
int index2 = ((DOMOrder) node2).getUid();
return index1 <= index2;
}
else
{
// isNodeAfter will return true if node is after countedNode
// in document order. The base isNodeAfter is sloooow (relatively).
return DOMHelper.isNodeAfter(node1, node2);
}
}
/**
* Get the XPath-model parent of a node. This version takes advantage
* of the DOM Level 2 Attr.ownerElement() method; the base version we
* would otherwise inherit is prepared to fall back on exhaustively
* walking the document to find an Attr's parent.
*
* @param node Node to be examined
*
* @return the DOM parent of the input node, if there is one, or the
* ownerElement if the input node is an Attr, or null if the node is
* a Document, a DocumentFragment, or an orphan.
*/
public static Node getParentOfNode(Node node)
{
Node parent=node.getParentNode();
if(parent==null && (Node.ATTRIBUTE_NODE == node.getNodeType()) )
parent=((Attr) node).getOwnerElement();
return parent;
}
/**
* Returns the local name of the given node, as defined by the
* XML Namespaces specification. This is prepared to handle documents
* built using DOM Level 1 methods by falling back upon explicitly
* parsing the node name.
*
* @param n Node to be examined
*
* @return String containing the local name, or null if the node
* was not assigned a Namespace.
*/
public String getLocalNameOfNode(Node n)
{
String name = n.getLocalName();
return (null == name) ? super.getLocalNameOfNode(n) : name;
}
/**
* Returns the Namespace Name (Namespace URI) for the given node.
* In a Level 2 DOM, you can ask the node itself. Note, however, that
* doing so conflicts with our decision in getLocalNameOfNode not
* to trust the that the DOM was indeed created using the Level 2
* methods. If Level 1 methods were used, these two functions will
* disagree with each other.
* <p>
* TODO: Reconcile with getLocalNameOfNode.
*
* @param n Node to be examined
*
* @return String containing the Namespace URI bound to this DOM node
* at the time the Node was created.
*/
public String getNamespaceOfNode(Node n)
{
return n.getNamespaceURI();
}
/** Field m_useDOM2getNamespaceURI is a compile-time flag which
* gates some of the parser options used to build a DOM -- but
* that code is commented out at this time and nobody else
* references it, so I've commented this out as well. */
//private boolean m_useDOM2getNamespaceURI = false;
}
1.1 xml-xalan/java/src/org/apache/xml/utils/DOMHelper.java
Index: DOMHelper.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
import java.util.Hashtable;
import java.util.Vector;
import org.w3c.dom.*;
import javax.xml.transform.TransformerException;
import org.apache.xml.res.XMLErrorResources;
import org.apache.xml.res.XMLMessages;
// Imported JAVA API for XML Parsing 1.0 classes
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.xml.dtm.ref.DTMNodeProxy;
/**
* @deprecated Since the introduction of the DTM, this class will be removed.
* This class provides a front-end to DOM implementations, providing
* a number of utility functions that either aren't yet standardized
* by the DOM spec or that are defined in optional DOM modules and
* hence may not be present in all DOMs.
*/
public class DOMHelper
{
/**
* DOM Level 1 did not have a standard mechanism for creating a new
* Document object. This function provides a DOM-implementation-independent
* abstraction for that for that concept. It's typically used when
* outputting a new DOM as the result of an operation.
* <p>
* TODO: This isn't directly compatable with DOM Level 2.
* The Level 2 createDocument call also creates the root
* element, and thus requires that you know what that element will be
* before creating the Document. We should think about whether we want
* to change this code, and the callers, so we can use the DOM's own
* method. (It's also possible that DOM Level 3 may relax this
* sequence, but you may give up some intelligence in the DOM by
* doing so; the intent was that knowing the document type and root
* element might let the DOM automatically switch to a specialized
* subclass for particular kinds of documents.)
*
* @return The newly created DOM Document object, with no children, or
* null if we can't find a DOM implementation that permits creating
* new empty Documents.
*/
public static Document createDocument()
{
try
{
// Use an implementation of the JAVA API for XML Parsing 1.0 to
// create a DOM Document node to contain the result.
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
dfactory.setNamespaceAware(true);
dfactory.setValidating(true);
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Document outNode = docBuilder.newDocument();
return outNode;
}
catch (ParserConfigurationException pce)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CREATEDOCUMENT_NOT_SUPPORTED, null));
//"createDocument() not supported in XPathContext!");
// return null;
}
}
/**
* <meta name="usage" content="advanced"/>
* Tells, through the combination of the default-space attribute
* on xsl:stylesheet, xsl:strip-space, xsl:preserve-space, and the
* xml:space attribute, whether or not extra whitespace should be stripped
* from the node. Literal elements from template elements should
* <em>not</em> be tested with this function.
* @param textNode A text node from the source tree.
* @return true if the text node should be stripped of extra whitespace.
*
* @throws javax.xml.transform.TransformerException
*/
public boolean shouldStripSourceNode(Node textNode)
throws javax.xml.transform.TransformerException
{
// return (null == m_envSupport) ? false :
m_envSupport.shouldStripSourceNode(textNode);
return false;
}
/**
* Supports the XPath function GenerateID by returning a unique
* identifier string for any given DOM Node.
* <p>
* Warning: The base implementation uses the Node object's hashCode(),
* which is NOT guaranteed to be unique. If that method hasn't been
* overridden in this DOM ipmlementation, most Java implementions will
* derive it from the object's address and should be OK... but if
* your DOM uses a different definition of hashCode (eg hashing the
* contents of the subtree), or if your DOM may have multiple objects
* that represent a single Node in the data structure (eg via proxying),
* you may need to find another way to assign a unique identifier.
* <p>
* Also, be aware that if nodes are destroyed and recreated, there is
* an open issue regarding whether an ID may be reused. Currently
* we're assuming that the input document is stable for the duration
* of the XPath/XSLT operation, so this shouldn't arise in this context.
* <p>
* (DOM Level 3 is investigating providing a unique node "key", but
* that won't help Level 1 and Level 2 implementations.)
*
* @param node whose identifier you want to obtain
*
* @return a string which should be different for every Node object.
*/
public String getUniqueID(Node node)
{
return "N" + Integer.toHexString(node.hashCode()).toUpperCase();
}
/**
* Figure out whether node2 should be considered as being later
* in the document than node1, in Document Order as defined
* by the XPath model. This may not agree with the ordering defined
* by other XML applications.
* <p>
* There are some cases where ordering isn't defined, and neither are
* the results of this function -- though we'll generally return true.
*
* TODO: Make sure this does the right thing with attribute nodes!!!
*
* @param node1 DOM Node to perform position comparison on.
* @param node2 DOM Node to perform position comparison on .
*
* @return false if node2 comes before node1, otherwise return true.
* You can think of this as
* <code>(node1.documentOrderPosition <=
node2.documentOrderPosition)</code>.
*/
public static boolean isNodeAfter(Node node1, Node node2)
{
if (node1 == node2 || isNodeTheSame(node1, node2))
return true;
// Default return value, if there is no defined ordering
boolean isNodeAfter = true;
Node parent1 = getParentOfNode(node1);
Node parent2 = getParentOfNode(node2);
// Optimize for most common case
if (parent1 == parent2 || isNodeTheSame(parent1, parent2)) // then we
know they are siblings
{
if (null != parent1)
isNodeAfter = isNodeAfterSibling(parent1, node1, node2);
else
{
// If both parents are null, ordering is not defined.
// We're returning a value in lieu of throwing an exception.
// Not a case we expect to arise in XPath, but beware if you
// try to reuse this method.
// We can just fall through in this case, which allows us
// to hit the debugging code at the end of the function.
//return isNodeAfter;
}
}
else
{
// General strategy: Figure out the lengths of the two
// ancestor chains, reconcile the lengths, and look for
// the lowest common ancestor. If that ancestor is one of
// the nodes being compared, it comes before the other.
// Otherwise perform a sibling compare.
//
// NOTE: If no common ancestor is found, ordering is undefined
// and we return the default value of isNodeAfter.
// Count parents in each ancestor chain
int nParents1 = 2, nParents2 = 2; // include node & parent obtained
above
while (parent1 != null)
{
nParents1++;
parent1 = getParentOfNode(parent1);
}
while (parent2 != null)
{
nParents2++;
parent2 = getParentOfNode(parent2);
}
// Initially assume scan for common ancestor starts with
// the input nodes.
Node startNode1 = node1, startNode2 = node2;
// If one ancestor chain is longer, adjust its start point
// so we're comparing at the same depths
if (nParents1 < nParents2)
{
// Adjust startNode2 to depth of startNode1
int adjust = nParents2 - nParents1;
for (int i = 0; i < adjust; i++)
{
startNode2 = getParentOfNode(startNode2);
}
}
else if (nParents1 > nParents2)
{
// adjust startNode1 to depth of startNode2
int adjust = nParents1 - nParents2;
for (int i = 0; i < adjust; i++)
{
startNode1 = getParentOfNode(startNode1);
}
}
Node prevChild1 = null, prevChild2 = null; // so we can "back up"
// Loop up the ancestor chain looking for common parent
while (null != startNode1)
{
if (startNode1 == startNode2 || isNodeTheSame(startNode1,
startNode2)) // common parent?
{
if (null == prevChild1) // first time in loop?
{
// Edge condition: one is the ancestor of the other.
isNodeAfter = (nParents1 < nParents2) ? true : false;
break; // from while loop
}
else
{
// Compare ancestors below lowest-common as siblings
isNodeAfter = isNodeAfterSibling(startNode1, prevChild1,
prevChild2);
break; // from while loop
}
} // end if(startNode1 == startNode2)
// Move up one level and try again
prevChild1 = startNode1;
startNode1 = getParentOfNode(startNode1);
prevChild2 = startNode2;
startNode2 = getParentOfNode(startNode2);
} // end while(parents exist to examine)
} // end big else (not immediate siblings)
// WARNING: The following diagnostic won't report the early
// "same node" case. Fix if/when needed.
/* -- please do not remove... very useful for diagnostics --
System.out.println("node1 =
"+node1.getNodeName()+"("+node1.getNodeType()+")"+
", node2 = "+node2.getNodeName()
+"("+node2.getNodeType()+")"+
", isNodeAfter = "+isNodeAfter); */
return isNodeAfter;
} // end isNodeAfter(Node node1, Node node2)
/**
* Use DTMNodeProxy to determine whether two nodes are the same.
*
* @param node1 The first DOM node to compare.
* @param node2 The second DOM node to compare.
* @return true if the two nodes are the same.
*/
public static boolean isNodeTheSame(Node node1, Node node2)
{
if (node1 instanceof DTMNodeProxy && node2 instanceof DTMNodeProxy)
return ((DTMNodeProxy)node1).equals((DTMNodeProxy)node2);
else
return (node1 == node2);
}
/**
* Figure out if child2 is after child1 in document order.
* <p>
* Warning: Some aspects of "document order" are not well defined.
* For example, the order of attributes is considered
* meaningless in XML, and the order reported by our model will
* be consistant for a given invocation but may not
* match that of either the source file or the serialized output.
*
* @param parent Must be the parent of both child1 and child2.
* @param child1 Must be the child of parent and not equal to child2.
* @param child2 Must be the child of parent and not equal to child1.
* @return true if child 2 is after child1 in document order.
*/
private static boolean isNodeAfterSibling(Node parent, Node child1,
Node child2)
{
boolean isNodeAfterSibling = false;
short child1type = child1.getNodeType();
short child2type = child2.getNodeType();
if ((Node.ATTRIBUTE_NODE != child1type)
&& (Node.ATTRIBUTE_NODE == child2type))
{
// always sort attributes before non-attributes.
isNodeAfterSibling = false;
}
else if ((Node.ATTRIBUTE_NODE == child1type)
&& (Node.ATTRIBUTE_NODE != child2type))
{
// always sort attributes before non-attributes.
isNodeAfterSibling = true;
}
else if (Node.ATTRIBUTE_NODE == child1type)
{
NamedNodeMap children = parent.getAttributes();
int nNodes = children.getLength();
boolean found1 = false, found2 = false;
// Count from the start until we find one or the other.
for (int i = 0; i < nNodes; i++)
{
Node child = children.item(i);
if (child1 == child || isNodeTheSame(child1, child))
{
if (found2)
{
isNodeAfterSibling = false;
break;
}
found1 = true;
}
else if (child2 == child || isNodeTheSame(child2, child))
{
if (found1)
{
isNodeAfterSibling = true;
break;
}
found2 = true;
}
}
}
else
{
// TODO: Check performance of alternate solution:
// There are two choices here: Count from the start of
// the document until we find one or the other, or count
// from one until we find or fail to find the other.
// Either can wind up scanning all the siblings in the worst
// case, which on a wide document can be a lot of work but
// is more typically is a short list.
// Scanning from the start involves two tests per iteration,
// but it isn't clear that scanning from the middle doesn't
// yield more iterations on average.
// We should run some testcases.
Node child = parent.getFirstChild();
boolean found1 = false, found2 = false;
while (null != child)
{
// Node child = children.item(i);
if (child1 == child || isNodeTheSame(child1, child))
{
if (found2)
{
isNodeAfterSibling = false;
break;
}
found1 = true;
}
else if (child2 == child || isNodeTheSame(child2, child))
{
if (found1)
{
isNodeAfterSibling = true;
break;
}
found2 = true;
}
child = child.getNextSibling();
}
}
return isNodeAfterSibling;
} // end isNodeAfterSibling(Node parent, Node child1, Node child2)
//==========================================================
// SECTION: Namespace resolution
//==========================================================
/**
* <meta name="usage" content="internal"/>
* Get the depth level of this node in the tree (equals 1 for
* a parentless node).
*
* @param n Node to be examined.
* @return the number of ancestors, plus one
*/
public short getLevel(Node n)
{
short level = 1;
while (null != (n = getParentOfNode(n)))
{
level++;
}
return level;
}
/**
* Given an XML Namespace prefix and a context in which the prefix
* is to be evaluated, return the Namespace Name this prefix was
* bound to. Note that DOM Level 3 is expected to provide a version of
* this which deals with the DOM's "early binding" behavior.
*
* Default handling:
*
* @param prefix String containing namespace prefix to be resolved,
* without the ':' which separates it from the localname when used
* in a Node Name. The empty sting signifies the default namespace
* at this point in the document.
* @param namespaceContext Element which provides context for resolution.
* (We could extend this to work for other nodes by first seeking their
* nearest Element ancestor.)
*
* @return a String containing the Namespace URI which this prefix
* represents in the specified context.
*/
public String getNamespaceForPrefix(String prefix, Element namespaceContext)
{
int type;
Node parent = namespaceContext;
String namespace = null;
if (prefix.equals("xml"))
{
namespace = QName.S_XMLNAMESPACEURI; // Hardcoded, per Namespace spec
}
else if(prefix.equals("xmlns"))
{
// Hardcoded in the DOM spec, expected to be adopted by
// Namespace spec. NOTE: Namespace declarations _must_ use
// the xmlns: prefix; other prefixes declared as belonging
// to this namespace will not be recognized and should
// probably be rejected by parsers as erroneous declarations.
namespace = "http://www.w3.org/2000/xmlns/";
}
else
{
// Attribute name for this prefix's declaration
String declname=(prefix=="")
? "xmlns"
: "xmlns:"+prefix;
// Scan until we run out of Elements or have resolved the namespace
while ((null != parent) && (null == namespace)
&& (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
|| (type == Node.ENTITY_REFERENCE_NODE)))
{
if (type == Node.ELEMENT_NODE)
{
// Look for the appropriate Namespace Declaration
attribute,
// either "xmlns:prefix" or (if prefix is "") "xmlns".
// TODO: This does not handle "implicit declarations"
// which may be created when the DOM is edited. DOM
Level
// 3 will define how those should be interpreted. But
// this issue won't arise in freshly-parsed DOMs.
// NOTE: declname is set earlier, outside the loop.
Attr
attr=((Element)parent).getAttributeNode(declname);
if(attr!=null)
{
namespace = attr.getNodeValue();
break;
}
}
parent = getParentOfNode(parent);
}
}
return namespace;
}
/**
* An experiment for the moment.
*/
Hashtable m_NSInfos = new Hashtable();
/** Object to put into the m_NSInfos table that tells that a node has not
been
* processed, but has xmlns namespace decls. */
protected static final NSInfo m_NSInfoUnProcWithXMLNS = new NSInfo(false,
true);
/** Object to put into the m_NSInfos table that tells that a node has not
been
* processed, but has no xmlns namespace decls. */
protected static final NSInfo m_NSInfoUnProcWithoutXMLNS = new NSInfo(false,
false);
/** Object to put into the m_NSInfos table that tells that a node has not
been
* processed, and has no xmlns namespace decls, and has no ancestor decls.
*/
protected static final NSInfo m_NSInfoUnProcNoAncestorXMLNS =
new NSInfo(false, false, NSInfo.ANCESTORNOXMLNS);
/** Object to put into the m_NSInfos table that tells that a node has been
* processed, and has xmlns namespace decls. */
protected static final NSInfo m_NSInfoNullWithXMLNS = new NSInfo(true,
true);
/** Object to put into the m_NSInfos table that tells that a node has been
* processed, and has no xmlns namespace decls. */
protected static final NSInfo m_NSInfoNullWithoutXMLNS = new NSInfo(true,
false);
/** Object to put into the m_NSInfos table that tells that a node has been
* processed, and has no xmlns namespace decls. and has no ancestor decls.
*/
protected static final NSInfo m_NSInfoNullNoAncestorXMLNS =
new NSInfo(true, false, NSInfo.ANCESTORNOXMLNS);
/** Vector of node (odd indexes) and NSInfos (even indexes) that tell if
* the given node is a candidate for ancestor namespace processing. */
protected Vector m_candidateNoAncestorXMLNS = new Vector();
/**
* Returns the namespace of the given node. Differs from simply getting
* the node's prefix and using getNamespaceForPrefix in that it attempts
* to cache some of the data in NSINFO objects, to avoid repeated lookup.
* TODO: Should we consider moving that logic into getNamespaceForPrefix?
*
* @param n Node to be examined.
*
* @return String containing the Namespace Name (uri) for this node.
* Note that this is undefined for any nodes other than Elements and
* Attributes.
*/
public String getNamespaceOfNode(Node n)
{
String namespaceOfPrefix;
boolean hasProcessedNS;
NSInfo nsInfo;
short ntype = n.getNodeType();
if (Node.ATTRIBUTE_NODE != ntype)
{
Object nsObj = m_NSInfos.get(n); // return value
nsInfo = (nsObj == null) ? null : (NSInfo) nsObj;
hasProcessedNS = (nsInfo == null) ? false : nsInfo.m_hasProcessedNS;
}
else
{
hasProcessedNS = false;
nsInfo = null;
}
if (hasProcessedNS)
{
namespaceOfPrefix = nsInfo.m_namespace;
}
else
{
namespaceOfPrefix = null;
String nodeName = n.getNodeName();
int indexOfNSSep = nodeName.indexOf(':');
String prefix;
if (Node.ATTRIBUTE_NODE == ntype)
{
if (indexOfNSSep > 0)
{
prefix = nodeName.substring(0, indexOfNSSep);
}
else
{
// Attributes don't use the default namespace, so if
// there isn't a prefix, we're done.
return namespaceOfPrefix;
}
}
else
{
prefix = (indexOfNSSep >= 0)
? nodeName.substring(0, indexOfNSSep) : "";
}
boolean ancestorsHaveXMLNS = false;
boolean nHasXMLNS = false;
if (prefix.equals("xml"))
{
namespaceOfPrefix = QName.S_XMLNAMESPACEURI;
}
else
{
int parentType;
Node parent = n;
while ((null != parent) && (null == namespaceOfPrefix))
{
if ((null != nsInfo)
&& (nsInfo.m_ancestorHasXMLNSAttrs
== nsInfo.ANCESTORNOXMLNS))
{
break;
}
parentType = parent.getNodeType();
if ((null == nsInfo) || nsInfo.m_hasXMLNSAttrs)
{
boolean elementHasXMLNS = false;
if (parentType == Node.ELEMENT_NODE)
{
NamedNodeMap nnm = parent.getAttributes();
for (int i = 0; i < nnm.getLength(); i++)
{
Node attr = nnm.item(i);
String aname = attr.getNodeName();
if (aname.charAt(0) == 'x')
{
boolean isPrefix = aname.startsWith("xmlns:");
if (aname.equals("xmlns") || isPrefix)
{
if (n == parent)
nHasXMLNS = true;
elementHasXMLNS = true;
ancestorsHaveXMLNS = true;
String p = isPrefix ? aname.substring(6) : "";
if (p.equals(prefix))
{
namespaceOfPrefix = attr.getNodeValue();
break;
}
}
}
}
}
if ((Node.ATTRIBUTE_NODE != parentType) && (null == nsInfo)
&& (n != parent))
{
nsInfo = elementHasXMLNS
? m_NSInfoUnProcWithXMLNS : m_NSInfoUnProcWithoutXMLNS;
m_NSInfos.put(parent, nsInfo);
}
}
if (Node.ATTRIBUTE_NODE == parentType)
{
parent = getParentOfNode(parent);
}
else
{
m_candidateNoAncestorXMLNS.addElement(parent);
m_candidateNoAncestorXMLNS.addElement(nsInfo);
parent = parent.getParentNode();
}
if (null != parent)
{
Object nsObj = m_NSInfos.get(parent); // return value
nsInfo = (nsObj == null) ? null : (NSInfo) nsObj;
}
}
int nCandidates = m_candidateNoAncestorXMLNS.size();
if (nCandidates > 0)
{
if ((false == ancestorsHaveXMLNS) && (null == parent))
{
for (int i = 0; i < nCandidates; i += 2)
{
Object candidateInfo = m_candidateNoAncestorXMLNS.elementAt(i
+ 1);
if (candidateInfo == m_NSInfoUnProcWithoutXMLNS)
{
m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i),
m_NSInfoUnProcNoAncestorXMLNS);
}
else if (candidateInfo == m_NSInfoNullWithoutXMLNS)
{
m_NSInfos.put(m_candidateNoAncestorXMLNS.elementAt(i),
m_NSInfoNullNoAncestorXMLNS);
}
}
}
m_candidateNoAncestorXMLNS.removeAllElements();
}
}
if (Node.ATTRIBUTE_NODE != ntype)
{
if (null == namespaceOfPrefix)
{
if (ancestorsHaveXMLNS)
{
if (nHasXMLNS)
m_NSInfos.put(n, m_NSInfoNullWithXMLNS);
else
m_NSInfos.put(n, m_NSInfoNullWithoutXMLNS);
}
else
{
m_NSInfos.put(n, m_NSInfoNullNoAncestorXMLNS);
}
}
else
{
m_NSInfos.put(n, new NSInfo(namespaceOfPrefix, nHasXMLNS));
}
}
}
return namespaceOfPrefix;
}
/**
* Returns the local name of the given node. If the node's name begins
* with a namespace prefix, this is the part after the colon; otherwise
* it's the full node name.
*
* @param n the node to be examined.
*
* @return String containing the Local Name
*/
public String getLocalNameOfNode(Node n)
{
String qname = n.getNodeName();
int index = qname.indexOf(':');
return (index < 0) ? qname : qname.substring(index + 1);
}
/**
* Returns the element name with the namespace prefix (if any) replaced
* by the Namespace URI it was bound to. This is not a standard
* representation of a node name, but it allows convenient
* single-string comparison of the "universal" names of two nodes.
*
* @param elem Element to be examined.
*
* @return String in the form "namespaceURI:localname" if the node
* belongs to a namespace, or simply "localname" if it doesn't.
* @see #getExpandedAttributeName
*/
public String getExpandedElementName(Element elem)
{
String namespace = getNamespaceOfNode(elem);
return (null != namespace)
? namespace + ":" + getLocalNameOfNode(elem)
: getLocalNameOfNode(elem);
}
/**
* Returns the attribute name with the namespace prefix (if any) replaced
* by the Namespace URI it was bound to. This is not a standard
* representation of a node name, but it allows convenient
* single-string comparison of the "universal" names of two nodes.
*
* @param attr Attr to be examined
*
* @return String in the form "namespaceURI:localname" if the node
* belongs to a namespace, or simply "localname" if it doesn't.
* @see #getExpandedElementName
*/
public String getExpandedAttributeName(Attr attr)
{
String namespace = getNamespaceOfNode(attr);
return (null != namespace)
? namespace + ":" + getLocalNameOfNode(attr)
: getLocalNameOfNode(attr);
}
//==========================================================
// SECTION: DOM Helper Functions
//==========================================================
/**
* Tell if the node is ignorable whitespace. Note that this can
* be determined only in the context of a DTD or other Schema,
* and that DOM Level 2 has nostandardized DOM API which can
* return that information.
* @deprecated
*
* @param node Node to be examined
*
* @return CURRENTLY HARDCODED TO FALSE, but should return true if
* and only if the node is of type Text, contains only whitespace,
* and does not appear as part of the #PCDATA content of an element.
* (Note that determining this last may require allowing for
* Entity References.)
*/
public boolean isIgnorableWhitespace(Text node)
{
boolean isIgnorable = false; // return value
// TODO: I can probably do something to figure out if this
// space is ignorable from just the information in
// the DOM tree.
// -- You need to be able to distinguish whitespace
// that is #PCDATA from whitespace that isn't. That requires
// DTD support, which won't be standardized until DOM Level 3.
return isIgnorable;
}
/**
* Get the first unparented node in the ancestor chain.
* @deprecated
*
* @param node Starting node, to specify which chain to chase
*
* @return the topmost ancestor.
*/
public Node getRoot(Node node)
{
Node root = null;
while (node != null)
{
root = node;
node = getParentOfNode(node);
}
return root;
}
/**
* Get the root node of the document tree, regardless of
* whether or not the node passed in is a document node.
* <p>
* TODO: This doesn't handle DocumentFragments or "orphaned" subtrees
* -- it's currently returning ownerDocument even when the tree is
* not actually part of the main Document tree. We should either
* rewrite the description to say that it finds the Document node,
* or change the code to walk up the ancestor chain.
*
* @param n Node to be examined
*
* @return the Document node. Note that this is not the correct answer
* if n was (or was a child of) a DocumentFragment or an orphaned node,
* as can arise if the DOM has been edited rather than being generated
* by a parser.
*/
public Node getRootNode(Node n)
{
int nt = n.getNodeType();
return ( (Node.DOCUMENT_NODE == nt) || (Node.DOCUMENT_FRAGMENT_NODE ==
nt) )
? n : n.getOwnerDocument();
}
/**
* Test whether the given node is a namespace decl node. In DOM Level 2
* this can be done in a namespace-aware manner, but in Level 1 DOMs
* it has to be done by testing the node name.
*
* @param n Node to be examined.
*
* @return boolean -- true iff the node is an Attr whose name is
* "xmlns" or has the "xmlns:" prefix.
*/
public boolean isNamespaceNode(Node n)
{
if (Node.ATTRIBUTE_NODE == n.getNodeType())
{
String attrName = n.getNodeName();
return (attrName.startsWith("xmlns:") || attrName.equals("xmlns"));
}
return false;
}
/**
* Obtain the XPath-model parent of a DOM node -- ownerElement for Attrs,
* parent for other nodes.
* <p>
* Background: The DOM believes that you must be your Parent's
* Child, and thus Attrs don't have parents. XPath said that Attrs
* do have their owning Element as their parent. This function
* bridges the difference, either by using the DOM Level 2 ownerElement
* function or by using a "silly and expensive function" in Level 1
* DOMs.
* <p>
* (There's some discussion of future DOMs generalizing ownerElement
* into ownerNode and making it work on all types of nodes. This
* still wouldn't help the users of Level 1 or Level 2 DOMs)
* <p>
*
* @param node Node whose XPath parent we want to obtain
*
* @return the parent of the node, or the ownerElement if it's an
* Attr node, or null if the node is an orphan.
*
* @throws RuntimeException if the Document has no root element.
* This can't arise if the Document was created
* via the DOM Level 2 factory methods, but is possible if other
* mechanisms were used to obtain it
*/
public static Node getParentOfNode(Node node) throws RuntimeException
{
Node parent;
short nodeType = node.getNodeType();
if (Node.ATTRIBUTE_NODE == nodeType)
{
Document doc = node.getOwnerDocument();
/*
TBD:
if(null == doc)
{
throw new
RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT,
null));//"Attribute child does not have an owner document!");
}
*/
// Given how expensive the tree walk may be, we should first ask
// whether this DOM can answer the question for us. The additional
// test does slow down Level 1 DOMs slightly. DOMHelper2, which
// is currently specialized for Xerces, assumes it can use the
// Level 2 solution. We might want to have an intermediate stage,
// which would assume DOM Level 2 but not assume Xerces.
//
// (Shouldn't have to check whether impl is null in a compliant DOM,
// but let's be paranoid for a moment...)
DOMImplementation impl=doc.getImplementation();
if(impl!=null && impl.hasFeature("Core","2.0"))
{
parent=((Attr)node).getOwnerElement();
return parent;
}
// DOM Level 1 solution, as fallback. Hugely expensive.
Element rootElem = doc.getDocumentElement();
if (null == rootElem)
{
throw new RuntimeException(
XMLMessages.createXMLMessage(
XMLErrorResources.ER_CHILD_HAS_NO_OWNER_DOCUMENT_ELEMENT,
null)); //"Attribute child does not have an owner document
element!");
}
parent = locateAttrParent(rootElem, node);
}
else
{
parent = node.getParentNode();
// if((Node.DOCUMENT_NODE != nodeType) && (null == parent))
// {
// throw new RuntimeException("Child does not have parent!");
// }
}
return parent;
}
/**
* Given an ID, return the element. This can work only if the document
* is interpreted in the context of a DTD or Schema, since otherwise
* we don't know which attributes are or aren't IDs.
* <p>
* Note that DOM Level 1 had no ability to retrieve this information.
* DOM Level 2 introduced it but does not promise that it will be
* supported in all DOMs; those which can't support it will always
* return null.
* <p>
* TODO: getElementByID is currently unimplemented. Support DOM Level 2?
*
* @param id The unique identifier to be searched for.
* @param doc The document to search within.
* @return CURRENTLY HARDCODED TO NULL, but it should be:
* The node which has this unique identifier, or null if there
* is no such node or this DOM can't reliably recognize it.
*/
public Element getElementByID(String id, Document doc)
{
return null;
}
/**
* The getUnparsedEntityURI function returns the URI of the unparsed
* entity with the specified name in the same document as the context
* node (see [3.3 Unparsed Entities]). It returns the empty string if
* there is no such entity.
* <p>
* XML processors may choose to use the System Identifier (if one
* is provided) to resolve the entity, rather than the URI in the
* Public Identifier. The details are dependent on the processor, and
* we would have to support some form of plug-in resolver to handle
* this properly. Currently, we simply return the System Identifier if
* present, and hope that it a usable URI or that our caller can
* map it to one.
* TODO: Resolve Public Identifiers... or consider changing function name.
* <p>
* If we find a relative URI
* reference, XML expects it to be resolved in terms of the base URI
* of the document. The DOM doesn't do that for us, and it isn't
* entirely clear whether that should be done here; currently that's
* pushed up to a higher levelof our application. (Note that DOM Level
* 1 didn't store the document's base URI.)
* TODO: Consider resolving Relative URIs.
* <p>
* (The DOM's statement that "An XML processor may choose to
* completely expand entities before the structure model is passed
* to the DOM" refers only to parsed entities, not unparsed, and hence
* doesn't affect this function.)
*
* @param name A string containing the Entity Name of the unparsed
* entity.
* @param doc Document node for the document to be searched.
*
* @return String containing the URI of the Unparsed Entity, or an
* empty string if no such entity exists.
*/
public String getUnparsedEntityURI(String name, Document doc)
{
String url = "";
DocumentType doctype = doc.getDoctype();
if (null != doctype)
{
NamedNodeMap entities = doctype.getEntities();
if(null == entities)
return url;
Entity entity = (Entity) entities.getNamedItem(name);
if(null == entity)
return url;
String notationName = entity.getNotationName();
if (null != notationName) // then it's unparsed
{
// The draft says: "The XSLT processor may use the public
// identifier to generate a URI for the entity instead of the URI
// specified in the system identifier. If the XSLT processor does
// not use the public identifier to generate the URI, it must use
// the system identifier; if the system identifier is a relative
// URI, it must be resolved into an absolute URI using the URI of
// the resource containing the entity declaration as the base
// URI [RFC2396]."
// So I'm falling a bit short here.
url = entity.getSystemId();
if (null == url)
{
url = entity.getPublicId();
}
else
{
// This should be resolved to an absolute URL, but that's hard
// to do from here.
}
}
}
return url;
}
/**
* Support for getParentOfNode; walks a DOM tree until it finds
* the Element which owns the Attr. This is hugely expensive, and
* if at all possible you should use the DOM Level 2 Attr.ownerElement()
* method instead.
* <p>
* The DOM Level 1 developers expected that folks would keep track
* of the last Element they'd seen and could recover the info from
* that source. Obviously that doesn't work very well if the only
* information you've been presented with is the Attr. The DOM Level 2
* getOwnerElement() method fixes that, but only for Level 2 and
* later DOMs.
*
* @param elem Element whose subtree is to be searched for this Attr
* @param attr Attr whose owner is to be located.
*
* @return the first Element whose attribute list includes the provided
* attr. In modern DOMs, this will also be the only such Element. (Early
* DOMs had some hope that Attrs might be sharable, but this idea has
* been abandoned.)
*/
private static Node locateAttrParent(Element elem, Node attr)
{
Node parent = null;
// This should only be called for Level 1 DOMs, so we don't have to
// worry about namespace issues. In later levels, it's possible
// for a DOM to have two Attrs with the same NodeName but
// different namespaces, and we'd need to get getAttributeNodeNS...
// but later levels also have Attr.getOwnerElement.
Attr check=elem.getAttributeNode(attr.getNodeName());
if(check==attr)
parent = elem;
if (null == parent)
{
for (Node node = elem.getFirstChild(); null != node;
node = node.getNextSibling())
{
if (Node.ELEMENT_NODE == node.getNodeType())
{
parent = locateAttrParent((Element) node, attr);
if (null != parent)
break;
}
}
}
return parent;
}
/**
* The factory object used for creating nodes
* in the result tree.
*/
protected Document m_DOMFactory = null;
/**
* Store the factory object required to create DOM nodes
* in the result tree. In fact, that's just the result tree's
* Document node...
*
* @param domFactory The DOM Document Node within whose context
* the result tree will be built.
*/
public void setDOMFactory(Document domFactory)
{
this.m_DOMFactory = domFactory;
}
/**
* Retrieve the factory object required to create DOM nodes
* in the result tree.
*
* @return The result tree's DOM Document Node.
*/
public Document getDOMFactory()
{
if (null == this.m_DOMFactory)
{
this.m_DOMFactory = createDocument();
}
return this.m_DOMFactory;
}
/**
* Get the textual contents of the node. See
* getNodeData(Node,FastStringBuffer) for discussion of how
* whitespace nodes are handled.
*
* @param node DOM Node to be examined
* @return String containing a concatenation of all the
* textual content within that node.
* @see #getNodeData(Node,FastStringBuffer)
*
*/
public static String getNodeData(Node node)
{
FastStringBuffer buf = StringBufferPool.get();
String s;
try
{
getNodeData(node, buf);
s = (buf.length() > 0) ? buf.toString() : "";
}
finally
{
StringBufferPool.free(buf);
}
return s;
}
/**
* Retrieve the text content of a DOM subtree, appending it into a
* user-supplied FastStringBuffer object. Note that attributes are
* not considered part of the content of an element.
* <p>
* There are open questions regarding whitespace stripping.
* Currently we make no special effort in that regard, since the standard
* DOM doesn't yet provide DTD-based information to distinguish
* whitespace-in-element-context from genuine #PCDATA. Note that we
* should probably also consider xml:space if/when we address this.
* DOM Level 3 may solve the problem for us.
*
* @param node Node whose subtree is to be walked, gathering the
* contents of all Text or CDATASection nodes.
* @param buf FastStringBuffer into which the contents of the text
* nodes are to be concatenated.
*/
public static void getNodeData(Node node, FastStringBuffer buf)
{
switch (node.getNodeType())
{
case Node.DOCUMENT_FRAGMENT_NODE :
case Node.DOCUMENT_NODE :
case Node.ELEMENT_NODE :
{
for (Node child = node.getFirstChild(); null != child;
child = child.getNextSibling())
{
getNodeData(child, buf);
}
}
break;
case Node.TEXT_NODE :
case Node.CDATA_SECTION_NODE :
buf.append(node.getNodeValue());
break;
case Node.ATTRIBUTE_NODE :
buf.append(node.getNodeValue());
break;
case Node.PROCESSING_INSTRUCTION_NODE :
// warning(XPATHErrorResources.WG_PARSING_AND_PREPARING);
break;
default :
// ignore
break;
}
}
}
1.1 xml-xalan/java/src/org/apache/xml/utils/DOMOrder.java
Index: DOMOrder.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
/**
* @deprecated Since the introduction of the DTM, this class will be removed.
* Nodes that implement this index can return a document order index.
* Eventually, this will be replaced by DOM 3 methods.
* (compareDocumentOrder and/or compareTreePosition.)
*/
public interface DOMOrder
{
/**
* Get the UID (document order index).
*
* @return integer whose relative value corresponds to document order
* -- that is, if node1.getUid()<node2.getUid(), node1 comes before
* node2, and if they're equal node1 and node2 are the same node. No
* promises are made beyond that.
*/
public int getUid();
}
1.1 xml-xalan/java/src/org/apache/xml/utils/Constants.java
Index: Constants.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
/**
* <meta name="usage" content="advanced"/>
* Primary constants used by the XSLT Processor
*/
public class Constants
{
/**
* Mnemonics for standard XML Namespace URIs, as Java Strings:
* <ul>
* <li>S_XMLNAMESPACEURI (http://www.w3.org/XML/1998/namespace) is the
* URI permanantly assigned to the "xml:" prefix. This is used for some
* features built into the XML specification itself, such as xml:space
* and xml:lang. It was defined by the W3C's XML Namespaces spec.</li>
* <li>S_XSLNAMESPACEURL (http://www.w3.org/1999/XSL/Transform) is the
* URI which indicates that a name may be an XSLT directive. In most
* XSLT stylesheets, this is bound to the "xsl:" prefix. It's defined
* by the W3C's XSLT Recommendation.</li>
* <li>S_OLDXSLNAMESPACEURL (http://www.w3.org/XSL/Transform/1.0) was
* used in early prototypes of XSLT processors for much the same purpose
* as S_XSLNAMESPACEURL. It is now considered obsolete, and the version
* of XSLT which it signified is not fully compatable with the final
* XSLT Recommendation, so what it really signifies is a badly obsolete
* stylesheet.</li>
* </ul> */
public static final String
S_XMLNAMESPACEURI = "http://www.w3.org/XML/1998/namespace",
S_XSLNAMESPACEURL = "http://www.w3.org/1999/XSL/Transform",
S_OLDXSLNAMESPACEURL = "http://www.w3.org/XSL/Transform/1.0";
/** Authorship mnemonics, as Java Strings. Not standardized,
* as far as I know.
* <ul>
* <li>S_VENDOR -- the name of the organization/individual who published
* this XSLT processor. </li>
* <li>S_VENDORURL -- URL where one can attempt to retrieve more
* information about this publisher and product.</li>
* </ul>
*/
public static final String
S_VENDOR = "Apache Software Foundation",
S_VENDORURL = "http://xml.apache.org";
/** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace
*(http://xml.apache.org/xalan) predefined to signify Xalan's
* built-in XSLT Extensions. When used in stylesheets, this is often
* bound to the "xalan:" prefix.
*/
public static final String
S_BUILTIN_EXTENSIONS_URL = "http://xml.apache.org/xalan";
/**
* The old built-in extension url. It is still supported for
* backward compatibility.
*/
public static final String
S_BUILTIN_OLD_EXTENSIONS_URL = "http://xml.apache.org/xslt";
/**
* Xalan extension namespaces.
*/
public static final String
// The old namespace for Java extension
S_EXTENSIONS_OLD_JAVA_URL = "http://xml.apache.org/xslt/java",
// The new namespace for Java extension
S_EXTENSIONS_JAVA_URL = "http://xml.apache.org/xalan/java",
S_EXTENSIONS_LOTUSXSL_JAVA_URL = "http://xsl.lotus.com/java",
S_EXTENSIONS_XALANLIB_URL = "http://xml.apache.org/xalan",
S_EXTENSIONS_REDIRECT_URL = "http://xml.apache.org/xalan/redirect",
S_EXTENSIONS_PIPE_URL = "http://xml.apache.org/xalan/PipeDocument",
S_EXTENSIONS_SQL_URL = "http://xml.apache.org/xalan/sql";
/**
* EXSLT extension namespaces.
*/
public static final String
S_EXSLT_COMMON_URL = "http://exslt.org/common",
S_EXSLT_MATH_URL = "http://exslt.org/math",
S_EXSLT_SETS_URL = "http://exslt.org/sets",
S_EXSLT_DATETIME_URL = "http://exslt.org/dates-and-times",
S_EXSLT_FUNCTIONS_URL = "http://exslt.org/functions",
S_EXSLT_DYNAMIC_URL = "http://exslt.org/dynamic",
S_EXSLT_STRINGS_URL = "http://exslt.org/strings";
/**
* The minimum version of XSLT supported by this processor.
*/
public static final double XSLTVERSUPPORTED = 1.0;
}
1.1
xml-xalan/java/src/org/apache/xml/utils/ThreadControllerWrapper.java
Index: ThreadControllerWrapper.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Lotus
* Development Corporation., http://www.lotus.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.utils;
/**
* A utility class that wraps the ThreadController, which is used
* by IncrementalSAXSource for the incremental building of DTM.
*/
public class ThreadControllerWrapper
{
/** The ThreadController pool */
static ThreadController m_tpool = new ThreadController();
/**
* Change the ThreadController that will be used to
* manage the transform threads.
*
* @param tp A ThreadController object
*/
public static void setThreadController(ThreadController tpool)
{
m_tpool = tpool;
}
public static Thread runThread(Runnable runnable, int priority)
{
return m_tpool.run(runnable, priority);
}
public static void waitThread(Thread worker, Runnable task)
throws InterruptedException
{
m_tpool.waitThread(worker, task);
}
/**
* Thread controller utility class for incremental SAX source. Must
* be overriden with a derived class to support thread pooling.
*
* All thread-related stuff is in this class.
*/
public static class ThreadController
{
/**
* Will get a thread from the pool, execute the task
* and return the thread to the pool.
*
* The return value is used only to wait for completion
*
*
* NEEDSDOC @param task
* @param priority if >0 the task will run with the given priority
* ( doesn't seem to be used in xalan, since it's allways the default )
* @returns The thread that is running the task, can be used
* to wait for completion
*
* NEEDSDOC ($objectName$) @return
*/
public Thread run(Runnable task, int priority)
{
Thread t = new Thread(task);
t.start();
// if( priority > 0 )
// t.setPriority( priority );
return t;
}
/**
* Wait until the task is completed on the worker
* thread.
*
* NEEDSDOC @param worker
* NEEDSDOC @param task
*
* @throws InterruptedException
*/
public void waitThread(Thread worker, Runnable task)
throws InterruptedException
{
// This should wait until the transformThread is considered not alive.
worker.join();
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]