import org.apache.cocoon.acting.AbstractAction;
import org.apache.cocoon.servlet.multipart.Part;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.http.HttpRequest;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.thread.ThreadSafe;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* This action takes care about file uploading.
* as input parameters will be:<br>
* number-of-files - int - specified in the upload form<br>
* file-form-field-prefix - name of form field
* name of form field for processing will be file-form-field-prefix + number-of-files
* i.e. "myfile1", ...<br>
* upload-directory - path where the file/s will be saved<br>
* overwrite-file - deny, allow, rename<br>
* Action returns back to sitemap the path+name of uploaded files
*
* @author Roman Hrivik
*/
public class FileUploadAction extends AbstractAction
implements ThreadSafe
{
/**
* number-of-files parameter name
*/
private static final String PARAM_NUMBER_OF_FILES = "number-of-files";
/**
* file-form-field-prefix parameter name
*/
private static final String PARAM_FILE_FORM_FIELD_PREFIX = "file-form-field-prefix";
/**
* upload-directory parameter name
*/
private static final String PARAM_UPLOAD_DIRECTORY = "upload-directory";
/**
* overwrite-file parameter name
*/
private static final String PARAM_OVERWRITE_FILE = "overwrite-file";
/**
* overwrite deny
*/
private static final String OVERWRITE_DENY = "deny";
/**
* overwrite allow
*/
private static final String OVERWRITE_ALLOW = "allow";
/**
* overwrite rename
*/
private static final String OVERWRITE_RENAME = "rename";
/**
* default form prefix parameter name for file upload
*/
private static final String DEFAULT_PARAM_FILE_FORM_FIELD_PREFIX = "file";
/**
* default upload directory WEB-INF/work
*/
private static final String DEFAULT_PARAM_UPLOAD_DIRECTORY_VALUE = "/WEB-INF/work/upload";
/**
* cached logger
*/
private static Logger myLogger;
/**
* is debug enabled
*/
private boolean isDebugEnabled;
/**
* is warn enabled
*/
private boolean isWarnEnabled;
/**
* is error enabled
*/
private boolean isErrorEnabled;
/**
* file-form-field-prefix - name of form field
*/
private String parFileFormFieldPrefix;
/**
* number-of-files - int - specified in the upload form
*/
private int parNumberOfFiles;
/**
* upload-directory - path where the file/s will be saved
*/
private String parUploadDirectory;
/**
* overwrite-file - deny, allow, rename
*/
private String parOverwriteFile;
/**
* Controls the processing against some values of the
* <code>Dictionary</code> objectModel and returns a
* <code>Map</code> object with values used in subsequent
* sitemap substitution patterns.
* NOTE: This interface is designed so that implentations can be
* <code>ThreadSafe<code>.
* When an action is ThreadSafe, only one instance serves all requests : this
* reduces memory usage and avoids pooling.
* @param resolver The <code>SourceResolver</code> in charge
* @param objectModel The <code>Map</code> with object of the
* calling environment which can be used
* to select values this controller may need
* (ie Request, Response).
* @param source A source <code>String</code> to the Action
* @param parameters The <code>Parameters</code> for this invocation
* @param redirector
* @return Map The returned <code>Map</code> object with
* sitemap substitution values which can be used
* in subsequent elements attributes like src="">
* using a xpath like _expression_: src=""
* If the return value is null the processing inside
* the <map:act> element of the sitemap will
* be skipped.
* @throws java.lang.Exception
* @exception Exception Indicates something is totally wrong
*/
public Map act(
Redirector redirector,
SourceResolver resolver,
Map objectModel,
String source,
Parameters parameters)
throws Exception {
/*
* get logger instance
*/
if (myLogger == null) {
myLogger = getLogger();
isDebugEnabled = myLogger.isDebugEnabled();
isWarnEnabled = myLogger.isWarnEnabled();
isErrorEnabled = myLogger.isErrorEnabled();
}
if (isDebugEnabled) {
myLogger.debug("FileUploadAction start");
}
/*
* fileMap keeps FileUploadInfo about uploaded files
*/
Map fileMap = new HashMap();
/*
* read sitemap parameters
*/
try {
parNumberOfFiles = Integer.parseInt(parameters.getParameter(PARAM_NUMBER_OF_FILES, "0"));
} catch (Exception e) {
parNumberOfFiles = 0;
if (isErrorEnabled) {
myLogger.error("NumberFormatException in parameter " + PARAM_NUMBER_OF_FILES);
}
/*
* stop processing action -> return null
*/
return null;
}
parFileFormFieldPrefix = parameters.getParameter(PARAM_FILE_FORM_FIELD_PREFIX, DEFAULT_PARAM_FILE_FORM_FIELD_PREFIX);
parUploadDirectory = parameters.getParameter(PARAM_UPLOAD_DIRECTORY, DEFAULT_PARAM_UPLOAD_DIRECTORY_VALUE);
parOverwriteFile = parameters.getParameter(PARAM_OVERWRITE_FILE, OVERWRITE_DENY);
if (isDebugEnabled) {
myLogger.debug("input parameters readed/default setted: "
+ PARAM_NUMBER_OF_FILES + "=" + parNumberOfFiles + " "
+ PARAM_FILE_FORM_FIELD_PREFIX + "=" + parFileFormFieldPrefix + " "
+ PARAM_OVERWRITE_FILE + "=" + parOverwriteFile + " "
+ PARAM_UPLOAD_DIRECTORY + "=" + parUploadDirectory + " "
+ PARAM_FILE_FORM_FIELD_PREFIX + "=" + parFileFormFieldPrefix + " "
);
}
/*
* get request
*/
Request req = ObjectModelHelper.getRequest(objectModel);
/*
* get context to generate realPath
*/
Context context = ObjectModelHelper.getContext(objectModel);
if (req instanceof HttpRequest) {
HttpRequest request = (HttpRequest) req;
/*
* create necessary directory structure
*/
File uplDir = new File(parUploadDirectory);
if (isDebugEnabled) {
myLogger.debug("upload directory is: "
+ uplDir.getAbsolutePath()
);
}
if (uplDir.isAbsolute() == false) {
// check for first relative slash
if(parUploadDirectory.indexOf('/') != 0) {
parUploadDirectory = "/" + parUploadDirectory;
}
uplDir = new File(context.getRealPath(parUploadDirectory));
}
if (isDebugEnabled) {
myLogger.debug("absolute upload directory is: "
+ uplDir.getAbsolutePath()
);
}
if (uplDir.exists() == false) {
uplDir.mkdirs();
if (isDebugEnabled) {
myLogger.debug("directory path does not exist creating directories: "
+ uplDir.getAbsolutePath()
+ " successfully: " + uplDir.exists()
);
}
}
/*
* go thrue form parameters
* add to return Map FileUploadInfo object to get informations about
* uploaded file
*/
if (isDebugEnabled) {
myLogger.debug("going thrue "+parNumberOfFiles+" form parameters ");
}
for (int i = 1; i <= parNumberOfFiles; i++) {
/*
* create file informations and put it to return map
*/
FileUploadInfo fileInfo = new FileUploadInfo();
fileInfo.setFormFieldName((parFileFormFieldPrefix + i));
/*
* get Part
*/
Part filePart = (Part) request.get(fileInfo.getFormFieldName());
if (filePart != null) {
// do upload flag
boolean doUpload = true;
// set fileinfo
fileInfo.setOriginalFileName(filePart.getUploadName());
fileInfo.setUploadedFileName(fileInfo.getOriginalFileName());
// define file target
File target = new File(uplDir, fileInfo.getUploadedFileName());
// check if target exist
if ( target.exists()
&& parOverwriteFile.equalsIgnoreCase(OVERWRITE_RENAME)) {
// rename file
fileInfo.setUploadedFileName("" + System.currentTimeMillis() + "" + i + "_" + fileInfo.getOriginalFileName());
fileInfo.setRenamed(true);
target = new File(uplDir, fileInfo.getUploadedFileName());
}
else if ( target.exists()
&& parOverwriteFile.equalsIgnoreCase(OVERWRITE_DENY)) {
// skip writing file
doUpload = false;
fileInfo.setUploaded(false);
}
// otherwise OVERWRITE_ALLOW
fileInfo.setPhysicalFilePath(target.getAbsolutePath());
if (doUpload) {
// when success set uploaded true otherwise = false
fileInfo.setUploaded( saveFile(filePart, target) );
}
}
/*
* put fileinfo to filemap
* as sitemap accepts only String values - file info will be separated
*/
fileMap.put(fileInfo.getFormFieldName() + "renamed", Boolean.toString(fileInfo.isRenamed()));
fileMap.put(fileInfo.getFormFieldName() + "uploaded", Boolean.toString(fileInfo.isUploaded()));
fileMap.put(fileInfo.getFormFieldName() + "originalFileName", fileInfo.getOriginalFileName());
fileMap.put(fileInfo.getFormFieldName() + "physicalFilePath", fileInfo.getPhysicalFilePath());
fileMap.put(fileInfo.getFormFieldName() + "uploadedFileName", fileInfo.getUploadedFileName());
if (isDebugEnabled) {
myLogger.debug("file info added to return map. "
+ fileInfo.toString());
}
} // end for (int i = 1; i <= parNumberOfFiles; i++)
} // end if (req instanceof MultipartHttpServletRequest)
else
{
if (isWarnEnabled) {
myLogger.warn("file upload is not enabled");
}
return null;
}
return fileMap;
}
/**
* save uploaded Part to target
* @param filePart represents a file part parsed from a http post stream.
* @param target - target file to save
* @return boolean true when file was saved
*/
private boolean saveFile(Part filePart, File target)
{
if (isDebugEnabled) {
myLogger.debug("saving file to "
+ target.getAbsolutePath());
}
BufferedInputStream in = null;
BufferedOutputStream out = null;
byte [] buff = new byte[8192];
int bytesRead;
boolean flag = true;
try {
in = new BufferedInputStream(filePart.getInputStream());
out = new BufferedOutputStream(new FileOutputStream(target));
// write
while((bytesRead = in.read(buff, 0, buff.length)) != -1) {
out.write(buff, 0, bytesRead);
}
} catch (FileNotFoundException e) {
// log error
flag = false;
if (isErrorEnabled) {
myLogger.error("FileNotFoundException: "
+ e.toString());
}
} catch (IOException e) {
// log error
flag = false;
if (isErrorEnabled) {
myLogger.error("IOException: "
+ e.toString());
}
} catch (Exception e) {
// log error
flag = false;
if (isErrorEnabled) {
myLogger.error("Exception: "
+ e.toString());
}
}
finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.flush();
out.close();
}
} catch (IOException e1) {
// log error
flag = false;
if (isErrorEnabled) {
myLogger.error("IOException: "
+ e1.toString());
}
}
}
if (target.exists() == false) {
flag = false;
}
if (flag && isDebugEnabled) {
myLogger.debug("file saved "
+ target.getAbsolutePath());
}
else {
myLogger.debug("file NOT saved "
+ target.getAbsolutePath());
}
return flag;
}
}
-----Original Message-----Hi there!
From: Madhavi Thottempudi [mailto:[EMAIL PROTECTED]
Sent: Wednesday, May 26, 2004 7:47 AM
To: [EMAIL PROTECTED]
Subject: uploading file in cocoon2.1.4
I am trying to upload a zip file and save it somewhere on the hard-drive.
I am using cocoon 2.1.4. Can anybody suggest me what is the best way to upload files in cocoon2.1.4 version.
I am doing as shown below and I am not able to pick up the file. Don't know where I am going wrong. Any suggestions or tips on this
matter would be of great help to me. Thanks in advance.
In xsl:
--------------------
<form action="" method="post" enctype="multipart/form-data"><input type="file" name="uploadedFile"/> <br/> <input name="submit" type="submit"/>
</form>
In sitemap:
--------------------------------
actions:
<map:action name="fileupload" src=""/>
pipeline:
<map:match pattern="upload"><map:act type="fileupload"> <map:parameter name="uploadedFile" value="{request-param:uploadedFile}"/> <map:serialize type="xhtml"/> </map:act>
</map:match>
My java class file:
--------------------------------
public class UploadPackage extends AbstractLogEnabled implements Action
{
public Map act(Redirector redirector,
SourceResolver resolver,
Map objectModel,
String src,
Parameters parameters) throws Exception {
Request request = ObjectModelHelper.getRequest(objectModel);
Part filePart = (PartOnDisk) request.get("uploadedFile");
if (filePart != null) {
getLogger().debug("Uploaded file name = " + filePart.getFileName());
} else {
getLogger().debug("File not found");
}
return java.util.Collections.EMPTY_MAP;
}
}