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.DelegatingMetaClass;
23  import groovy.lang.GroovyObjectSupport;
24  import groovy.lang.MetaClass;
25  import groovy.lang.Writable;
26  
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.List;
31  import java.util.Map;
32  
33  
34  /***
35   * @author John Wilson
36   *
37   */
38  
39  public abstract class GPathResult extends GroovyObjectSupport implements Writable, Buildable {
40    protected final GPathResult parent;
41    protected final String name;
42    protected final String namespacePrefix;
43    protected final Map namespaceMap = new HashMap();
44    protected final Map namespaceTagHints;
45   
46    /***
47     * @param parent
48     * @param name
49     */
50    public GPathResult(final GPathResult parent, final String name, final String namespacePrefix, final Map namespaceTagHints) {
51      if (parent == null) {
52        // we are the top of the tree
53        this.parent = this;
54        this.namespaceMap.put("xml", "http://www.w3.org/XML/1998/namespace");  // The XML namespace is always defined
55      } else {
56        this.parent = parent;
57        this.namespaceMap.putAll(parent.namespaceMap);
58      }
59      this.name = name;
60      this.namespacePrefix = namespacePrefix;
61      this.namespaceTagHints = namespaceTagHints;
62      
63      setMetaClass(getMetaClass()); // wrap the standard MetaClass with the delegate
64    }
65  
66      /* (non-Javadoc)
67       * @see groovy.lang.GroovyObjectSupport#setMetaClass(groovy.lang.MetaClass)
68       */
69      public void setMetaClass(final MetaClass metaClass) {
70      final MetaClass newMetaClass = new DelegatingMetaClass(metaClass) {
71                                          /* (non-Javadoc)
72                                           * @see groovy.lang.DelegatingMetaClass#getAttribute(java.lang.Object, java.lang.String)
73                                           */
74                                          public Object getAttribute(Object object, String attribute) {
75                                              return GPathResult.this.getProperty("@" + attribute);
76                                          }
77                                      };
78  
79          super.setMetaClass(newMetaClass);
80      }
81  
82  public Object getProperty(final String property) {
83      if ("..".equals(property)) {
84        return parent();
85      } else if ("*".equals(property)){
86        return children();
87      } else if (property.startsWith("@")) {
88        if (property.indexOf(":") != -1) {
89        final int i = property.indexOf(":");
90  
91          return new Attributes(this, "@" + property.substring(i + 1), property.substring(1, i), this.namespaceTagHints);
92        } else {
93          return new Attributes(this, property, this.namespaceTagHints);
94        }
95      } else {
96        if (property.indexOf(":") != -1) {
97        final int i = property.indexOf(":");
98  
99          return new NodeChildren(this, property.substring(i + 1), property.substring(0, i), this.namespaceTagHints);
100       } else {
101         return new NodeChildren(this, property, this.namespaceTagHints);
102       }
103     }
104   }
105 
106   public String name() {
107     return this.name;
108   }
109 
110   public GPathResult parent() {
111     return this.parent;
112   }
113 
114   public GPathResult children() {
115     return new NodeChildren(this, this.namespaceTagHints);
116   }
117 
118   public String toString() {
119     return text();
120   }
121   
122   public GPathResult declareNamespace(final Map newNamespaceMapping) {
123     this.namespaceMap.putAll(newNamespaceMapping);
124     
125     return this; 
126   }
127   
128   /* (non-Javadoc)
129    * @see java.lang.Object#equals(java.lang.Object)
130    */
131   public boolean equals(Object obj) {
132     return text().equals(obj.toString());
133   }
134 
135   public Object getAt(final int index) {
136   final Iterator iter = iterator();
137   int count = 0;
138   
139   
140     while (iter.hasNext()) {
141       if (count++ == index) {
142         return iter.next();
143       } else {
144         iter.next();
145       }
146     }
147     
148     throw new ArrayIndexOutOfBoundsException(index);
149   }
150   
151   public List list() {
152   final Iterator iter = nodeIterator();
153   final List result = new LinkedList();
154   
155     while (iter.hasNext()) {
156       result.add(iter.next());
157     }
158     
159     return result;
160   }
161 
162   public abstract int size();
163   
164   public abstract String text();
165   
166   public abstract GPathResult parents();
167   
168   public abstract Iterator childNodes();
169   
170   public abstract Iterator iterator();
171   
172   public abstract GPathResult find(Closure closure);
173   
174   public abstract GPathResult findAll(Closure closure);
175   
176   public abstract Iterator nodeIterator();
177 }