001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028
029 package edu.wisc.ssec.mcidasv.util;
030
031 import java.util.ArrayList;
032 import java.util.List;
033
034 import org.w3c.dom.Attr;
035 import org.w3c.dom.Element;
036 import org.w3c.dom.NamedNodeMap;
037 import org.w3c.dom.Node;
038 import org.w3c.dom.NodeList;
039
040 /**
041 * A collection of utilities for XML..
042 *
043 */
044 public abstract class XmlUtil extends ucar.unidata.xml.XmlUtil {
045
046 /**
047 * Print all the attributes of the given node
048 *
049 * @param parent
050 */
051 public static void printNode(Node parent) {
052 if (parent==null) {
053 System.out.println("null node!");
054 return;
055 }
056 System.out.println(parent.getNodeName() + " node:");
057 NamedNodeMap attrs = parent.getAttributes();
058 for(int i = 0 ; i<attrs.getLength() ; i++) {
059 Attr attribute = (Attr)attrs.item(i);
060 System.out.println(" " + attribute.getName()+" = "+attribute.getValue());
061 }
062 }
063
064 /**
065 * Find all of the descendant elements of the given parent Node
066 * whose tag name.equals the given tag.
067 *
068 * @param parent The root of the xml dom tree to search.
069 * @param tag The tag name to match.
070 * @return The list of descendants that match the given tag.
071 */
072 public static List<String> findDescendantNamesWithSeparator(Node parent, String tag, String separator) {
073 List<String> found = new ArrayList<String>();
074 findDescendantNamesWithSeparator(parent, tag, "", separator, found);
075 return found;
076 }
077
078 /**
079 * Find all of the descendant elements of the given parent Node
080 * whose tag name equals the given tag.
081 *
082 * @param parent The root of the xml dom tree to search.
083 * @param tag The tag name to match.
084 * @param found The list of descendants that match the given tag.
085 */
086 private static void findDescendantNamesWithSeparator(Node parent, String tag, String descendants, String separator, List<String> found) {
087 if (parent instanceof Element) {
088 String elementName = ((Element)parent).getAttribute("name");
089 if (!elementName.isEmpty()) {
090 descendants += ((Element)parent).getAttribute("name");
091 }
092 if (parent.getNodeName().equals(tag)) {
093 found.add(descendants);
094 }
095 if (!elementName.isEmpty()) {
096 descendants += separator;
097 }
098 }
099 NodeList children = parent.getChildNodes();
100 for (int i = 0; i < children.getLength(); i++) {
101 Node child = children.item(i);
102 findDescendantNamesWithSeparator(child, tag, descendants, separator, found);
103 }
104 }
105
106 /**
107 * Find the element described by nameList (path)
108 *
109 * @param parent
110 * @param nameList
111 * @return
112 */
113 public static Element getElementAtNamedPath(Node parent, List<String>nameList) {
114 return getMakeElementAtNamedPath(parent, nameList, "", false);
115 }
116
117 /**
118 * Make the element described by nameList (path)
119 *
120 * @param parent
121 * @param nameList
122 * @return
123 */
124 public static Element makeElementAtNamedPath(Node parent, List<String>nameList, String tagname) {
125 return getMakeElementAtNamedPath(parent, nameList, tagname, true);
126 }
127
128 /**
129 * Find the element described by nameList (path)
130 *
131 * @param parent
132 * @param nameList
133 * @return
134 */
135 public static Element getMakeElementAtNamedPath(Node parent, List<String> nameList, String tagName, boolean makeNew) {
136 Element thisElement = null;
137 if (parent instanceof Element && !nameList.isEmpty()) {
138 for (int i=0; i < nameList.size(); i++) {
139 String thisName = nameList.get(i);
140 NodeList children = parent.getChildNodes();
141 boolean foundChild = false;
142 for (int j=0; j < children.getLength(); j++) {
143 Node child = children.item(j);
144 if (!(child instanceof Element)) continue;
145 if (XmlUtil.getAttribute(child, "name").equals(thisName)) {
146 if (i == nameList.size()-1) thisElement = (Element)child;
147 parent = child;
148 foundChild = true;
149 break;
150 }
151 }
152
153 // Didn't find it where we expected to. Create a new one.
154 if (makeNew && !foundChild && parent instanceof Element) {
155 try {
156 Element newElement = XmlUtil.create(tagName, (Element)parent);
157 newElement.setAttribute("name", thisName);
158 parent.appendChild(newElement);
159 parent = newElement;
160 thisElement = newElement;
161 } catch (Exception ex) {
162 System.err.println("Error making new " + tagName + " node named " + thisName);
163 break;
164 }
165 }
166 }
167 }
168 return thisElement;
169 }
170 }