zongaro 2002/10/22 13:17:16
Modified: java/src/org/apache/xalan/templates Tag: XSLTC_DTM
ElemExtensionCall.java
java/src/org/apache/xalan/transformer Tag: XSLTC_DTM
KeyTable.java
java/src/org/apache/xpath/axes Tag: XSLTC_DTM
NodeSequence.java
Log:
Updating XSLTC_DTM branch with latest changes from MAIN branch.
Revision Changes Path
No revision
No revision
1.27.2.3 +46 -35
xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java
Index: ElemExtensionCall.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemExtensionCall.java,v
retrieving revision 1.27.2.2
retrieving revision 1.27.2.3
diff -u -r1.27.2.2 -r1.27.2.3
--- ElemExtensionCall.java 12 Sep 2002 16:07:32 -0000 1.27.2.2
+++ ElemExtensionCall.java 22 Oct 2002 20:17:15 -0000 1.27.2.3
@@ -223,6 +223,23 @@
}
}
+
+ /**
+ * Return true if this extension element has a <xsl:fallback> child
element.
+ *
+ * @return true if this extension element has a <xsl:fallback> child
element.
+ */
+ public boolean hasFallbackChildren()
+ {
+ for (ElemTemplateElement child = m_firstChild; child != null;
+ child = child.m_nextSibling)
+ {
+ if (child.getXSLToken() == Constants.ELEMNAME_FALLBACK)
+ return true;
+ }
+
+ return false;
+ }
/**
@@ -234,8 +251,7 @@
*
* @throws TransformerException
*/
- public void execute(
- TransformerImpl transformer)
+ public void execute(TransformerImpl transformer)
throws TransformerException
{
@@ -248,7 +264,17 @@
if (null == nsh)
{
- executeFallbacks(transformer);
+ if (hasFallbackChildren())
+ {
+ executeFallbacks(transformer);
+ }
+ else
+ {
+ TransformerException te = new
TransformerException(XSLMessages.createMessage(
+ XSLTErrorResources.ER_CALL_TO_EXT_FAILED, new
Object[]{getNodeName()}));
+ transformer.getErrorListener().fatalError(te);
+ }
+
return;
}
@@ -260,42 +286,27 @@
catch (Exception e)
{
- // System.out.println(e);
- // e.printzStackTrace();
- String msg = e.getMessage();
-
- TransformerException te;
- if(e instanceof TransformerException)
- {
- te = (TransformerException)e;
- }
- else
- {
- if(null != msg)
- te = new TransformerException(e);
- else
- te = new
TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_UNKNOWN_ERROR_CALLING_EXTENSION,
null), e); //"Unknown error when calling extension!", e);
- }
- if(null == te.getLocator())
- te.setLocator(this);
-
- if (null != msg)
- {
- if (msg.indexOf("fatal") >= 0)
+ if (hasFallbackChildren())
+ executeFallbacks(transformer);
+ else
+ {
+ if(e instanceof TransformerException)
{
- transformer.getErrorListener().fatalError(te);
+ TransformerException te = (TransformerException)e;
+ if(null == te.getLocator())
+ te.setLocator(this);
+
+ transformer.getErrorListener().fatalError(te);
+ }
+ else if (e instanceof RuntimeException)
+ {
+ transformer.getErrorListener().fatalError(new
TransformerException(e));
}
- else if(e instanceof RuntimeException)
- transformer.getErrorListener().error(te); // ??
else
- transformer.getErrorListener().warning(te);
-
+ {
+ transformer.getErrorListener().warning(new
TransformerException(e));
+ }
}
- else
- transformer.getErrorListener().error(te); // ??
-
- executeFallbacks(
- transformer);
}
}
catch(org.xml.sax.SAXException se)
No revision
No revision
1.11.2.2 +155 -22
xml-xalan/java/src/org/apache/xalan/transformer/KeyTable.java
Index: KeyTable.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/KeyTable.java,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.2
diff -u -r1.11.2.1 -r1.11.2.2
--- KeyTable.java 24 Aug 2002 12:39:05 -0000 1.11.2.1
+++ KeyTable.java 22 Oct 2002 20:17:15 -0000 1.11.2.2
@@ -60,23 +60,28 @@
import java.util.Vector;
import javax.xml.transform.TransformerException;
-import org.apache.xml.dtm.DTM;
+
+import org.apache.xml.utils.NodeVector;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.XMLString;
+import org.apache.xml.utils.WrappedRuntimeException;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XNull;
+import org.apache.xalan.templates.KeyDeclaration;
/**
* <meta name="usage" content="advanced"/>
* Table of element keys, keyed by document node. An instance of this
* class is keyed by a Document node that should be matched with the
- * root of the current context. It contains a table of name mappings
- * to tables that contain mappings of identifier values to nodes.
+ * root of the current context.
*/
public class KeyTable
{
-
/**
* The document key. This table should only be used with contexts
* whose Document roots match this key.
@@ -84,9 +89,20 @@
private int m_docKey;
/**
+ * Vector of KeyDeclaration instances holding the key declarations.
+ */
+ private Vector m_keyDeclarations;
+
+ /**
+ * Hold a cache of key() function result for each ref.
+ * Key is XMLString, the ref value
+ * Value is XNodeSet, the key() function result for the given ref value.
+ */
+ private Hashtable m_refsTable = null;
+
+ /**
* Get the document root matching this key.
*
- *
* @return the document root matching this key
*/
public int getDocKey()
@@ -119,46 +135,163 @@
int doc, PrefixResolver nscontext, QName name, Vector
keyDeclarations, XPathContext xctxt)
throws javax.xml.transform.TransformerException
{
-
m_docKey = doc;
+ m_keyDeclarations = keyDeclarations;
KeyIterator ki = new KeyIterator(name, keyDeclarations);
-
+
m_keyNodes = new XNodeSet(ki);
m_keyNodes.allowDetachToRelease(false);
-
m_keyNodes.setRoot(doc, xctxt);
-
- }
+ }
/**
* Given a valid element key, return the corresponding node list.
*
- * @param The name of the key, which must match the 'name' attribute on
xsl:key.
+ * @param name The name of the key, which must match the 'name' attribute
on xsl:key.
* @param ref The value that must match the value found by the 'match'
attribute on xsl:key.
- * @return If the name was not declared with xsl:key, this will return
null,
- * if the identifier is not found, it will return null,
- * otherwise it will return a LocPathIterator instance.
+ * @return a set of nodes referenced by the key named <CODE>name</CODE>
and the reference <CODE>ref</CODE>. If no node is referenced by this key, an
empty node set is returned.
*/
public XNodeSet getNodeSetDTMByKey(QName name, XMLString ref)
+
{
- Vector keyDecls = getKeyIterator().getKeyDeclarations();
- org.apache.xml.dtm.DTMIterator keyNodes = m_keyNodes.iter();
- XNodeSet refNodes = new XNodeSet( new KeyRefIterator(name, ref,
keyDecls, keyNodes) );
-
- // I don't think setRoot needs to be called on refNodes!
- return refNodes;
+ XNodeSet refNodes = (XNodeSet) getRefsTable().get(ref);
+ // clone wiht reset the node set
+ try
+ {
+ if (refNodes != null)
+ {
+ refNodes = (XNodeSet) refNodes.cloneWithReset();
+ }
+ }
+ catch (CloneNotSupportedException e)
+ {
+ refNodes = null;
+ }
+
+ if (refNodes == null) {
+ // create an empty XNodeSet
+ KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
+ XPathContext xctxt = ki.getXPathContext();
+ refNodes = new XNodeSet(xctxt.getDTMManager()) {
+ public void setRoot(int nodeHandle, Object environment) {
+ // Root cannot be set on non-iterated node sets. Ignore it.
+ }
+ };
+ refNodes.reset();
+ }
+ return refNodes;
}
/**
* Get Key Name for this KeyTable
*
- *
* @return Key name
*/
public QName getKeyTableName()
{
return getKeyIterator().getName();
}
-
+
+ /**
+ * @return key declaration for the key associated to this KeyTable
+ */
+ private KeyDeclaration getKeyDeclaration() {
+ int nDeclarations = m_keyDeclarations.size();
+
+ // Walk through each of the declarations made with xsl:key
+ for (int i = 0; i < nDeclarations; i++)
+ {
+ KeyDeclaration kd = (KeyDeclaration) m_keyDeclarations.elementAt(i);
+
+ // Only continue if the name on this key declaration
+ // matches the name on the iterator for this walker.
+ if (kd.getName().equals(getKeyTableName()))
+ {
+ return kd;
+ }
+ }
+
+ // should never happen
+ return null;
+ }
+
+ /**
+ * @return lazy initialized refs table associating evaluation of key
function
+ * with a XNodeSet
+ */
+ private Hashtable getRefsTable()
+ {
+ if (m_refsTable == null)
+ {
+ m_refsTable = new Hashtable(89); // initial capacity set to a prime
number to improve hash algorithm performance
+
+ KeyIterator ki = (KeyIterator) (m_keyNodes).getContainedIter();
+ XPathContext xctxt = ki.getXPathContext();
+
+ KeyDeclaration keyDeclaration = getKeyDeclaration();
+
+ int currentNode;
+ m_keyNodes.reset();
+ while (DTM.NULL != (currentNode = m_keyNodes.nextNode()))
+ {
+ try
+ {
+ XObject xuse = keyDeclaration.getUse().execute(xctxt, currentNode,
ki.getPrefixResolver());
+
+ if (xuse.getType() != xuse.CLASS_NODESET)
+ {
+ XMLString exprResult = xuse.xstr();
+ addValueInRefsTable(xctxt, exprResult, currentNode);
+ }
+ else
+ {
+ DTMIterator i = ((XNodeSet)xuse).iterRaw();
+ int currentNodeInUseClause;
+
+ while (DTM.NULL != (currentNodeInUseClause = i.nextNode()))
+ {
+ DTM dtm = xctxt.getDTM(currentNodeInUseClause);
+ XMLString exprResult =
dtm.getStringValue(currentNodeInUseClause);
+ addValueInRefsTable(xctxt, exprResult, currentNode);
+ }
+ }
+ }
+ catch (TransformerException te)
+ {
+ throw new WrappedRuntimeException(te);
+ }
+ }
+ }
+ return m_refsTable;
+ }
+
+ /**
+ * Add an association between a ref and a node in the m_refsTable.
+ * Requires that m_refsTable != null
+ * @param xctxt XPath context
+ * @param ref the value of the use clause of the current key for the given
node
+ * @param node the node to reference
+ */
+ private void addValueInRefsTable(XPathContext xctxt, XMLString ref, int
node) {
+
+ XNodeSet nodes = (XNodeSet) m_refsTable.get(ref);
+ if (nodes == null)
+ {
+ nodes = new XNodeSet(node, xctxt.getDTMManager());
+ nodes.nextNode();
+ m_refsTable.put(ref, nodes);
+ }
+ else
+ {
+ // Nodes are passed to this method in document order. Since we need to
+ // suppress duplicates, we only need to check against the last entry
+ // in each nodeset. We use nodes.nextNode after each entry so we can
+ // easily compare node against the current node.
+ if (nodes.getCurrentNode() != node) {
+ nodes.mutableNodeset().addNode(node);
+ nodes.nextNode();
+ }
+ }
+ }
}
No revision
No revision
1.2.2.2 +4 -0
xml-xalan/java/src/org/apache/xpath/axes/NodeSequence.java
Index: NodeSequence.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/axes/NodeSequence.java,v
retrieving revision 1.2.2.1
retrieving revision 1.2.2.2
diff -u -r1.2.2.1 -r1.2.2.2
--- NodeSequence.java 29 Jul 2002 00:01:32 -0000 1.2.2.1
+++ NodeSequence.java 22 Oct 2002 20:17:15 -0000 1.2.2.2
@@ -66,6 +66,7 @@
import org.apache.xml.dtm.DTMFilter;
import org.apache.xml.utils.NodeVector;
import org.apache.xpath.Expression;
+import org.apache.xpath.NodeSetDTM;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XObject;
@@ -534,6 +535,9 @@
{
if(hasCache())
{
+ if (m_obj instanceof NodeSetDTM) {
+ return ((NodeSetDTM)m_obj).getLength();
+ }
if(-1 == m_last)
{
int pos = m_next;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]