You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by he...@apache.org on 2006/07/20 19:23:13 UTC

svn commit: r423995 [1/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/

Author: hermanns
Date: Thu Jul 20 10:23:12 2006
New Revision: 423995

URL: http://svn.apache.org/viewvc?rev=423995&view=rev
Log:
XSLT Views + XML Mapping + HashMap support
o backport of new XSLT support from WW-2.2.3
Issue number:  WW-492
Obtained from: 
Submitted by:  Pat Niemeyer
Reviewed by:   Rainer Hermanns
CVS: ----------------------------------------------------------------------
CVS: Issue number:
CVS:   If this change addresses one or more issues,
CVS:   then enter the issue number(s) here.
CVS: Obtained from:
CVS:   If this change has been taken from another system,
CVS:   then name the system in this line, otherwise delete it.
CVS: Submitted by:
CVS:   If this code has been contributed to the project by someone else; i.e.,
CVS:   they sent us a patch or a set of diffs, then include their name/email
CVS:   address here. If this is your work then delete this line.
CVS: Reviewed by:
CVS:   If we are doing pre-commit code reviews and someone else has
CVS:   reviewed your changes, include their name(s) here.
CVS:   If you have not had it reviewed then delete this line.

Added:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java   (with props)
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java   (with props)
Removed:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionNodeList.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/DOMAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/DefaultAdapterNode.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/DefaultElementAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/DocumentAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ToStringAdapter.java
Modified:
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
    struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,133 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.*;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * AbstractAdapterElement extends the abstract Node type and implements
+ * the DOM Element interface.
+ */
+public abstract class AbstractAdapterElement extends AbstractAdapterNode implements Element {
+
+    private Map attributeAdapters;
+
+    public AbstractAdapterElement() { }
+
+    public void setAttribute(String string, String string1) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    protected Map getAttributeAdapters() {
+        if ( attributeAdapters == null )
+            attributeAdapters = buildAttributeAdapters();
+        return attributeAdapters;
+    }
+
+    protected Map buildAttributeAdapters() {
+        return new HashMap();
+    }
+
+    /**
+     * No attributes, return empty attributes if asked.
+     */
+    public String getAttribute(String string) {
+        return "";
+    }
+
+    public void setAttributeNS(String string, String string1, String string2) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public String getAttributeNS(String string, String string1) {
+        return null;
+    }
+
+    public Attr setAttributeNode(Attr attr) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Attr getAttributeNode( String name ) {
+        return (Attr)getAttributes().getNamedItem( name );
+    }
+
+    public Attr setAttributeNodeNS(Attr attr) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Attr getAttributeNodeNS(String string, String string1) {
+        throw operationNotSupported();
+    }
+
+    public String getNodeName() {
+        return getTagName();
+    }
+
+    public short getNodeType() {
+        return Node.ELEMENT_NODE;
+    }
+
+    public String getTagName() {
+        return getPropertyName();
+    }
+
+    public boolean hasAttribute(String string) {
+        return false;
+    }
+
+    public boolean hasAttributeNS(String string, String string1) {
+        return false;
+    }
+
+    public boolean hasChildNodes() {
+        return getElementsByTagName("*").getLength() > 0;
+    }
+
+    public void removeAttribute(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void removeAttributeNS(String string, String string1) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Attr removeAttributeNode(Attr attr) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttributeNode(Attr attr, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public TypeInfo getSchemaTypeInfo() {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttribute(String string, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttributeNS(String string, String string1, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+}
+

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,375 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.StrutsException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+/**
+ * AbstractAdapterNode is the base for childAdapters that expose a read-only view
+ * of a Java object as a DOM Node.  This class implements the core parent-child
+ * and sibling node traversal functionality shared by all adapter type nodes
+ * and used in proxy node support.
+ *
+ * @see AbstractAdapterElement
+ */
+public abstract class AbstractAdapterNode implements AdapterNode {
+
+    private static final NamedNodeMap EMPTY_NAMEDNODEMAP =
+            new NamedNodeMap() {
+                public int getLength() {
+                    return 0;
+                }
+
+                public Node item(int index) {
+                    return null;
+                }
+
+                public Node getNamedItem(String name) {
+                    return null;
+                }
+
+                public Node removeNamedItem(String name) throws DOMException {
+                    return null;
+                }
+
+                public Node setNamedItem(Node arg) throws DOMException {
+                    return null;
+                }
+
+                public Node setNamedItemNS(Node arg) throws DOMException {
+                    return null;
+                }
+
+                public Node getNamedItemNS(String namespaceURI, String localName) {
+                    return null;
+                }
+
+                public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
+                    return null;
+                }
+            };
+
+    private List<Node> childAdapters;
+    private Log log = LogFactory.getLog(this.getClass());
+
+    // The domain object that we are adapting
+    private Object propertyValue;
+    private String propertyName;
+    private AdapterNode parent;
+    private AdapterFactory adapterFactory;
+
+
+    public AbstractAdapterNode() {
+        if (LogFactory.getLog(getClass()).isDebugEnabled()) {
+            LogFactory.getLog(getClass()).debug("Creating " + this);
+        }
+    }
+
+    /**
+     *
+     * @param adapterFactory
+     * @param parent
+     * @param propertyName
+     * @param value
+     */
+    protected void setContext(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setAdapterFactory(adapterFactory);
+        setParent(parent);
+        setPropertyName(propertyName);
+        setPropertyValue(value);
+    }
+
+    /**
+     * subclasses override to produce their children
+     *
+     * @return List of child adapters.
+     */
+    protected List<Node> buildChildAdapters() {
+        return new ArrayList<Node>();
+    }
+
+    /**
+     * Lazily initialize child childAdapters
+     */
+    protected List<Node> getChildAdapters() {
+        if (childAdapters == null) {
+            childAdapters = buildChildAdapters();
+        }
+        return childAdapters;
+    }
+
+    public Node getChildBeforeOrAfter(Node child, boolean before) {
+        log.debug("getChildBeforeOrAfter: ");
+        List adapters = getChildAdapters();
+        log.debug("childAdapters = " + adapters);
+        log.debug("child = " + child);
+        int index = adapters.indexOf(child);
+        if (index < 0)
+            throw new StrutsException(child + " is no child of " + this);
+        int siblingIndex = before ? index - 1 : index + 1;
+        return ((0 < siblingIndex) && (siblingIndex < adapters.size())) ?
+                ((Node) adapters.get(siblingIndex)) : null;
+    }
+
+    public Node getChildAfter(Node child) {
+        log.trace("getChildafter");
+        return getChildBeforeOrAfter(child, false/*after*/);
+    }
+
+    public Node getChildBefore(Node child) {
+        log.trace("getchildbefore");
+        return getChildBeforeOrAfter(child, true/*after*/);
+    }
+
+    public NodeList getElementsByTagName(String tagName) {
+        if (tagName.equals("*")) {
+            return getChildNodes();
+        } else {
+            LinkedList<Node> filteredChildren = new LinkedList<Node>();
+
+            for (Node adapterNode : getChildAdapters()) {
+                if (adapterNode.getNodeName().equals(tagName)) {
+                    filteredChildren.add(adapterNode);
+                }
+            }
+
+            return new SimpleNodeList(filteredChildren);
+        }
+    }
+
+    public NodeList getElementsByTagNameNS(String string, String string1) {
+        // TODO:
+        return null;
+    }
+
+    // Begin Node methods
+
+    public NamedNodeMap getAttributes() {
+        return EMPTY_NAMEDNODEMAP;
+    }
+
+    public NodeList getChildNodes() {
+        NodeList nl = new SimpleNodeList(getChildAdapters());
+        if (log.isDebugEnabled())
+            log.debug("getChildNodes for tag: "
+                    + getNodeName() + " num children: " + nl.getLength());
+        return nl;
+    }
+
+    public Node getFirstChild() {
+        return (getChildNodes().getLength() > 0) ? getChildNodes().item(0) : null;
+    }
+
+    public Node getLastChild() {
+        return (getChildNodes().getLength() > 0) ? getChildNodes().item(getChildNodes().getLength() - 1) : null;
+    }
+
+
+    public String getLocalName() {
+        return null;
+    }
+
+    public String getNamespaceURI() {
+        return null;
+    }
+
+    public void setNodeValue(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public String getNodeValue() throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Document getOwnerDocument() {
+        return null;
+    }
+
+    public Node getParentNode() {
+        log.trace("getParentNode");
+        return getParent();
+    }
+
+    public AdapterNode getParent() {
+        return parent;
+    }
+
+    public void setParent(AdapterNode parent) {
+        this.parent = parent;
+    }
+
+    public Object getPropertyValue() {
+        return propertyValue;
+    }
+
+    public void setPropertyValue(Object prop) {
+        this.propertyValue = prop;
+    }
+
+    public void setPrefix(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public String getPrefix() {
+        return null;
+    }
+
+    public Node getNextSibling() {
+        Node next = getParent().getChildAfter(this);
+        if (log.isTraceEnabled()) {
+            log.trace("getNextSibling on " + getNodeName() + ": "
+                    + ((next == null) ? "null" : next.getNodeName()));
+        }
+
+        return getParent().getChildAfter(this);
+    }
+
+    public Node getPreviousSibling() {
+        return getParent().getChildBefore(this);
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropertyName(String name) {
+        this.propertyName = name;
+    }
+
+    public AdapterFactory getAdapterFactory() {
+        return adapterFactory;
+    }
+
+    public void setAdapterFactory(AdapterFactory adapterFactory) {
+        this.adapterFactory = adapterFactory;
+    }
+
+    public boolean isSupported(String string, String string1) {
+        throw operationNotSupported();
+    }
+
+    public Node appendChild(Node node) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Node cloneNode(boolean b) {
+        log.trace("cloneNode");
+        throw operationNotSupported();
+    }
+
+    public boolean hasAttributes() {
+        return false;
+    }
+
+    public boolean hasChildNodes() {
+        return false;
+    }
+
+    public Node insertBefore(Node node, Node node1) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void normalize() {
+        log.trace("normalize");
+        throw operationNotSupported();
+    }
+
+    public Node removeChild(Node node) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public Node replaceChild(Node node, Node node1) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    // Begin DOM 3 methods
+
+    public boolean isDefaultNamespace(String string) {
+        throw operationNotSupported();
+    }
+
+    public String lookupNamespaceURI(String string) {
+        throw operationNotSupported();
+    }
+
+    public String getNodeName() {
+        throw operationNotSupported();
+    }
+
+    public short getNodeType() {
+        throw operationNotSupported();
+    }
+
+    public String getBaseURI() {
+        throw operationNotSupported();
+    }
+
+    public short compareDocumentPosition(Node node) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public String getTextContent() throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void setTextContent(String string) throws DOMException {
+        throw operationNotSupported();
+
+    }
+
+    public boolean isSameNode(Node node) {
+        throw operationNotSupported();
+    }
+
+    public String lookupPrefix(String string) {
+        throw operationNotSupported();
+    }
+
+    public boolean isEqualNode(Node node) {
+        throw operationNotSupported();
+    }
+
+    public Object getFeature(String string, String string1) {
+        throw operationNotSupported();
+    }
+
+    public Object setUserData(String string, Object object, UserDataHandler userDataHandler) {
+        throw operationNotSupported();
+    }
+
+    public Object getUserData(String string) {
+        throw operationNotSupported();
+    }
+
+    // End node methods
+
+    protected StrutsException operationNotSupported() {
+        return new StrutsException("Operation not supported.");
+    }
+
+    public String toString() {
+        return getClass() + ": " + getNodeName() + " parent=" + getParentNode();
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,234 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.apache.struts2.StrutsException;
+import org.w3c.dom.*;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * AdapterFactory produces Node adapters for Java object types.
+ * Adapter classes are generally instantiated dynamically via a no-args constructor
+ * and populated with their context information via the AdapterNode interface.
+ *
+ * This factory supports proxying of generic DOM Node trees, allowing arbitrary
+ * Node types to be mixed together.  You may simply return a Document or Node
+ * type as an object property and it will appear as a sub-tree in the XML as
+ * you'd expect. See #proxyNode().
+ *
+ * Customization of the result XML can be accomplished by providing
+ * alternate adapters for Java types.  Adapters are associated with Java
+ * types through the registerAdapterType() method.
+ *
+ * For example, since there is no default Date adapter, Date objects will be
+ * rendered with the generic Bean introspecting adapter, producing output
+ * like:
+ * <pre>
+     <date>
+        <date>19</date>
+        <day>1</day>
+        <hours>0</hours>
+        <minutes>7</minutes>
+        <month>8</month>
+        <seconds>4</seconds>
+        <time>1127106424531</time>
+        <timezoneOffset>300</timezoneOffset>
+        <year>105</year>
+    </date>
+ * </pre>
+ *
+ * By extending the StringAdapter and overriding its normal behavior we can
+ * create a custom Date formatter:
+ *
+ * <pre>
+      public static class CustomDateAdapter extends StringAdapter {
+        protected String getStringValue() {
+            Date date = (Date)getPropertyValue();
+            return DateFormat.getTimeInstance( DateFormat.FULL ).format( date );
+        }
+    }
+ * </pre>
+ *
+ * Producing output like:
+ *
+<pre>
+     <date>12:02:54 AM CDT</date>
+ </pre>
+ *
+ * The StringAdapter (which is normally invoked only to adapt String values)
+ * is a useful base for these kinds of customizations and can produce
+ * structured XML output as well as plain text by setting its parseStringAsXML()
+ * property to true.
+ *
+ * See provided examples.
+ */
+public class AdapterFactory {
+
+    /**
+     * Map<Class, Class<AdapterNode>>
+     */
+    private Map<Class, Class> adapterTypes = new HashMap<Class, Class>();
+
+    /**
+     * Register an adapter type for a Java class type.
+     *
+     * @param type        the Java class type which is to be handled by the adapter.
+     * @param adapterType The adapter class, which implements AdapterNode.
+     */
+    public void registerAdapterType(Class type, Class adapterType) {
+        adapterTypes.put(type, adapterType);
+    }
+
+    /**
+     * Create a top level Document adapter for the specified Java object.
+     * The document will have a root element with the specified property name
+     * and contain the specified Java object content.
+     *
+     * @param propertyName The name of the root document element
+     * @return
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    public Document adaptDocument(String propertyName, Object propertyValue)
+            throws IllegalAccessException, InstantiationException {
+        //if ( propertyValue instanceof Document )
+        //	return (Document)propertyValue;
+
+        return new SimpleAdapterDocument(this, null, propertyName, propertyValue);
+    }
+
+
+    /**
+     * Create an Node adapter for a child element.
+     * Note that the parent of the created node must be an AdapterNode, however
+     * the child node itself may be any type of Node.
+     *
+     * @see #adaptDocument( String, Object )
+     */
+    public Node adaptNode(AdapterNode parent, String propertyName, Object value) {
+        Class adapterClass = getAdapterForValue(value);
+        if (adapterClass != null)
+            return constructAdapterInstance(adapterClass, parent, propertyName, value);
+
+        // If the property is a Document, "unwrap" it to the root element
+        if (value instanceof Document)
+            value = ((Document) value).getDocumentElement();
+
+        // If the property is already a Node, proxy it
+        if (value instanceof Node)
+            return proxyNode(parent, (Node) value);
+
+        // Check other supported types or default to generic JavaBean introspecting adapter
+        Class valueType = value.getClass();
+
+        if (valueType.isArray())
+            adapterClass = ArrayAdapter.class;
+        else if (value instanceof String || value instanceof Number || valueType.isPrimitive())
+            adapterClass = StringAdapter.class;
+        else if (value instanceof Collection)
+            adapterClass = CollectionAdapter.class;
+        else if (value instanceof Map)
+            adapterClass = MapAdapter.class;
+        else
+            adapterClass = BeanAdapter.class;
+
+        return constructAdapterInstance(adapterClass, parent, propertyName, value);
+    }
+
+    /**
+     * Construct a proxy adapter for a value that is an existing DOM Node.
+     * This allows arbitrary DOM Node trees to be mixed in with our results.
+     * The proxied nodes are read-only and currently support only
+     * limited types of Nodes including Element, Text, and Attributes.  (Other
+     * Node types may be ignored by the proxy and not appear in the result tree).
+     * <p/>
+     * // TODO:
+     * NameSpaces are not yet supported.
+     * <p/>
+     * This method is primarily for use by the adapter node classes.
+     */
+    public Node proxyNode(AdapterNode parent, Node node) {
+        // If the property is a Document, "unwrap" it to the root element
+        if (node instanceof Document)
+            node = ((Document) node).getDocumentElement();
+
+        if (node == null)
+            return null;
+        if (node.getNodeType() == Node.ELEMENT_NODE)
+            return new ProxyElementAdapter(this, parent, (Element) node);
+        if (node.getNodeType() == Node.TEXT_NODE)
+            return new ProxyTextNodeAdapter(this, parent, (Text) node);
+        if (node.getNodeType() == Node.ATTRIBUTE_NODE)
+            return new ProxyAttrAdapter(this, parent, (Attr) node);
+
+        return null; // Unsupported Node type - ignore for now
+    }
+
+    public NamedNodeMap proxyNamedNodeMap(AdapterNode parent, NamedNodeMap nnm) {
+        return new ProxyNamedNodeMap(this, parent, nnm);
+    }
+
+    /**
+     * Create an instance of an adapter dynamically and set its context via
+     * the AdapterNode interface.
+     */
+    private Node constructAdapterInstance(Class adapterClass, AdapterNode parent, String propertyName, Object propertyValue) {
+        // Check to see if the class has a no-args constructor
+        try {
+            adapterClass.getConstructor(new Class []{});
+        } catch (NoSuchMethodException e1) {
+            throw new StrutsException("Adapter class: " + adapterClass
+                    + " does not have a no-args consructor.");
+        }
+
+        try {
+            AdapterNode adapterNode = (AdapterNode) adapterClass.newInstance();
+            adapterNode.setAdapterFactory(this);
+            adapterNode.setParent(parent);
+            adapterNode.setPropertyName(propertyName);
+            adapterNode.setPropertyValue(propertyValue);
+
+            return adapterNode;
+
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+            throw new StrutsException("Cannot adapt " + propertyValue + " (" + propertyName + ") :" + e.getMessage());
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+            throw new StrutsException("Cannot adapt " + propertyValue + " (" + propertyName + ") :" + e.getMessage());
+        }
+    }
+
+    /**
+     * Create an appropriate adapter for a null value.
+     *
+     * @param parent
+     * @param propertyName
+     */
+    public Node adaptNullValue(BeanAdapter parent, String propertyName) {
+        return new StringAdapter(this, parent, propertyName, "null");
+    }
+
+    //TODO: implement Configuration option to provide additional adapter classes
+    public Class getAdapterForValue(Object value) {
+        return adapterTypes.get(value.getClass());
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java Thu Jul 20 10:23:12 2006
@@ -19,20 +19,57 @@
 
 import org.w3c.dom.Node;
 
-
 /**
  */
 public interface AdapterNode extends Node {
 
-    Node getNextSibling(AdapterNode child);
-
-    AdapterNode getParentAdapterNode();
-
+    /**
+     * The adapter factory that created this node.
+     */
+    AdapterFactory getAdapterFactory();
+
+    /**
+     * The adapter factory that created this node.
+     */
+    void setAdapterFactory(AdapterFactory factory);
+
+    /**
+     * The parent adapter node of this node. Note that our parent must be another adapter node, but our children may be any
+     * kind of Node.
+     */
+    AdapterNode getParent();
+
+    /**
+     * The parent adapter node of this node. Note that our parent must be another adapter node, but our children may be any
+     * kind of Node.
+     */
+    void setParent(AdapterNode parent);
+
+    /**
+     * The child node before the specified sibling
+     */
+    Node getChildBefore(Node thisNode);
+
+    /**
+     * The child node after the specified sibling
+     */
+    Node getChildAfter(Node thisNode);
+
+    /**
+     * The name of the Java object (property) that we are adapting
+     */
     String getPropertyName();
 
-    DOMAdapter getRootAdapter();
-
-    Object getValue();
+    /**
+     * The name of the Java object (property) that we are adapting
+     */
+    void setPropertyName(String name);
+
+    /**
+     * The Java object (property) that we are adapting
+     */
+    Object getPropertyValue();
 
-    int getDepth();
+    /** The Java object (property) that we are adapting */
+    void setPropertyValue(Object prop );
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java Thu Jul 20 10:23:12 2006
@@ -19,6 +19,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -26,23 +27,24 @@
 
 /**
  */
-public class ArrayAdapter extends DefaultElementAdapter {
+public class ArrayAdapter extends AbstractAdapterElement {
 
     private Log log = LogFactory.getLog(this.getClass());
 
-
-    public ArrayAdapter(DOMAdapter rootAdapter, AdapterNode parent, String propertyName, Object value) {
-        super(rootAdapter, parent, propertyName, value);
+    public ArrayAdapter() {
     }
 
+    public ArrayAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setContext(adapterFactory, parent, propertyName, value);
+    }
 
-    protected List buildChildrenAdapters() {
-        List children = new ArrayList();
-        Object[] values = (Object[]) getValue();
-
-        for (int i = 0; i < values.length; i++) {
-            AdapterNode childAdapter = getRootAdapter().adapt(getRootAdapter(), this, "item", values[i]);
-            if( childAdapter != null)
+    protected List<Node> buildChildAdapters() {
+        List<Node> children = new ArrayList<Node>();
+        Object[] values = (Object[]) getPropertyValue();
+
+        for (Object value : values) {
+            Node childAdapter = getAdapterFactory().adaptNode(this, "item", value);
+            if (childAdapter != null)
                 children.add(childAdapter);
 
             if (log.isDebugEnabled()) {

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java Thu Jul 20 10:23:12 2006
@@ -20,11 +20,14 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.struts2.StrutsException;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
 
 import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -32,71 +35,102 @@
 
 
 /**
+ * This class is the most general type of adapter, utilizing reflective introspection to present a DOM view of all of
+ * the public properties of its value.  For example, a property returning a JavaBean such as:
+ *
+ * <pre>
+ * public Person getMyPerson() { ... }
+ * ...
+ * class Person {
+ * 		public String getFirstName();
+ * 		public String getLastName();
+ * }
+ * </pre>
+ *
+ * would be rendered as: <myPerson> <firstName>...</firstName> <lastName>...</lastName> </myPerson>
  */
-public class BeanAdapter extends DefaultElementAdapter {
+public class BeanAdapter extends AbstractAdapterElement {
+    //~ Static fields/initializers /////////////////////////////////////////////
 
     private static final Object[] NULLPARAMS = new Object[0];
 
     /**
-     * Cache can savely be static because the cached information is
-     * the same for all instances of this class.
+     * Cache can savely be static because the cached information is the same for all instances of this class.
      */
-    private static Map propertyDescriptorCache;
+    private static Map<Class, PropertyDescriptor[]> propertyDescriptorCache;
 
+    //~ Instance fields ////////////////////////////////////////////////////////
 
     private Log log = LogFactory.getLog(this.getClass());
 
+    //~ Constructors ///////////////////////////////////////////////////////////
 
-    public BeanAdapter(DOMAdapter rootAdapter, AdapterNode parent, String propertyName, Object value) {
-        super(rootAdapter, parent, propertyName, value);
+    public BeanAdapter() {
     }
 
+    public BeanAdapter(
+            AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setContext(adapterFactory, parent, propertyName, value);
+    }
+
+    //~ Methods ////////////////////////////////////////////////////////////////
 
     public String getTagName() {
         return getPropertyName();
     }
 
-    protected List buildChildrenAdapters() {
-        List newAdapters = new ArrayList();
-        Class type = getValue().getClass();
-        PropertyDescriptor[] props = getPropertyDescriptors(getValue());
+    public NodeList getChildNodes() {
+        NodeList nl = super.getChildNodes();
+        // Log child nodes for debug:
+        if (log.isDebugEnabled() && nl != null) {
+            log.debug("BeanAdapter getChildNodes for: " + getTagName());
+            log.debug(nl.toString());
+        }
+        return nl;
+    }
+
+    protected List<Node> buildChildAdapters() {
+        log.debug("BeanAdapter building children.  PropName = " + getPropertyName());
+        List<Node> newAdapters = new ArrayList<Node>();
+        Class type = getPropertyValue().getClass();
+        PropertyDescriptor[] props = getPropertyDescriptors(getPropertyValue());
 
         if (props.length > 0) {
-            for (int i = 0; i < props.length; i++) {
-                Method m = props[i].getReadMethod();
+            for (PropertyDescriptor prop : props) {
+                Method m = prop.getReadMethod();
+                log.debug("Bean reading property method: " + m.getName());
 
                 if (m == null) {
                     //FIXME: write only property or indexed access
                     continue;
                 }
 
-                String propertyName = props[i].getName();
-                if (! getRootAdapter().isAdaptable(getRootAdapter(), this, propertyName))
-                    continue;
-
-                Object propertyValue = null;
+                String propertyName = prop.getName();
+                Object propertyValue;
 
-                /** 999 white magic hack start 999 **
-                 * some property accessors will throw exceptions, e.g. getLocale() in struts.ActionSupport *grrr*
-                 * IMHO property accessors should not have those side effects - meier@meisterbohne.de
-                 */
+                /*
+                    Unwrap any invocation target exceptions and log them.
+                    We really need a way to control which properties are accessed.
+                    Perhaps with annotations in Java5?
+                */
                 try {
-                    propertyValue = m.invoke(getValue(), NULLPARAMS);
+                    propertyValue = m.invoke(getPropertyValue(), NULLPARAMS);
                 } catch (Exception e) {
-                    log.error("Exception when checking property " + propertyName, e);
+                    if (e instanceof InvocationTargetException)
+                        e = (Exception) ((InvocationTargetException) e).getTargetException();
+                    log.error(e);
                     continue;
                 }
 
-                /** 999 white magic hack end 999 **/
-                AdapterNode childAdapter;
+                Node childAdapter;
 
                 if (propertyValue == null) {
-                    childAdapter = getRootAdapter().adaptNullValue(getRootAdapter(), this, propertyName);
+                    childAdapter = getAdapterFactory().adaptNullValue(this, propertyName);
                 } else {
-                    childAdapter = getRootAdapter().adapt(getRootAdapter(), this, propertyName, propertyValue);
+                    childAdapter = getAdapterFactory().adaptNode(this, propertyName, propertyValue);
                 }
 
-                if( childAdapter != null)
+                if (childAdapter != null)
                     newAdapters.add(childAdapter);
 
                 if (log.isDebugEnabled()) {
@@ -105,9 +139,8 @@
             }
         } else {
             // No properties found
-            log.info("Class " + type.getName() + " has no readable properties, " + " trying to adapt " + getPropertyName() + " with ToStringAdapter...");
-
-            //newAdapters.add(new ToStringAdapter(getRootAdapter(), this, getPropertyName(), getValue()));
+            log.info(
+                    "Class " + type.getName() + " has no readable properties, " + " trying to adapt " + getPropertyName() + " with StringAdapter...");
         }
 
         return newAdapters;
@@ -119,10 +152,10 @@
     private synchronized PropertyDescriptor[] getPropertyDescriptors(Object bean) {
         try {
             if (propertyDescriptorCache == null) {
-                propertyDescriptorCache = new HashMap();
+                propertyDescriptorCache = new HashMap<Class, PropertyDescriptor[]>();
             }
 
-            PropertyDescriptor[] props = (PropertyDescriptor[]) propertyDescriptorCache.get(bean.getClass());
+            PropertyDescriptor[] props = propertyDescriptorCache.get(bean.getClass());
 
             if (props == null) {
                 log.debug("Caching property descriptor for " + bean.getClass().getName());
@@ -132,8 +165,8 @@
 
             return props;
         } catch (IntrospectionException e) {
-            throw new StrutsException("Error getting property descriptors for " 
-                    + bean + " : " + e.getMessage(), e);
+            e.printStackTrace();
+            throw new StrutsException("Error getting property descriptors for " + bean + " : " + e.getMessage());
         }
     }
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java Thu Jul 20 10:23:12 2006
@@ -19,6 +19,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,23 +29,23 @@
 
 /**
  */
-public class CollectionAdapter extends DefaultElementAdapter {
+public class CollectionAdapter extends AbstractAdapterElement {
 
     private Log log = LogFactory.getLog(this.getClass());
 
+	public CollectionAdapter() { }
 
-    public CollectionAdapter(DOMAdapter rootAdapter, AdapterNode parent, String propertyName, Object value) {
-        super(rootAdapter, parent, propertyName, value);
+	public CollectionAdapter(AdapterFactory rootAdapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setContext(rootAdapterFactory, parent, propertyName, value);
     }
 
-
-    protected List buildChildrenAdapters() {
-        Collection values = (Collection) getValue();
-        List children = new ArrayList(values.size());
-
-        for (Iterator i = values.iterator(); i.hasNext();) {
-            AdapterNode childAdapter = getRootAdapter().adapt(getRootAdapter(), this, "item", i.next());
-            if( childAdapter != null)
+    protected List<Node> buildChildAdapters() {
+        Collection values = (Collection) getPropertyValue();
+        List<Node> children = new ArrayList<Node>(values.size());
+
+        for (Object value : values) {
+            Node childAdapter = getAdapterFactory().adaptNode(this, "item", value);
+            if (childAdapter != null)
                 children.add(childAdapter);
 
             if (log.isDebugEnabled()) {

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,83 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.Node;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * MapAdapter adapters a java.util.Map type to an XML DOM with the following
+ * structure:
+ * <pre>
+ * 	<myMap>
+ * 		<entry>
+ * 			<key>...</key>
+ * 			<value>...</value>
+ * 		</entry>
+ * 		...
+ * 	</myMap>
+ * </pre>
+ */
+public class MapAdapter extends AbstractAdapterElement {
+
+    public MapAdapter() { }
+
+    public MapAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Map value) {
+        setContext( adapterFactory, parent, propertyName, value );
+    }
+
+    public Map map() {
+        return (Map)getPropertyValue();
+    }
+
+    protected List<Node> buildChildAdapters() {
+        List<Node> children = new ArrayList<Node>(map().entrySet().size());
+
+        for (Object o : map().entrySet()) {
+            Map.Entry entry = (Map.Entry) o;
+            Object key = entry.getKey();
+            Object value = entry.getValue();
+            EntryElement child = new EntryElement(
+                    getAdapterFactory(), this, "entry", key, value);
+            children.add(child);
+        }
+
+        return children;
+    }
+
+    class EntryElement extends AbstractAdapterElement {
+        Object key, value;
+
+        public EntryElement(  AdapterFactory adapterFactory,
+                              AdapterNode parent, String propertyName, Object key, Object value ) {
+            setContext( adapterFactory, parent, propertyName, null/*we have two values*/ );
+            this.key = key;
+            this.value = value;
+        }
+
+        protected List<Node> buildChildAdapters() {
+            List<Node> children = new ArrayList<Node>();
+            children.add( getAdapterFactory().adaptNode( this, "key", key ) );
+            children.add( getAdapterFactory().adaptNode( this, "value", value ) );
+            return children;
+        }
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,82 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.TypeInfo;
+
+/**
+ * ProxyAttrAdapter is a pass-through adapter for objects which already
+ * implement the Attr interface.  All methods are proxied to the underlying
+ * Node except node traversal (e.g. getParent()) related methods which
+ * are implemented by the abstract adapter node to work with the parent adapter.
+ */
+public class ProxyAttrAdapter extends ProxyNodeAdapter implements Attr {
+
+    public ProxyAttrAdapter(AdapterFactory factory, AdapterNode parent, Attr value) {
+        super(factory, parent, value);
+    }
+
+    // convenience
+    protected Attr attr() {
+        return (Attr) getPropertyValue();
+    }
+
+    // Proxied Attr methods
+
+    public String getName() {
+        return attr().getName();
+    }
+
+    public boolean getSpecified() {
+        return attr().getSpecified();
+    }
+
+    public String getValue() {
+        return attr().getValue();
+    }
+
+    public void setValue(String string) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Element getOwnerElement() {
+        return (Element) getParent();
+    }
+
+    // DOM level 3
+
+    public TypeInfo getSchemaTypeInfo() {
+        throw operationNotSupported();
+    }
+
+    public boolean isId() {
+        throw operationNotSupported();
+    }
+
+    // end DOM level 3
+
+    // End Proxied Attr methods
+
+    public String toString() {
+        return "ProxyAttribute for: " + attr();
+    }
+}
+

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,160 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * ProxyElementAdapter is a pass-through adapter for objects which already
+ * implement the Element interface.  All methods are proxied to the underlying
+ * Node except getParent(), getNextSibling() and getPreviousSibling(), which
+ * are implemented by the abstract adapter node to work with the parent adapter.
+ *
+ * Note: this class wants to be (extend) both an AbstractElementAdapter
+ * and ProxyElementAdapter, but its proxy-ness is winning right now.
+ */
+public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
+
+    private Log log = LogFactory.getLog(this.getClass());
+
+    public ProxyElementAdapter(AdapterFactory factory, AdapterNode parent, Element value) {
+        super(factory, parent, value);
+    }
+
+    /**
+     * Get the proxied Element
+     */
+    protected Element element() {
+        return (Element) getPropertyValue();
+    }
+
+    protected List<Node> buildChildAdapters() {
+        List<Node> adapters = new ArrayList<Node>();
+        NodeList children = node().getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            Node adapter = wrap(child);
+            if (adapter != null) {
+                log.debug("wrapped child node: " + child.getNodeName());
+                adapters.add(adapter);
+            }
+        }
+        return adapters;
+    }
+
+    // Proxied Element methods
+
+    public String getTagName() {
+        return element().getTagName();
+    }
+
+    public boolean hasAttribute(String name) {
+        return element().hasAttribute(name);
+    }
+
+    public String getAttribute(String name) {
+        return element().getAttribute(name);
+    }
+
+    public boolean hasAttributeNS(String namespaceURI, String localName) {
+        return element().hasAttributeNS(namespaceURI, localName);
+    }
+
+    public Attr getAttributeNode(String name) {
+        log.debug("wrapping attribute");
+        return (Attr) wrap(element().getAttributeNode(name));
+    }
+
+    // I'm overriding this just for clarity.  The base impl is correct.
+    public NodeList getElementsByTagName(String name) {
+        return super.getElementsByTagName(name);
+    }
+
+    public String getAttributeNS(String namespaceURI, String localName) {
+        return element().getAttributeNS(namespaceURI, localName);
+    }
+
+    public Attr getAttributeNodeNS(String namespaceURI, String localName) {
+        return (Attr) wrap(element().getAttributeNodeNS(namespaceURI, localName));
+    }
+
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+        return super.getElementsByTagNameNS(namespaceURI, localName);
+    }
+
+    // Unsupported mutators of Element
+
+    public void removeAttribute(String name) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setAttribute(String name, String value) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Attr setAttributeNode(Attr newAttr) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    // end proxied Element methods
+
+    // unsupported DOM level 3 methods
+
+    public TypeInfo getSchemaTypeInfo() {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttribute(String string, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttributeNS(String string, String string1, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public void setIdAttributeNode(Attr attr, boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    // end DOM level 3 methods
+
+    public String toString() {
+        return "ProxyElement for: " + element();
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,78 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.DOMException;
+
+/**
+ * A NamedNodeMap that wraps the Nodes returned in their proxies.
+ *
+ * Note: Since maps have no guaranteed order we don't need to worry about identity
+ * here as we do with "child" adapters.  In that case we need to preserve identity
+ * in order to support finding the next/previous siblings.
+ */
+public class ProxyNamedNodeMap implements NamedNodeMap {
+
+    private NamedNodeMap nodes;
+    private AdapterFactory adapterFactory;
+    private AdapterNode parent;
+
+    public ProxyNamedNodeMap(AdapterFactory factory, AdapterNode parent, NamedNodeMap nodes) {
+        this.nodes = nodes;
+        this.adapterFactory = factory;
+        this.parent = parent;
+    }
+
+    protected Node wrap(Node node) {
+        return adapterFactory.proxyNode(parent, node);
+    }
+
+    public int getLength() {
+        return nodes.getLength();
+    }
+
+    public Node item(int index) {
+        return wrap(nodes.item(index));
+    }
+
+    public Node getNamedItem(String name) {
+        return wrap(nodes.getNamedItem(name));
+    }
+
+    public Node removeNamedItem(String name) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Node setNamedItem(Node arg) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Node setNamedItemNS(Node arg) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Node getNamedItemNS(String namespaceURI, String localName) {
+        return wrap(nodes.getNamedItemNS(namespaceURI, localName));
+    }
+
+    public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,131 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.DOMException;
+
+/**
+ * ProxyNodeAdapter is a read-only delegating adapter for objects which already
+ * implement the Node interface.  All methods are proxied to the underlying
+ * Node except getParent(), getNextSibling() and getPreviousSibling(), which
+ * are implemented by the abstract adapter node to work with the parent adapter.
+ */
+public abstract class ProxyNodeAdapter extends AbstractAdapterNode {
+    
+    private Log log = LogFactory.getLog(this.getClass());
+
+    public ProxyNodeAdapter(AdapterFactory factory, AdapterNode parent, Node value) {
+        setContext(factory, parent, "document"/*propname unused*/, value);
+        log.debug("proxied node is: " + value);
+        log.debug("node class is: " + value.getClass());
+        log.debug("node type is: " + value.getNodeType());
+        log.debug("node name is: " + value.getNodeName());
+    }
+
+    /**
+     * Get the proxied Node value
+     */
+    protected Node node() {
+        return (Node) getPropertyValue();
+    }
+
+    /**
+     * Get and adapter to wrap the proxied node.
+     *
+     * @param node
+     */
+    protected Node wrap(Node node) {
+        return getAdapterFactory().proxyNode(this, node);
+    }
+
+    protected NamedNodeMap wrap(NamedNodeMap nnm) {
+        return getAdapterFactory().proxyNamedNodeMap(this, nnm);
+    }
+    //protected NodeList wrap( NodeList nl ) { }
+
+    //protected Node unwrap( Node child ) {
+    //	return ((ProxyNodeAdapter)child).node();
+    //}
+
+    // Proxied Node methods
+
+    public String getNodeName() {
+        log.trace("getNodeName");
+        return node().getNodeName();
+    }
+
+    public String getNodeValue() throws DOMException {
+        log.trace("getNodeValue");
+        return node().getNodeValue();
+    }
+
+    public short getNodeType() {
+        if (log.isTraceEnabled())
+            log.trace("getNodeType: " + getNodeName() + ": " + node().getNodeType());
+        return node().getNodeType();
+    }
+
+    public NamedNodeMap getAttributes() {
+        NamedNodeMap nnm = wrap(node().getAttributes());
+        if (log.isTraceEnabled())
+            log.trace("getAttributes: " + nnm);
+        return nnm;
+    }
+
+    public boolean hasChildNodes() {
+        log.trace("hasChildNodes");
+        return node().hasChildNodes();
+    }
+
+    public boolean isSupported(String s, String s1) {
+        log.trace("isSupported");
+        // Is this ok?  What kind of features are they asking about?
+        return node().isSupported(s, s1);
+    }
+
+    public String getNamespaceURI() {
+        log.trace("getNamespaceURI");
+        return node().getNamespaceURI();
+    }
+
+    public String getPrefix() {
+        log.trace("getPrefix");
+        return node().getPrefix();
+    }
+
+    public String getLocalName() {
+        log.trace("getLocalName");
+        return node().getLocalName();
+    }
+
+    public boolean hasAttributes() {
+        log.trace("hasAttributes");
+        return node().hasAttributes();
+    }
+
+    // End proxied Node methods
+
+    public String toString() {
+        return "ProxyNode for: " + node();
+    }
+}
+

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,94 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.Text;
+import org.w3c.dom.DOMException;
+
+/**
+ * ProxyTextNodeAdapter is a pass-through adapter for objects which already
+ * implement the Text interface.  All methods are proxied to the underlying
+ * Node except getParent(), getNextSibling() and getPreviousSibling(), which
+ * are implemented by the abstract adapter node to work with the parent adapter.
+ */
+public class ProxyTextNodeAdapter extends ProxyNodeAdapter implements Text {
+
+    public ProxyTextNodeAdapter(AdapterFactory factory, AdapterNode parent, Text value) {
+        super(factory, parent, value);
+    }
+
+    // convenience
+    Text text() {
+        return (Text) getPropertyValue();
+    }
+
+    public String toString() {
+        return "ProxyTextNode for: " + text();
+    }
+
+    public Text splitText(int offset) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getLength() {
+        return text().getLength();
+    }
+
+    public void deleteData(int offset, int count) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getData() throws DOMException {
+        return text().getData();
+    }
+
+    public String substringData(int offset, int count) throws DOMException {
+        return text().substringData(offset, count);
+    }
+
+    public void replaceData(int offset, int count, String arg) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void insertData(int offset, String arg) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void appendData(String arg) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setData(String data) throws DOMException {
+        throw new UnsupportedOperationException();
+    }
+
+    // DOM level 3
+
+    public boolean isElementContentWhitespace() {
+        throw operationNotSupported();
+    }
+
+    public String getWholeText() {
+        throw operationNotSupported();
+    }
+
+    public Text replaceWholeText(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+}
+

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java Thu Jul 20 10:23:12 2006
@@ -29,36 +29,41 @@
 
 
 /**
+ * ServletURIResolver is a URIResolver that can retrieve resources from the servlet context using the scheme "res".
+ * e.g.
  *
+ * A URI resolver is called when a stylesheet uses an xsl:include, xsl:import, or document() function to find the
+ * resource (file).
  */
 public class ServletURIResolver implements URIResolver {
 
-    protected static Log log = LogFactory.getLog(URIResolver.class);
-    static final String protocol = "res:";
-
+    private Log log = LogFactory.getLog(getClass());
+    static final String PROTOCOL = "res:";
 
     private ServletContext sc;
 
-
     public ServletURIResolver(ServletContext sc) {
+        log.trace("ServletURIResolver: " + sc);
         this.sc = sc;
     }
 
-
     public Source resolve(String href, String base) throws TransformerException {
-        if (href.startsWith(protocol)) {
-            String res = href.substring(protocol.length());
+        log.debug("ServletURIResolver resolve(): href=" + href + ", base=" + base);
+        if (href.startsWith(PROTOCOL)) {
+            String res = href.substring(PROTOCOL.length());
             log.debug("Resolving resource <" + res + ">");
 
             InputStream is = sc.getResourceAsStream(res);
 
             if (is == null) {
-                throw new TransformerException("Resource " + res + " not found in resources.");
+                throw new TransformerException(
+                        "Resource " + res + " not found in resources.");
             }
 
             return new StreamSource(is);
         }
 
-        throw new TransformerException("Cannot handle procotol of resource " + href);
+        throw new TransformerException(
+                "Cannot handle procotol of resource " + href);
     }
 }

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,240 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.*;
+import org.apache.struts2.StrutsException;
+
+import java.util.List;
+import java.util.Arrays;
+
+/**
+ * SimpleAdapterDocument adapted a Java object and presents it as
+ * a Document.  This class represents the Document container and uses
+ * the AdapterFactory to produce a child adapter for the wrapped object.
+ * The adapter produced must be of an Element type or an exception is thrown.
+ *
+ * Note: in theory we could base this on AbstractAdapterElement and then allow
+ * the wrapped object to be a more general Node type.  We would just use
+ * ourselves as the root element.  However I don't think this is an issue as
+ * people expect Documents to wrap Elements.
+ */
+public class SimpleAdapterDocument extends AbstractAdapterNode implements Document {
+
+    private Element rootElement;
+
+    public SimpleAdapterDocument(
+            AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setContext(adapterFactory, parent, propertyName, value);
+
+    }
+
+    public void setPropertyValue(Object prop) {
+        super.setPropertyValue(prop);
+        rootElement = null; // recreate the root element
+    }
+
+    /**
+     * Lazily construct the root element adapter from the value object.
+     */
+    private Element getRootElement() {
+        if (rootElement != null)
+            return rootElement;
+
+        Node node = getAdapterFactory().adaptNode(
+                this, getPropertyName(), getPropertyValue());
+        if (node instanceof Element)
+            rootElement = (Element) node;
+        else
+            throw new StrutsException(
+                    "Document adapter expected to wrap an Element type.  Node is not an element:" + node);
+
+        return rootElement;
+    }
+
+    protected List<Node> getChildAdapters() {
+        return Arrays.asList(new Node[]{getRootElement()});
+    }
+
+    public NodeList getChildNodes() {
+        return new NodeList() {
+            public Node item(int i) {
+                return getRootElement();
+            }
+
+            public int getLength() {
+                return 1;
+            }
+        };
+    }
+
+    public DocumentType getDoctype() {
+        return null;
+    }
+
+    public Element getDocumentElement() {
+        return getRootElement();
+    }
+
+    public Element getElementById(String string) {
+        return null;
+    }
+
+    public NodeList getElementsByTagName(String string) {
+        return null;
+    }
+
+    public NodeList getElementsByTagNameNS(String string, String string1) {
+        return null;
+    }
+
+    public Node getFirstChild() {
+        return getRootElement();
+    }
+
+    public DOMImplementation getImplementation() {
+        return null;
+    }
+
+    public Node getLastChild() {
+        return getRootElement();
+    }
+
+    public String getNodeName() {
+        return "#document";
+    }
+
+    public short getNodeType() {
+        return Node.DOCUMENT_NODE;
+    }
+
+    public Attr createAttribute(String string) throws DOMException {
+        return null;
+    }
+
+    public Attr createAttributeNS(String string, String string1) throws DOMException {
+        return null;
+    }
+
+    public CDATASection createCDATASection(String string) throws DOMException {
+        return null;
+    }
+
+    public Comment createComment(String string) {
+        return null;
+    }
+
+    public DocumentFragment createDocumentFragment() {
+        return null;
+    }
+
+    public Element createElement(String string) throws DOMException {
+        return null;
+    }
+
+    public Element createElementNS(String string, String string1) throws DOMException {
+        return null;
+    }
+
+    public EntityReference createEntityReference(String string) throws DOMException {
+        return null;
+    }
+
+    public ProcessingInstruction createProcessingInstruction(String string, String string1) throws DOMException {
+        return null;
+    }
+
+    public Text createTextNode(String string) {
+        return null;
+    }
+
+    public boolean hasChildNodes() {
+        return true;
+    }
+
+    public Node importNode(Node node, boolean b) throws DOMException {
+        return null;
+    }
+
+    public Node getChildAfter(Node child) {
+        return null;
+    }
+
+    public Node getChildBefore(Node child) {
+        return null;
+    }
+
+    // DOM level 3
+
+    public String getInputEncoding() {
+        throw operationNotSupported();
+    }
+
+    public String getXmlEncoding() {
+        throw operationNotSupported();
+    }
+
+    public boolean getXmlStandalone() {
+        throw operationNotSupported();
+    }
+
+    public void setXmlStandalone(boolean b) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public String getXmlVersion() {
+        throw operationNotSupported();
+    }
+
+    public void setXmlVersion(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public boolean getStrictErrorChecking() {
+        throw operationNotSupported();
+    }
+
+    public void setStrictErrorChecking(boolean b) {
+        throw operationNotSupported();
+    }
+
+    public String getDocumentURI() {
+        throw operationNotSupported();
+    }
+
+    public void setDocumentURI(String string) {
+        throw operationNotSupported();
+    }
+
+    public Node adoptNode(Node node) throws DOMException {
+        throw operationNotSupported();
+    }
+
+    public DOMConfiguration getDomConfig() {
+        throw operationNotSupported();
+    }
+
+    public void normalizeDocument() {
+        throw operationNotSupported();
+    }
+
+    public Node renameNode(Node node, String string, String string1) throws DOMException {
+        return null;
+    }
+    // end DOM level 3
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,55 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.List;
+
+public class SimpleNodeList implements NodeList {
+
+    private Log log = LogFactory.getLog(SimpleNodeList.class);
+
+    private List<Node> nodes;
+
+    public SimpleNodeList(List<Node> nodes) {
+        this.nodes = nodes;
+    }
+
+    public int getLength() {
+        if (log.isTraceEnabled())
+            log.trace("getLength: " + nodes.size());
+        return nodes.size();
+    }
+
+    public Node item(int i) {
+        log.trace("getItem: " + i);
+        return nodes.get(i);
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer("SimpleNodeList: [");
+        for (int i = 0; i < getLength(); i++)
+            sb.append(item(i).getNodeName() + ',');
+        sb.append("]");
+        return sb.toString();
+    }
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java Thu Jul 20 10:23:12 2006
@@ -26,12 +26,15 @@
 /**
  * 
  */
-public class SimpleTextNode extends DefaultAdapterNode implements Text, AdapterNode {
+public class SimpleTextNode extends AbstractAdapterNode implements Node, Text {
 
-    public SimpleTextNode(DOMAdapter rootAdapter, AdapterNode parent, String propertyName, Object value) {
-        super(rootAdapter, parent, propertyName, value);
+    public SimpleTextNode(AdapterFactory rootAdapterFactory, AdapterNode parent, String propertyName, Object value) {
+        setContext(rootAdapterFactory, parent, propertyName, value);
     }
 
+    protected String getStringValue() {
+        return getPropertyValue().toString();
+    }
 
     public void setData(String string) throws DOMException {
         throw new StrutsException("Operation not supported");
@@ -81,7 +84,19 @@
         return getStringValue().substring(beginIndex, endIndex);
     }
 
-    private String getStringValue() {
-        return getValue().toString();
+    // DOM level 3
+
+    public boolean isElementContentWhitespace() {
+        throw operationNotSupported();
+    }
+
+    public String getWholeText() {
+        throw operationNotSupported();
     }
+
+    public Text replaceWholeText(String string) throws DOMException {
+        throw operationNotSupported();
+    }
+    // end DOM level 3
+
 }

Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java?rev=423995&view=auto
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java (added)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java Thu Jul 20 10:23:12 2006
@@ -0,0 +1,121 @@
+/*
+ * $Id: AdapterNode.java 418521 2006-07-01 23:36:50Z mrdon $
+ *
+ * Copyright 2006 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.struts2.views.xslt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.StrutsException;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.io.IOException;
+
+import com.opensymphony.util.XMLUtils;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * StringAdapter adapts a Java String value to a DOM Element with the specified
+ * property name containing the String's text.
+ * e.g. a property <pre>String getFoo() { return "My Text!"; }</pre>
+ * will appear in the result DOM as:
+ * <foo>MyText!</foo>
+ *
+ * Subclasses may override the getStringValue() method in order to use StringAdapter
+ * as a simplified custom XML adapter for Java types.  A subclass can enable XML
+ * parsing of the value string via the setParseStringAsXML() method and then
+ * override getStringValue() to return a String containing the custom formatted XML.
+ *
+ */
+public class StringAdapter extends AbstractAdapterElement {
+
+    private Log log = LogFactory.getLog(this.getClass());
+    boolean parseStringAsXML;
+
+    public StringAdapter() {
+    }
+
+    public StringAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, String value) {
+        setContext(adapterFactory, parent, propertyName, value);
+    }
+
+    /**
+     * Get the object to be adapted as a String value.
+     * <p/>
+     * This method can be overridden by subclasses that wish to use StringAdapter
+     * as a simplified customizable XML adapter for Java types. A subclass can
+     * enable parsing of the value string as containing XML text via the
+     * setParseStringAsXML() method and then override getStringValue() to return a
+     * String containing the custom formatted XML.
+     */
+    protected String getStringValue() {
+        return getPropertyValue().toString();
+    }
+
+    protected List<Node> buildChildAdapters() {
+        Node node;
+        if (getParseStringAsXML()) {
+            log.debug("parsing string as xml: " + getStringValue());
+            // Parse the String to a DOM, then proxy that as our child
+            try {
+                node = XMLUtils.parse(getStringValue());
+            } catch (ParserConfigurationException e) {
+                throw new StrutsException(e);
+            } catch (IOException e) {
+                throw new StrutsException(e);
+            } catch (SAXException e) {
+                throw new StrutsException(e);
+            }
+            node = getAdapterFactory().proxyNode(this, node);
+        } else {
+            log.debug("using string as is: " + getStringValue());
+            // Create a Text node as our child
+            node = new SimpleTextNode(getAdapterFactory(), this, "text", getStringValue());
+        }
+
+        List<Node> children = new ArrayList<Node>();
+        children.add(node);
+        return children;
+    }
+
+    /**
+     * Is this StringAdapter to interpret its string values as containing
+     * XML Text?
+     *
+     * @see #setParseStringAsXML(boolean)
+     */
+    public boolean getParseStringAsXML() {
+        return parseStringAsXML;
+    }
+
+    /**
+     * When set to true the StringAdapter will interpret its String value
+     * as containing XML text and parse it to a DOM Element.  The new DOM
+     * Element will be a child of this String element. (i.e. wrapped in an
+     * element of the property name specified for this StringAdapter).
+     *
+     * @param parseStringAsXML
+     * @see #getParseStringAsXML()
+     */
+    public void setParseStringAsXML(boolean parseStringAsXML) {
+        this.parseStringAsXML = parseStringAsXML;
+    }
+
+}

Propchange: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Re: svn commit: r423995 [1/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt /

Posted by Ted Husted <hu...@apache.org>.
There's a link on the licenses page.

* http://apache.org/licenses/

It's the same one that committers file.

-Ted.

On 7/24/06, Rainer Hermanns <he...@aixcept.de> wrote:
> Wendy, Ted,
>
> I will ask Pat to send in a CLA. Which form does he need to sign?
> Can you point me to the required CLA form please?
>
> tia,
> Rainer
>
> > On 7/22/06, Wendy Smoak <ws...@gmail.com> wrote:
> >> > URL: http://svn.apache.org/viewvc?rev=423995&view=rev
> >> > Log:
> >> > XSLT Views + XML Mapping + HashMap support
> >> > o backport of new XSLT support from WW-2.2.3
> >> > Issue number:  WW-492
> >> > Obtained from:
> >> > Submitted by:  Pat Niemeyer
> >>
> >> This looks like a lot of new code. Do we need (or have) a contributor
> >> agreement for it?
> >
> > +1
> >
> > I don't see a ASF Contributors License Agreement on file for Pat
> > Niemeyer. We should ask that one be filed, so that we have providence
> > for the code.
> >
> > * http://apache.org/licenses/
> >
> > We don't always require CLAs for incidental patches, but this appears
> > to be a contribution spanning several classes.
> >
> > -Ted.
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
> > For additional commands, e-mail: dev-help@struts.apache.org
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
> For additional commands, e-mail: dev-help@struts.apache.org
>
>


-- 
HTH, Ted.
* http://www.husted.com/struts/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: svn commit: r423995 [1/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt /

Posted by Rainer Hermanns <he...@aixcept.de>.
Wendy, Ted,

I will ask Pat to send in a CLA. Which form does he need to sign?
Can you point me to the required CLA form please?

tia,
Rainer

> On 7/22/06, Wendy Smoak <ws...@gmail.com> wrote:
>> > URL: http://svn.apache.org/viewvc?rev=423995&view=rev
>> > Log:
>> > XSLT Views + XML Mapping + HashMap support
>> > o backport of new XSLT support from WW-2.2.3
>> > Issue number:  WW-492
>> > Obtained from:
>> > Submitted by:  Pat Niemeyer
>>
>> This looks like a lot of new code. Do we need (or have) a contributor
>> agreement for it?
>
> +1
>
> I don't see a ASF Contributors License Agreement on file for Pat
> Niemeyer. We should ask that one be filed, so that we have providence
> for the code.
>
> * http://apache.org/licenses/
>
> We don't always require CLAs for incidental patches, but this appears
> to be a contribution spanning several classes.
>
> -Ted.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
> For additional commands, e-mail: dev-help@struts.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: svn commit: r423995 [1/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/

Posted by Ted Husted <hu...@apache.org>.
On 7/22/06, Wendy Smoak <ws...@gmail.com> wrote:
> > URL: http://svn.apache.org/viewvc?rev=423995&view=rev
> > Log:
> > XSLT Views + XML Mapping + HashMap support
> > o backport of new XSLT support from WW-2.2.3
> > Issue number:  WW-492
> > Obtained from:
> > Submitted by:  Pat Niemeyer
>
> This looks like a lot of new code. Do we need (or have) a contributor
> agreement for it?

+1

I don't see a ASF Contributors License Agreement on file for Pat
Niemeyer. We should ask that one be filed, so that we have providence
for the code.

* http://apache.org/licenses/

We don't always require CLAs for incidental patches, but this appears
to be a contribution spanning several classes.

-Ted.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: svn commit: r423995 [1/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/

Posted by Wendy Smoak <ws...@gmail.com>.
On 7/20/06, hermanns@apache.org <he...@apache.org> wrote:
> Author: hermanns
> Date: Thu Jul 20 10:23:12 2006
> New Revision: 423995
>
> URL: http://svn.apache.org/viewvc?rev=423995&view=rev
> Log:
> XSLT Views + XML Mapping + HashMap support
> o backport of new XSLT support from WW-2.2.3
> Issue number:  WW-492
> Obtained from:
> Submitted by:  Pat Niemeyer

This looks like a lot of new code. Do we need (or have) a contributor
agreement for it?

-- 
Wendy

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org