blob: 724b419469122ea2c93597553090b167746cccf3 [file] [log] [blame]
package org.apache.turbine.services.xmlrpc.util;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Turbine" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import javax.mail.internet.MimeUtility;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.turbine.Turbine;
import org.apache.turbine.services.servlet.TurbineServlet;
/**
* A Handler for use with the XML-RPC service that will deal
* with clients sending file to the server (Turbine application)
* and clients getting files from the server (Turbine application).
*
* 1) In the first case where the client sends a file to the server,
* the client has encoded the file contents and passes those
* encoded file contents on to the server:
*
* Client --------> encoded file contents -------------> Server
*
* The server must then decode the file contents and write the
* decoded file contents to disk.
*
* 2) In the second case where the client gets a file from the
* the server, the server has encoded the file contents and
* passes those encoded file contents on to the client:
*
* Client <------- encoded file contents <------------- Server
*
* The client must then decode the file contents and write the
* decoded file contents to disk.
*
* @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
* @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
* @version $Id$
* @deprecated This is not scope of the Service itself but of an
* application which uses the service. This class shouldn't
* be part of Turbine but of an addon application.
*/
public class FileHandler
{
/** Logging */
private static Log log = LogFactory.getLog(FileHandler.class);
/**
* Default Constructor
*/
public FileHandler()
{
}
/**
* The client has indicated that it would like
* to send a file to the server and have it
* stored in a certain location on the server.
*
* So a client Turbine application might use the
* following bit of code to send a file to a server
* Turbine application:
*
* TurbineXmlRpc.executeRpc("file.send", params)
*
* Where:
*
* params.get(0) = contents of the file as a string.
* params.get(1) = the name the file should have when it lands.
* params.get(2) = property describing where the file should land.
*
* @param fileContents The contents of the file to store. It
* is assumed that any xml content is properly encoded!
*
* @param fileName Name to give the file created to store
* the contents.
*
* @param targetLocationProperty storage location of this file
* is controlled by this property that is specified in
* the TR.props file or an included properties file.
*/
public boolean send(String fileContents,
String targetLocationProperty,
String fileName)
{
/*
* Simply take the file contents that have been sent
* by the client and write them to disk in the
* specified location: targetLocationProperty specifies
* the directory in which to place the fileContents
* with the name fileName.
*/
return writeFileContents(fileContents, targetLocationProperty,
fileName);
}
/**
* The client has indicated that it would like
* to get a file from the server.
*
* So a client Turbine application might use the
* following bit of code to get a file from a server
* Turbine application:
*
* TurbineXmlRpc.executeRpc("file.get", params)
*
* Where:
*
* params.get(0) = the name the file should have when it lands.
* params.get(1) = property describing where the file should land.
*
* @param fileName Name to give the file created to store
* the contents.
*
* @param targetLocationProperty storage location of this file
* is controlled by this property that is specified in
* the TR.props file or an included properties file.
*
* @return the file contents encoded with base64.
*/
public String get(String targetLocationProperty,
String fileName)
{
/*
* Place the contents of the file with the name
* fileName in the directory specified by
* targetLocationProperty.
*/
return readFileContents(targetLocationProperty, fileName);
}
/**
* Return the content of file encoded for transfer
*
* @param targetLocationProperty path to file to encode.
* @param fileName file to encode
* @return String encoded contents of the requested file.
*/
public static String readFileContents(String targetLocationProperty,
String fileName)
{
String location =
Turbine.getConfiguration().getString(targetLocationProperty);
if (StringUtils.isEmpty(location))
{
log.error("Could not load Property for location "
+ targetLocationProperty);
return null;
}
File tmpF = new File(".");
StringBuffer sb = new StringBuffer();
sb.append(location);
sb.append(File.separator);
sb.append(fileName);
String file = TurbineServlet.getRealPath(sb.toString());
StringWriter sw = null;
BufferedReader reader = null;
try
{
/*
* This little routine was borrowed from the
* velocity ContentResource class.
*/
sw = new StringWriter();
reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(file)));
char buf[] = new char[1024];
int len = 0;
while ((len = reader.read(buf, 0, 1024)) != -1)
{
sw.write(buf, 0, len);
}
return MimeUtility.encodeText(sw.toString(), "UTF-8", "B");
}
catch (IOException ioe)
{
log.error("[FileHandler] Unable to encode the contents " +
"of the request file.", ioe);
return null;
}
finally
{
try
{
if (sw != null)
{
sw.close();
}
if (reader != null)
{
reader.close();
}
}
catch (Exception e)
{
}
}
}
public static boolean writeFileContents(String fileContents,
String targetLocationProperty,
String fileName)
{
String location =
Turbine.getConfiguration().getString(targetLocationProperty);
if (StringUtils.isEmpty(location))
{
log.error("Could not load Property for location "
+ targetLocationProperty);
return false;
}
/*
* The target location is always within the webapp to
* make the application fully portable. So use the TurbineServlet
* service to map the target location in the webapp space.
*/
File targetLocation = new File(
TurbineServlet.getRealPath(location));
if (!targetLocation.exists())
{
/*
* If the target location doesn't exist then
* attempt to create the target location and any
* necessary parent directories as well.
*/
if (!targetLocation.mkdirs())
{
log.error("[FileHandler] Could not create target location: " +
targetLocation + ". Cannot transfer file from client.");
return false;
}
else
{
log.info("[FileHandler] Creating target location:" +
targetLocation +
" in order to complete file transfer from client.");
}
}
FileWriter fileWriter = null;
try
{
/*
* Try to create the target file and write it out
* to the target location.
*/
fileWriter = new FileWriter(
targetLocation + "/" + fileName);
/*
* It is assumed that the file has been encoded
* and therefore must be decoded before the
* contents of the file are stored to disk.
*/
fileWriter.write(MimeUtility.decodeText(fileContents));
return true;
}
catch (IOException ioe)
{
log.error("[FileHandler] Could not write the decoded file " +
"contents to disk for the following reason.", ioe);
return false;
}
finally
{
try
{
if (fileWriter != null)
{
fileWriter.close();
}
}
catch (Exception e)
{
}
}
}
/**
* Method to allow a client to remove a file from
* the server
*
* @param sourceLocationProperty
* @param sourceFileName
*/
public static void remove(String sourceLocationProperty,
String sourceFileName)
{
String location =
Turbine.getConfiguration().getString(sourceLocationProperty);
if (StringUtils.isEmpty(location))
{
log.error("Could not load Property for location "
+ sourceLocationProperty);
return;
}
/*
* The target location is always within the webapp to
* make the application fully portable. So use the TurbineServlet
* service to map the target location in the webapp space.
*/
File sourceFile =
new File(TurbineServlet.getRealPath(sourceLocationProperty
+ "/" + sourceFileName));
if (sourceFile.exists())
{
sourceFile.delete();
}
}
}