View Javadoc
1   /*
2    * @(#)XMLParsing.java	1.6 05/11/17
3    * 
4    * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are met:
8    *
9    * -Redistribution of source code must retain the above copyright notice, this
10   *  list of conditions and the following disclaimer.
11   *
12   * -Redistribution in binary form must reproduce the above copyright notice,
13   *  this list of conditions and the following disclaimer in the documentation
14   *  and/or other materials provided with the distribution.
15   *
16   * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17   * be used to endorse or promote products derived from this software without
18   * specific prior written permission.
19   *
20   * This software is provided "AS IS," without a warranty of any kind. ALL
21   * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22   * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23   * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
24   * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25   * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26   * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27   * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28   * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29   * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30   * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31   *
32   * You acknowledge that this software is not designed, licensed or intended
33   * for use in the design, construction, operation or maintenance of any
34   * nuclear facility.
35   */
36  
37  package jnlp.sample.servlet;
38  
39  import org.w3c.dom.Attr;
40  import org.w3c.dom.Element;
41  import org.w3c.dom.NamedNodeMap;
42  import org.w3c.dom.Node;
43  import org.w3c.dom.Text;
44  
45  import java.util.ArrayList;
46  import java.util.List;
47  
48  /**
49   * Contains handy methods for looking up information
50   * stored in XMLNodes.
51   */
52  public class XMLParsing
53  {
54  
55      public static XMLNode convert( Node n )
56      {
57          if ( n == null )
58          {
59              return null;
60          }
61          else if ( n instanceof Text )
62          {
63              Text tn = (Text) n;
64              return new XMLNode( tn.getNodeValue() );
65          }
66          else if ( n instanceof Element )
67          {
68              Element en = (Element) n;
69  
70              XMLAttribute xmlatts = null;
71              NamedNodeMap attributes = en.getAttributes();
72              for ( int i = attributes.getLength() - 1; i >= 0; i-- )
73              {
74                  Attr ar = (Attr) attributes.item( i );
75                  xmlatts = new XMLAttribute( ar.getName(), ar.getValue(), xmlatts );
76              }
77  
78              // Convert childern
79              XMLNode thisNode = new XMLNode( en.getNodeName(), xmlatts, null, null );
80              ;
81              XMLNode last = null;
82              Node nn = en.getFirstChild();
83              while ( nn != null )
84              {
85                  if ( thisNode.getNested() == null )
86                  {
87                      last = convert( nn );
88                      thisNode.setNested( last );
89                  }
90                  else
91                  {
92                      XMLNode nnode = convert( nn );
93                      last.setNext( nnode );
94                      last = nnode;
95                  }
96                  last.setParent( thisNode );
97                  nn = nn.getNextSibling();
98              }
99  
100             return thisNode;
101         }
102         return null;
103     }
104 
105     /**
106      * Returns true if the path exists in the document, otherwise false
107      */
108     static public boolean isElementPath( XMLNode root, String path )
109     {
110         return findElementPath( root, path ) != null;
111     }
112 
113 
114     /**
115      * Returns a string describing the current location in the DOM
116      */
117     static public String getPathString( XMLNode e )
118     {
119         return ( e == null || !( e.isElement() ) ) ? "" : getPathString( e.getParent() ) + "<" + e.getName() + ">";
120     }
121 
122 
123     /**
124      * Like getElementContents(...) but with a defaultValue of null
125      */
126     static public String getElementContent( XMLNode root, String path )
127     {
128         return getElementContent( root, path, null );
129     }
130 
131     /**
132      * Like getElementContents(...) but with a defaultValue of null
133      */
134     static public String[] getMultiElementContent( XMLNode root, String path )
135     {
136         final List list = new ArrayList();
137         visitElements( root, path, new ElementVisitor()
138         {
139             public void visitElement( XMLNode n )
140             {
141                 String value = getElementContent( n, "" );
142                 if ( value != null )
143                 {
144                     list.add( value );
145                 }
146             }
147         } );
148         if ( list.size() == 0 )
149         {
150             return null;
151         }
152         return (String[]) list.toArray( new String[list.size()] );
153     }
154 
155     /**
156      * Returns the value of the last element tag in the path, e.g.,  <..><tag>value</tag>. The DOM is assumes
157      * to be normalized. If no value is found, the defaultvalue is returned
158      */
159     static public String getElementContent( XMLNode root, String path, String defaultvalue )
160     {
161         XMLNode e = findElementPath( root, path );
162         if ( e == null )
163         {
164             return defaultvalue;
165         }
166         XMLNode n = e.getNested();
167         if ( n != null && !n.isElement() )
168         {
169             return n.getName();
170         }
171         return defaultvalue;
172     }
173 
174     /**
175      * Parses a path string of the form <tag1><tag2><tag3> and returns the specific Element
176      * node for that tag, or null if it does not exist. If multiple elements exists with same
177      * path the first is returned
178      */
179     static public XMLNode findElementPath( XMLNode elem, String path )
180     {
181         // End condition. Root null -> path does not exist
182         if ( elem == null )
183         {
184             return null;
185         }
186         // End condition. String empty, return current root
187         if ( path == null || path.length() == 0 )
188         {
189             return elem;
190         }
191 
192         // Strip of first tag
193         int idx = path.indexOf( '>' );
194         String head = path.substring( 1, idx );
195         String tail = path.substring( idx + 1 );
196         return findElementPath( findChildElement( elem, head ), tail );
197     }
198 
199     /**
200      * Returns an child element with the current tag name or null.
201      */
202     static public XMLNode findChildElement( XMLNode elem, String tag )
203     {
204         XMLNode n = elem.getNested();
205         while ( n != null )
206         {
207             if ( n.isElement() && n.getName().equals( tag ) )
208             {
209                 return n;
210             }
211             n = n.getNext();
212         }
213         return null;
214     }
215 
216     /**
217      * Iterator class
218      */
219     public abstract static class ElementVisitor
220     {
221         abstract public void visitElement( XMLNode e );
222     }
223 
224     /**
225      * Visits all elements which matches the <path>. The iteration is only
226      * done on the last elment in the path.
227      */
228     static public void visitElements( XMLNode root, String path, ElementVisitor ev )
229     {
230         // Get last element in path
231         int idx = path.lastIndexOf( '<' );
232         String head = path.substring( 0, idx );
233         String tag = path.substring( idx + 1, path.length() - 1 );
234 
235         XMLNode elem = findElementPath( root, head );
236         if ( elem == null )
237         {
238             return;
239         }
240 
241         // Iterate through all child nodes
242         XMLNode n = elem.getNested();
243         while ( n != null )
244         {
245             if ( n.isElement() && n.getName().equals( tag ) )
246             {
247                 ev.visitElement( n );
248             }
249             n = n.getNext();
250         }
251     }
252 
253     static public void visitChildrenElements( XMLNode elem, ElementVisitor ev )
254     {
255         // Iterate through all child nodes
256         XMLNode n = elem.getNested();
257         while ( n != null )
258         {
259             if ( n.isElement() )
260             {
261                 ev.visitElement( n );
262             }
263             n = n.getNext();
264         }
265     }
266 }
267