mirror of https://github.com/apache/archiva.git
Migrating xml tools to standard API
This commit is contained in:
parent
78170d5ed0
commit
842ec05b5d
|
@ -19,25 +19,23 @@ package org.apache.archiva.repository.metadata;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.archiva.common.utils.FileUtils;
|
||||
import org.apache.archiva.model.ArchivaRepositoryMetadata;
|
||||
import org.apache.archiva.model.Plugin;
|
||||
import org.apache.archiva.repository.storage.StorageAsset;
|
||||
import org.apache.archiva.xml.XMLException;
|
||||
import org.apache.archiva.xml.XMLWriter;
|
||||
import org.apache.archiva.xml.XmlUtil;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
|
@ -81,10 +79,15 @@ public class RepositoryMetadataWriter
|
|||
public static void write( ArchivaRepositoryMetadata metadata, Writer writer )
|
||||
throws RepositoryMetadataException
|
||||
{
|
||||
Document doc = DocumentHelper.createDocument();
|
||||
Document doc = null;
|
||||
try {
|
||||
doc = XmlUtil.createDocument();
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RepositoryMetadataException("Could not create xml doc " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
Element root = DocumentHelper.createElement( "metadata" );
|
||||
doc.setRootElement( root );
|
||||
Element root = doc.createElement( "metadata" );
|
||||
doc.appendChild(root);
|
||||
|
||||
addOptionalElementText( root, "groupId", metadata.getGroupId() );
|
||||
addOptionalElementText( root, "artifactId", metadata.getArtifactId() );
|
||||
|
@ -92,16 +95,16 @@ public class RepositoryMetadataWriter
|
|||
|
||||
if ( CollectionUtils.isNotEmpty( metadata.getPlugins() ) )
|
||||
{
|
||||
Element plugins = root.addElement( "plugins" );
|
||||
Element plugins = XmlUtil.addChild(root, "plugins" );
|
||||
|
||||
List<Plugin> pluginList = metadata.getPlugins();
|
||||
Collections.sort( pluginList, PluginComparator.INSTANCE );
|
||||
|
||||
for ( Plugin plugin : metadata.getPlugins() )
|
||||
{
|
||||
Element p = plugins.addElement( "plugin" );
|
||||
p.addElement( "prefix" ).setText( plugin.getPrefix() );
|
||||
p.addElement( "artifactId" ).setText( plugin.getArtifactId() );
|
||||
Element p = XmlUtil.addChild(plugins, "plugin" );
|
||||
XmlUtil.addChild(doc, p, "prefix" ).setTextContent( plugin.getPrefix() );
|
||||
XmlUtil.addChild(doc, p, "artifactId" ).setTextContent( plugin.getArtifactId() );
|
||||
addOptionalElementText( p, "name", plugin.getName() );
|
||||
}
|
||||
}
|
||||
|
@ -112,14 +115,14 @@ public class RepositoryMetadataWriter
|
|||
|| StringUtils.isNotBlank( metadata.getLastUpdated() ) //
|
||||
|| ( metadata.getSnapshotVersion() != null ) )
|
||||
{
|
||||
Element versioning = root.addElement( "versioning" );
|
||||
Element versioning = XmlUtil.addChild(root, "versioning" );
|
||||
|
||||
addOptionalElementText( versioning, "latest", metadata.getLatestVersion() );
|
||||
addOptionalElementText( versioning, "release", metadata.getReleasedVersion() );
|
||||
|
||||
if ( metadata.getSnapshotVersion() != null )
|
||||
{
|
||||
Element snapshot = versioning.addElement( "snapshot" );
|
||||
Element snapshot = XmlUtil.addChild(versioning, "snapshot" );
|
||||
String bnum = String.valueOf( metadata.getSnapshotVersion().getBuildNumber() );
|
||||
addOptionalElementText( snapshot, "buildNumber", bnum );
|
||||
addOptionalElementText( snapshot, "timestamp", metadata.getSnapshotVersion().getTimestamp() );
|
||||
|
@ -127,12 +130,12 @@ public class RepositoryMetadataWriter
|
|||
|
||||
if ( CollectionUtils.isNotEmpty( metadata.getAvailableVersions() ) )
|
||||
{
|
||||
Element versions = versioning.addElement( "versions" );
|
||||
Element versions = XmlUtil.addChild(versioning, "versions" );
|
||||
Iterator<String> it = metadata.getAvailableVersions().iterator();
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
String version = it.next();
|
||||
versions.addElement( "version" ).setText( version );
|
||||
XmlUtil.addChild(versions, "version" ).setTextContent( version );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +159,7 @@ public class RepositoryMetadataWriter
|
|||
return;
|
||||
}
|
||||
|
||||
elem.addElement( elemName ).setText( text );
|
||||
XmlUtil.addChild(elem, elemName ).setTextContent( text );
|
||||
}
|
||||
|
||||
private static class PluginComparator
|
||||
|
|
|
@ -42,22 +42,11 @@
|
|||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.archiva</groupId>
|
||||
<artifactId>archiva-test-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package org.apache.archiva.xml;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.commons.collections4.Closure;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Gather the text from a collection of {@link Element}'s into a {@link List}
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ElementTextListClosure
|
||||
implements Closure
|
||||
{
|
||||
private List<String> list = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void execute( Object input )
|
||||
{
|
||||
if ( input instanceof Element )
|
||||
{
|
||||
Element elem = (Element) input;
|
||||
list.add( elem.getTextTrim() );
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getList()
|
||||
{
|
||||
return list;
|
||||
}
|
||||
}
|
|
@ -20,29 +20,28 @@ package org.apache.archiva.xml;
|
|||
*/
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Attribute;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Namespace;
|
||||
import org.dom4j.Node;
|
||||
import org.dom4j.QName;
|
||||
import org.dom4j.XPath;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.*;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* XMLReader - a set of common xml utility methods for reading content out of an xml file.
|
||||
|
@ -56,6 +55,25 @@ public class XMLReader
|
|||
private Document document;
|
||||
|
||||
private Map<String, String> namespaceMap = new HashMap<>();
|
||||
private Map<String, String> reverseNamespaceMap = new HashMap<>();
|
||||
|
||||
private class NamespaceCtx implements NamespaceContext {
|
||||
|
||||
@Override
|
||||
public String getNamespaceURI(String prefix) {
|
||||
return namespaceMap.get(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix(String namespaceURI) {
|
||||
return reverseNamespaceMap.get(namespaceURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator getPrefixes(String namespaceURI) {
|
||||
return namespaceMap.keySet().iterator();
|
||||
}
|
||||
}
|
||||
|
||||
public XMLReader( String type, Path file )
|
||||
throws XMLException
|
||||
|
@ -97,41 +115,69 @@ public class XMLReader
|
|||
this.documentType = type;
|
||||
this.xmlUrl = url;
|
||||
|
||||
SAXReader reader = new SAXReader();
|
||||
// SAXReader reader = new SAXReader();
|
||||
|
||||
try (InputStream in = url.openStream())
|
||||
|
||||
|
||||
try (InputStream in = url.openStream(); Reader reader = new LatinEntityResolutionReader(new BufferedReader(new InputStreamReader(in, "UTF-8"))))
|
||||
{
|
||||
InputStreamReader inReader = new InputStreamReader( in, Charset.forName( "UTF-8" ) );
|
||||
LatinEntityResolutionReader latinReader = new LatinEntityResolutionReader( inReader );
|
||||
this.document = reader.read( latinReader );
|
||||
}
|
||||
catch ( DocumentException e )
|
||||
{
|
||||
throw new XMLException( "Unable to parse " + documentType + " xml " + xmlUrl + ": " + e.getMessage(), e );
|
||||
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setExpandEntityReferences(false);
|
||||
dbf.setValidating(false);
|
||||
// dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,"false");
|
||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,true);
|
||||
// dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
// To suppress error output at System.err
|
||||
db.setErrorHandler(new ErrorHandler() {
|
||||
@Override
|
||||
public void warning(SAXParseException exception) throws SAXException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException exception) throws SAXException {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException exception) throws SAXException {
|
||||
throw exception;
|
||||
}
|
||||
});
|
||||
this.document = db.parse(new InputSource(reader));
|
||||
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new XMLException( "Unable to open stream to " + url + ": " + e.getMessage(), e );
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new XMLException("Unable to start parser "+e.getMessage());
|
||||
} catch (SAXException e) {
|
||||
throw new XMLException("Unable to parse file "+e.getMessage());
|
||||
}
|
||||
|
||||
Element root = this.document.getRootElement();
|
||||
Element root = this.document.getDocumentElement();
|
||||
if ( root == null )
|
||||
{
|
||||
throw new XMLException( "Invalid " + documentType + " xml: root element is null." );
|
||||
}
|
||||
|
||||
if ( !StringUtils.equals( root.getName(), documentType ) )
|
||||
if ( !StringUtils.equals( root.getLocalName(), documentType ) )
|
||||
{
|
||||
throw new XMLException(
|
||||
"Invalid " + documentType + " xml: Unexpected root element <" + root.getName() + ">, expected <"
|
||||
+ documentType + ">" );
|
||||
"Invalid " + documentType + " xml: Unexpected root element <" + root.getLocalName() + ">, expected <"
|
||||
+ documentType + ">" + root.getNodeName() );
|
||||
}
|
||||
}
|
||||
|
||||
public String getDefaultNamespaceURI()
|
||||
{
|
||||
Namespace namespace = this.document.getRootElement().getNamespace();
|
||||
return namespace.getURI();
|
||||
String namespace = this.document.getNamespaceURI();
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public void addNamespaceMapping( String elementName, String uri )
|
||||
|
@ -142,48 +188,55 @@ public class XMLReader
|
|||
public Element getElement( String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
XPath xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.selectSingleNode( document );
|
||||
XPathExpression xpath = null;
|
||||
try {
|
||||
xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.evaluate( document, XPathConstants.NODE);
|
||||
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( evaluated instanceof Element )
|
||||
{
|
||||
return (Element) evaluated;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElement( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
if ( evaluated instanceof Element )
|
||||
{
|
||||
return (Element) evaluated;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElement( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
}
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new XMLException("Could not parse xpath expression");
|
||||
}
|
||||
}
|
||||
|
||||
private XPath createXPath( String xpathExpr )
|
||||
{
|
||||
XPath xpath = document.createXPath( xpathExpr );
|
||||
private XPathExpression createXPath(String xpathExpr ) throws XPathExpressionException {
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
if ( !this.namespaceMap.isEmpty() )
|
||||
{
|
||||
xpath.setNamespaceURIs( this.namespaceMap );
|
||||
xpath.setNamespaceContext(new NamespaceCtx());
|
||||
}
|
||||
return xpath;
|
||||
return xpath.compile(xpathExpr);
|
||||
}
|
||||
|
||||
public boolean hasElement( String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
XPath xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.selectSingleNode( document );
|
||||
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return false;
|
||||
XPathExpression xpath = null;
|
||||
try {
|
||||
xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.evaluate( document, XPathConstants.NODE );
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new XMLException("Could not create xpath expression");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,32 +244,26 @@ public class XMLReader
|
|||
*/
|
||||
public void removeNamespaces()
|
||||
{
|
||||
removeNamespaces( this.document.getRootElement() );
|
||||
removeNamespaces( this.document.getDocumentElement() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove namespaces from element recursively.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeNamespaces( Element elem )
|
||||
public void removeNamespaces( Node elem )
|
||||
{
|
||||
elem.setQName( QName.get( elem.getName(), Namespace.NO_NAMESPACE, elem.getQualifiedName() ) );
|
||||
if (elem.getNodeType() == Node.ELEMENT_NODE || elem.getNodeType() == Node.ATTRIBUTE_NODE) {
|
||||
document.renameNode(elem, null, elem.getLocalName());
|
||||
|
||||
Node n;
|
||||
Node n;
|
||||
|
||||
Iterator<Node> it = elem.elementIterator();
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
n = it.next();
|
||||
NodeList nodeList = elem.getChildNodes();
|
||||
|
||||
switch ( n.getNodeType() )
|
||||
{
|
||||
case Node.ATTRIBUTE_NODE:
|
||||
( (Attribute) n ).setNamespace( Namespace.NO_NAMESPACE );
|
||||
break;
|
||||
case Node.ELEMENT_NODE:
|
||||
removeNamespaces( (Element) n );
|
||||
break;
|
||||
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
n = nodeList.item(i);
|
||||
removeNamespaces(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,102 +271,74 @@ public class XMLReader
|
|||
public String getElementText( Node context, String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
XPath xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.selectSingleNode( context );
|
||||
XPathExpression xpath = null;
|
||||
try {
|
||||
xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.evaluate( context, XPathConstants.NODE );
|
||||
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( evaluated instanceof Element )
|
||||
{
|
||||
Element evalElem = (Element) evaluated;
|
||||
return evalElem.getTextTrim();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElementText( Node, Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
if ( evaluated instanceof Element )
|
||||
{
|
||||
Element evalElem = (Element) evaluated;
|
||||
return XmlUtil.getText(evalElem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElementText( Node, Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
}
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new XMLException("Could not parse xpath expression");
|
||||
}
|
||||
}
|
||||
|
||||
public String getElementText( String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
XPath xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.selectSingleNode( document );
|
||||
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( evaluated instanceof Element )
|
||||
{
|
||||
Element evalElem = (Element) evaluated;
|
||||
return evalElem.getTextTrim();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElementText( Expr: " + xpathExpr + " ) resulted in non-Element type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
}
|
||||
return getElementText(document, xpathExpr);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Element> getElementList( String xpathExpr )
|
||||
public List<Node> getElementList( String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
XPath xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.evaluate( document );
|
||||
XPathExpression xpath = null;
|
||||
try {
|
||||
xpath = createXPath( xpathExpr );
|
||||
Object evaluated = xpath.evaluate( document, XPathConstants.NODESET);
|
||||
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ( evaluated == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/* The xpath.evaluate(Context) method can return:
|
||||
* 1) A Collection or List of dom4j Nodes.
|
||||
* 2) A single dom4j Node.
|
||||
*/
|
||||
NodeList nl = (NodeList) evaluated;
|
||||
List<Node> nodeList = new ArrayList<>();
|
||||
for (int i = 0 ; i<nl.getLength(); i++) {
|
||||
nodeList.add(nl.item(i));
|
||||
}
|
||||
return nodeList;
|
||||
|
||||
if ( evaluated instanceof List )
|
||||
{
|
||||
return (List<Element>) evaluated;
|
||||
}
|
||||
else if ( evaluated instanceof Node )
|
||||
{
|
||||
List<Element> ret = new ArrayList<>();
|
||||
ret.add( (Element) evaluated );
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown evaluated type.
|
||||
throw new XMLException( ".getElementList( Expr: " + xpathExpr + " ) resulted in non-List type -> ("
|
||||
+ evaluated.getClass().getName() + ") " + evaluated );
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new XMLException("Could not parse xpath expression");
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getElementListText( String xpathExpr )
|
||||
throws XMLException
|
||||
{
|
||||
List<Element> elemList = getElementList( xpathExpr );
|
||||
List<Node> elemList = getElementList( xpathExpr );
|
||||
if ( elemList == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> ret = new ArrayList<>();
|
||||
for ( Iterator<Element> iter = elemList.iterator(); iter.hasNext(); )
|
||||
{
|
||||
Element listelem = iter.next();
|
||||
ret.add( listelem.getTextTrim() );
|
||||
}
|
||||
return ret;
|
||||
return elemList.stream().filter(n -> n instanceof Element).map(n -> XmlUtil.getText(n)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,67 +19,78 @@ package org.apache.archiva.xml;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* XMLWriter - Making writing XML files easier.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class XMLWriter
|
||||
{
|
||||
public class XMLWriter {
|
||||
/**
|
||||
* Write the Document to the provided Writer, leaving the Writer open.
|
||||
*
|
||||
* @param doc the document to write.
|
||||
* @param doc the document to write.
|
||||
* @param writer the writer to write to.
|
||||
* @throws XMLException if there was a problem writing the xml to the writer.
|
||||
*/
|
||||
public static void write( Document doc, Writer writer )
|
||||
throws XMLException
|
||||
{
|
||||
write( doc, writer, false );
|
||||
public static void write(Document doc, Writer writer)
|
||||
throws XMLException {
|
||||
write(doc, writer, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the Document to the provided Writer, with an option to close the writer upon completion.
|
||||
*
|
||||
* @param doc the document to write.
|
||||
* @param doc the document to write.
|
||||
* @param writer the writer to write to.
|
||||
* @param close true to close the writer on completion.
|
||||
* @param close true to close the writer on completion.
|
||||
* @throws XMLException if there was a problem writing the xml to the writer.
|
||||
*/
|
||||
public static void write( Document doc, Writer writer, boolean close )
|
||||
throws XMLException
|
||||
{
|
||||
org.dom4j.io.XMLWriter xmlwriter = null;
|
||||
public static void write(Document doc, Writer writer, boolean close)
|
||||
throws XMLException {
|
||||
|
||||
try
|
||||
{
|
||||
OutputFormat outputFormat = OutputFormat.createPrettyPrint();
|
||||
xmlwriter = new org.dom4j.io.XMLWriter( writer, outputFormat );
|
||||
xmlwriter.write( doc );
|
||||
xmlwriter.flush();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new XMLException( "Unable to write xml contents to writer: " + e.getMessage(), e );
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ( close && ( xmlwriter != null ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
xmlwriter.close();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
/* quietly ignore */
|
||||
try {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
try {
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Indent not supported
|
||||
}
|
||||
// Writing the XML declaration, because the JDK implementation does not create a newline
|
||||
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
StreamResult result = new StreamResult(writer);
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
DOMSource source = new DOMSource(doc);
|
||||
transformer.transform(source, result);
|
||||
|
||||
|
||||
} catch (TransformerException e) {
|
||||
throw new XMLException("Could not create the xml transformer: " + e.getMessage(), e);
|
||||
} catch (IOException e) {
|
||||
throw new XMLException("Could not write to xml output: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (writer!=null) {
|
||||
if (close) {
|
||||
try {
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
/* quietly ignore */
|
||||
}
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
/* quietly ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package org.apache.archiva.xml;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import org.w3c.dom.*;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
public class XmlUtil {
|
||||
|
||||
|
||||
public static Document createDocument() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.newDocument();
|
||||
}
|
||||
|
||||
public static Element addChild(Document doc, Element parent, String name) {
|
||||
Element el = doc.createElement(name);
|
||||
parent.appendChild(el);
|
||||
return el;
|
||||
}
|
||||
|
||||
public static Element addChild(Element parent, String name) {
|
||||
Document doc = parent.getOwnerDocument();
|
||||
Element el = doc.createElement(name);
|
||||
parent.appendChild(el);
|
||||
return el;
|
||||
}
|
||||
|
||||
public static String getText(Node element) {
|
||||
if (element!=null) {
|
||||
element.normalize();
|
||||
try {
|
||||
String txt = element.getTextContent();
|
||||
if (txt!=null) {
|
||||
return txt.trim();
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Node getChild(Element parent, String name) {
|
||||
NodeList elList = parent.getElementsByTagName(name);
|
||||
if (elList.getLength()>0) {
|
||||
return elList.item(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getChildText(Element parent, String name) {
|
||||
return getText(getChild(parent, name));
|
||||
}
|
||||
|
||||
}
|
|
@ -19,8 +19,6 @@ package org.apache.archiva.xml;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -204,30 +202,6 @@ public class LatinEntityResolutionReaderTest
|
|||
assertProperRead( expected, "no-prolog-with-entities.xml", 409600 );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReaderLeftOver()
|
||||
throws IOException
|
||||
{
|
||||
Path inputFile = getExampleXml( "maven-metadata-leftover.xml" );
|
||||
//Bits from RepositoryMetadataReader.read
|
||||
InputStream in = null;
|
||||
SAXReader reader = new SAXReader();
|
||||
URL url = inputFile.toUri().toURL();
|
||||
in = url.openStream();
|
||||
InputStreamReader inReader = new InputStreamReader( in, Charset.forName( "UTF-8" ) );
|
||||
LatinEntityResolutionReader latinReader = new LatinEntityResolutionReader( inReader );
|
||||
try
|
||||
{
|
||||
reader.read( latinReader );
|
||||
}
|
||||
catch ( DocumentException e )
|
||||
{
|
||||
Assert.fail( "Should not have failed here." + e );
|
||||
IOException ioe = new IOException();
|
||||
ioe.initCause( e );
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoLatinEntitiesHugeLine()
|
||||
|
|
|
@ -19,8 +19,9 @@ package org.apache.archiva.xml;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.dom4j.Element;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
|
@ -34,14 +35,14 @@ import java.util.List;
|
|||
public class XMLReaderTest
|
||||
extends AbstractArchivaXmlTestCase
|
||||
{
|
||||
private void assertElementTexts( List<Element> elementList, String[] expectedTexts )
|
||||
private void assertElementTexts( List<Node> elementList, String[] expectedTexts )
|
||||
{
|
||||
assertEquals( "Element List Size", expectedTexts.length, elementList.size() );
|
||||
|
||||
List<String> texts = new ArrayList<>();
|
||||
for ( Element element : elementList )
|
||||
for ( Node element : elementList )
|
||||
{
|
||||
texts.add( element.getTextTrim() );
|
||||
texts.add( element.getTextContent().trim());
|
||||
}
|
||||
|
||||
for ( int i = 0; i < expectedTexts.length; i++ )
|
||||
|
@ -58,7 +59,7 @@ public class XMLReaderTest
|
|||
Path xmlFile = getExampleXml( "no-prolog-basic.xml" );
|
||||
XMLReader reader = new XMLReader( "basic", xmlFile );
|
||||
|
||||
List<Element> fruits = reader.getElementList( "//basic/fruits/fruit" );
|
||||
List<Node> fruits = reader.getElementList( "//basic/fruits/fruit" );
|
||||
assertElementTexts( fruits, new String[] { "apple", "cherry", "pear", "peach" } );
|
||||
}
|
||||
|
||||
|
@ -69,7 +70,7 @@ public class XMLReaderTest
|
|||
Path xmlFile = getExampleXml( "no-prolog-with-entities.xml" );
|
||||
XMLReader reader = new XMLReader( "basic", xmlFile );
|
||||
|
||||
List<Element> names = reader.getElementList( "//basic/names/name" );
|
||||
List<Node> names = reader.getElementList( "//basic/names/name" );
|
||||
assertElementTexts( names, new String[] { TRYGVIS, INFINITE_ARCHIVA } );
|
||||
}
|
||||
|
||||
|
@ -80,7 +81,7 @@ public class XMLReaderTest
|
|||
Path xmlFile = getExampleXml( "no-prolog-with-utf8.xml" );
|
||||
XMLReader reader = new XMLReader( "basic", xmlFile );
|
||||
|
||||
List<Element> names = reader.getElementList( "//basic/names/name" );
|
||||
List<Node> names = reader.getElementList( "//basic/names/name" );
|
||||
assertElementTexts( names, new String[] { TRYGVIS, INFINITE_ARCHIVA } );
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,7 @@ public class XMLReaderTest
|
|||
Path xmlFile = getExampleXml( "prolog-with-utf8.xml" );
|
||||
XMLReader reader = new XMLReader( "basic", xmlFile );
|
||||
|
||||
List<Element> names = reader.getElementList( "//basic/names/name" );
|
||||
List<Node> names = reader.getElementList( "//basic/names/name" );
|
||||
assertElementTexts( names, new String[] { TRYGVIS, INFINITE_ARCHIVA } );
|
||||
}
|
||||
|
||||
|
@ -104,9 +105,9 @@ public class XMLReaderTest
|
|||
XMLReader reader = new XMLReader( "metadata", xmlFile );
|
||||
reader.removeNamespaces();
|
||||
|
||||
Element groupId = reader.getElement( "//metadata/groupId" );
|
||||
Element groupId = (Element) reader.getElement( "//metadata/groupId" );
|
||||
assertNotNull( groupId );
|
||||
assertEquals( "org.codehaus.mojo", groupId.getTextTrim() );
|
||||
assertEquals( "org.codehaus.mojo", groupId.getTextContent().trim() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@ package org.apache.archiva.xml;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,6 @@ public class XMLWriterTest
|
|||
StringBuilder expected = new StringBuilder();
|
||||
|
||||
expected.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
|
||||
expected.append( "\n" );
|
||||
expected.append( "<basic>\n" );
|
||||
expected.append( " <names>\n" );
|
||||
expected.append( " <name>" ).append( TRYGVIS ).append( "</name>\n" );
|
||||
|
@ -49,12 +49,19 @@ public class XMLWriterTest
|
|||
expected.append( " </names>\n" );
|
||||
expected.append( "</basic>\n" );
|
||||
|
||||
Element basic = DocumentHelper.createElement( "basic" );
|
||||
Document doc = DocumentHelper.createDocument( basic );
|
||||
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element basic = doc.createElement("basic");
|
||||
doc.appendChild(basic);
|
||||
Element names = doc.createElement( "names" );
|
||||
basic.appendChild(names);
|
||||
Element name = doc.createElement("name");
|
||||
name.setTextContent(TRYGVIS);
|
||||
names.appendChild(name);
|
||||
name = doc.createElement("name");
|
||||
name.setTextContent(INFINITE_ARCHIVA);
|
||||
|
||||
Element names = basic.addElement( "names" );
|
||||
names.addElement( "name" ).setText( TRYGVIS );
|
||||
names.addElement( "name" ).setText( INFINITE_ARCHIVA );
|
||||
names.appendChild(name);
|
||||
|
||||
StringWriter actual = new StringWriter();
|
||||
XMLWriter.write( doc, actual );
|
||||
|
|
|
@ -24,10 +24,12 @@ import org.apache.archiva.model.SnapshotVersion;
|
|||
import org.apache.archiva.repository.storage.StorageAsset;
|
||||
import org.apache.archiva.xml.XMLException;
|
||||
import org.apache.archiva.xml.XMLReader;
|
||||
import org.apache.archiva.xml.XmlUtil;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -115,22 +117,28 @@ public class MavenMetadataReader
|
|||
if ( snapshotElem != null )
|
||||
{
|
||||
SnapshotVersion snapshot = new SnapshotVersion();
|
||||
snapshot.setTimestamp( snapshotElem.elementTextTrim( "timestamp" ) );
|
||||
String tmp = snapshotElem.elementTextTrim( "buildNumber" );
|
||||
if ( NumberUtils.isNumber( tmp ) )
|
||||
snapshot.setTimestamp(XmlUtil.getChildText(snapshotElem, "timestamp"));
|
||||
String buildNumber = XmlUtil.getChildText(snapshotElem, "buildNumber");
|
||||
if ( NumberUtils.isCreatable( buildNumber ) )
|
||||
{
|
||||
snapshot.setBuildNumber( NumberUtils.toInt( tmp ) );
|
||||
snapshot.setBuildNumber( NumberUtils.toInt( buildNumber ) );
|
||||
}
|
||||
metadata.setSnapshotVersion( snapshot );
|
||||
}
|
||||
|
||||
for ( Element plugin : xml.getElementList( "//metadata/plugins/plugin" ) )
|
||||
for ( Node node : xml.getElementList( "//metadata/plugins/plugin" ) )
|
||||
{
|
||||
Plugin p = new Plugin();
|
||||
p.setPrefix( plugin.elementTextTrim( "prefix" ) );
|
||||
p.setArtifactId( plugin.elementTextTrim( "artifactId" ) );
|
||||
p.setName( plugin.elementTextTrim( "name" ) );
|
||||
metadata.addPlugin( p );
|
||||
if (node instanceof Element) {
|
||||
Element plugin = (Element) node;
|
||||
Plugin p = new Plugin();
|
||||
String prefix = plugin.getElementsByTagName("prefix").item(0).getTextContent().trim();
|
||||
p.setPrefix(prefix);
|
||||
String artifactId = plugin.getElementsByTagName("artifactId").item(0).getTextContent().trim();
|
||||
p.setArtifactId(artifactId);
|
||||
String name = plugin.getElementsByTagName("name").item(0).getTextContent().trim();
|
||||
p.setName(name);
|
||||
metadata.addPlugin(p);
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
|
|
|
@ -258,7 +258,6 @@ public class RepositoryServletRepositoryGroupTest
|
|||
WebResponse response = getServletUnitClient().getResource( request );
|
||||
|
||||
Path returnedMetadata = getProjectBase().resolve( "target/test-classes/retrievedMetadataFile.xml" );
|
||||
System.out.println( response.getContentAsString() );
|
||||
org.apache.archiva.common.utils.FileUtils.writeStringToFile( returnedMetadata, Charset.defaultCharset(), response.getContentAsString() );
|
||||
ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( returnedMetadata );
|
||||
|
||||
|
@ -285,7 +284,7 @@ public class RepositoryServletRepositoryGroupTest
|
|||
assertResponseOK( response );
|
||||
|
||||
assertThat( response.getContentAsString() )
|
||||
.startsWith( "add113b0d7f8c6adb92a5015a7a3701081edf998" );
|
||||
.startsWith( "f8a7a858a46887368adf0b30874de1f807d91453" );
|
||||
|
||||
// request the md5 checksum of the metadata
|
||||
request = new GetMethodWebRequest( "http://machine.com/repository/" + REPO_GROUP_WITH_VALID_REPOS + "/dummy/"
|
||||
|
@ -295,7 +294,7 @@ public class RepositoryServletRepositoryGroupTest
|
|||
assertResponseOK( response );
|
||||
|
||||
assertThat( response.getContentAsString() )
|
||||
.startsWith( "5b85ea4aa5f52bb76760041a52f98de8" );
|
||||
.startsWith( "cec864b66849153dd45fddb7cdde12b2" );
|
||||
}
|
||||
|
||||
// MRM-901
|
||||
|
|
Loading…
Reference in New Issue