001    /**
002     * 
003     * Copyright 2005 LogicBlaze, Inc. http://www.logicblaze.com
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    package groovy.util;
019    
020    import groovy.xml.QName;
021    
022    import java.util.ArrayList;
023    import java.util.Collection;
024    import java.util.Iterator;
025    
026    /**
027     * A List implementation which is returned by queries on a {@link Node}
028     * which provides some XPath like helper methods for GPath.
029     */
030    public class NodeList extends ArrayList {
031    
032        public NodeList() {
033        }
034    
035        public NodeList(Collection collection) {
036            super(collection);
037        }
038    
039        public NodeList(int size) {
040            super(size);
041        }
042        
043        /**
044         * Provides lookup of elements by non-namespaced name.
045         *
046         * @return the nodes of interest which match name
047         * @param name the name or shortcut key for nodes of interest
048         */
049        public NodeList getAt(String name) {
050            NodeList answer = new NodeList();
051            for (Iterator iter = iterator(); iter.hasNext();) {
052                Object child = iter.next();
053                if (child instanceof Node) {
054                    Node childNode = (Node) child;
055                    Object temp = childNode.get(name);
056                    if (temp instanceof Collection) {
057                        answer.addAll((Collection) temp);
058                    }
059                    else {
060                        answer.add(temp);
061                    }
062                }
063            }
064            return answer;
065        }
066    
067        /**
068         * Provides lookup of elements by QName.
069         *
070         * @return the nodes of interest which match name
071         * @param name the name or shortcut key for nodes of interest
072         */
073        public NodeList getAt(QName name) {
074            NodeList answer = new NodeList();
075            for (Iterator iter = iterator(); iter.hasNext();) {
076                Object child = iter.next();
077                if (child instanceof Node) {
078                    Node childNode = (Node) child;
079                    NodeList temp = childNode.getAt(name);
080                    answer.addAll(temp);
081                }
082            }
083            return answer;
084        }
085    
086        /**
087         * Returns the text value of all of the elements in the collection.
088         * 
089         * @return the text value of all the elements in the collection or null
090         */
091        public String text() {
092            String previousText = null;
093            StringBuffer buffer = null;
094            for (Iterator iter = this.iterator(); iter.hasNext();) {
095                Object child = iter.next();
096                String text = null;
097                if (child instanceof String) {
098                    text = (String) child;
099                }
100                else if (child instanceof Node) {
101                    text = ((Node) child).text();
102                }
103                if (text != null) {
104                    if (previousText == null) {
105                        previousText = text;
106                    }
107                    else {
108                        if (buffer == null) {
109                            buffer = new StringBuffer();
110                            buffer.append(previousText);
111                        }
112                        buffer.append(text);
113                    }
114                }
115            }
116            if (buffer != null) {
117                return buffer.toString();
118            }
119            if (previousText != null) {
120                return previousText;
121            }
122            return "";
123        }
124    }