/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source 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 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.jstl.el;
import com.caucho.el.Expr;
import com.caucho.jsp.PageContextImpl;
import com.caucho.jstl.NameValueTag;
import com.caucho.util.L10N;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.Vfs;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.el.ELContext;
import javax.el.ELException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.logging.Logger;
public class XmlTransformTag extends BodyTagSupport implements NameValueTag {
private static final Logger log
= Logger.getLogger(XmlTransformTag.class.getName());
private static final L10N L = new L10N(XmlTransformTag.class);
private Expr _xml;
private Expr _xslt;
private Expr _xmlSystemId;
private Expr _xsltSystemId;
private String _var;
private String _scope;
private Expr _result;
private ArrayList<String> _paramNames = new ArrayList<String>();
private ArrayList<String> _paramValues = new ArrayList<String>();
/**
* Sets the JSP-EL XML value.
*/
public void setXml(Expr xml)
{
setDoc(xml);
}
/**
* Sets the JSP-EL XML value.
*/
public void setDoc(Expr xml)
{
_xml = xml;
}
/**
* Sets the JSP-EL XML value.
*/
public void setXslt(Expr xslt)
{
_xslt = xslt;
}
/**
* Sets the JSP-EL XML system id expr.
*/
public void setXmlSystemId(Expr xmlSystemId)
{
_xmlSystemId = xmlSystemId;
}
/**
* Sets the JSP-EL XML system id expr.
*/
public void setDocSystemId(Expr xmlSystemId)
{
_xmlSystemId = xmlSystemId;
}
/**
* Sets the JSP-EL XSLT system id.
*/
public void setXsltSystemId(Expr xsltSystemId)
{
_xsltSystemId = xsltSystemId;
}
/**
* Sets the variable
*/
public void setVar(String var)
{
_var = var;
}
/**
* Sets the scope
*/
public void setScope(String scope)
{
_scope = scope;
}
/**
* Sets the result
*/
public void setResult(Expr result)
{
_result = result;
}
/**
* Adds a parameter.
*/
public void addParam(String name, String value)
{
_paramNames.add(name);
_paramValues.add(value);
}
/**
* Process the tag.
*/
public int doStartTag()
throws JspException
{
_paramNames.clear();
_paramValues.clear();
return EVAL_BODY_BUFFERED;
}
/**
* Process the tag.
*/
public int doEndTag()
throws JspException
{
try {
PageContextImpl pageContext = (PageContextImpl) this.pageContext;
ELContext env = pageContext.getELContext();
JspWriter out = pageContext.getOut();
TransformerFactory factory = TransformerFactory.newInstance();
Source source = getSource(_xslt, _xsltSystemId);
Transformer transformer = factory.newTransformer(source);
for (int i = 0; i < _paramNames.size(); i++) {
String name = _paramNames.get(i);
String value = _paramValues.get(i);
transformer.setParameter(name, value);
}
if (_xml != null)
source = getSource(_xml, _xmlSystemId);
else {
BodyContent bodyContent = getBodyContent();
source = new StreamSource(bodyContent.getReader());
source.setSystemId(((HttpServletRequest) pageContext.getRequest()).getRequestURI());
}
Result result;
Node top = null;
if (_result != null) {
result = (Result) _result.evalObject(env);
}
else if (_var != null) {
top = new com.caucho.xml.QDocument();
result = new DOMResult(top);
}
else
result = new StreamResult(out);
transformer.transform(source, result);
if (_var != null)
CoreSetTag.setValue(pageContext, _var, _scope, top);
} catch (Exception e) {
throw new JspException(e);
}
return SKIP_BODY;
}
private Source getSource(Expr xmlExpr, Expr systemIdExpr)
throws JspException
{
try {
PageContextImpl pageContext = (PageContextImpl) this.pageContext;
Object xmlObj = xmlExpr.evalObject(pageContext.getELContext());
String systemId = null;
Source source = null;
if (systemIdExpr != null)
systemId = systemIdExpr.evalString(pageContext.getELContext());
source = convertToSource(xmlObj, systemId);
return source;
} catch (ELException e) {
throw new JspException(e);
}
}
public static Source convertToSource(Object xmlObj, String systemId)
throws JspException
{
if (xmlObj instanceof String) {
ReadStream is = Vfs.openString((String) xmlObj);
return new StreamSource(is, systemId);
}
else if (xmlObj instanceof InputStream) {
return new StreamSource((InputStream) xmlObj, systemId);
}
else if (xmlObj instanceof Reader) {
return new StreamSource((Reader) xmlObj, systemId);
}
else if (xmlObj instanceof Node) {
return new DOMSource((Node) xmlObj, systemId);
}
else if (xmlObj instanceof NodeList) {
return new DOMSource(((NodeList) xmlObj).item(0), systemId);
}
else if (xmlObj instanceof Source)
return (Source) xmlObj;
else if (xmlObj instanceof ArrayList) {
ArrayList list = (ArrayList) xmlObj;
if (list.size() > 0)
return convertToSource(list.get(0), systemId);
}
throw new JspException(L.l("unknown xml object type '{0}' '{1}'",
xmlObj, xmlObj.getClass()));
}
}