Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2003-2008 the original author or authors.
   *
   * 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 groovy.util.slurpersupport;
 
 
 import java.io.Writer;
 import java.util.List;
 import java.util.Map;

Author(s):
John Wilson
 
 
 public class Node implements Writable {
     private final String name;
     private final Map attributes;
     private final Map attributeNamespaces;
     private final String namespaceURI;
     private final List children = new LinkedList();
     private final Stack replacementNodeStack = new Stack();
 
     public Node(final Node parentfinal String namefinal Map attributesfinal Map attributeNamespacesfinal String namespaceURI) {
         this. = name;
         this. = attributes;
         this. = attributeNamespaces;
         this. = namespaceURI;
     }
 
     public String name() {
         return this.;
     }
 
     public String namespaceURI() {
         return this.;
     }
 
     public Map attributes() {
         return this.;
     }
 
     public List children() {
         return this.;
     }
 
     public void addChild(final Object child) {
         this..add(child);
     }
 
     public void replaceNode(final Closure replacementClosurefinal GPathResult result) {
         this..push(new ReplacementNode() {
             public void build(final GroovyObject builderfinal Map namespaceMapfinal Map namespaceTagHints) {
                 final Closure c = (ClosurereplacementClosure.clone();
                 Node.this..pop(); // disable the replacement whilst the closure is being executed
                 c.setDelegate(builder);
                 c.call(new Object[]{result});
                 Node.this..push(this);
             }
         });
     }
 
 
     protected void replaceBody(final Object newValue) {
         this..clear();
         this..add(newValue);
     }
 
     protected void appendNode(final Object newValuefinal GPathResult result) {
         if (newValue instanceof Closure) {
             this..add(new ReplacementNode() {
                 public void build(final GroovyObject builderfinal Map namespaceMapfinal Map namespaceTagHints) {
                     final Closure c = (Closure) ((ClosurenewValue).clone();
                     c.setDelegate(builder);
                     c.call(new Object[]{result});
                 }
             });
         } else {
            this..add(newValue);
        }
    }
    /* (non-Javadoc)
    * @see org.codehaus.groovy.sandbox.util.slurpersupport.Node#text()
    */
    public String text() {
        final StringBuffer buff = new StringBuffer();
        final Iterator iter = this..iterator();
        while (iter.hasNext()) {
            final Object child = iter.next();
            if (child instanceof Node) {
                buff.append(((Nodechild).text());
            } else {
                buff.append(child);
            }
        }
        return buff.toString();
    }
    /* (non-Javadoc)
    * @see org.codehaus.groovy.sandbox.util.slurpersupport.Node#childNodes()
    */
    public Iterator childNodes() {
        return new Iterator() {
            private final Iterator iter = Node.this..iterator();
            private Object nextElementNodes = getNextElementNodes();
            public boolean hasNext() {
                return this. != null;
            }
            public Object next() {
                try {
                    return this.;
                } finally {
                    this. = getNextElementNodes();
                }
            }
            public void remove() {
                throw new UnsupportedOperationException();
            }
            private Object getNextElementNodes() {
                while (.hasNext()) {
                    final Object node = .next();
                    if (node instanceof Node) {
                        return node;
                    }
                }
                return null;
            }
        };
    }
    /* (non-Javadoc)
    * @see org.codehaus.groovy.sandbox.util.slurpersupport.Node#writeTo(java.io.Writer)
    */
    public Writer writeTo(final Writer outthrows IOException {
        if (this..empty()) {
            final Iterator iter = this..iterator();
            while (iter.hasNext()) {
                final Object child = iter.next();
                if (child instanceof Writable) {
                    ((Writablechild).writeTo(out);
                } else {
                    out.write(child.toString());
                }
            }
            return out;
        } else {
            return ((Writablethis..peek()).writeTo(out);
        }
    }
    public void build(final GroovyObject builderfinal Map namespaceMapfinal Map namespaceTagHints) {
        if (this..empty()) {
            final Closure rest = new Closure(null) {
                public Object doCall(final Object o) {
                    buildChildren(buildernamespaceMapnamespaceTagHints);
                    return null;
                }
            };
            if (this..length() == 0 && this..isEmpty()) {
                builder.invokeMethod(this.new Object[]{this.rest});
            } else {
                final List newTags = new LinkedList();
                builder.getProperty("mkp");
                final List namespaces = (Listbuilder.invokeMethod("getNamespaces"new Object[]{});
                final Map current = (Mapnamespaces.get(0);
                final Map pending = (Mapnamespaces.get(1);
                if (this..isEmpty()) {
                    builder.getProperty(getTagFor(this.currentpendingnamespaceMapnamespaceTagHintsnewTagsbuilder));
                    builder.invokeMethod(this.new Object[]{this.rest});
                } else {
                    final Map attributesWithNamespaces = new HashMap(this.);
                    final Iterator attrs = this..keySet().iterator();
                    while (attrs.hasNext()) {
                        final Object key = attrs.next();
                        final Object attributeNamespaceURI = this..get(key);
                        if (attributeNamespaceURI != null) {
                            attributesWithNamespaces.put(getTagFor(attributeNamespaceURIcurrentpendingnamespaceMapnamespaceTagHintsnewTagsbuilder) +
                                    "$" + keyattributesWithNamespaces.remove(key));
                        }
                    }
                    builder.getProperty(getTagFor(this.currentpendingnamespaceMapnamespaceTagHintsnewTagsbuilder));
                    builder.invokeMethod(this.new Object[]{attributesWithNamespacesrest});
                }
                // remove the new tags we had to define for this element
                if (!newTags.isEmpty()) {
                    final Iterator iter = newTags.iterator();
                    do {
                        pending.remove(iter.next());
                    } while (iter.hasNext());
                }
            }
        } else {
            ((ReplacementNodethis..peek()).build(buildernamespaceMapnamespaceTagHints);
        }
    }
    private static String getTagFor(final Object namespaceURIfinal Map current,
                                    final Map pendingfinal Map localfinal Map tagHints,
                                    final List newTagsfinal GroovyObject builder) {
        String tag = findNamespaceTag(pendingnamespaceURI); // look in the namespaces whose declaration has already been emitted
        if (tag == null) {
            tag = findNamespaceTag(currentnamespaceURI);  // look in the namespaces who will be declared at the next element
            if (tag == null) {
                // we have to declare the namespace - choose a tag
                tag = findNamespaceTag(localnamespaceURI);  // If the namespace has been decared in the GPath expression use that tag
                if (tag == null || tag.length() == 0) {
                    tag = findNamespaceTag(tagHintsnamespaceURI);  // If the namespace has been used in the parse documant use that tag
                }
                if (tag == null || tag.length() == 0) { // otherwise make up a new tag and check it has not been used before
                    int suffix = 0;
                    do {
                        final String posibleTag = "tag" + suffix++;
                        if (!pending.containsKey(posibleTag) && !current.containsKey(posibleTag) && !local.containsKey(posibleTag)) {
                            tag = posibleTag;
                        }
                    } while (tag == null);
                }
                final Map newNamespace = new HashMap();
                newNamespace.put(tagnamespaceURI);
                builder.getProperty("mkp");
                builder.invokeMethod("declareNamespace"new Object[]{newNamespace});
                newTags.add(tag);
            }
        }
        return tag;
    }
    private static String findNamespaceTag(final Map tagMapfinal Object namespaceURI) {
        if (tagMap.containsValue(namespaceURI)) {
            final Iterator entries = tagMap.entrySet().iterator();
            while (entries.hasNext()) {
                final Map.Entry entry = (Map.Entryentries.next();
                if (namespaceURI.equals(entry.getValue())) {
                    return (Stringentry.getKey();
                }
            }
        }
        return null;
    }
    private void buildChildren(final GroovyObject builderfinal Map namespaceMapfinal Map namespaceTagHints) {
        final Iterator iter = this..iterator();
        while (iter.hasNext()) {
            final Object child = iter.next();
            if (child instanceof Node) {
                ((Nodechild).build(buildernamespaceMapnamespaceTagHints);
            } else if (child instanceof Buildable) {
                ((Buildablechild).build(builder);
            } else {
                builder.getProperty("mkp");
                builder.invokeMethod("yield"new Object[]{child});
            }
        }
    }
New to GrepCode? Check out our FAQ X