sboag 99/12/12 23:46:59
Modified: src/org/apache/xalan/xpath/dtm DTM.java DTMLiaison.java
DTMNodeLocator.java DTMProxy.java
Log:
Primarily fixes for self::@foo patterns... added getFirstAttribute. Also
fixed problem with indexOf with qnames.
Revision Changes Path
1.5 +169 -67 xml-xalan/src/org/apache/xalan/xpath/dtm/DTM.java
Index: DTM.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTM.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DTM.java 1999/11/27 08:53:23 1.4
+++ DTM.java 1999/12/13 07:46:58 1.5
@@ -70,8 +70,10 @@
import org.apache.xerces.dom.ElementDefinitionImpl;
import org.apache.xerces.dom.EntityImpl;
import org.apache.xalan.xpath.xml.ProblemListener;
+import org.apache.xalan.xpath.xml.StringToStringTable;
+import org.apache.xalan.xpath.xml.StringVector;
+import org.apache.xalan.xpath.xml.StringToStringTableVector;
-
/**
* <code>DTM</code> is an XML document model expressed as a table rather than
* an object tree. It attempts to be very compact, and to support very
@@ -139,9 +141,6 @@
// Impossible prefix to look up the default namespace
public static final String DEFAULT_PREFIX_STR = "#:::";
- // Namespace lookup. This is actually a stack of hashtables
- Vector namespaceTable = new Vector(64);
-
// Handshaking for updates of simul read/write
final int UPDATE_FREQUENCY=10;
int update_counter=UPDATE_FREQUENCY;
@@ -164,8 +163,16 @@
IntToObjectMap m_elementDecls = new IntToObjectMap();
IntMap m_idMap = new IntMap();
+
+ /**
+ * Namespace lookup. This is actually a stack of StringToStringTables
+ */
+ StringToStringTableVector namespaceTable = new
StringToStringTableVector(64);
- private Hashtable m_emptyNamespace = new Hashtable();
+ /**
+ * Default empty namespace
+ */
+ private StringToStringTable m_emptyNamespace = new StringToStringTable();
// This needs to be set before calling run()
private InputSource m_inputSource = null;
@@ -221,6 +228,8 @@
fSchemaValidator = new NullSchemaValidator(fStringPool,
fErrorReporter, fEntityHandler);
return fSchemaValidator;
}
+
+ boolean m_throwNewError = true;
/**
@@ -230,17 +239,25 @@
{
try
{
+ m_throwNewError = true;
parse(m_inputSource);
}
- catch(Exception se)
+ catch(Exception e)
{
+ e.printStackTrace();
// Make sure nobody is still waiting
synchronized (this)
{
m_isError = true;
notifyAll();
-
- boolean shouldThrow = m_problemListener.message(se.getMessage());
+ String msg = e.getMessage();
+ if(null == msg)
+ {
+ // m_throwNewError = false;
+ e.printStackTrace();
+ }
+ else
+ m_problemListener.message(msg);
}
// Should I throw again?? In general, how should
// the error be handled from here.
@@ -338,7 +355,8 @@
public void appendAccumulatedText()
{
// No text pending
- if (charStartPos == charOffsets.slotsUsed())
+ int slotsUsed = charOffsets.slotsUsed();
+ if (charStartPos == slotsUsed)
return;
int nodetype = org.w3c.dom.Node.TEXT_NODE;
@@ -351,7 +369,7 @@
// Short Form, single block
int w0, w1, w2, w3;
- if (charStartPos == charOffsets.slotsUsed()-1)
+ if (charStartPos == slotsUsed-1)
{
charOffsets.readSlot(charStartPos+1, gotslot);
// W0 Low: Node Type, with flag if ignorable whitespace
@@ -506,21 +524,22 @@
int colonpos = name.indexOf(':');
String prefix = (colonpos <= 0) ? "" : name.substring(0, colonpos);
- String attrname, attrvalue;
// Push a new namespace context
- Hashtable pushNS = m_emptyNamespace;
+ StringToStringTable pushNS = m_emptyNamespace;
// Process any new namespace declarations
for (int i = 0; i < atts.getLength(); i++)
{
- attrname = atts.getName(i);
- if (attrname.startsWith("xmlns:") || attrname.equals("xmlns"))
+ String attrname = atts.getName(i);
+ boolean isPrefix = attrname.startsWith("xmlns:");
+ if (isPrefix || attrname.equals("xmlns"))
{
- attrvalue = atts.getValue(i);
+ int index = attrname.indexOf(':');
+ String p = isPrefix ? attrname.substring(index+1) : "";
if(m_emptyNamespace == pushNS)
- pushNS = new Hashtable();
- pushNS.put(new
Integer(stringToInt(attrname.substring(7))),attrvalue);
+ pushNS = new StringToStringTable();
+ pushNS.put(p, atts.getValue(i));
}
}
namespaceTable.addElement(pushNS);
@@ -545,10 +564,10 @@
// Append the attributes
for (int i = 0; i < atts.getLength(); i++)
{
- attrname = atts.getName(i);
+ String attrname = atts.getName(i);
System.out.println(attrname);
// ***** OBSOLETE, SHOULD PRODUCE SUBTREE!
- attrvalue = atts.getValue(i);
+ String attrvalue = atts.getValue(i);
// W0 Low: Node Type.
// W0 High: Namespace
@@ -597,13 +616,11 @@
appendAccumulatedText();
String name=intToString(elementNameIndex);
- int colonpos = name.indexOf(':');
- String prefix = (colonpos <= 0) ? "" : name.substring(0, colonpos);
String attrname, attrvalue;
// Push a new namespace context
- Hashtable pushNS=m_emptyNamespace;
+ StringToStringTable pushNS=m_emptyNamespace;
// Process any new namespace declarations
if(attrListIndex!=-1)
@@ -619,42 +636,49 @@
attrvalue = fStringPool.toString(xmlAttrList.getAttValue(index));
String nsprefix = attrname.substring(6);
if(m_emptyNamespace == pushNS)
- pushNS = new Hashtable();
+ pushNS = new StringToStringTable();
pushNS.put(nsprefix,attrvalue);
}
else if(attrname.equals("xmlns"))
{
attrvalue = fStringPool.toString(xmlAttrList.getAttValue(index));
if(m_emptyNamespace == pushNS)
- pushNS = new Hashtable();
+ pushNS = new StringToStringTable();
pushNS.put(DEFAULT_PREFIX_STR,attrvalue);
}
}
}
namespaceTable.addElement(pushNS);
- // This is ugly, but we have to be able to tell if a default namespace
- // is in effect.
- if((prefix.length() == 0) &&
(resolveNamespace(DEFAULT_PREFIX_STR).length() > 0))
+ // Scope some stuff...
+ int ourslot;
{
- prefix = DEFAULT_PREFIX_STR;
- }
-
- // W0 Low: Node Type.
- // W0 High: Namespace
- int w0 = org.w3c.dom.Node.ELEMENT_NODE |
(stringToInt(resolveNamespace(prefix)) << 16);
- // W1: Parent
- int w1 = currentParent;
- // W2: Next. Initialize as 0 (unresolved)
- int w2 = 0;
- // W3: Tagname
- int w3 = elementNameIndex;
+ int colonpos = name.indexOf(':');
+ String prefix = (colonpos <= 0) ? null : name.substring(0, colonpos);
+ // This is ugly, but we have to be able to tell if a default namespace
+ // is in effect.
+ if((null == prefix) && isDefaultNamespaceInEffect())
+ {
+ prefix = null;
+ }
- // Add this element to the document
- int ourslot = appendNode(w0, w1, w2, w3);
+ // W0 Low: Node Type.
+ // W0 High: Namespace
+ int w0 = org.w3c.dom.Node.ELEMENT_NODE |
(stringToInt(resolveNamespace(prefix)) << 16);
+ // W1: Parent
+ int w1 = currentParent;
+ // W2: Next. Initialize as 0 (unresolved)
+ int w2 = 0;
+ // W3: Tagname
+ int w3 = elementNameIndex;
+ // Add this element to the document
+ ourslot = appendNode(w0, w1, w2, w3);
+
+ }
// Change append context
currentParent = ourslot;
+
previousSibling = 0;
IntMap elemMap = (IntMap)m_elementDecls.get(elementNameIndex);
@@ -685,10 +709,11 @@
}
}
- colonpos = attrname.indexOf(':');
+ int w0;
+ int colonpos = attrname.indexOf(':');
if(colonpos > 0)
{
- prefix = attrname.substring(0, colonpos);
+ String prefix = attrname.substring(0, colonpos);
w0 = org.w3c.dom.Node.ATTRIBUTE_NODE |
(stringToInt(resolveNamespace(prefix)) << 16);
}
else
@@ -696,11 +721,11 @@
w0 = org.w3c.dom.Node.ATTRIBUTE_NODE;
}
// W1: Parent
- w1 = currentParent;
+ int w1 = currentParent;
// W2: Next (not yet resolved)
- w2 = 0;
+ int w2 = 0;
// W3: Tagname
- w3 = xmlAttrList.getAttrName(index);
+ int w3 = xmlAttrList.getAttrName(index);
// Add this element to the document
ourslot = appendNode(w0, w1, w2, w3);
@@ -775,7 +800,7 @@
previousSiblingWasParent = true;
// Pop a level of namespace table
- namespaceTable.removeElementAt(namespaceTable.size()-1);
+ namespaceTable.removeLastElem();
}
@@ -1436,22 +1461,19 @@
{
if(TRACE)
System.out.println("DTM: getFirstChild");
-
- // 0 is Document; first child is node 1.
- if (position == 0)
- return 1;
-
+
// Examine the node in question
nodes.readSlot(position, gotslot);
// If not an element or Attribute or EntRef, child is null
int type = (gotslot[0] & 0xFFFF);
if ((type != Node.ELEMENT_NODE) &&
- (type != Node.ATTRIBUTE_NODE) &&
- (type != Node.ENTITY_REFERENCE_NODE))
+ (type != Node.ENTITY_REFERENCE_NODE) &&
+ (type != Node.DOCUMENT_NODE))
return -1;
- int parent = gotslot[1];
+ // 0 is Document; first child is node 1.
+ int parent = (position == 0) ? 1 : gotslot[1];
// Advance to first non-Attr child
// (First child of any kind is at position+1, thereafter walk sibs)
@@ -1479,7 +1501,14 @@
while (kid != -1)
{
nodes.readSlot(kid,gotslot);
- if((gotslot[1] == position) && ((gotslot[0]&0xff) !=
Node.ATTRIBUTE_NODE))
+ boolean isAttr = ((gotslot[0]&0xff) == Node.ATTRIBUTE_NODE);
+ if(isAttr)
+ {
+ // kid=getNextSibling(kid); // Since attrs have 2 nodes, advance by 2
+ // if(kid == -1)
+ // break;
+ }
+ else if(gotslot[1] == position)
return kid;
else if(gotslot[1] == parent)
break; // already to next sibling.
@@ -1490,7 +1519,62 @@
}
return -1;
}
+
+ /**
+ * DTM read API: Given a node index, get the index of the node's first
child.
+ * If not yet resolved, waits for more nodes to be added to the document
and
+ * tries again
+ * @param postition int Index of this node's record.
+ * @return int DTM node-number of first child, or -1 to indicate none
exists.
+ */
+ public int getFirstAttribute(int position)
+ {
+ if(TRACE)
+ System.out.println("DTM: getFirstAttribute");
+
+ // Examine the node in question
+ nodes.readSlot(position, gotslot);
+
+ // If not an element or Attribute or EntRef, child is null
+ int type = (gotslot[0] & 0xFFFF);
+ if (type != Node.ELEMENT_NODE)
+ return -1;
+
+ // 0 is Document; first child is node 1.
+ int parent = (position == 0) ? 1 : gotslot[1];
+
+ // Advance to first non-Attr child
+ // (First child of any kind is at position+1, thereafter walk sibs)
+ int kid=position+1;
+ while((kid > nodes.lastUsed) && !done)
+ {
+ synchronized (this)
+ {
+ try
+ {
+ if(m_isError)
+ break;
+ if(DEBUG_WAITS)
+ System.out.println("Waiting... getFirstChild");
+ wait();
+ }
+ catch (InterruptedException e)
+ {
+ // That's OK, it's as good a time as any to check again
+ }
+ }
+ }
+
+ nodes.readSlot(kid,gotslot);
+ boolean isAttr = ((gotslot[0]&0xff) == Node.ATTRIBUTE_NODE);
+ if(isAttr)
+ {
+ return kid;
+ }
+ return -1;
+ }
+
/**
* DTM read API: Given a node index, advance to the next attribute. If an
* element, we advance to its first attribute; if an attr, we advance to
@@ -1634,7 +1718,7 @@
int type = nodes.readEntry(position, 0) & 0xFF;
if (type == Node.ELEMENT_NODE ||
type == Node.ATTRIBUTE_NODE ||
- type == Node.ENTITY_REFERENCE_NODE )
+ type == Node.ENTITY_REFERENCE_NODE)
{
int nextSib = nodes.readEntry(position, 2);
if(nextSib != 0)
@@ -1669,7 +1753,17 @@
}
}
}
- throw new RuntimeException("Error occured!");
+ // For now I'm going to be bad and try and recover...
+ if(false)
+ {
+ if(m_throwNewError)
+ throw new RuntimeException("Error occured!");
+ }
+ else
+ {
+ m_problemListener.message("Problem occured in DTM in getNextSibling...
trying to recover");
+ }
+ return -1;
}
/**
@@ -2213,17 +2307,25 @@
*/
private String resolveNamespace(String prefix)
{
- if(prefix==null || prefix=="")
+ if(prefix==null || prefix.length() == 0)
prefix=DEFAULT_PREFIX_STR;
- for(int i=namespaceTable.size()-1;i>=0;--i)
- {
- Hashtable locals=(Hashtable)namespaceTable.elementAt(i);
- String nsuri = (String) locals.get(prefix);
- if (nsuri != null)
- return nsuri;
- }
- return "";
+
+ String nsuri = namespaceTable.get((prefix==null || prefix.length() == 0)
?
+ DEFAULT_PREFIX_STR : prefix);
+ return (null == nsuri) ? "" : nsuri;
+ }
+
+ /**
+ * Internal routine: Look up a namespace in the current parent-element's
+ * context, by consulting the stacked hashtables.
+ * @param prefix String prefix to be resolved
+ * @return String Namespace URI which that prefix currently points to.
+ */
+ private boolean isDefaultNamespaceInEffect()
+ {
+ return namespaceTable.containsKey(DEFAULT_PREFIX_STR);
}
+
/**
* This feature determines whether entity references within
1.5 +2 -1 xml-xalan/src/org/apache/xalan/xpath/dtm/DTMLiaison.java
Index: DTMLiaison.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMLiaison.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DTMLiaison.java 1999/12/03 08:43:13 1.4
+++ DTMLiaison.java 1999/12/13 07:46:58 1.5
@@ -187,7 +187,8 @@
m_document = parser.getDocument();
if(null != source.getSystemId())
{
- getSourceDocsTable().put(source.getSystemId(), m_document);
+ if(null != getSourceDocsTable())
+ getSourceDocsTable().put(source.getSystemId(), m_document);
}
}
}
1.5 +1 -1
xml-xalan/src/org/apache/xalan/xpath/dtm/DTMNodeLocator.java
Index: DTMNodeLocator.java
===================================================================
RCS file:
/home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMNodeLocator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DTMNodeLocator.java 1999/11/28 04:25:12 1.4
+++ DTMNodeLocator.java 1999/12/13 07:46:58 1.5
@@ -264,7 +264,7 @@
DTM dtm = dtmp.dtm;
// Walk across the kids until all have been accounted for.
- for (int child = dtm.getNextAttribute(dtmpPos);
+ for (int child = dtm.getFirstAttribute(dtmpPos);
child != -1;
child = dtm.getNextAttribute(child))
{
1.3 +1 -1 xml-xalan/src/org/apache/xalan/xpath/dtm/DTMProxy.java
Index: DTMProxy.java
===================================================================
RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/dtm/DTMProxy.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DTMProxy.java 1999/11/23 04:06:02 1.2
+++ DTMProxy.java 1999/12/13 07:46:58 1.3
@@ -71,7 +71,7 @@
* @see org.w3c.dom
*/
public class DTMProxy
- implements Node, Document, Text, Element, Attr, ProcessingInstruction
+ implements Node, Document, Text, Element, Attr, ProcessingInstruction,
Comment
{
DTM dtm;
int node;