/** * 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.processor.serializer; import org.orbeon.dom.Document; import org.orbeon.oxf.common.OXFException; import org.orbeon.oxf.http.ApacheHttpUrlConnection; import org.orbeon.oxf.pipeline.api.PipelineContext; import org.orbeon.oxf.pipeline.api.TransformerXMLReceiver; import org.orbeon.oxf.processor.CacheableInputReader; import org.orbeon.oxf.processor.ProcessorImpl; import org.orbeon.oxf.processor.ProcessorInput; import org.orbeon.oxf.processor.ProcessorInputOutputInfo; import org.orbeon.oxf.processor.generator.URLGenerator; import org.orbeon.oxf.resources.ResourceManagerWrapper; import org.orbeon.oxf.resources.URLFactory; import org.orbeon.oxf.resources.handler.OXFHandler; import org.orbeon.oxf.util.StringUtils; import org.orbeon.oxf.xml.TransformerUtils; import org.orbeon.oxf.xml.XPathUtils; import javax.xml.transform.stream.StreamResult; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; public class URLSerializer extends ProcessorImpl { public URLSerializer() { addInputInfo(new ProcessorInputOutputInfo(INPUT_CONFIG, URLGenerator.URL_NAMESPACE_URI)); addInputInfo(new ProcessorInputOutputInfo(INPUT_DATA)); } public void start(PipelineContext pipelineContext) { try { // Create the URL from the configuration final URL url = readCacheInputAsObject(pipelineContext, getInputByName(INPUT_CONFIG), new CacheableInputReader<URL>() { public URL read(PipelineContext context, ProcessorInput input) { final Document configDocument = readInputAsOrbeonDom(context, input); final String urlString = XPathUtils.selectStringValueNormalize(configDocument, "/config/url"); return URLFactory.createURL(StringUtils.trimAllToEmpty(urlString)); } }); serialize(pipelineContext, url); } catch (Exception e) { throw new OXFException(e); } } public void serialize(PipelineContext pipelineContext, URL url) { try { if (OXFHandler.PROTOCOL.equals(url.getProtocol())) { // NOTE: This is probably done as an optimization. Is this really necessary? final OutputStream os = ResourceManagerWrapper.instance().getOutputStream(url.getFile()); try { final TransformerXMLReceiver identity = TransformerUtils.getIdentityTransformerHandler(); identity.setResult(new StreamResult(os)); readInputAsSAX(pipelineContext, INPUT_DATA, identity); } finally { // Clean up if (os != null) os.close(); } } else { // Open the URL // TODO: Use PropertiesApacheHttpClient directly so we can remove support for POST/PUT in ApacheHttpUrlConnection. final URLConnection conn = url.openConnection(); try { conn.setDoOutput(true); if (! (conn instanceof ApacheHttpUrlConnection)) conn.connect(); final OutputStream os = conn.getOutputStream(); try { // Create an identity transformer and start the transformation final TransformerXMLReceiver identity = TransformerUtils.getIdentityTransformerHandler(); identity.setResult(new StreamResult(os)); readInputAsSAX(pipelineContext, INPUT_DATA, identity); } finally { // Clean up if (os != null) os.close(); } if (conn instanceof ApacheHttpUrlConnection) conn.connect(); } finally { // Clean up if (conn instanceof HttpURLConnection) ((HttpURLConnection) conn).disconnect(); } } } catch (Exception e) { throw new OXFException(e); } } }