/**
* 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);
}
}
}