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