blob: 9f5561b6ee95bf3580e4dcf0ae8a3197dcc5996a [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2008 Oracle
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Konstantin Komissarchik - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.wst.common.project.facet.core.util.internal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
*/
public final class DomUtil
{
public static Document doc( final Reader r )
{
final DocumentBuilder docbuilder = docbuilder();
try
{
return docbuilder.parse( new InputSource( r ) );
}
catch( IOException e )
{
throw new XmlParseException( e );
}
catch( SAXParseException e )
{
throw new XmlParseException( e );
}
catch( SAXException e )
{
throw new XmlParseException( e );
}
}
public static Document doc( final InputStream stream )
{
final DocumentBuilder docbuilder = docbuilder();
try
{
return docbuilder.parse( stream );
}
catch( IOException e )
{
throw new XmlParseException( e );
}
catch( SAXParseException e )
{
throw new XmlParseException( e );
}
catch( SAXException e )
{
throw new XmlParseException( e );
}
}
public static Document doc( final String str )
{
return doc( new StringReader( str ) );
}
public static Document doc( final File f )
{
InputStream stream = null;
try
{
stream = new BufferedInputStream( new FileInputStream( f ) );
return doc( stream );
}
catch( IOException e )
{
throw new XmlParseException( e );
}
finally
{
if( stream != null )
{
try
{
stream.close();
}
catch( IOException e ) {}
}
}
}
public static Document doc()
{
return docbuilder().newDocument();
}
public static Element root( final Reader r )
{
return doc( r ).getDocumentElement();
}
public static Element root( final String str )
{
return doc( str ).getDocumentElement();
}
public static Element root( final File f )
{
return doc( f ).getDocumentElement();
}
public static Element element( final Element el,
final String name )
{
final NodeList nodes = el.getChildNodes();
for( int i = 0, n = nodes.getLength(); i < n; i++ )
{
final Node node = nodes.item( i );
if( node.getNodeType() == Node.ELEMENT_NODE &&
basename( node.getNodeName() ).equals( name ) )
{
return (Element) node;
}
}
return null;
}
public static Iterable<Element> elements( final Element el )
{
return new ElementsIterator( el.getChildNodes() );
}
public static Iterable<Element> elements( final Element el,
final String name )
{
return new ElementsIterator( el.getChildNodes(), name );
}
public static Iterable<Element> elements( final NodeList nodes )
{
return new ElementsIterator( nodes );
}
public static Iterable<Element> elements( final NodeList nodes,
final String name )
{
return new ElementsIterator( nodes, name );
}
public static final class ElementsIterator
implements Iterator<Element>, Iterable<Element>
{
private final NodeList nodes;
private final int length;
private final String name;
private int position;
private Element element;
public ElementsIterator( final NodeList nodes )
{
this( nodes, null );
}
public ElementsIterator( final NodeList nodes,
final String name )
{
this.nodes = nodes;
this.length = nodes.getLength();
this.position = -1;
this.name = name;
advance();
}
private void advance()
{
this.element = null;
this.position++;
for( ; this.position < this.length && this.element == null;
this.position++ )
{
final Node node = this.nodes.item( this.position );
if( node.getNodeType() == Node.ELEMENT_NODE &&
( this.name == null ||
basename( node.getNodeName() ).equals( this.name ) ) )
{
this.element = (Element) node;
}
}
}
public boolean hasNext()
{
return ( this.element != null );
}
public Element next()
{
final Element el = this.element;
if( el == null )
{
throw new NoSuchElementException();
}
advance();
return el;
}
public void remove()
{
throw new UnsupportedOperationException();
}
public Iterator<Element> iterator()
{
return this;
}
}
public static String text( final Element el )
{
final NodeList nodes = el.getChildNodes();
String str = null;
StringBuilder buf = null;
for( int i = 0, n = nodes.getLength(); i < n; i++ )
{
final Node node = nodes.item( i );
final short nodeType = node.getNodeType();
if( nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE )
{
final String val = node.getNodeValue();
if( buf != null )
{
buf.append( val );
}
else if( str != null )
{
buf = new StringBuilder();
buf.append( str );
buf.append( val );
str = null;
}
else
{
str = val;
}
}
}
if( buf != null )
{
return buf.toString();
}
else
{
return str;
}
}
public static String text( final Element el,
final String childElementName )
{
final Element childElement = element( el, childElementName );
if( childElement == null )
{
return null;
}
else
{
return text( childElement );
}
}
public static String basename( final String name )
{
final int colon = name.indexOf( ':' );
if( colon != -1 )
{
return name.substring( colon + 1 );
}
else
{
return name;
}
}
public static void write( final Document doc,
final File file )
{
try
{
final DOMSource source = new DOMSource( doc );
final StreamResult result = new StreamResult( file );
final TransformerFactory factory = TransformerFactory.newInstance();
final Transformer transformer = factory.newTransformer();
transformer.transform( source, result );
}
catch( TransformerConfigurationException e )
{
throw new RuntimeException( e );
}
catch( TransformerException e )
{
throw new RuntimeException( e );
}
}
private static DocumentBuilder docbuilder()
{
try
{
final DocumentBuilderFactory factory
= DocumentBuilderFactory.newInstance();
factory.setValidating( false );
factory.setNamespaceAware( true );
factory.setIgnoringComments( false );
final DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver
(
new EntityResolver()
{
public InputSource resolveEntity( final String publicID,
final String systemID )
{
return new InputSource( new StringReader( "" ) ); //$NON-NLS-1$
}
}
);
return builder;
}
catch( ParserConfigurationException e )
{
throw new RuntimeException( e );
}
}
}