![JAR search and dependency download from the Maven repository](/logo.png)
org.redline_rpm.XmlEditor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redline-td Show documentation
Show all versions of redline-td Show documentation
Redline is a pure Java library for manipulating RPM Package Manager packages.
The newest version!
package org.redline_rpm;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Stack;
import static javax.xml.xpath.XPathConstants.NODE;
import static javax.xml.xpath.XPathConstants.NODESET;
import static javax.xml.xpath.XPathConstants.NUMBER;
public class XmlEditor implements Serializable {
static final long serialVersionUID = 1L;
private transient Stack< Node> context = new Stack< Node>();
private transient boolean modified;
private transient XPath xpath;
public XmlEditor() {}
public XmlEditor( Document document) { setDocument( document); }
public void setDocument( Document document) {
context.push( document.getDocumentElement());
this.modified = false;
}
public Document getDocument() { return context.peek().getOwnerDocument(); }
public void pushContext( Node node) { context.push( node); }
public Node popContext() { return context.pop(); }
public void clearContext() { while ( context.size() > 1) context.pop(); }
public void startPrefixMapping( String uri, String prefix) {
NAMESPACE_CONTEXT.addNamespace( uri, prefix);
}
public boolean isModified() { return modified; }
public void setModified( boolean modified) { this.modified = modified; }
public void read( File file) throws SAXException, IOException {
setDocument( readDocument( file));
}
public void read( InputStream in) throws SAXException, IOException {
setDocument( readDocument( in));
}
public void write( File file) throws IOException {
modified = false;
write( context.peek().getOwnerDocument(), file);
}
public void write( OutputStream out) throws IOException { modified = false; write( context.peek().getOwnerDocument(), out); }
public void write( ContentHandler handler) throws IOException {
try {
TransformerFactory.newInstance().newTransformer().transform( new DOMSource( context.peek().getOwnerDocument()), new SAXResult( handler));
modified = false;
} catch ( TransformerConfigurationException e) {
assert false;
throw new RuntimeException( "no transformer", e);
} catch ( TransformerException e) {
Throwable t = e.getCause();
if ( t instanceof IOException) throw ( IOException) t;
assert false;
throw new RuntimeException( "transformer failed", e);
}
}
public Node createNode( String path) {
modified = true;
return findNode( path, true);
}
public Node findNode( String path) {
return findNode( path, false);
}
private Node findNode( String path, boolean create) {
try {
Node result = ( Node) xpath( path).evaluate( context.peek(), NODE);
if ( !create || result != null) return result;
int pos = path.lastIndexOf( '/');
Element parent;
String name;
if ( pos >= 0) {
parent = ( Element) findNode( path.substring( 0, pos), true);
name = path.substring( pos + 1);
} else {
parent = ( Element) context.peek();
name = path;
}
return newNode( parent, name);
} catch ( XPathExpressionException e) {
throw new RuntimeException( path, e);
}
}
public Iterable< Node> findNodes( String path) {
try {
final NodeList list = ( NodeList) xpath( path).evaluate( context.peek(), NODESET);
return new Iterable< Node>() {
public Iterator< Node> iterator() {
return new Iterator< Node>() {
int count;
public boolean hasNext() { return count != list.getLength(); }
public Node next() { return list.item( count++); }
public void remove() { throw new UnsupportedOperationException(); }
};
}
};
} catch ( XPathExpressionException e) {
throw new RuntimeException( path, e);
}
}
public void setValue( String path, String value) {
modified = true;
setValue( createNode( path), value);
}
public String getValue( String path) {
Node n = findNode( path);
if ( n == null) return null;
return n.getNodeValue();
}
public Number getValueAsNumber( String path) {
try {
return ( Number) xpath( path).evaluate( context.peek(), NUMBER);
} catch ( XPathExpressionException e) {
throw new RuntimeException( path, e);
}
}
public String getValue( String path, String def) {
String value = getValue( path);
return value == null ? def : value;
}
public boolean getBoolean( String path) { return getBoolean( path, false); }
public boolean getBoolean( String path, boolean def) {
String value = getValue( path);
return value == null ? def : Boolean.valueOf( value);
}
public int getInteger( String path) { return getInteger( path, 0); }
public int getInteger( String path, int def) {
String value = getValue( path);
return value == null ? def : Integer.parseInt( value);
}
private URI getBaseURIFor( Node node) {
try {
return new URI( xpath( "ancestor-or-self::*/@xml:base").evaluate( node));
} catch ( XPathExpressionException e) {
assert false;
} catch ( URISyntaxException e) {
assert true;
}
return null;
}
public URI getBaseURI() {
return getBaseURIFor( context.peek());
}
public URI getValueAsURI( String path) {
try {
String result = getValue( path);
if ( result == null || "".equals( result)) return null;
return new URI( result);
} catch ( URISyntaxException e) {
return null;
}
}
public URI getValueAsFullURI( String path) {
URI base = getBaseURIFor( findNode( path));
URI result = getValueAsURI( path);
if ( result != null && base != null) result = base.resolve( result);
return result;
}
public void deleteNodes( String path) {
modified = true;
try {
NodeList list = ( NodeList) xpath( path).evaluate( context.peek(), NODESET);
int n = list.getLength();
for ( int i = 0; i < n; i++) {
Node node = list.item( i);
if ( node instanceof Attr) {
Attr attr = ( Attr) node;
attr.getOwnerElement().removeAttributeNode( attr);
} else {
node.getParentNode().removeChild( node);
}
}
} catch ( XPathExpressionException e) {
throw new RuntimeException( path, e);
}
}
public Node appendNode( String path) {
modified = true;
int pos = path.lastIndexOf( '/');
if ( pos >= 0) return newNode( appendNode( path.substring( 0, pos)), path.substring( pos + 1));
return newNode( path);
}
public void appendCollection( String nodePath, Collection< ?> values) {
modified = true;
for (Object value : values) {
setValue(appendNode(nodePath), value.toString());
}
}
public void replaceCollection( String nodePath, Collection< ?> values) {
modified = true;
deleteNodes( nodePath);
appendCollection( nodePath, values);
}
public Collection< String> nodesToText( String path, Collection< String> result) {
Iterable< Node> nodes = findNodes( path);
for ( Node node : nodes) {
String string = normalizeString( node.getNodeValue());
if ( string == null) continue;
result.add( string);
}
return result;
}
public ContentHandler contentHandler() {
return new ContentHandler() {
private Node current = context.peek();
private Document doc = context.peek().getOwnerDocument();
public void characters( char[] ch, int start, int length) {
String s = new String( ch, start, length);
if ( current instanceof Text) {
(( Text) current).appendData( s);
} else {
Text text = doc.createTextNode( s);
current.appendChild( text);
current = text;
}
}
public void startElement( String namespaceURI, String localName, String qName, Attributes atts) {
Element element = doc.createElementNS( namespaceURI, qName);
int n = atts.getLength();
for ( int i = 0; i < n; i++) {
element.setAttribute( atts.getQName( i), atts.getValue( i));
}
if ( current instanceof Text) {
current.getParentNode().appendChild( element);
} else {
current.appendChild( element);
}
current = element;
}
public void endElement( String namespaceURI, String localName, String qName) {
if ( current instanceof Text) current = current.getParentNode();
current = current.getParentNode();
}
public void processingInstruction( String target, String data) {
ProcessingInstruction pi = doc.createProcessingInstruction( target, data);
current.getParentNode().appendChild( pi);
current = pi;
}
public void startDocument() {}
public void endDocument() {}
public void startPrefixMapping( String prefix, String uri) {}
public void endPrefixMapping( String prefix) {}
public void ignorableWhitespace( char[] ch, int start, int length) {}
public void setDocumentLocator( Locator locator) {}
public void skippedEntity( String name) {}
};
}
public Node newNode( String name) { return newNode( context.peek(), name); }
// Static API follows
public static Document readDocument( File file) throws SAXException, IOException {
InputStream in = new FileInputStream( file);
Document result = readDocument( in);
in.close();
return result;
}
public static Document readDocument( InputStream in) throws SAXException, IOException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware( true);
return factory.newDocumentBuilder().parse( in);
} catch ( ParserConfigurationException e) {
assert false;
throw new RuntimeException( "usable DOM parser", e);
}
}
public static void write( Document doc, File file) throws IOException {
OutputStream out = new FileOutputStream( file);
write( doc, out);
out.close();
}
public static void write( Document doc, OutputStream out) throws IOException {
try {
doc.normalize();
Source source = new DOMSource( doc);
Result result = new StreamResult( out);
Transformer xslt = TransformerFactory.newInstance().newTransformer();
xslt.setOutputProperty( OutputKeys.ENCODING, "iso-8859-1");
xslt.setOutputProperty( OutputKeys.INDENT, "yes");
xslt.transform( source, result);
} catch ( TransformerConfigurationException e) {
assert false;
throw new RuntimeException( "no transformer", e);
} catch ( TransformerException e) {
Throwable t = e.getCause();
if ( t instanceof IOException) throw ( IOException) t;
assert false;
throw new RuntimeException( "transformer failed", e);
}
}
private static void setValue( Node node, String value) {
if ( node instanceof Text) {
node.setNodeValue( value);
} else if ( node instanceof Attr) {
if ( value == null) {
Attr attr = ( Attr) node;
attr.getOwnerElement().removeAttributeNode( attr);
} else {
node.setNodeValue( value);
}
} else {
deleteNodeAndFollowingSiblings( node.getFirstChild());
if ( value != null) node.appendChild( node.getOwnerDocument().createTextNode( value));
}
}
private static void deleteNodeAndFollowingSiblings( Node node) {
if ( node == null) return;
Node parent = node.getParentNode();
while ( true) {
Node sib = node.getNextSibling();
if ( sib == null) break;
parent.removeChild( sib);
}
parent.removeChild( node);
}
private static Node newNode( Node parent, String name) {
Document doc = parent.getOwnerDocument();
if ( "text()".equals( name)) {
Text child = doc.createTextNode( "");
parent.appendChild( child);
return child;
}
if ( name.charAt( 0) == '@') {
name = name.substring( 1);
Attr attr = doc.createAttributeNS( mapNamespacePrefix( name), name);
(( Element) parent).setAttributeNode( attr);
return attr;
}
Element child = doc.createElementNS( mapNamespacePrefix( name), name);
parent.appendChild( child);
return child;
}
private static String mapNamespacePrefix( String name) {
int pos = name.indexOf( ':');
if ( pos < 0) return null;
String prefix = name.substring( 0, pos);
return NAMESPACE_CONTEXT.getNamespaceURI( prefix);
}
public static String normalizeString( String string) {
if ( string == null) return null;
string = string.trim();
if ( "".equals( string)) return null;
return string;
}
private void writeObject( final ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
long length;
CountingOutputStream buf = new CountingOutputStream();
write( buf);
length = buf.size();
out.writeLong( length);
write( out);
}
private void readObject( final ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
read( new InputStream() {
private long length = in.readLong();
public int read() throws IOException {
if ( length <= 0) return -1;
length--;
return in.read();
}
public int read( byte[] b) throws IOException {
return read( b, 0, b.length);
}
public int read( byte[] b, int off, int len) throws IOException {
if ( length <= 0) return -1;
if ( len > length) len = ( int) length;
int result = in.read( b, off, len);
length -= result;
return result;
}
public long skip( long n) throws IOException {
if ( length <= 0) return 0;
if ( n > length) n = length;
long result = in.skip( n);
length -= result;
return result;
}
});
} catch ( SAXException e) {
IOException x = new IOException();
x.initCause( e);
throw x;
}
}
private static final SimpleNamespaceContext NAMESPACE_CONTEXT = new SimpleNamespaceContext();
static {
NAMESPACE_CONTEXT.addNamespace( "http://www.w3.org/XML/1998/namespace", "xml");
}
private XPathExpression xpath( String path) throws XPathExpressionException {
if ( xpath == null) xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext( NAMESPACE_CONTEXT);
return xpath.compile( path);
}
private static class CountingOutputStream extends FilterOutputStream {
private long count;
public CountingOutputStream() { super( null); }
public CountingOutputStream( OutputStream out) { super( out); }
public void write( int b) throws IOException {
count++;
if ( out != null) out.write( b);
}
public void write( byte[] b, int off, int len) throws IOException {
count += len;
if ( out != null) out.write( b, off, len);
}
public void flush() throws IOException {
if ( out != null) out.flush();
}
public long size() { return count; }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy