View Javadoc

    1   /*
    2    * Copyright 2005 John G. Wilson
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17
    18  package groovy.util.slurpersupport;
    19
    20  import groovy.lang.Buildable;
    21  import groovy.lang.Closure;
    22  import groovy.lang.GroovyObject;
    23  import groovy.lang.GroovyRuntimeException;
    24
    25  import java.io.IOException;
    26  import java.io.Writer;
    27  import java.util.Iterator;
    28  import java.util.Map;
    29
    30  import org.codehaus.groovy.runtime.InvokerHelper;
    31
    32  /***
    33   * @author John Wilson
    34   *
    35   */
    36
    37  class NodeChildren extends GPathResult {
    38    private int size = -1;
    39
    40    /***
    41     * @param parent
    42     * @param name
    43     * @param namespacePrefix
    44     */
    45    public NodeChildren(final GPathResult parent, final String name, final String namespacePrefix, final Map namespaceTagHints) {
    46      super(parent, name, namespacePrefix, namespaceTagHints);
    47    }
    48
    49    /***
    50     * @param parent
    51     * @param name
    52     */
    53    public NodeChildren(final GPathResult parent, final String name, final Map namespaceTagHints) {
    54      this(parent, name, "*", namespaceTagHints);
    55    }
    56
    57    /***
    58     * @param parent
    59     */
    60    public NodeChildren(final GPathResult parent, final Map namespaceTagHints) {
    61      this(parent, "*", namespaceTagHints);
    62    }
    63
    64    /* (non-Javadoc)
    65     * @see org.codehaus.groovy.sandbox.util.GPathResult#childNodes()
    66     */
    67    public Iterator childNodes() {
    68      return new Iterator() {
    69                  private final Iterator iter = NodeChildren.this.parent.childNodes();
    70                  private Iterator childIter = nextChildIter();
    71
    72                    /* (non-Javadoc)
    73                     * @see java.util.Iterator#hasNext()
    74                     */
    75                    public boolean hasNext() {
    76                      return this.childIter != null;
    77                    }
    78
    79                    /* (non-Javadoc)
    80                     * @see java.util.Iterator#next()
    81                     */
    82                    public Object next() {
    83                      while (this.childIter != null) {
    84                        try {
    85                          if (this.childIter.hasNext()) {
    86                            return this.childIter.next();
    87                          }
    88                        } finally {
    89                          if (!this.childIter.hasNext()) {
    90                            this.childIter = nextChildIter();
    91                          }
    92                        }
    93                      }
    94
    95                      return null;
    96                    }
    97
    98                    /* (non-Javadoc)
    99                     * @see java.util.Iterator#remove()
    100                    */
    101                   public void remove() {
    102                     throw new UnsupportedOperationException();
    103                   }
    104
    105                   /***
    106                    * @return
    107                    */
    108                   private Iterator nextChildIter() {
    109                     while (this.iter.hasNext()) {
    110                     final Node node = (Node)this.iter.next();
    111
    112                       if (NodeChildren.this.name.equals(node.name())) {
    113                       final Iterator result = node.childNodes();
    114
    115                         if (result.hasNext()) {
    116                           if ("*".equals(NodeChildren.this.namespacePrefix) ||
    117                              ("".equals(NodeChildren.this.namespacePrefix) && "".equals(node.namespaceURI())) ||
    118                              node.namespaceURI().equals(NodeChildren.this.namespaceMap.get(NodeChildren.this.namespacePrefix)))
    119                           {
    120                             return result;
    121                           }
    122                         }
    123                       }
    124                     }
    125
    126                     return null;
    127                   }
    128     };
    129   }
    130
    131   /* (non-Javadoc)
    132    * @see org.codehaus.groovy.sandbox.util.slurpersupport.GPathResult#iterator()
    133    */
    134   public Iterator iterator() {
    135     return new Iterator() {
    136       final Iterator iter = nodeIterator();
    137
    138       public boolean hasNext() {
    139         return this.iter.hasNext();
    140       }
    141
    142       public Object next() {
    143         return new NodeChild((Node)this.iter.next(), NodeChildren.this.parent, NodeChildren.this.namespaceTagHints);
    144       }
    145
    146       public void remove() {
    147         throw new UnsupportedOperationException();
    148       }
    149     };
    150   }
    151
    152   /* (non-Javadoc)
    153    * @see org.codehaus.groovy.sandbox.util.GPathResult#iterator()
    154    */
    155   public Iterator nodeIterator() {
    156     if ("*".equals(this.name)) {
    157       return this.parent.childNodes();
    158     } else {
    159       return new NodeIterator(this.parent.childNodes()) {
    160                     /* (non-Javadoc)
    161                      * @see org.codehaus.groovy.sandbox.util.slurpersupport.NodeIterator#getNextNode(java.util.Iterator)
    162                      */
    163                     protected Object getNextNode(Iterator iter) {
    164                       while (iter.hasNext()) {
    165                         final Node node = (Node)iter.next();
    166
    167                           if (NodeChildren.this.name.equals(node.name())) {
    168                             if ("*".equals(NodeChildren.this.namespacePrefix) ||
    169                                 ("".equals(NodeChildren.this.namespacePrefix) && "".equals(node.namespaceURI())) ||
    170                                 node.namespaceURI().equals(NodeChildren.this.namespaceMap.get(NodeChildren.this.namespacePrefix)))
    171                              {
    172                                return node;
    173                              }
    174                           }
    175                         }
    176
    177                         return null;
    178                    }
    179                   };
    180     }
    181   }
    182
    183   /* (non-Javadoc)
    184    * @see org.codehaus.groovy.sandbox.util.GPathResult#parents()
    185    */
    186   public GPathResult parents() {
    187     // TODO Auto-generated method stub
    188     throw new GroovyRuntimeException("parents() not implemented yet");
    189   }
    190
    191   /* (non-Javadoc)
    192    * @see org.codehaus.groovy.sandbox.util.GPathResult#size()
    193    */
    194   public synchronized int size() {
    195     if (this.size == -1) {
    196     final Iterator iter = nodeIterator();
    197
    198       this.size = 0;
    199       while (iter.hasNext()) {
    200         iter.next();
    201         this.size++;
    202       }
    203     }
    204
    205     return this.size;
    206   }
    207
    208   /* (non-Javadoc)
    209    * @see org.codehaus.groovy.sandbox.util.GPathResult#text()
    210    */
    211   public String text() {
    212   final StringBuffer buf = new StringBuffer();
    213   final Iterator iter = nodeIterator();
    214
    215     while (iter.hasNext()) {
    216       buf.append(((Node)iter.next()).text());
    217     }
    218
    219     return buf.toString();
    220   }
    221
    222   /* (non-Javadoc)
    223    * @see org.codehaus.groovy.sandbox.util.slurpersupport.GPathResult#find(groovy.lang.Closure)
    224    */
    225   public GPathResult find(final Closure closure) {
    226   final Iterator iter = iterator();
    227
    228     while (iter.hasNext()) {
    229     final Object node = iter.next();
    230
    231       if (InvokerHelper.asBool(closure.call(new Object[]{node}))) {
    232         return (GPathResult)node;
    233       }
    234     }
    235
    236     return new NoChildren(this, this.name, this.namespaceTagHints);
    237   }
    238
    239   /* (non-Javadoc)
    240    * @see org.codehaus.groovy.sandbox.util.slurpersupport.GPathResult#findAll(groovy.lang.Closure)
    241    */
    242   public GPathResult findAll(final Closure closure) {
    243     return new FilteredNodeChildren(this, closure, this.namespaceTagHints);
    244   }
    245
    246   /* (non-Javadoc)
    247    * @see org.codehaus.groovy.sandbox.markup.Buildable#build(groovy.lang.GroovyObject)
    248    */
    249   public void build(final GroovyObject builder) {
    250   final Iterator iter = nodeIterator();
    251
    252     while (iter.hasNext()) {
    253     final Object next = iter.next();
    254
    255       if (next instanceof Buildable) {
    256         ((Buildable)next).build(builder);
    257       } else {
    258         ((Node)next).build(builder, this.namespaceMap, this.namespaceTagHints);
    259       }
    260     }
    261   }
    262
    263   /* (non-Javadoc)
    264    * @see groovy.lang.Writable#writeTo(java.io.Writer)
    265    */
    266   public Writer writeTo(final Writer out) throws IOException {
    267   final Iterator iter = nodeIterator();
    268
    269     while (iter.hasNext()) {
    270       ((Node)iter.next()).writeTo(out);
    271     }
    272
    273     return out;
    274   }
    275 }