/** * Copyright (C) 2010 Orbeon, Inc. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License, or (at your option) any later version. * * This program 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 Lesser General Public License for more details. * * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html */ package org.orbeon.oxf.xforms.function.xxforms; import org.orbeon.oxf.pipeline.api.PipelineContext; import org.orbeon.oxf.processor.transformer.TransformerURIResolver; import org.orbeon.oxf.xforms.function.XFormsFunction; import org.orbeon.oxf.xml.XMLParsing; import org.orbeon.oxf.xml.XMLReceiverAdapter; import org.orbeon.saxon.expr.ExpressionVisitor; import org.orbeon.saxon.expr.StaticContext; import org.orbeon.saxon.expr.XPathContext; import org.orbeon.saxon.om.Item; import org.orbeon.saxon.trans.XPathException; import org.orbeon.saxon.value.BooleanValue; import org.orbeon.saxon.value.StringValue; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import javax.xml.transform.sax.SAXSource; /* * NOTE: this class inspired by Saxon's UnparsedText.java. */ public class XXFormsDocBase64 extends XFormsFunction { private String expressionBaseURI; public static final int DOC_BASE64 = 0; public static final int DOC_BASE64_AVAILABLE = 1; @Override public void checkArguments(ExpressionVisitor visitor) throws XPathException { if (expressionBaseURI == null) { final StaticContext env = visitor.getStaticContext(); super.checkArguments(visitor); expressionBaseURI = env.getBaseURI(); } } @Override public Item evaluateItem(XPathContext context) throws XPathException { final StringValue result; try { final StringValue url = (StringValue) argument[0].evaluateItem(context); if (url == null) { return null; } result = new StringValue(readFile(url.getStringValue(), expressionBaseURI)); } catch (XPathException e) { if (operation == DOC_BASE64_AVAILABLE) { return BooleanValue.FALSE; } else { throw e; } } if (operation == DOC_BASE64_AVAILABLE) { return BooleanValue.TRUE; } else { return result; } } private CharSequence readFile(String href, String baseURI) throws XPathException { try { // Use resolver as it does a series of tasks for us, and use "binary" mode final TransformerURIResolver resolver = new TransformerURIResolver(null, PipelineContext.get(), null, XMLParsing.ParserConfiguration.PLAIN, "binary"); final StringBuilder sb = new StringBuilder(1024); // Get SAX source using crazy SAX API // Source produces a binary document (content Base64-encoded) final SAXSource source = (SAXSource) resolver.resolve(href, baseURI); final XMLReader xmlReader = source.getXMLReader(); xmlReader.setContentHandler(new XMLReceiverAdapter() { public void characters(char ch[], int start, int length) throws SAXException { // Append Base64-encoded text only sb.append(ch, start, length); } }); xmlReader.parse(source.getInputSource()); // Return content formatted as Base64 return sb.toString(); } catch (Exception e) { throw new XPathException(e); } } }