DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
based on thread http://marc.theaimsgroup.com/?t=106917261100001&r=1&w=2 StavrosKounis
Problem
File upload
Solution (example)
Using action.
- compile .java files and put them in build/webapp/WEB-INF/classes/com/mypackage
2. create a folder under cocoon samples (uploadexample) directory with dir structure:
uploadexample | +-content | +-style | +xsl
3. put the following files in the right folder
4. ask for http://...cocoon.../sample/uploadexample/
dont forget to enable upload in web.xml
sitemap.xmap
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:actions>
<map:action logger="sitemap.action.fileupload" name="file-upload-action" src="com.mypackage.FileUploadAction"/>
</map:actions>
</map:components>
<!-- =========================== Pipelines ================================= -->
<map:pipelines>
<map:pipeline>
<map:match pattern="uploadform.html">
<map:read mime-type="text/html" src="content/uploadform.html"/>
</map:match>
<map:match pattern="doupload">
<map:act type="file-upload-action">
<map:parameter name="number-of-files" value="3"/>
<map:parameter name="file-form-field-prefix" value="myfile"/>
<!-- for physical path use
<map:parameter name="upload-directory" value="C:\upload\test1"/>
-->
<!-- for relative path use -->
<map:parameter name="upload-directory" value="/WEB-INF/myupload/test1"/>
<map:parameter name="overwrite-file" value="rename"/>
<!-- action will return
file-form-field-prefix#number#renamed true / false
file-form-field-prefix#number#uploaded true / false
file-form-field-prefix#number#originalFileName - as was in request
file-form-field-prefix#number#physicalFilePath - full path to saved file
file-form-field-prefix#number#uploadedFileName - file name if was renamed
-->
<!-- when upload is OK run this -->
<map:generate src="content/okupload.xml"/>
<map:transform src="style/xsl/adduploadinfo.xsl">
<!-- action puts those map parameters -->
<!-- myfile1 -->
<map:parameter name="myfile1renamed" value="{myfile1renamed}"/>
<map:parameter name="myfile1uploaded" value="{myfile1uploaded}"/>
<map:parameter name="myfile1originalFileName" value="{myfile1originalFileName}"/>
<map:parameter name="myfile1physicalFilePath" value="{myfile1physicalFilePath}"/>
<map:parameter name="myfile1uploadedFileName" value="{myfile1uploadedFileName}"/>
<!-- myfile2 -->
<map:parameter name="myfile2renamed" value="{myfile2renamed}"/>
<map:parameter name="myfile2uploaded" value="{myfile2uploaded}"/>
<map:parameter name="myfile2originalFileName" value="{myfile2originalFileName}"/>
<map:parameter name="myfile2physicalFilePath" value="{myfile2physicalFilePath}"/>
<map:parameter name="myfile2uploadedFileName" value="{myfile2uploadedFileName}"/>
<!-- myfile3 -->
<map:parameter name="myfile3renamed" value="{myfile3renamed}"/>
<map:parameter name="myfile3uploaded" value="{myfile3uploaded}"/>
<map:parameter name="myfile3originalFileName" value="{myfile3originalFileName}"/>
<map:parameter name="myfile3physicalFilePath" value="{myfile3physicalFilePath}"/>
<map:parameter name="myfile3uploadedFileName" value="{myfile3uploadedFileName}"/>
</map:transform>
<map:transform src="style/xsl/page2html.xsl"/>
<map:serialize type="html"/>
</map:act>
<!-- when action is not OK it will continue there -->
<map:generate src="content/notokupload.xml"/>
<map:transform src="style/xsl/page2html.xsl"/>
<map:serialize type="html"/>
</map:match>
<map:match pattern="">
<map:redirect-to uri="uploadform.html"/>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
Content folder
content/notokupload.xml
content/okupload.xml
content/uploadform.html
notokupload.xml
<?xml version="1.0"?> <page> <title>file upload action</title> <content> <para>upload action is NOT ok</para> </content> </page>
okupload.xml
<?xml version="1.0"?> <page> <title>file upload action</title> <content> <para>upload action runs ok</para> <uploadinfo/> </content> </page>
uploadform.html
<html> <body> <form action="doupload" method="POST" enctype="multipart/form-data"> <input type="file" name="myfile1"><br> <input type="file" name="myfile2"><br> <input type="file" name="myfile3"><br> <input type="submit"> </form> </body> </html>
Style folder
style/xsl/adduploadinfo.xsl
style/xsl/page2html.xsl
adduploadinfo.xsl
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- myfile1 --> <xsl:param name="myfile1renamed"/> <xsl:param name="myfile1uploaded"/> <xsl:param name="myfile1originalFileName"/> <xsl:param name="myfile1physicalFilePath"/> <xsl:param name="myfile1uploadedFileName"/> <!-- myfile2 --> <xsl:param name="myfile2renamed"/> <xsl:param name="myfile2uploaded"/> <xsl:param name="myfile2originalFileName"/> <xsl:param name="myfile2physicalFilePath"/> <xsl:param name="myfile2uploadedFileName"/> <!-- myfile3 --> <xsl:param name="myfile3renamed"/> <xsl:param name="myfile3uploaded"/> <xsl:param name="myfile3originalFileName"/> <xsl:param name="myfile3physicalFilePath"/> <xsl:param name="myfile3uploadedFileName"/> <xsl:template match="*|@*|text()|node()|comment()|processing-instruction()"> <xsl:copy> <xsl:apply-templates select="*|@*|text()|node()|comment()|processing-instruction()"></xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="uploadinfo"> <!-- myfile1 --> <FileUploadInfo> <formFieldName>myfile1</formFieldName> <originalFileName><xsl:value-of select="$myfile1originalFileName"/></originalFileName> <physicalFilePath><xsl:value-of select="$myfile1physicalFilePath"/></physicalFilePath> <renamed><xsl:value-of select="$myfile1renamed"/></renamed> <uploaded><xsl:value-of select="$myfile1uploaded"/></uploaded> <uploadedFileName><xsl:value-of select="$myfile1uploadedFileName"/></uploadedFileName> </FileUploadInfo> <!-- myfile2 --> <FileUploadInfo> <formFieldName>myfile2</formFieldName> <originalFileName><xsl:value-of select="$myfile2originalFileName"/></originalFileName> <physicalFilePath><xsl:value-of select="$myfile2physicalFilePath"/></physicalFilePath> <renamed><xsl:value-of select="$myfile2renamed"/></renamed> <uploaded><xsl:value-of select="$myfile2uploaded"/></uploaded> <uploadedFileName><xsl:value-of select="$myfile2uploadedFileName"/></uploadedFileName> </FileUploadInfo> <!-- myfile3 --> <FileUploadInfo> <formFieldName>myfile3</formFieldName> <originalFileName><xsl:value-of select="$myfile3originalFileName"/></originalFileName> <physicalFilePath><xsl:value-of select="$myfile3physicalFilePath"/></physicalFilePath> <renamed><xsl:value-of select="$myfile3renamed"/></renamed> <uploaded><xsl:value-of select="$myfile3uploaded"/></uploaded> <uploadedFileName><xsl:value-of select="$myfile3uploadedFileName"/></uploadedFileName> </FileUploadInfo> </xsl:template> </xsl:stylesheet>
page2html.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="page">
<html>
<head>
<title>
<xsl:value-of select="title"/>
</title>
<link href="/styles/main.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="title">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="content">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="para">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="FileUploadInfo">
<p>
formFieldName: <b><xsl:value-of select="formFieldName"/></b><br/>
originalFileName: <xsl:value-of select="originalFileName"/><br/>
physicalFilePath: <xsl:value-of select="physicalFilePath"/><br/>
renamed: <xsl:value-of select="renamed"/><br/>
uploaded: <xsl:value-of select="uploaded"/><br/>
uploadedFileName: <xsl:value-of select="uploadedFileName"/>
</p>
</xsl:template>
<xsl:template match="@*|node()" priority="-2"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>
<xsl:template match="text()" priority="-1"><xsl:value-of select="."/></xsl:template>
</xsl:stylesheet>
Actions
FileUploadAction.java
package com.mypackage;
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="mydir/{myval}/foo"
* 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 thru 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;
// strip off path (IE for Windows includes it)
String filename = filePart.getUploadName();
int lastSlash = filename.lastIndexOf('\\');
filename = filename.substring(lastSlash+1);
// set fileinfo
fileInfo.setOriginalFileName(filename);
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;
}
}
FileUploadInfo.java
package com.mypackage;
import java.io.File;
/**
* @author Roman Hrivik
*
* Keeps informations about uploaded file with FileUploadAction
*
*/
public class FileUploadInfo {
/**
* original field name
*/
private String formFieldName;
/**
* original file name as it comes from user
*/
private String originalFileName;
/**
* full physical filepath
*/
private String physicalFilePath;
/**
* was file renamed with upload action
*/
private boolean renamed;
/**
* was file successfully uploaded
*/
private boolean uploaded;
/**
* uploaded file name - diffrent if was renamed
*/
private String uploadedFileName;
/**
* @return String formFieldName
*/
public String getFormFieldName() {
return formFieldName;
}
/**
* @param formFieldName
*/
public void setFormFieldName(String formFieldName) {
this.formFieldName = formFieldName;
}
/**
* @return String originalFileName
*/
public String getOriginalFileName() {
return originalFileName;
}
/**
* @param originalFileName
*/
public void setOriginalFileName(String originalFileName) {
this.originalFileName = originalFileName;
}
/**
* @return String physicalFilePath
*/
public String getPhysicalFilePath() {
return physicalFilePath;
}
/**
* @param physicalFilePath
*/
public void setPhysicalFilePath(String physicalFilePath) {
this.physicalFilePath = physicalFilePath;
}
/**
* @return boolean renamed
*/
public boolean isRenamed() {
return renamed;
}
/**
* @param renamed
*/
public void setRenamed(boolean renamed) {
this.renamed = renamed;
}
/**
* @return boolean uploaded
*/
public boolean isUploaded() {
return uploaded;
}
/**
* @param uploaded
*/
public void setUploaded(boolean uploaded) {
this.uploaded = uploaded;
}
/**
* @return String uploadedFileName
*/
public String getUploadedFileName() {
return uploadedFileName;
}
/**
* @param uploadedFileName
*/
public void setUploadedFileName(String uploadedFileName) {
this.uploadedFileName = uploadedFileName;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
return ("FileUploadInfo: "
+ " isUploaded=" + isUploaded()
+ " isRenamed=" + isRenamed()
+ " getFormFieldName=" + getFormFieldName()
+ " getOriginalFileName=" + getOriginalFileName()
+ " getPhysicalFilePath=" + getPhysicalFilePath()
);
}
}
Attachment: FileUpload.zip