001 /*
002 * Copyright 2005 John G. Wilson
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017
018 package groovy.util.slurpersupport;
019
020 import groovy.lang.Closure;
021 import groovy.lang.GroovyObject;
022 import groovy.lang.GroovyRuntimeException;
023
024 import java.io.IOException;
025 import java.io.Writer;
026 import java.util.Iterator;
027 import java.util.Map;
028
029 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
030
031 /**
032 * @author John Wilson
033 */
034
035 public class NodeChild extends GPathResult {
036 private final Node node;
037
038 public NodeChild(final Node node, final GPathResult parent, final String namespacePrefix, final Map namespaceTagHints) {
039 super(parent, node.name(), namespacePrefix, namespaceTagHints);
040 this.node = node;
041 }
042
043 public NodeChild(final Node node, final GPathResult parent, final Map namespaceTagHints) {
044 this(node, parent, "*", namespaceTagHints);
045 }
046
047 public int size() {
048 return 1;
049 }
050
051 public String text() {
052 return this.node.text();
053 }
054
055 public GPathResult parents() {
056 // TODO Auto-generated method stub
057 throw new GroovyRuntimeException("parents() not implemented yet");
058 }
059
060 public Iterator iterator() {
061 return new Iterator() {
062 private boolean hasNext = true;
063
064 public boolean hasNext() {
065 return this.hasNext;
066 }
067
068 public Object next() {
069 try {
070 return (this.hasNext) ? NodeChild.this : null;
071 } finally {
072 this.hasNext = false;
073 }
074 }
075
076 public void remove() {
077 throw new UnsupportedOperationException();
078 }
079 };
080 }
081
082 public Iterator nodeIterator() {
083 return new Iterator() {
084 private boolean hasNext = true;
085
086 public boolean hasNext() {
087 return this.hasNext;
088 }
089
090 public Object next() {
091 try {
092 return (this.hasNext) ? NodeChild.this.node : null;
093 } finally {
094 this.hasNext = false;
095 }
096 }
097
098 public void remove() {
099 throw new UnsupportedOperationException();
100 }
101 };
102 }
103
104 public Object getAt(final int index) {
105 if (index == 0) {
106 return node;
107 } else {
108 throw new ArrayIndexOutOfBoundsException(index);
109 }
110 }
111
112 public Map attributes() {
113 return this.node.attributes();
114 }
115
116 public Iterator childNodes() {
117 return this.node.childNodes();
118 }
119
120 public GPathResult find(final Closure closure) {
121 if (DefaultTypeTransformation.castToBoolean(closure.call(new Object[]{this.node}))) {
122 return this;
123 } else {
124 return new NoChildren(this, "", this.namespaceTagHints);
125 }
126 }
127
128 public GPathResult findAll(final Closure closure) {
129 return find(closure);
130 }
131
132 public void build(final GroovyObject builder) {
133 this.node.build(builder, this.namespaceMap, this.namespaceTagHints);
134 }
135
136 public Writer writeTo(final Writer out) throws IOException {
137 return this.node.writeTo(out);
138 }
139
140 protected void replaceNode(final Closure newValue) {
141 this.node.replaceNode(newValue, this);
142 }
143
144 protected void replaceBody(final Object newValue) {
145 this.node.replaceBody(newValue);
146 }
147
148 protected void appendNode(final Object newValue) {
149 this.node.appendNode(newValue, this);
150 }
151 }