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 }