You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2008/12/18 02:08:25 UTC
svn commit: r727606 - in
/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom:
CData.java Comment.java Document.java Element.java MapHolder.java Node.java
Raw.java Text.java
Author: hlship
Date: Wed Dec 17 17:08:25 2008
New Revision: 727606
URL: http://svn.apache.org/viewvc?rev=727606&view=rev
Log:
TAP5-417: Tapestry 5.0 Performance Improvements
- Optimize namespace URI to prefix resolution when rendering markup
Added:
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/MapHolder.java
Modified:
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java Wed Dec 17 17:08:25 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.dom;
import java.io.PrintWriter;
+import java.util.Map;
/**
* A node that stores parsed character content (CDATA). For XML documents (as per {@link MarkupModel#isXML()}, this
@@ -32,7 +33,7 @@
}
@Override
- void toMarkup(Document document, PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
MarkupModel model = document.getMarkupModel();
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java Wed Dec 17 17:08:25 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.dom;
import java.io.PrintWriter;
+import java.util.Map;
/**
* A node that represents a comment within the DOM.
@@ -31,7 +32,7 @@
}
@Override
- void toMarkup(Document document, PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
writer.print("<!-- ");
writer.print(comment);
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java Wed Dec 17 17:08:25 2008
@@ -17,6 +17,8 @@
import org.apache.tapestry5.ioc.internal.util.Defense;
import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.Map;
/**
* The root node of a DOM.
@@ -112,7 +114,7 @@
}
@Override
- public void toMarkup(Document document, PrintWriter writer)
+ public void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
if (rootElement == null) throw new IllegalStateException(DomMessages.noRootElement());
@@ -132,7 +134,9 @@
dtd.toMarkup(writer);
}
- rootElement.toMarkup(document, writer);
+ Map<String, String> initialNamespaceMap = Collections.emptyMap();
+
+ rootElement.toMarkup(document, writer, initialNamespaceMap);
}
@Override
@@ -163,4 +167,12 @@
{
dtd = new DTD(name, publicId, systemId);
}
+
+ @Override
+ protected Map<String, String> getNamespaceURIToPrefix()
+ {
+ if (rootElement == null) return Collections.emptyMap();
+
+ return rootElement.getNamespaceURIToPrefix();
+ }
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java Wed Dec 17 17:08:25 2008
@@ -16,10 +16,7 @@
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newLinkedList;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
import org.apache.tapestry5.ioc.internal.util.Defense;
-import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import java.io.PrintWriter;
@@ -138,11 +135,11 @@
*/
public Element attribute(String namespace, String name, String value)
{
- notBlank(name, "name");
+ Defense.notBlank(name, "name");
if (value == null) return this;
- if (attributes == null) attributes = newMap();
+ if (attributes == null) attributes = CollectionFactory.newMap();
if (!attributes.containsKey(name)) attributes.put(name, new Attribute(namespace, name, value));
@@ -174,7 +171,7 @@
*/
public Element forceAttributes(String... namesAndValues)
{
- if (attributes == null) attributes = newMap();
+ if (attributes == null) attributes = CollectionFactory.newMap();
int i = 0;
@@ -203,7 +200,7 @@
*/
public Element element(String name, String... namesAndValues)
{
- notBlank(name, "name");
+ Defense.notBlank(name, "name");
Element child = newChild(new Element(this, null, name));
@@ -221,14 +218,14 @@
*/
public Element elementNS(String namespace, String name)
{
- notBlank(name, "name");
+ Defense.notBlank(name, "name");
return newChild(new Element(this, namespace, name));
}
public Element elementAt(int index, String name, String... namesAndValues)
{
- notBlank(name, "name");
+ Defense.notBlank(name, "name");
Element child = new Element(this, null, name);
child.attributes(namesAndValues);
@@ -290,15 +287,15 @@
}
@Override
- void toMarkup(Document document, PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer, Map<String, String> containerNamespacePrefixToURI)
{
- Map<String, String> namespaceToPrefixMap = createNamespaceURIToNamespaceMap();
+ Map<String, String> localNamespacePrefixToURI = createNamespaceURIToPrefix(containerNamespacePrefixToURI);
MarkupModel markupModel = document.getMarkupModel();
StringBuilder builder = new StringBuilder();
- String prefixedElementName = toPrefixedName(namespaceToPrefixMap, namespace, name);
+ String prefixedElementName = toPrefixedName(localNamespacePrefixToURI, namespace, name);
builder.append("<").append(prefixedElementName);
@@ -308,7 +305,7 @@
{
Attribute attribute = attributes.get(key);
- attribute.render(markupModel, builder, namespaceToPrefixMap);
+ attribute.render(markupModel, builder, localNamespacePrefixToURI);
}
// Next, emit namespace declarations for each namespace.
@@ -343,7 +340,7 @@
writer.print(builder.toString());
- if (hasChildren) writeChildMarkup(document, writer);
+ if (hasChildren) writeChildMarkup(document, writer, localNamespacePrefixToURI);
// Dangerous -- perhaps it should be an error for a tag of type OMIT to even have children!
// We'll certainly be writing out unbalanced markup in that case.
@@ -383,7 +380,7 @@
{
Defense.notNull(id, "id");
- LinkedList<Element> queue = newLinkedList();
+ LinkedList<Element> queue = CollectionFactory.newLinkedList();
queue.add(this);
@@ -418,7 +415,7 @@
*/
public Element find(String path)
{
- notBlank(path, "path");
+ Defense.notBlank(path, "path");
Element search = this;
@@ -555,28 +552,18 @@
}
/**
- * Creates the URI to namespace map for this element, which reflects namespace mappings from containing elements. In
- * addition, automatic namespaces are defined for any URIs that are not explicitly mapped (this occurs sometimes in
- * Ajax partial render scenarios).
+ * Creates the URI to namespace prefix map for this element, which reflects namespace mappings from containing
+ * elements. In addition, automatic namespaces are defined for any URIs that are not explicitly mapped (this occurs
+ * sometimes in Ajax partial render scenarios).
*
* @return a mapping from namespace URI to namespace prefix
*/
- private Map<String, String> createNamespaceURIToNamespaceMap()
+ private Map<String, String> createNamespaceURIToPrefix(Map<String, String> containerNamespaceURIToPrefix)
{
- Map<String, String> result = CollectionFactory.newMap();
+ MapHolder holder = new MapHolder(containerNamespaceURIToPrefix);
- List<Element> elements = gatherParentElements();
+ holder.putAll(namespaceToPrefix);
- elements.add(this);
-
- for (Element e : elements)
- {
- // Put each namespace map, when present, overwriting child element's mappings
- // over parent elements (by virtue of order in the list).
-
- if (e.namespaceToPrefix != null)
- result.putAll(e.namespaceToPrefix);
- }
// result now contains all the mappings, including this element's.
@@ -587,10 +574,10 @@
// Add the namespace for the element as the default namespace.
- if (!result.containsKey(namespace))
+ if (!holder.getResult().containsKey(namespace))
{
defineNamespace(namespace, "");
- result.put(namespace, "");
+ holder.put(namespace, "");
}
}
@@ -599,21 +586,23 @@
if (attributes != null)
{
for (Attribute a : attributes.values())
- addMappingIfNeeded(result, a.namespace);
+ addMappingIfNeeded(holder, a.namespace);
}
- return result;
+ return holder.getResult();
}
- private void addMappingIfNeeded(Map<String, String> masterURItoPrefixMap, String namespace)
+ private void addMappingIfNeeded(MapHolder holder, String namespace)
{
if (InternalUtils.isBlank(namespace)) return;
- if (masterURItoPrefixMap.containsKey(namespace)) return;
+ Map<String, String> current = holder.getResult();
+
+ if (current.containsKey(namespace)) return;
// A missing namespace.
- Set<String> prefixes = CollectionFactory.newSet(masterURItoPrefixMap.values());
+ Set<String> prefixes = CollectionFactory.newSet(holder.getResult().values());
// A clumsy way to find a unique id for the new namespace.
@@ -624,9 +613,8 @@
if (!prefixes.contains(prefix))
{
-
defineNamespace(namespace, prefix);
- masterURItoPrefixMap.put(namespace, prefix);
+ holder.put(namespace, prefix);
return;
}
@@ -634,6 +622,31 @@
}
}
+ @Override
+ protected Map<String, String> getNamespaceURIToPrefix()
+ {
+ MapHolder holder = new MapHolder();
+
+ List<Element> elements = CollectionFactory.newList(this);
+
+ Element cursor = parent;
+
+ while (cursor != null)
+ {
+ elements.add(cursor);
+ cursor = cursor.parent;
+ }
+
+ // Reverse the list, so that later elements will overwrite earlier ones.
+
+ Collections.reverse(elements);
+
+ for (Element e : elements)
+ holder.putAll(e.namespaceToPrefix);
+
+ return holder.getResult();
+ }
+
/**
* Returns the parent elements containing this element, ordered by depth (the root element is first, the current
* element's parent is last).
Added: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/MapHolder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/MapHolder.java?rev=727606&view=auto
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/MapHolder.java (added)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/MapHolder.java Wed Dec 17 17:08:25 2008
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.dom;
+
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Used by {@link org.apache.tapestry5.dom.Element} to construct namespace URI to prefix maps.
+ *
+ * @since 5.0.19
+ */
+class MapHolder
+{
+ private final Map<String, String> startingMap;
+
+ private Map<String, String> localMap;
+
+ MapHolder()
+ {
+ this(Collections.<String, String>emptyMap());
+ }
+
+ MapHolder(Map<String, String> startingMap)
+ {
+ this.startingMap = startingMap;
+ }
+
+ void put(String key, String value)
+ {
+ getMutable().put(key, value);
+ }
+
+ Map<String, String> getMutable()
+ {
+ if (localMap == null)
+ localMap = CollectionFactory.newMap(startingMap);
+
+ return localMap;
+ }
+
+ void putAll(Map<String, String> map)
+ {
+ if (map == null || map.isEmpty()) return;
+
+ getMutable().putAll(map);
+ }
+
+ Map<String, String> getResult()
+ {
+ return localMap != null ? localMap : startingMap;
+ }
+}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java Wed Dec 17 17:08:25 2008
@@ -21,6 +21,7 @@
import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
/**
* A node within the DOM.
@@ -95,12 +96,12 @@
return children != null && !children.isEmpty();
}
- void writeChildMarkup(Document document, PrintWriter writer)
+ void writeChildMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
if (children == null) return;
for (Node child : children)
- child.toMarkup(writer);
+ child.toMarkup(document, writer, namespaceURIToPrefix);
}
/**
@@ -110,7 +111,7 @@
{
PrintOutCollector collector = new PrintOutCollector();
- writeChildMarkup(getDocument(), collector.getPrintWriter());
+ writeChildMarkup(getDocument(), collector.getPrintWriter(), null);
return collector.getPrintOut();
}
@@ -146,13 +147,20 @@
*/
public void toMarkup(PrintWriter writer)
{
- toMarkup(getDocument(), writer);
+ toMarkup(getDocument(), writer, getNamespaceURIToPrefix());
+ }
+
+ protected Map<String, String> getNamespaceURIToPrefix()
+ {
+ // For non-Elements, the container (which should be an Element) will provide the mapping.
+
+ return container.getNamespaceURIToPrefix();
}
/**
* Implemented by each subclass, with the document passed in for efficiency.
*/
- abstract void toMarkup(Document document, PrintWriter writer);
+ abstract void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix);
/**
* Moves this node so that it becomes a sibling of the element, ordered just before the element.
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java Wed Dec 17 17:08:25 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.dom;
import java.io.PrintWriter;
+import java.util.Map;
/**
* A specialized node in the document tree that contains raw markup to be printed to the client exactly as-is.
@@ -34,7 +35,7 @@
* Prints the text exactly as is, no translations, filtering, etc.
*/
@Override
- void toMarkup(Document document, PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
writer.print(text);
}
Modified: tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java?rev=727606&r1=727605&r2=727606&view=diff
==============================================================================
--- tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java (original)
+++ tapestry/tapestry5/branches/hlship-5.0-perf/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java Wed Dec 17 17:08:25 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry5.dom;
import java.io.PrintWriter;
+import java.util.Map;
/**
* A type of node that contains text.
@@ -46,7 +47,7 @@
}
@Override
- void toMarkup(Document document, PrintWriter writer)
+ void toMarkup(Document document, PrintWriter writer, Map<String, String> namespaceURIToPrefix)
{
String encoded = document.getMarkupModel().encode(buffer.toString());