You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by ha...@apache.org on 2002/12/16 11:05:51 UTC

cvs commit: xml-cocoon2/src/java/org/apache/cocoon/components/modules/input XMLMetaModule.java

haul        2002/12/16 02:05:51

  Modified:    src/java/org/apache/cocoon/components/modules/input
                        XMLMetaModule.java
  Log:
    <action dev="CH" type="add">
      XMLMetaModule returns DocumentWrapper instead of String.
    </action>
  
  Revision  Changes    Path
  1.7       +117 -27   xml-cocoon2/src/java/org/apache/cocoon/components/modules/input/XMLMetaModule.java
  
  Index: XMLMetaModule.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/modules/input/XMLMetaModule.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XMLMetaModule.java	5 Dec 2002 10:01:04 -0000	1.6
  +++ XMLMetaModule.java	16 Dec 2002 10:05:51 -0000	1.7
  @@ -50,13 +50,26 @@
   */
   package org.apache.cocoon.components.modules.input;
   
  -import org.apache.avalon.framework.configuration.Configuration;
  -import org.apache.avalon.framework.configuration.ConfigurationException;
  -
   import java.util.Iterator;
   import java.util.Map;
  +import java.util.HashMap;
  +import java.util.SortedSet;
  +import java.util.TreeSet;
   import java.util.Vector;
   
  +import org.apache.avalon.framework.component.Component;
  +import org.apache.avalon.framework.configuration.Configuration;
  +import org.apache.avalon.framework.configuration.ConfigurationException;
  +
  +import org.apache.cocoon.xml.dom.DOMUtil;
  +import org.apache.cocoon.xml.dom.DocumentWrapper;
  +import org.apache.cocoon.environment.ObjectModelHelper;
  +import org.apache.cocoon.environment.Request;
  +
  +import org.w3c.dom.Document;
  +import org.w3c.dom.Element;
  +import org.w3c.dom.Node;
  +
   /** 
    * Meta module that obtains values from other module and returns all
    * parameters as XML.
  @@ -97,8 +110,7 @@
    *   &lt;/my-root&gt;
    * </pre>
    *
  - * <p>Should produce Objects that are XMLizable and Document one
  - * day. Currently, produces only Strings.</p>
  + * <p>Produces Objects of type {@link org.apache.cocoon.xml.dom.DocumentWrapper DocumentWrapper}</p>
    *
    * @author <a href="mailto:haul@informatik.tu-darmstadt.de">Christian Haul</a>
    * @version CVS $Id$
  @@ -109,6 +121,9 @@
       protected String ignore = null;
       protected String use = null;
       protected String strip = null;
  +    protected Object config = null;
  +
  +    protected static final String CACHE_OBJECT_NAME = "org.apache.cocoon.component.modules.input.XMLMetaModule";
   
       final static Vector returnNames;
       static {
  @@ -126,6 +141,7 @@
           this.ignore = this.inputConf.getAttribute("ignore",this.ignore);
           this.use = this.inputConf.getAttribute("use",this.use);
           this.strip = this.inputConf.getAttribute("strip",this.strip);
  +        this.config = config;
       }
   
   
  @@ -145,6 +161,7 @@
               return null;
           }
   
  +
           // obtain correct configuration objects
           // default vs dynamic
           Configuration inputConfig = null;
  @@ -164,41 +181,114 @@
               }
           }
   
  +        // see whether the Document is already stored as request
  +        // attribute and return that
  +        Request request = ObjectModelHelper.getRequest(objectModel);
  +        Map cache = (Map) request.getAttribute(CACHE_OBJECT_NAME);
  +        Object key = (modeConf != null ? modeConf : this.config);
  +        Document doc = null;
  +
  +        if (cache != null && cache.containsKey(key)) {
  +            doc = (Document) cache.get(key);
  +            if (getLogger().isDebugEnabled())
  +                getLogger().debug("using cached copy "+doc);
  +            return doc;
  +        }
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("no cached copy "+cache+" / "+key);
  +
  +
  +        // get InputModule and all attribute names
           InputModule input = null;
           if (inputName != null) input = obtainModule(inputName);
   
  -        StringBuffer sb = new StringBuffer();
  -        sb.append('<').append(rootName).append('>');
  -
           Iterator names = getNames(objectModel, 
                                     this.input, this.defaultInput, this.inputConf,
                                     input, inputName, inputConfig);
  +
  +        // first, sort all attribute names that the DOM can be created in one go
  +        // while doing so, remove unwanted attributes
  +        SortedSet set = new TreeSet();
  +        String aName = null;
           while (names.hasNext()){
  -            String attribute = (String) names.next();
  -            if ((use == null || attribute.startsWith(use)) &&
  -                (ignore == null || !attribute.startsWith(ignore))) {
  -                Object[] values = getValues(attribute, objectModel,
  -                                            this.input, this.defaultInput, this.inputConf,
  -                                            input, inputName, inputConfig);
  -
  -                if (strip != null && attribute.startsWith(strip)) 
  -                    attribute = attribute.substring(strip.length());
  -                sb.append("<item name=\"").append(attribute).append("\">");
  -                if (values.length == 1) {
  -                    sb.append(values[0]);
  -                } else {
  -                    for (int i=0;i<values.length;i++){
  -                        sb.append("<value>").append(values[i]).append("</value>");
  +            aName = (String) names.next();
  +            if ((use == null || aName.startsWith(use)) &&
  +                (ignore == null || !aName.startsWith(ignore))) {
  +                set.add(aName);
  +            }
  +        }
  +
  +        try {
  +            names = set.iterator();
  +            
  +            // create new document and append root node
  +            doc = DOMUtil.createDocument();
  +            Element elem = doc.createElement(rootName);
  +            doc.appendChild(elem);
  +
  +            while (names.hasNext()){
  +                aName = (String) names.next();
  +                // obtain values from input module
  +                Object[] value = getValues(aName, objectModel,
  +                                           this.input, this.defaultInput, this.inputConf,
  +                                           input, inputName, inputConfig);
  +
  +                // strip unwanted prefix from attribute name if present
  +                if (strip != null && aName.startsWith(strip)) 
  +                    aName = aName.substring(strip.length());
  +
  +                if (value.length > 0) {
  +                    // add new node from xpath 
  +                    // (since the names are in a set, the node cannot exist already)
  +                    Node node = DOMUtil.selectSingleNode(doc.getDocumentElement(), aName);
  +                    node.appendChild( node.getOwnerDocument().createTextNode(value[0].toString()));
  +
  +                    if (value.length > 1) {
  +                        // if more than one value was obtained, append
  +                        // further nodes (same name)
  +
  +                        // isolate node name, selection expressions
  +                        // "[...]" may not be part of it
  +                        int endPos = aName.length() - (aName.endsWith("/") ? 1 : 0);
  +                        int startPos = aName.lastIndexOf("/", endPos) +1;
  +                        String nodeName = aName.substring(startPos, endPos);
  +                        if (nodeName.indexOf("[") != -1) {
  +                            endPos = nodeName.lastIndexOf("]");
  +                            startPos = nodeName.indexOf("[") +1;
  +                            nodeName = nodeName.substring(startPos, endPos);
  +                        }
  +
  +                        // append more nodes
  +                        Node parent = node.getParentNode();
  +                        for (int i = 1; i < value.length; i++) {
  +                            Node newNode = parent.getOwnerDocument().createElementNS(null, nodeName);
  +                            parent.appendChild( newNode );
  +                            newNode.appendChild( newNode.getOwnerDocument().createTextNode(value[i].toString()));
  +                        }
                       }
                   }
  -                sb.append("</item>");
               }
  +        } catch (Exception e) {
  +            throw new ConfigurationException(e.getMessage());
           }
  +
           if (input != null) releaseModule(input);
   
  -        sb.append('<').append('/').append(rootName).append('>');
  +        // create a wrapped instance that is XMLizable
  +        doc = new DocumentWrapper(doc);
   
  -        return sb.toString();        
  +        // store Document as request attribute
  +        if (cache == null)
  +            cache = new HashMap();
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("no cached copy "+cache+" / "+key);
  +        cache.put(key, doc);
  +        request.setAttribute(CACHE_OBJECT_NAME,cache);
  +        
  +        
  +        if (getLogger().isDebugEnabled())
  +            getLogger().debug("returning "+doc.toString());
  +        return doc;
       }
   
   
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     webmaster@xml.apache.org
To unsubscribe, e-mail:          cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org