1 package org.apache.maven.archiva.xml;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
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;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.net.MalformedURLException;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.List;
47 * XMLReader - a set of common xml utility methods for reading content out of an xml file.
51 public class XMLReader
55 private String documentType;
57 private Document document;
59 private Map<String, String> namespaceMap = new HashMap<String, String>();
61 public XMLReader( String type, File file )
66 throw new XMLException( "file does not exist: " + file.getAbsolutePath() );
71 throw new XMLException( "path is not a file: " + file.getAbsolutePath() );
74 if ( !file.canRead() )
76 throw new XMLException( "Cannot read xml file due to permissions: " + file.getAbsolutePath() );
81 init( type, file.toURL() );
83 catch ( MalformedURLException e )
85 throw new XMLException( "Unable to translate file " + file + " to URL: " + e.getMessage(), e );
89 public XMLReader( String type, URL url )
95 private void init( String type, URL url )
98 this.documentType = type;
101 InputStream in = null;
102 SAXReader reader = new SAXReader();
106 in = url.openStream();
107 InputStreamReader inReader = new InputStreamReader( in, "UTF-8" );
108 LatinEntityResolutionReader latinReader = new LatinEntityResolutionReader( inReader );
109 this.document = reader.read( latinReader );
111 catch ( DocumentException e )
113 throw new XMLException( "Unable to parse " + documentType + " xml " + xmlUrl + ": " + e.getMessage(), e );
115 catch ( IOException e )
117 throw new XMLException( "Unable to open stream to " + url + ": " + e.getMessage(), e );
121 IOUtils.closeQuietly( in );
124 Element root = this.document.getRootElement();
127 throw new XMLException( "Invalid " + documentType + " xml: root element is null." );
130 if ( !StringUtils.equals( root.getName(), documentType ) )
132 throw new XMLException( "Invalid " + documentType + " xml: Unexpected root element <" + root.getName()
133 + ">, expected <" + documentType + ">" );
137 public String getDefaultNamespaceURI()
139 Namespace namespace = this.document.getRootElement().getNamespace();
140 return namespace.getURI();
143 public void addNamespaceMapping( String elementName, String uri )
145 this.namespaceMap.put( elementName, uri );
148 public Element getElement( String xpathExpr )
151 XPath xpath = createXPath( xpathExpr );
152 Object evaluated = xpath.selectSingleNode( document );
154 if ( evaluated == null )
159 if ( evaluated instanceof Element )
161 Element evalElem = (Element) evaluated;
166 // Unknown evaluated type.
167 throw new XMLException( ".getElement( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
168 + evaluated.getClass().getName() + ") " + evaluated );
172 private XPath createXPath( String xpathExpr )
174 XPath xpath = document.createXPath( xpathExpr );
175 if ( !this.namespaceMap.isEmpty() )
177 xpath.setNamespaceURIs( this.namespaceMap );
182 public boolean hasElement( String xpathExpr )
185 XPath xpath = createXPath( xpathExpr );
186 Object evaluated = xpath.selectSingleNode( document );
188 if ( evaluated == null )
197 * Remove namespaces from entire document.
199 public void removeNamespaces()
201 removeNamespaces( this.document.getRootElement() );
205 * Remove namespaces from element recursively.
207 public void removeNamespaces( Element elem )
209 elem.setQName( QName.get( elem.getName(), Namespace.NO_NAMESPACE, elem.getQualifiedName() ) );
213 Iterator<Node> it = elem.elementIterator();
214 while ( it.hasNext() )
218 switch ( n.getNodeType() )
220 case Node.ATTRIBUTE_NODE:
221 ( (Attribute) n ).setNamespace( Namespace.NO_NAMESPACE );
223 case Node.ELEMENT_NODE:
224 removeNamespaces( (Element) n );
230 public String getElementText( Node context, String xpathExpr )
233 XPath xpath = createXPath( xpathExpr );
234 Object evaluated = xpath.selectSingleNode( context );
236 if ( evaluated == null )
241 if ( evaluated instanceof Element )
243 Element evalElem = (Element) evaluated;
244 return evalElem.getTextTrim();
248 // Unknown evaluated type.
249 throw new XMLException( ".getElementText( Node, Expr: " + xpathExpr
250 + " ) resulted in non-Element type -> (" + evaluated.getClass().getName() + ") " + evaluated );
254 public String getElementText( String xpathExpr )
257 XPath xpath = createXPath( xpathExpr );
258 Object evaluated = xpath.selectSingleNode( document );
260 if ( evaluated == null )
265 if ( evaluated instanceof Element )
267 Element evalElem = (Element) evaluated;
268 return evalElem.getTextTrim();
272 // Unknown evaluated type.
273 throw new XMLException( ".getElementText( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
274 + evaluated.getClass().getName() + ") " + evaluated );
278 public List<Element> getElementList( String xpathExpr )
281 XPath xpath = createXPath( xpathExpr );
282 Object evaluated = xpath.evaluate( document );
284 if ( evaluated == null )
289 /* The xpath.evaluate(Context) method can return:
290 * 1) A Collection or List of dom4j Nodes.
291 * 2) A single dom4j Node.
294 if ( evaluated instanceof List )
296 return (List<Element>) evaluated;
298 else if ( evaluated instanceof Node )
300 List<Element> ret = new ArrayList<Element>();
301 ret.add( (Element) evaluated );
306 // Unknown evaluated type.
307 throw new XMLException( ".getElementList( Expr: " + xpathExpr + " ) resulted in non-List type -> ("
308 + evaluated.getClass().getName() + ") " + evaluated );
312 public List<String> getElementListText( String xpathExpr )
315 List<Element> elemList = getElementList( xpathExpr );
316 if ( elemList == null )
321 List<String> ret = new ArrayList<String>();
322 for ( Iterator<Element> iter = elemList.iterator(); iter.hasNext(); )
324 Element listelem = iter.next();
325 ret.add( listelem.getTextTrim() );