You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ru...@apache.org on 2002/08/18 15:59:30 UTC
cvs commit: xml-axis/java/src/org/apache/axis/utils DOM2Writer.java NSStack.java axisNLS.properties
rubys 2002/08/18 06:59:29
Modified: java/src/org/apache/axis/encoding
DeserializationContextImpl.java
SerializationContextImpl.java
java/src/org/apache/axis/utils DOM2Writer.java NSStack.java
axisNLS.properties
Log:
Rewrite NSStack for performance.
Revision Changes Path
1.46 +1 -1 xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java
Index: DeserializationContextImpl.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/DeserializationContextImpl.java,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- DeserializationContextImpl.java 16 Aug 2002 17:04:55 -0000 1.45
+++ DeserializationContextImpl.java 18 Aug 2002 13:59:29 -0000 1.46
@@ -282,7 +282,7 @@
**/
public ArrayList getCurrentNSMappings()
{
- return (ArrayList)namespaces.peek().clone();
+ return namespaces.cloneFrame();
}
/**
1.57 +2 -4 xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java
Index: SerializationContextImpl.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/encoding/SerializationContextImpl.java,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- SerializationContextImpl.java 16 Aug 2002 17:37:02 -0000 1.56
+++ SerializationContextImpl.java 18 Aug 2002 13:59:29 -0000 1.57
@@ -902,9 +902,7 @@
}
}
- ArrayList currentMappings = nsStack.peek();
- for (int i = 0; i < currentMappings.size(); i++) {
- Mapping map = (Mapping)currentMappings.get(i);
+ for (Mapping map=nsStack.topOfFrame(); map!=null; map=nsStack.next()) {
StringBuffer sb = new StringBuffer("xmlns");
if (!map.getPrefix().equals("")) {
sb.append(":");
@@ -941,7 +939,7 @@
}
nsStack.pop();
- nsStack.peek().clear();
+ nsStack.clearFrame();
if (writingStartTag) {
writer.write("/>");
1.13 +6 -7 xml-axis/java/src/org/apache/axis/utils/DOM2Writer.java
Index: DOM2Writer.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/DOM2Writer.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- DOM2Writer.java 12 Aug 2002 22:52:14 -0000 1.12
+++ DOM2Writer.java 18 Aug 2002 13:59:29 -0000 1.13
@@ -103,11 +103,7 @@
public static void serializeAsXML(Node node, Writer writer,
boolean omitXMLDecl)
{
- PrintWriter out = new PrintWriter(writer);
- if (!omitXMLDecl)
- out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- print(node, null, out, false, 0);
- out.flush();
+ serializeAsXML(node, writer, omitXMLDecl, false);
}
/**
@@ -120,7 +116,8 @@
PrintWriter out = new PrintWriter(writer);
if (!omitXMLDecl)
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- print(node, null, out, pretty, 0);
+ NSStack namespaceStack = new NSStack();
+ print(node, namespaceStack, out, pretty, 0);
out.flush();
}
@@ -157,7 +154,7 @@
case Node.ELEMENT_NODE :
{
- namespaceStack = new NSStack(namespaceStack);
+ namespaceStack.push();
if (pretty) {
for (int i = 0; i < indent; i++)
@@ -261,6 +258,8 @@
if (pretty)
out.print(JavaUtils.LS);
}
+
+ namespaceStack.pop();
break;
}
1.27 +131 -147 xml-axis/java/src/org/apache/axis/utils/NSStack.java
Index: NSStack.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/NSStack.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- NSStack.java 12 Aug 2002 22:52:13 -0000 1.26
+++ NSStack.java 18 Aug 2002 13:59:29 -0000 1.27
@@ -63,116 +63,138 @@
import java.util.Iterator;
/**
+ * The abstraction this class provides is a push down stack of variable
+ * length frames of prefix to namespace mappings. Used for keeping track
+ * of what namespaces are active at any given point as an XML document is
+ * traversed or produced.
+ *
+ * From a performance point of view, this data will both be modified frequently
+ * (at a minimum, there will be one push and pop per XML element processed),
+ * and scanned frequently (many of the "good" mappings will be at the bottom
+ * of the stack). The one saving grace is that the expected maximum
+ * cardinalities of the number of frames and the number of total mappings
+ * is only in the dozens, representing the nesting depth of an XML document
+ * and the number of active namespaces at any point in the processing.
+ *
+ * Accordingly, this stack is implemented as a single array, will null
+ * values used to indicate frame boundaries.
+ *
* @author: James Snell
* @author Glen Daniels (gdaniels@macromedia.com)
+ * @author Sam Ruby (rubys@us.ibm.com)
*/
public class NSStack {
protected static Log log =
LogFactory.getLog(NSStack.class.getName());
- private static final ArrayList EMPTY = new ArrayList();
-
- private Stack stack = new Stack();
-
- private NSStack parent = null;
-
- public NSStack() {}
-
- public NSStack(ArrayList table) {
- push(table);
- }
-
- public NSStack(NSStack parent) {
- this.parent = parent;
+ private Mapping[] stack;
+ private int top = 0;
+ private int iterator = 0;
+
+ public NSStack() {
+ stack = new Mapping[32];
+ stack[0] = null;
}
+ /**
+ * Create a new frame at the top of the stack.
+ */
public void push() {
- if (stack == null) stack = new Stack();
-
- if (log.isTraceEnabled())
- log.trace("NSPush (" + stack.size() + ")");
+ top ++;
- stack.push(EMPTY);
- }
-
- public void push(ArrayList table) {
- if (stack == null) stack = new Stack();
+ if (top >= stack.length) {
+ Mapping newstack[] = new Mapping[stack.length*2];
+ System.arraycopy (stack, 0, newstack, 0, stack.length);
+ stack = newstack;
+ }
if (log.isTraceEnabled())
- log.trace("NSPush (" + stack.size() + ")");
+ log.trace("NSPush (" + stack.length + ")");
- if (table.size() == 0)
- stack.push(EMPTY);
- else
- stack.push(table);
- }
-
- public ArrayList peek() {
- if (stack.isEmpty())
- if (parent != null)
- return parent.peek();
- else
- return EMPTY;
-
-
- return (ArrayList)stack.peek();
+ stack[top] = null;
}
- public ArrayList pop() {
- if (stack.isEmpty()) {
+ /**
+ * Remove the top frame from the stack.
+ */
+ public void pop() {
+ while (stack[top] != null) top--;
+
+ if (top == 0) {
if (log.isTraceEnabled())
log.trace("NSPop (" + JavaUtils.getMessage("empty00") + ")");
- if (parent != null)
- return parent.pop();
-
- return null;
+ return;
}
+ top--;
+
if (log.isTraceEnabled()){
- ArrayList t = (ArrayList)stack.pop();
- log.trace("NSPop (" + stack.size() + ")");
- return t;
- } else {
- return (ArrayList)stack.pop();
+ log.trace("NSPop (" + stack.length + ")");
}
}
- public void add(String namespaceURI, String prefix) {
- if (stack.isEmpty()) push();
- ArrayList table = peek();
- if (table == EMPTY) {
- table = new ArrayList();
- stack.pop();
- stack.push(table);
- }
- // Replace duplicate prefixes (last wins - this could also fault)
- for (Iterator i = table.iterator(); i.hasNext();) {
- Mapping mapping = (Mapping)i.next();
- if (mapping.getPrefix().equals(prefix)) {
- mapping.setNamespaceURI(namespaceURI);
- return;
- }
+ /**
+ * Return a copy of the current frame.
+ */
+ public ArrayList cloneFrame() {
+ ArrayList clone = new ArrayList();
+
+ topOfFrame();
+
+ while (iterator <= top) clone.add(stack[iterator++]);
+
+ return clone;
+ }
+
+ /**
+ * Remove all mappings from the current frame.
+ */
+ public void clearFrame() {
+ while (stack[top] != null) top--;
+ }
+
+ /**
+ * Reset the embedded iterator in this class to the top of the current
+ * (i.e., last) frame. Note that this is not threadsafe, nor does it
+ * provide multiple iterators, so don't use this recursively. Nor
+ * should you modify the stack while iterating over it.
+ */
+ public Mapping topOfFrame() {
+ iterator = top;
+ while (stack[iterator] != null) iterator--;
+ iterator++;
+ return next();
+ }
+
+ /**
+ * Return the next namespace mapping in the top frame.
+ */
+ public Mapping next() {
+ if (iterator > top) {
+ return null;
+ } else {
+ return stack[iterator++];
}
- table.add(new Mapping(namespaceURI, prefix));
}
-
+
/**
- * remove a namespace from the topmost table on the stack
+ * Add a mapping for a namespaceURI to the specified prefix to the top
+ * frame in the stack. If the prefix is already mapped in that frame,
+ * remap it to the (possibly different) namespaceURI.
*/
- /*
- public void remove(String namespaceURI) {
- if (stack.isEmpty()) return;
- ArrayList current = peek();
- for (int i = 0; i < current.size(); i++) {
- Mapping map = (Mapping)current.get(i);
- if (map.getNamespaceURI().equals(namespaceURI)) {
- current.removeElementAt(i);
- return; // ???
+ public void add(String namespaceURI, String prefix) {
+ // Replace duplicate prefixes (last wins - this could also fault)
+ for (int cursor=top; stack[cursor]!=null; cursor--) {
+ if (stack[cursor].getPrefix().equals(prefix)) {
+ stack[cursor].setNamespaceURI(namespaceURI);
+ return;
}
}
+
+ push();
+ stack[top] = new Mapping(namespaceURI, prefix);
}
- */
/**
* Return an active prefix for the given namespaceURI. NOTE : This
@@ -193,99 +215,61 @@
if ((namespaceURI == null) || (namespaceURI.equals("")))
return null;
- if (!stack.isEmpty()) {
- for (int n = stack.size() - 1; n >= 0; n--) {
- ArrayList t = (ArrayList)stack.get(n);
-
- for (int i = 0; i < t.size(); i++) {
- Mapping map = (Mapping)t.get(i);
- if (map.getNamespaceURI().equals(namespaceURI)) {
- String possiblePrefix = map.getPrefix();
- if (getNamespaceURI(possiblePrefix).equals(namespaceURI) &&
- (!noDefault || !"".equals(possiblePrefix)))
- return possiblePrefix;
- }
- }
+ for (int cursor=top; cursor>0; cursor--) {
+ Mapping map = stack[cursor];
+ if (map == null) continue;
+
+ if (map.getNamespaceURI().equals(namespaceURI)) {
+ String possiblePrefix = map.getPrefix();
+ if (getNamespaceURI(possiblePrefix).equals(namespaceURI) &&
+ (!noDefault || !"".equals(possiblePrefix)))
+ return possiblePrefix;
}
}
- if (parent != null)
- return parent.getPrefix(namespaceURI);
return null;
}
+ /**
+ * Return an active prefix for the given namespaceURI, including
+ * the default prefix ("").
+ */
public String getPrefix(String namespaceURI) {
return getPrefix(namespaceURI, false);
}
+ /**
+ * Given a prefix, return the associated namespace (if any).
+ */
public String getNamespaceURI(String prefix) {
if (prefix == null)
prefix = "";
+
+ for (int cursor=top; cursor>0; cursor--) {
+ Mapping map = stack[cursor];
+ if (map == null) continue;
- if (!stack.isEmpty()) {
- for (int n = stack.size() - 1; n >= 0; n--) {
- ArrayList t = (ArrayList)stack.get(n);
-
- for (int i = 0; i < t.size(); i++) {
- Mapping map = (Mapping)t.get(i);
- if (map.getPrefix().equals(prefix))
- return map.getNamespaceURI();
- }
- }
+ if (map.getPrefix().equals(prefix))
+ return map.getNamespaceURI();
}
- if (parent != null)
- return parent.getNamespaceURI(prefix);
-
- if (log.isTraceEnabled()){
- log.trace("--" + JavaUtils.getMessage("noPrefix00", "" + this, prefix));
- dump("--");
- log.trace("--" + JavaUtils.getMessage("end00"));
- }
-
return null;
}
- public boolean isDeclared(String namespaceURI) {
- if (!stack.isEmpty()) {
- for (int n = stack.size() - 1; n >= 0; n--) {
- ArrayList t = (ArrayList)stack.get(n);
- if ((t != null) && (t != EMPTY)) {
- for (int i = 0; i < t.size(); i++) {
- if (((Mapping)t.get(i)).getNamespaceURI().
- equals(namespaceURI))
- return true;
- }
- }
- }
- }
-
- if (parent != null)
- return parent.isDeclared(namespaceURI);
-
- return false;
- }
-
+ /**
+ * Produce a trace dump of the entire stack, starting from the top and
+ * including frame markers.
+ */
public void dump(String dumpPrefix)
{
- Enumeration e = stack.elements();
- while (e.hasMoreElements()) {
- ArrayList list = (ArrayList)e.nextElement();
-
- if (list == null) {
- log.trace(dumpPrefix + JavaUtils.getMessage("nullTable00"));
- continue;
- }
+ for (int cursor=top; cursor>0; cursor--) {
+ Mapping map = stack[cursor];
- for (int i = 0; i < list.size(); i++) {
- Mapping map = (Mapping)list.get(i);
+ if (map == null) {
+ log.trace(dumpPrefix + JavaUtils.getMessage("stackFrame00"));
+ } else {
log.trace(dumpPrefix + map.getNamespaceURI() + " -> " + map.getPrefix());
}
- }
-
- if (parent != null) {
- log.trace(dumpPrefix + "--" + JavaUtils.getMessage("parent00"));
- parent.dump(dumpPrefix + "--");
}
}
}
1.46 +1 -1 xml-axis/java/src/org/apache/axis/utils/axisNLS.properties
Index: axisNLS.properties
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/axisNLS.properties,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- axisNLS.properties 16 Aug 2002 20:07:55 -0000 1.45
+++ axisNLS.properties 18 Aug 2002 13:59:29 -0000 1.46
@@ -460,7 +460,6 @@
nullProvider00=Null provider type passed to WSDDProvider!
nullResponse00=Null response message!
-nullTable00=null table??
oddDigits00=Odd number of digits in hex string
ok00=OK
@@ -574,6 +573,7 @@
start00={0} starting up on port {1}.
startElem00=Start element {0}
startPrefix00=Start prefix mapping ''{0}'' -> ''{1}''
+stackFrame00=Stack frame marker
test00=...
test01=.{0}.
test02={0}, {1}.