001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.sdm.spa;
031
032import java.io.BufferedReader;
033import java.io.ByteArrayInputStream;
034import java.io.StringReader;
035import java.util.Iterator;
036import java.util.LinkedList;
037import java.util.List;
038import java.util.StringTokenizer;
039import java.util.Vector;
040
041import javax.xml.parsers.DocumentBuilder;
042import javax.xml.parsers.DocumentBuilderFactory;
043
044import org.w3c.dom.Document;
045import org.w3c.dom.Element;
046import org.w3c.dom.Node;
047
048/**
049 * @author zcheng
050 * 
051 *         To change this generated comment edit the template variable
052 *         "typecomment": Window>Preferences>Java>Templates. To enable and
053 *         disable the creation of type comments go to
054 *         Window>Preferences>Java>Code Generation.
055 */
056public class XMLUtil {
057
058        /**
059         * Constructor for XMLUtil.
060         */
061        public XMLUtil() {
062
063        }
064
065        private String getItemValue(String in, String path) {
066
067                Vector items = getItems(in, path);
068                if (items.size() > 0) {
069                        return (String) items.elementAt(0);
070                } else {
071                        return null;
072                }
073
074        }
075
076        public Vector getItems(String input, String xpath) {
077                Vector result = new Vector();
078                String res = "";
079                try {
080
081                        // Since we are not able to handle DTD types,
082                        // We will delete the head, any line that starts with <! will be
083                        // discarded.
084                        StringReader sr = new StringReader(input);
085                        BufferedReader br = new BufferedReader(sr);
086                        StringBuffer sb = new StringBuffer();
087                        String line;
088                        while ((line = br.readLine()) != null) {
089                                if (!line.trim().startsWith("<!"))
090                                        sb.append(line + "\n");
091                        }
092                        input = sb.toString();
093
094                        DocumentBuilderFactory factory = DocumentBuilderFactory
095                                        .newInstance();
096
097                        factory.setValidating(false);
098                        DocumentBuilder builder = factory.newDocumentBuilder();
099                        ByteArrayInputStream bis = new ByteArrayInputStream(input
100                                        .getBytes());
101
102                        Document document = builder.parse(bis);
103
104                        Element docElement;
105                        docElement = document.getDocumentElement();
106                        Element el = docElement;
107
108                        // here we will loop through the xpath
109                        StringTokenizer st = new StringTokenizer(xpath, "/");
110                        List items = null;
111                        String restpath = "";
112                        // skip the root
113                        if (st.hasMoreTokens())
114                                st.nextToken();
115
116                        while (st.hasMoreTokens()) {
117                                String val = st.nextToken();
118                                // We need to test whether currrent tag has
119                                // only one item or not.
120                                items = childElementList(el, val);
121                                if (items != null && items.size() > 1) {
122                                        // here we need to extract from the rest path
123                                        // Now we need to extract info from all items
124                                        while (st.hasMoreTokens()) {
125                                                restpath = restpath + "/" + st.nextToken();
126                                        }
127
128                                } else {
129                                        // only one item in the element
130                                        el = firstChildElement(el, val);
131                                }
132
133                        }
134                        // extract information from the rest paths
135                        if (items != null && items.size() > 0) {
136                                Iterator iter = items.iterator();
137                                while (iter.hasNext()) {
138                                        Element item = (Element) iter.next();
139                                        String value = extractItem(item, restpath);
140                                        if (value != null) {
141                                                res = res + value + ":";
142                                                // System.out.println(value);
143                                                result.add(value);
144                                        }
145                                }
146                        }
147
148                } catch (Exception e) {
149                        e.printStackTrace();
150                }
151
152                return result;
153        }
154
155        /**
156         * Method extractItem. Extract info according to the xpath from the element.
157         * 
158         * @param el
159         * @param xpath
160         * @return String
161         */
162        private String extractItem(Element el, String xpath) {
163                StringTokenizer st = new StringTokenizer(xpath, "/");
164                String result = null;
165                while (st.hasMoreTokens()) {
166                        String val = st.nextToken();
167                        el = firstChildElement(el, val);
168                }
169                result = elementValue(el);
170
171                return result;
172
173        }
174
175        /**
176         * Return the text (node value) of the first node under this, works best if
177         * normalized.
178         */
179        public static String elementValue(Element element) {
180                if (element == null)
181                        return null;
182                // make sure we get all the text there...
183                element.normalize();
184                Node textNode = element.getFirstChild();
185
186                if (textNode == null)
187                        return null;
188                // should be of type text
189                return textNode.getNodeValue();
190        }
191
192        /**
193         * Return a List of Element objects that have the given name and are
194         * immediate children of the given element; if name is null, all child
195         * elements will be included.
196         */
197        private List childElementList(Element element, String childElementName) {
198                if (element == null)
199                        return null;
200
201                List elements = new LinkedList();
202                Node node = element.getFirstChild();
203
204                if (node != null) {
205                        do {
206                                if (node.getNodeType() == Node.ELEMENT_NODE
207                                                && (childElementName == null || childElementName
208                                                                .equals(node.getNodeName()))) {
209                                        Element childElement = (Element) node;
210
211                                        elements.add(childElement);
212                                }
213                        } while ((node = node.getNextSibling()) != null);
214                }
215                return elements;
216        }
217
218        private Element firstChildElement(Element element, String childElementName) {
219                if (element == null)
220                        return null;
221                // get the first element with the given name
222                Node node = element.getFirstChild();
223
224                if (node != null) {
225                        do {
226                                if (node.getNodeType() == Node.ELEMENT_NODE
227                                                && (childElementName == null || childElementName
228                                                                .equals(node.getNodeName()))) {
229                                        Element childElement = (Element) node;
230
231                                        return childElement;
232                                }
233                        } while ((node = node.getNextSibling()) != null);
234                }
235                return null;
236        }
237
238}