]> source.dussan.org Git - archiva.git/blob
759519e13507d4dd38e91d24c84d46d190b85ae3
[archiva.git] /
1 package org.apache.maven.archiva.xml;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.commons.io.IOUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.dom4j.Attribute;
25 import org.dom4j.Document;
26 import org.dom4j.DocumentException;
27 import org.dom4j.Element;
28 import org.dom4j.Namespace;
29 import org.dom4j.Node;
30 import org.dom4j.QName;
31 import org.dom4j.XPath;
32 import org.dom4j.io.SAXReader;
33
34 import java.io.File;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.net.MalformedURLException;
39 import java.net.URL;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.List;
44 import java.util.Map;
45
46 /**
47  * XMLReader - a set of common xml utility methods for reading content out of an xml file. 
48  *
49  * @version $Id$
50  */
51 public class XMLReader
52 {
53     private URL xmlUrl;
54
55     private String documentType;
56
57     private Document document;
58
59     private Map<String, String> namespaceMap = new HashMap<String, String>();
60
61     public XMLReader( String type, File file )
62         throws XMLException
63     {
64         if ( !file.exists() )
65         {
66             throw new XMLException( "file does not exist: " + file.getAbsolutePath() );
67         }
68
69         if ( !file.isFile() )
70         {
71             throw new XMLException( "path is not a file: " + file.getAbsolutePath() );
72         }
73
74         if ( !file.canRead() )
75         {
76             throw new XMLException( "Cannot read xml file due to permissions: " + file.getAbsolutePath() );
77         }
78
79         try
80         {
81             init( type, file.toURL() );
82         }
83         catch ( MalformedURLException e )
84         {
85             throw new XMLException( "Unable to translate file " + file + " to URL: " + e.getMessage(), e );
86         }
87     }
88
89     public XMLReader( String type, URL url )
90         throws XMLException
91     {
92         init( type, url );
93     }
94
95     private void init( String type, URL url )
96         throws XMLException
97     {
98         this.documentType = type;
99         this.xmlUrl = url;
100
101         InputStream in = null;
102         SAXReader reader = new SAXReader();
103         
104         try
105         {
106             in = url.openStream();
107             InputStreamReader inReader = new InputStreamReader( in, "UTF-8" );
108             LatinEntityResolutionReader latinReader = new LatinEntityResolutionReader( inReader );
109             this.document = reader.read( latinReader );
110         }
111         catch ( DocumentException e )
112         {
113             throw new XMLException( "Unable to parse " + documentType + " xml " + xmlUrl + ": " + e.getMessage(), e );
114         }
115         catch ( IOException e )
116         {
117             throw new XMLException( "Unable to open stream to " + url + ": " + e.getMessage(), e );
118         }
119         finally
120         {
121             IOUtils.closeQuietly( in );
122         }
123
124         Element root = this.document.getRootElement();
125         if ( root == null )
126         {
127             throw new XMLException( "Invalid " + documentType + " xml: root element is null." );
128         }
129
130         if ( !StringUtils.equals( root.getName(), documentType ) )
131         {
132             throw new XMLException( "Invalid " + documentType + " xml: Unexpected root element <" + root.getName()
133                 + ">, expected <" + documentType + ">" );
134         }
135     }
136
137     public String getDefaultNamespaceURI()
138     {
139         Namespace namespace = this.document.getRootElement().getNamespace();
140         return namespace.getURI();
141     }
142
143     public void addNamespaceMapping( String elementName, String uri )
144     {
145         this.namespaceMap.put( elementName, uri );
146     }
147
148     public Element getElement( String xpathExpr )
149         throws XMLException
150     {
151         XPath xpath = createXPath( xpathExpr );
152         Object evaluated = xpath.selectSingleNode( document );
153
154         if ( evaluated == null )
155         {
156             return null;
157         }
158
159         if ( evaluated instanceof Element )
160         {
161             Element evalElem = (Element) evaluated;
162             return evalElem;
163         }
164         else
165         {
166             // Unknown evaluated type.
167             throw new XMLException( ".getElement( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
168                 + evaluated.getClass().getName() + ") " + evaluated );
169         }
170     }
171
172     private XPath createXPath( String xpathExpr )
173     {
174         XPath xpath = document.createXPath( xpathExpr );
175         if ( !this.namespaceMap.isEmpty() )
176         {
177             xpath.setNamespaceURIs( this.namespaceMap );
178         }
179         return xpath;
180     }
181
182     public boolean hasElement( String xpathExpr )
183         throws XMLException
184     {
185         XPath xpath = createXPath( xpathExpr );
186         Object evaluated = xpath.selectSingleNode( document );
187
188         if ( evaluated == null )
189         {
190             return false;
191         }
192
193         return true;
194     }
195
196     /**
197      * Remove namespaces from entire document.
198      */
199     public void removeNamespaces()
200     {
201         removeNamespaces( this.document.getRootElement() );
202     }
203
204     /**
205      * Remove namespaces from element recursively.
206      */
207     public void removeNamespaces( Element elem )
208     {
209         elem.setQName( QName.get( elem.getName(), Namespace.NO_NAMESPACE, elem.getQualifiedName() ) );
210
211         Node n;
212
213         Iterator<Node> it = elem.elementIterator();
214         while ( it.hasNext() )
215         {
216             n = it.next();
217
218             switch ( n.getNodeType() )
219             {
220                 case Node.ATTRIBUTE_NODE:
221                     ( (Attribute) n ).setNamespace( Namespace.NO_NAMESPACE );
222                     break;
223                 case Node.ELEMENT_NODE:
224                     removeNamespaces( (Element) n );
225                     break;
226             }
227         }
228     }
229
230     public String getElementText( Node context, String xpathExpr )
231         throws XMLException
232     {
233         XPath xpath = createXPath( xpathExpr );
234         Object evaluated = xpath.selectSingleNode( context );
235
236         if ( evaluated == null )
237         {
238             return null;
239         }
240
241         if ( evaluated instanceof Element )
242         {
243             Element evalElem = (Element) evaluated;
244             return evalElem.getTextTrim();
245         }
246         else
247         {
248             // Unknown evaluated type.
249             throw new XMLException( ".getElementText( Node, Expr: " + xpathExpr
250                 + " ) resulted in non-Element type -> (" + evaluated.getClass().getName() + ") " + evaluated );
251         }
252     }
253
254     public String getElementText( String xpathExpr )
255         throws XMLException
256     {
257         XPath xpath = createXPath( xpathExpr );
258         Object evaluated = xpath.selectSingleNode( document );
259
260         if ( evaluated == null )
261         {
262             return null;
263         }
264
265         if ( evaluated instanceof Element )
266         {
267             Element evalElem = (Element) evaluated;
268             return evalElem.getTextTrim();
269         }
270         else
271         {
272             // Unknown evaluated type.
273             throw new XMLException( ".getElementText( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
274                 + evaluated.getClass().getName() + ") " + evaluated );
275         }
276     }
277
278     public List<Element> getElementList( String xpathExpr )
279         throws XMLException
280     {
281         XPath xpath = createXPath( xpathExpr );
282         Object evaluated = xpath.evaluate( document );
283
284         if ( evaluated == null )
285         {
286             return null;
287         }
288
289         /* The xpath.evaluate(Context) method can return:
290          *   1) A Collection or List of dom4j Nodes. 
291          *   2) A single dom4j Node.
292          */
293
294         if ( evaluated instanceof List )
295         {
296             return (List<Element>) evaluated;
297         }
298         else if ( evaluated instanceof Node )
299         {
300             List<Element> ret = new ArrayList<Element>();
301             ret.add( (Element) evaluated );
302             return ret;
303         }
304         else
305         {
306             // Unknown evaluated type.
307             throw new XMLException( ".getElementList( Expr: " + xpathExpr + " ) resulted in non-List type -> ("
308                 + evaluated.getClass().getName() + ") " + evaluated );
309         }
310     }
311
312     public List<String> getElementListText( String xpathExpr )
313         throws XMLException
314     {
315         List<Element> elemList = getElementList( xpathExpr );
316         if ( elemList == null )
317         {
318             return null;
319         }
320
321         List<String> ret = new ArrayList<String>();
322         for ( Iterator<Element> iter = elemList.iterator(); iter.hasNext(); )
323         {
324             Element listelem = iter.next();
325             ret.add( listelem.getTextTrim() );
326         }
327         return ret;
328     }
329
330 }