Initial revision
From-SVN: r102074
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/* ErrorListenerErrorHandler.java -
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.xml.libxmlj.transform;
|
||||
|
||||
import javax.xml.transform.ErrorListener;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Provides a SAX ErrorHandler interface to an ErrorListener.
|
||||
*
|
||||
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
|
||||
*/
|
||||
class ErrorListenerErrorHandler
|
||||
implements ErrorHandler
|
||||
{
|
||||
|
||||
private ErrorListener listener;
|
||||
|
||||
ErrorListenerErrorHandler (ErrorListener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void warning (SAXParseException e)
|
||||
throws SAXException
|
||||
{
|
||||
try
|
||||
{
|
||||
listener.warning (new TransformerException (e));
|
||||
}
|
||||
catch (TransformerException te)
|
||||
{
|
||||
throw getSAXException (te);
|
||||
}
|
||||
}
|
||||
|
||||
public void error (SAXParseException e)
|
||||
throws SAXException
|
||||
{
|
||||
try
|
||||
{
|
||||
listener.error (new TransformerException (e));
|
||||
}
|
||||
catch (TransformerException te)
|
||||
{
|
||||
throw getSAXException (te);
|
||||
}
|
||||
}
|
||||
|
||||
public void fatalError (SAXParseException e)
|
||||
throws SAXException
|
||||
{
|
||||
try
|
||||
{
|
||||
listener.fatalError (new TransformerException (e));
|
||||
}
|
||||
catch (TransformerException te)
|
||||
{
|
||||
throw getSAXException (te);
|
||||
}
|
||||
}
|
||||
|
||||
private SAXException getSAXException (TransformerException e)
|
||||
{
|
||||
Throwable cause = e.getCause ();
|
||||
if (cause instanceof SAXException)
|
||||
{
|
||||
return (SAXException) cause;
|
||||
}
|
||||
return new SAXException (e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,572 @@
|
||||
/* GnomeTransformer.java -
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.xml.libxmlj.transform;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.xml.transform.ErrorListener;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.SourceLocator;
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Templates;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
|
||||
import gnu.xml.libxmlj.dom.GnomeDocument;
|
||||
import gnu.xml.libxmlj.sax.GnomeXMLReader;
|
||||
import gnu.xml.libxmlj.util.NamedInputStream;
|
||||
import gnu.xml.libxmlj.util.StandaloneLocator;
|
||||
import gnu.xml.libxmlj.util.XMLJ;
|
||||
|
||||
/**
|
||||
* An implementation of {@link javax.xml.transform.Transformer} which
|
||||
* performs XSLT transformation using <code>libxslt</code>.
|
||||
*
|
||||
* @author Julian Scheid
|
||||
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
|
||||
*/
|
||||
public class GnomeTransformer
|
||||
extends Transformer
|
||||
implements Templates
|
||||
{
|
||||
|
||||
/**
|
||||
* The parameters added by the user via {@link setParameter()}.
|
||||
*/
|
||||
private Map parameters;
|
||||
|
||||
/**
|
||||
* The output properties set by the user.
|
||||
*/
|
||||
private Properties outputProperties;
|
||||
|
||||
/**
|
||||
* The URI resolver to use during transformation.
|
||||
*/
|
||||
private URIResolver resolver;
|
||||
|
||||
/**
|
||||
* The error listener for transformation errors.
|
||||
*/
|
||||
private ErrorListener errorListener;
|
||||
|
||||
/**
|
||||
* Handle to the source stylesheet.
|
||||
* This is a native pointer of type xsltStylesheetPtr.
|
||||
*/
|
||||
private Object stylesheet;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param source the XSLT stylesheet document source
|
||||
* @param resolver the resolver to use during transformation
|
||||
* @param errorListener the error listener for transformation errors
|
||||
*/
|
||||
GnomeTransformer (Source source,
|
||||
URIResolver resolver,
|
||||
ErrorListener errorListener)
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
this.resolver = resolver;
|
||||
this.errorListener = errorListener;
|
||||
parameters = new HashMap ();
|
||||
outputProperties = new Properties ();
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
stylesheet = newStylesheet ();
|
||||
}
|
||||
else if (source instanceof StreamSource)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamSource ss = (StreamSource) source;
|
||||
NamedInputStream in = XMLJ.getInputStream (ss);
|
||||
String systemId = ss.getSystemId ();
|
||||
String publicId = ss.getPublicId ();
|
||||
String base = XMLJ.getBaseURI (systemId);
|
||||
byte[] detectBuffer = in.getDetectBuffer ();
|
||||
if (detectBuffer == null)
|
||||
{
|
||||
String msg = "No document element";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
stylesheet = newStylesheetFromStream (in, detectBuffer, publicId,
|
||||
systemId, base,
|
||||
(resolver != null),
|
||||
(errorListener != null));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformerConfigurationException (e);
|
||||
}
|
||||
}
|
||||
else if (source instanceof DOMSource)
|
||||
{
|
||||
DOMSource ds = (DOMSource) source;
|
||||
Node node = ds.getNode ();
|
||||
if (!(node instanceof GnomeDocument))
|
||||
{
|
||||
String msg = "Node is not a GnomeDocument";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
GnomeDocument doc = (GnomeDocument) node;
|
||||
stylesheet = newStylesheetFromDoc (doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = "Source type not supported (" + source + ")";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
private GnomeTransformer (Object stylesheet,
|
||||
URIResolver resolver,
|
||||
ErrorListener errorListener,
|
||||
Map parameters,
|
||||
Properties outputProperties)
|
||||
{
|
||||
this.stylesheet = stylesheet;
|
||||
this.resolver = resolver;
|
||||
this.errorListener = errorListener;
|
||||
this.parameters = parameters;
|
||||
this.outputProperties = outputProperties;
|
||||
}
|
||||
|
||||
private native Object newStylesheet ()
|
||||
throws TransformerConfigurationException;
|
||||
|
||||
private native Object newStylesheetFromStream (InputStream in,
|
||||
byte[] detectBuffer,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String base,
|
||||
boolean entityResolver,
|
||||
boolean errorHandler)
|
||||
throws TransformerConfigurationException;
|
||||
|
||||
private native Object newStylesheetFromDoc (GnomeDocument doc)
|
||||
throws TransformerConfigurationException;
|
||||
|
||||
//--- Implementation of javax.xml.transform.Transformer follows.
|
||||
|
||||
// Set, get and clear the parameters to use on transformation
|
||||
|
||||
public synchronized void setParameter (String parameter, Object value)
|
||||
{
|
||||
parameters.put (parameter, value);
|
||||
}
|
||||
|
||||
public synchronized Object getParameter (String name)
|
||||
{
|
||||
return parameters.get (name);
|
||||
}
|
||||
|
||||
public synchronized void clearParameters ()
|
||||
{
|
||||
parameters.clear ();
|
||||
}
|
||||
|
||||
// Set and get the ErrorListener to use on transformation
|
||||
|
||||
public void setErrorListener (ErrorListener listener)
|
||||
{
|
||||
this.errorListener = listener;
|
||||
}
|
||||
|
||||
public ErrorListener getErrorListener ()
|
||||
{
|
||||
return errorListener;
|
||||
}
|
||||
|
||||
// Set and get the URIResolver to use on transformation
|
||||
|
||||
public void setURIResolver (URIResolver resolver)
|
||||
{
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public URIResolver getURIResolver ()
|
||||
{
|
||||
return resolver;
|
||||
}
|
||||
|
||||
// Set the output properties to use on transformation; get default
|
||||
// output properties and output properties specified in the
|
||||
// stylesheet or by the user.
|
||||
|
||||
public void setOutputProperties (Properties outputProperties)
|
||||
{
|
||||
// Note: defensive copying
|
||||
this.outputProperties = new Properties (outputProperties);
|
||||
}
|
||||
|
||||
public void setOutputProperty (String name, String value)
|
||||
{
|
||||
outputProperties.setProperty (name, value);
|
||||
}
|
||||
|
||||
public Properties getOutputProperties ()
|
||||
{
|
||||
// Note: defensive copying
|
||||
return new Properties (this.outputProperties);
|
||||
}
|
||||
|
||||
public String getOutputProperty (String name)
|
||||
{
|
||||
return outputProperties.getProperty (name);
|
||||
}
|
||||
|
||||
// -- Templates --
|
||||
|
||||
public Transformer newTransformer ()
|
||||
{
|
||||
return new GnomeTransformer (stylesheet, resolver, errorListener,
|
||||
new HashMap (parameters),
|
||||
new Properties (outputProperties));
|
||||
}
|
||||
|
||||
// -- transform --
|
||||
|
||||
/**
|
||||
* Transforms the given source and writes the result to the
|
||||
* given target.
|
||||
*/
|
||||
public void transform (Source source, Result result)
|
||||
throws TransformerException
|
||||
{
|
||||
if (source instanceof StreamSource)
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamSource ss = (StreamSource) source;
|
||||
NamedInputStream in = XMLJ.getInputStream (ss);
|
||||
String publicId = ss.getPublicId ();
|
||||
String systemId = ss.getSystemId ();
|
||||
String base = XMLJ.getBaseURI (systemId);
|
||||
byte[] detectBuffer = in.getDetectBuffer ();
|
||||
if (detectBuffer == null)
|
||||
{
|
||||
throw new TransformerException ("No document element");
|
||||
}
|
||||
if (result instanceof StreamResult)
|
||||
{
|
||||
OutputStream out = XMLJ.getOutputStream ((StreamResult) result);
|
||||
transformStreamToStream (in, detectBuffer, publicId, systemId,
|
||||
base, (resolver != null),
|
||||
(errorListener != null), out);
|
||||
}
|
||||
else if (result instanceof DOMResult)
|
||||
{
|
||||
DOMResult dr = (DOMResult) result;
|
||||
GnomeDocument ret =
|
||||
transformStreamToDoc (in, detectBuffer, publicId, systemId,
|
||||
base, (resolver != null),
|
||||
(errorListener != null));
|
||||
dr.setNode (ret);
|
||||
dr.setSystemId (null);
|
||||
}
|
||||
else if (result instanceof SAXResult)
|
||||
{
|
||||
SAXResult sr = (SAXResult) result;
|
||||
transformStreamToSAX (in, detectBuffer, publicId, systemId,
|
||||
base, (resolver != null),
|
||||
(errorListener != null),
|
||||
getSAXContext (sr));
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = "Result type not supported (" + result + ")";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformerException (e);
|
||||
}
|
||||
}
|
||||
else if (source instanceof DOMSource)
|
||||
{
|
||||
DOMSource ds = (DOMSource) source;
|
||||
Node node = ds.getNode ();
|
||||
if (!(node instanceof GnomeDocument))
|
||||
{
|
||||
String msg = "Node is not a GnomeDocument (" + node + ")";
|
||||
throw new TransformerException (msg);
|
||||
}
|
||||
GnomeDocument doc = (GnomeDocument) node;
|
||||
if (result instanceof StreamResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
OutputStream out = XMLJ.getOutputStream ((StreamResult) result);
|
||||
transformDocToStream (doc, out);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformerException (e);
|
||||
}
|
||||
}
|
||||
else if (result instanceof DOMResult)
|
||||
{
|
||||
DOMResult dr = (DOMResult) result;
|
||||
GnomeDocument ret = transformDocToDoc (doc);
|
||||
dr.setNode (ret);
|
||||
dr.setSystemId (null);
|
||||
}
|
||||
else if (result instanceof SAXResult)
|
||||
{
|
||||
SAXResult sr = (SAXResult) result;
|
||||
transformDocToSAX (doc, getSAXContext (sr));
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = "Result type not supported";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String msg = "Source type not supported";
|
||||
throw new TransformerConfigurationException (msg);
|
||||
}
|
||||
}
|
||||
|
||||
private GnomeXMLReader getSAXContext (SAXResult result)
|
||||
{
|
||||
GnomeXMLReader ctx = new GnomeXMLReader ();
|
||||
ctx.setContentHandler (result.getHandler ());
|
||||
ctx.setLexicalHandler (result.getLexicalHandler ());
|
||||
if (errorListener != null)
|
||||
{
|
||||
ErrorHandler errorHandler =
|
||||
new ErrorListenerErrorHandler (errorListener);
|
||||
ctx.setErrorHandler (errorHandler);
|
||||
}
|
||||
if (resolver != null)
|
||||
{
|
||||
EntityResolver entityResolver =
|
||||
new URIResolverEntityResolver (resolver);
|
||||
ctx.setEntityResolver (entityResolver);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
private native void transformStreamToStream (InputStream in,
|
||||
byte[] detectBuffer,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String base,
|
||||
boolean entityResolver,
|
||||
boolean errorHandler,
|
||||
OutputStream out)
|
||||
throws TransformerException;
|
||||
|
||||
private native GnomeDocument transformStreamToDoc (InputStream in,
|
||||
byte[] detectBuffer,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String base,
|
||||
boolean entityResolver,
|
||||
boolean errorHandler)
|
||||
throws TransformerException;
|
||||
|
||||
private native void transformStreamToSAX (InputStream in,
|
||||
byte[] detectBuffer,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String base,
|
||||
boolean entityResolver,
|
||||
boolean errorHandler,
|
||||
GnomeXMLReader out)
|
||||
throws TransformerException;
|
||||
|
||||
private native void transformDocToStream (GnomeDocument in,
|
||||
OutputStream out)
|
||||
throws TransformerException;
|
||||
|
||||
private native GnomeDocument transformDocToDoc (GnomeDocument in)
|
||||
throws TransformerException;
|
||||
|
||||
private native void transformDocToSAX (GnomeDocument in,
|
||||
GnomeXMLReader out)
|
||||
throws TransformerException;
|
||||
|
||||
/*
|
||||
* Retrieve parameters as a string array.
|
||||
* This is a convenience method called from native code.
|
||||
*/
|
||||
private String[] getParameterArray ()
|
||||
{
|
||||
String[] parameterArray = new String[parameters.size () * 2];
|
||||
int index = 0;
|
||||
for (Iterator it = parameters.keySet ().iterator ();
|
||||
it.hasNext ();
|
||||
++index)
|
||||
{
|
||||
String parameterKey = (String) it.next ();
|
||||
String parameterValue = (String) parameters.get (parameterKey);
|
||||
parameterArray[index * 2 + 0] = parameterKey;
|
||||
parameterArray[index * 2 + 1] =
|
||||
"'" + ((parameterValue != null) ? parameterValue : "") + "'";
|
||||
// FIXME encode parameter value correctly for XPath
|
||||
}
|
||||
return parameterArray;
|
||||
}
|
||||
|
||||
// -- Free xsltStylesheet handle --
|
||||
|
||||
public void finalize ()
|
||||
{
|
||||
if (stylesheet != null)
|
||||
{
|
||||
free ();
|
||||
stylesheet = null;
|
||||
}
|
||||
}
|
||||
|
||||
private native void free ();
|
||||
|
||||
// -- Callbacks --
|
||||
|
||||
private InputStream resolveEntity (String publicId, String systemId)
|
||||
throws TransformerException
|
||||
{
|
||||
if (resolver != null)
|
||||
{
|
||||
systemId = resolver.resolve (null, systemId).getSystemId ();
|
||||
}
|
||||
if (systemId == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
URL url = new URL (systemId);
|
||||
return XMLJ.getInputStream (url);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformerException (e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDocumentLocator (Object ctx, Object loc)
|
||||
{
|
||||
}
|
||||
|
||||
private void warning (String message,
|
||||
int lineNumber,
|
||||
int columnNumber,
|
||||
String publicId,
|
||||
String systemId)
|
||||
throws TransformerException
|
||||
{
|
||||
if (errorListener == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SourceLocator l = new StandaloneLocator (lineNumber,
|
||||
columnNumber,
|
||||
publicId,
|
||||
systemId);
|
||||
errorListener.warning (new TransformerException (message, l));
|
||||
}
|
||||
|
||||
private void error (String message,
|
||||
int lineNumber,
|
||||
int columnNumber,
|
||||
String publicId,
|
||||
String systemId)
|
||||
throws TransformerException
|
||||
{
|
||||
if (errorListener == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SourceLocator l = new StandaloneLocator (lineNumber,
|
||||
columnNumber,
|
||||
publicId,
|
||||
systemId);
|
||||
errorListener.error (new TransformerException (message, l));
|
||||
}
|
||||
|
||||
private void fatalError (String message,
|
||||
int lineNumber,
|
||||
int columnNumber,
|
||||
String publicId,
|
||||
String systemId)
|
||||
throws TransformerException
|
||||
{
|
||||
if (errorListener == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SourceLocator l = new StandaloneLocator (lineNumber,
|
||||
columnNumber,
|
||||
publicId,
|
||||
systemId);
|
||||
errorListener.fatalError (new TransformerException (message, l));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/* GnomeTransformerFactory.java -
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.xml.libxmlj.transform;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
import javax.xml.transform.ErrorListener;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Templates;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import gnu.xml.libxmlj.util.XMLJ;
|
||||
|
||||
/**
|
||||
* An implementation of <code>TransformerFactory</code> producing
|
||||
* <code>Transformer</code> objects which use <code>libxslt</code>
|
||||
* for transformation.
|
||||
*
|
||||
* @author Julian Scheid
|
||||
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
|
||||
*/
|
||||
public class GnomeTransformerFactory
|
||||
extends TransformerFactory
|
||||
{
|
||||
|
||||
static
|
||||
{
|
||||
XMLJ.init ();
|
||||
}
|
||||
|
||||
/**
|
||||
* URIResolver set by user, or default implementation.
|
||||
*/
|
||||
private URIResolver uriResolver;
|
||||
|
||||
/**
|
||||
* ErrorListener set by user, or default implementation.
|
||||
*/
|
||||
private ErrorListener errorListener;
|
||||
|
||||
/**
|
||||
* Attributes set by user.
|
||||
*/
|
||||
private Map attributes = new HashMap ();
|
||||
|
||||
//--- Implementation of javax.xml.transform.TransformerFactory
|
||||
//--- follows.
|
||||
|
||||
// -- begin getAssociatedStylesheet implementation --
|
||||
|
||||
/**
|
||||
* Returns the stylesheet associated with the specified XML source, or
|
||||
* <code>null</code> if no associated stylesheet could be found.
|
||||
*/
|
||||
public Source getAssociatedStylesheet(Source source, String media,
|
||||
String title, String charset)
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
String href= null;
|
||||
String base = source.getSystemId();
|
||||
if (source instanceof DOMSource)
|
||||
{
|
||||
Node node = ((DOMSource) source).getNode();
|
||||
Document doc = (node.getNodeType() == Node.DOCUMENT_NODE) ?
|
||||
(Document) node : node.getOwnerDocument();
|
||||
if (base == null)
|
||||
{
|
||||
base = doc.getDocumentURI();
|
||||
}
|
||||
for (node = doc.getFirstChild(); node != null;
|
||||
node = node.getNextSibling())
|
||||
{
|
||||
if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
|
||||
"xml-stylesheet".equals(node.getNodeName()))
|
||||
{
|
||||
String data = node.getNodeValue();
|
||||
if (media != null &&
|
||||
!media.equals(parseParameter(data, "type")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (title != null &&
|
||||
!title.equals(parseParameter(data, "title")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
href = parseParameter(data, "href");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InputSource input;
|
||||
XMLReader parser = null;
|
||||
try
|
||||
{
|
||||
if (source instanceof SAXSource)
|
||||
{
|
||||
SAXSource sax = (SAXSource) source;
|
||||
input = sax.getInputSource();
|
||||
parser = sax.getXMLReader();
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamSource stream = (StreamSource) source;
|
||||
InputStream in = stream.getInputStream();
|
||||
input = new InputSource(in);
|
||||
}
|
||||
input.setSystemId(base);
|
||||
if (parser == null)
|
||||
{
|
||||
parser = createXMLReader();
|
||||
}
|
||||
AssociatedStylesheetHandler ash =
|
||||
new AssociatedStylesheetHandler();
|
||||
ash.media = media;
|
||||
ash.title = title;
|
||||
parser.setContentHandler(ash);
|
||||
parser.parse(input);
|
||||
href = ash.href;
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
throw new TransformerConfigurationException(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformerConfigurationException(e);
|
||||
}
|
||||
}
|
||||
if (href == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (base != null)
|
||||
{
|
||||
base = XMLJ.getBaseURI(base);
|
||||
}
|
||||
href = XMLJ.getAbsoluteURI(base, href);
|
||||
return new StreamSource(href);
|
||||
}
|
||||
|
||||
private XMLReader createXMLReader()
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
try
|
||||
{
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
return parser.getXMLReader();
|
||||
}
|
||||
catch (FactoryConfigurationError e)
|
||||
{
|
||||
throw new TransformerConfigurationException(e);
|
||||
}
|
||||
catch (ParserConfigurationException e)
|
||||
{
|
||||
throw new TransformerConfigurationException(e);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
throw new TransformerConfigurationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
class AssociatedStylesheetHandler
|
||||
extends DefaultHandler
|
||||
{
|
||||
|
||||
String media;
|
||||
String title;
|
||||
String href;
|
||||
|
||||
public void processingInstruction(String target, String data)
|
||||
throws SAXException
|
||||
{
|
||||
if ("xml-stylesheet".equals(target))
|
||||
{
|
||||
if (media != null && !media.equals(parseParameter(data, "type")))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (title != null && !title.equals(parseParameter(data, "title")))
|
||||
{
|
||||
return;
|
||||
}
|
||||
href = parseParameter(data, "href");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String parseParameter(String data, String name)
|
||||
{
|
||||
int start = data.indexOf(name + "=");
|
||||
if (start != -1)
|
||||
{
|
||||
start += name.length() + 2;
|
||||
char delim = data.charAt(start - 1);
|
||||
int end = data.indexOf(delim, start);
|
||||
if (end != -1)
|
||||
{
|
||||
return data.substring(start, end);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// -- end getAssociatedStylesheet implementation --
|
||||
|
||||
public synchronized void setAttribute (String name, Object value)
|
||||
{
|
||||
this.attributes.put (name, value);
|
||||
}
|
||||
|
||||
public synchronized Object getAttribute (String name)
|
||||
{
|
||||
return attributes.get (name);
|
||||
}
|
||||
|
||||
public void setErrorListener (ErrorListener errorListener)
|
||||
{
|
||||
this.errorListener = errorListener;
|
||||
}
|
||||
|
||||
public ErrorListener getErrorListener ()
|
||||
{
|
||||
return errorListener;
|
||||
}
|
||||
|
||||
public void setURIResolver (URIResolver uriResolver)
|
||||
{
|
||||
this.uriResolver = uriResolver;
|
||||
}
|
||||
|
||||
public URIResolver getURIResolver ()
|
||||
{
|
||||
return uriResolver;
|
||||
}
|
||||
|
||||
public boolean getFeature (String name)
|
||||
{
|
||||
return (StreamSource.FEATURE.equals (name) ||
|
||||
StreamResult.FEATURE.equals (name) ||
|
||||
DOMSource.FEATURE.equals (name) ||
|
||||
DOMResult.FEATURE.equals (name));
|
||||
}
|
||||
|
||||
public void setFeature(String name, boolean value)
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
throw new TransformerConfigurationException(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of class {@link Transformer} for a
|
||||
* null souce.
|
||||
*/
|
||||
public Transformer newTransformer ()
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
return newTransformer (null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of class {@link Transformer} for
|
||||
* the given souce.
|
||||
*/
|
||||
public Transformer newTransformer (Source source)
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
return new GnomeTransformer (source, uriResolver, errorListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new instance of class {@link Templates} for
|
||||
* the given souce.
|
||||
*/
|
||||
public Templates newTemplates (Source source)
|
||||
throws TransformerConfigurationException
|
||||
{
|
||||
return new GnomeTransformer (source, uriResolver, errorListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform native cleanup.
|
||||
*/
|
||||
public static native void freeLibxsltGlobal ();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* URIResolverEntityResolver.java -
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.xml.libxmlj.transform;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Provides an EntityResolver interface to a URIResolver.
|
||||
*
|
||||
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
|
||||
*/
|
||||
class URIResolverEntityResolver
|
||||
implements EntityResolver
|
||||
{
|
||||
|
||||
private URIResolver resolver;
|
||||
|
||||
URIResolverEntityResolver (URIResolver resolver)
|
||||
{
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public InputSource resolveEntity (String publicId, String systemId)
|
||||
throws SAXException, IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return SAXSource.sourceToInputSource (resolver.resolve (systemId,
|
||||
null));
|
||||
}
|
||||
catch (TransformerException e)
|
||||
{
|
||||
Throwable cause = e.getCause ();
|
||||
if (cause instanceof SAXException)
|
||||
{
|
||||
throw (SAXException) cause;
|
||||
}
|
||||
else if (cause instanceof IOException)
|
||||
{
|
||||
throw (IOException) cause;
|
||||
}
|
||||
throw new SAXException (e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<body>
|
||||
<p>
|
||||
A JAXP-compliant wrapper for the XSLT C library for Gnome, also
|
||||
known as libxslt. Allows to use libxslt via the Java API for XML
|
||||
processing.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Usage:</b>
|
||||
<li>Set the system property <code>javax.xml.transform.TransformerFactory</code>
|
||||
to <code>gnu.xml.libxmlj.GnomeTransformerFactory</code>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
</body>
|
||||
Reference in New Issue
Block a user