using iframe to manage upload of schemas - allows for calling an action listener once the upload is complete to validate the schema and present an error message inside the form in a pretty way.

added a small helper library for managing uploads without using a page reload.  modified uploadfileservlet to return a javascript snippet in the response body if the return-page parameter starts with javascript:

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4578 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ariel Backenroth
2006-12-12 09:51:27 +00:00
parent cb80c75014
commit b89434674c
5 changed files with 159 additions and 51 deletions

View File

@@ -18,6 +18,7 @@ package org.alfresco.web.app.servlet;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -47,7 +48,7 @@ import org.apache.commons.logging.LogFactory;
public class UploadFileServlet extends BaseServlet public class UploadFileServlet extends BaseServlet
{ {
private static final long serialVersionUID = -5482538466491052873L; private static final long serialVersionUID = -5482538466491052873L;
private static Log logger = LogFactory.getLog(UploadFileServlet.class); private static final Log logger = LogFactory.getLog(UploadFileServlet.class);
/** /**
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
@@ -68,7 +69,7 @@ public class UploadFileServlet extends BaseServlet
return; return;
} }
if (isMultipart == false) if (!isMultipart)
{ {
throw new AlfrescoRuntimeException("This servlet can only be used to handle file upload requests, make" + throw new AlfrescoRuntimeException("This servlet can only be used to handle file upload requests, make" +
"sure you have set the enctype attribute on your form to multipart/form-data"); "sure you have set the enctype attribute on your form to multipart/form-data");
@@ -85,11 +86,9 @@ public class UploadFileServlet extends BaseServlet
List<FileItem> fileItems = upload.parseRequest(request); List<FileItem> fileItems = upload.parseRequest(request);
Iterator<FileItem> iter = fileItems.iterator();
FileUploadBean bean = new FileUploadBean(); FileUploadBean bean = new FileUploadBean();
while(iter.hasNext()) for (FileItem item : fileItems)
{ {
FileItem item = iter.next();
if(item.isFormField()) if(item.isFormField())
{ {
if (item.getFieldName().equalsIgnoreCase("return-page")) if (item.getFieldName().equalsIgnoreCase("return-page"))
@@ -106,15 +105,13 @@ public class UploadFileServlet extends BaseServlet
String filename = item.getName(); String filename = item.getName();
if (filename != null && filename.length() != 0) if (filename != null && filename.length() != 0)
{ {
if (logger.isDebugEnabled() == true) if (logger.isDebugEnabled())
{ {
logger.debug("Processing uploaded file: " + filename); logger.debug("Processing uploaded file: " + filename);
} }
// workaround a bug in IE where the full path is returned // workaround a bug in IE where the full path is returned
// IE is only available for Windows so only check for the Windows path separator // IE is only available for Windows so only check for the Windows path separator
int idx = filename.lastIndexOf('\\'); int idx = filename.lastIndexOf('\\');
if (idx == -1) if (idx == -1)
{ {
// if there is no windows path separator check for *nix // if there is no windows path separator check for *nix
@@ -131,8 +128,7 @@ public class UploadFileServlet extends BaseServlet
bean.setFile(tempFile); bean.setFile(tempFile);
bean.setFileName(filename); bean.setFileName(filename);
bean.setFilePath(tempFile.getAbsolutePath()); bean.setFilePath(tempFile.getAbsolutePath());
session.setAttribute(FileUploadBean.getKey(uploadId), bean); if (logger.isDebugEnabled())
if (logger.isDebugEnabled() == true)
{ {
logger.debug("Temp file: " + tempFile.getAbsolutePath() + logger.debug("Temp file: " + tempFile.getAbsolutePath() +
" created from upload filename: " + filename); " created from upload filename: " + filename);
@@ -140,19 +136,39 @@ public class UploadFileServlet extends BaseServlet
} }
} }
} }
session.setAttribute(FileUploadBean.getKey(uploadId), bean);
if (returnPage == null || returnPage.length() == 0) if (returnPage == null || returnPage.length() == 0)
{ {
throw new AlfrescoRuntimeException("return-page parameter has not been supplied"); throw new AlfrescoRuntimeException("return-page parameter has not been supplied");
} }
// finally redirect if (returnPage.startsWith("javascript:"))
if (logger.isDebugEnabled() == true)
{ {
logger.debug("Upload servicing complete, redirecting to: " + returnPage); returnPage = returnPage.substring("javascript:".length());
} // finally redirect
if (logger.isDebugEnabled())
{
logger.debug("Sending back javascript response " + returnPage);
}
response.sendRedirect(returnPage); final PrintWriter out = response.getWriter();
out.println("<html><body><script type=\"text/javascript\">");
out.println(returnPage);
out.println("</script></body></html>");
out.close();
}
else
{
// finally redirect
if (logger.isDebugEnabled())
{
logger.debug("Upload servicing complete, redirecting to: " + returnPage);
}
response.sendRedirect(returnPage);
}
} }
catch (Throwable error) catch (Throwable error)
{ {

View File

@@ -465,7 +465,7 @@ public class CreateFormWizard
// refresh the current page // refresh the current page
return null; return null;
} }
/** /**
* Action handler called when the user wishes to remove an uploaded file * Action handler called when the user wishes to remove an uploaded file
*/ */
@@ -488,6 +488,25 @@ public class CreateFormWizard
return null; return null;
} }
public String validateSchema()
{
if (this.getSchemaFile() != null)
{
final FormsService ts = FormsService.getInstance();
try
{
final Document d = ts.parseXML(this.getSchemaFile());
final XSModel xsm = SchemaUtil.loadSchema(d);
}
catch (Exception e)
{
final String msg = "unable to parse " + this.getSchemaFileName();
this.removeUploadedSchemaFile();
Utils.addErrorMessage(msg, e);
}
}
return null;
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Bean Getters and Setters // Bean Getters and Setters
@@ -693,7 +712,6 @@ public class CreateFormWizard
final String msg = "unable to parse " + this.getSchemaFileName(); final String msg = "unable to parse " + this.getSchemaFileName();
this.removeUploadedSchemaFile(); this.removeUploadedSchemaFile();
Utils.addErrorMessage(msg, e); Utils.addErrorMessage(msg, e);
throw new AlfrescoRuntimeException(msg, e);
} }
} }
return result; return result;

View File

@@ -75,29 +75,29 @@ public class ActionLinkRenderer extends BaseRenderer
public void encodeEnd(FacesContext context, UIComponent component) throws IOException public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{ {
// always check for this flag - as per the spec // always check for this flag - as per the spec
if (component.isRendered() == true) if (!component.isRendered())
{ {
Writer out = context.getResponseWriter(); return;
}
Writer out = context.getResponseWriter();
UIActionLink link = (UIActionLink)component;
UIActionLink link = (UIActionLink)component; UIComponent verticalContiner = getVerticalContainer(link);
if (verticalContiner != null)
UIComponent verticalContiner = getVerticalContainer(link); {
if (verticalContiner != null) int padding = link.getPadding();
{
int padding = link.getPadding();
if (verticalContiner instanceof UIActions) if (verticalContiner instanceof UIActions)
{
padding = ((UIActions)verticalContiner).getVerticalSpacing();
}
// render as menu item style action link
out.write( renderMenuAction(context, link, padding) );
}
else
{ {
// render as action link padding = ((UIActions)verticalContiner).getVerticalSpacing();
out.write( renderActionLink(context, link) );
} }
// render as menu item style action link
out.write( renderMenuAction(context, link, padding) );
}
else
{
// render as action link
out.write( renderActionLink(context, link) );
} }
} }
@@ -190,6 +190,12 @@ public class ActionLinkRenderer extends BaseRenderer
} }
} }
if (attrs.get("id") != null)
{
linkBuf.append(" id=\"")
.append(attrs.get("id"))
.append("\"");
}
if (attrs.get("style") != null) if (attrs.get("style") != null)
{ {
linkBuf.append(" style=\"") linkBuf.append(" style=\"")

View File

@@ -19,8 +19,13 @@
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
<%@ page import="org.alfresco.web.bean.FileUploadBean" %> <%@ page import="org.alfresco.web.bean.FileUploadBean" %>
<%@ page import="org.alfresco.web.bean.wcm.CreateFormWizard" %>
<f:verbatim> <f:verbatim>
<script type="text/javascript" src="<%=request.getContextPath()%>/scripts/validation.js"> <script type="text/javascript"
src="<%=request.getContextPath()%>/scripts/validation.js">
</script>
<script type="text/javascript"
src="<%=request.getContextPath()%>/scripts/upload_helper.js">
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
@@ -29,7 +34,7 @@
function pageLoaded() function pageLoaded()
{ {
// document.getElementById("wizard:wizard-body:file-name").focus(); document.getElementById("wizard:wizard-body:file-input").focus();
document.getElementById("wizard").onsubmit = validate; document.getElementById("wizard").onsubmit = validate;
document.getElementById("wizard:next-button").onclick = function() {finishButtonPressed = true; clear_wizard();} document.getElementById("wizard:next-button").onclick = function() {finishButtonPressed = true; clear_wizard();}
document.getElementById("wizard:finish-button").onclick = function() {finishButtonPressed = true; clear_wizard();} document.getElementById("wizard:finish-button").onclick = function() {finishButtonPressed = true; clear_wizard();}
@@ -37,17 +42,22 @@
function validate() function validate()
{ {
return true; return true;
}
function handle_upload(target)
{
handle_upload_helper(target,
"<%= CreateFormWizard.FILE_SCHEMA %>",
upload_complete,
"<%= request.getContextPath() %>")
} }
function upload_file(el) function upload_complete(id, path)
{ {
el.form.method = "post"; var validate_button =
el.form.encType = "multipart/form-data"; document.getElementById("wizard:wizard-body:command_button_validate_schema");
// for IE validate_button.click();
el.form.encoding = "multipart/form-data";
el.form.action = "<%= request.getContextPath() %>/uploadFileServlet";
el.form.submit();
} }
</script> </script>
</f:verbatim> </f:verbatim>
@@ -75,15 +85,23 @@
<h:column id="column_schema"> <h:column id="column_schema">
<% <%
FileUploadBean upload = (FileUploadBean) FileUploadBean upload = (FileUploadBean)
session.getAttribute(FileUploadBean.getKey("schema")); session.getAttribute(FileUploadBean.getKey(CreateFormWizard.FILE_SCHEMA));
if (upload == null || upload.getFile() == null) if (upload == null || upload.getFile() == null)
{ {
%> %>
<f:verbatim> <f:verbatim>
<input type="hidden" name="upload-id" value="schema"/> <input id="wizard:wizard-body:file-input"
<input type="hidden" name="return-page" value="<%= request.getContextPath() %>/faces<%= request.getServletPath() %>"/> type="file"
<input id="wizard:wizard-body:file-input" type="file" size="35" name="alfFileInput" onchange="javascript:upload_file(this)"/> size="35"
name="alfFileInput"
onchange="javascript:handle_upload(this)"/>
</f:verbatim> </f:verbatim>
<h:commandButton id="command_button_validate_schema"
value=""
immediate="true"
style="display: none"
action="#{WizardManager.bean.validateSchema}"/>
<% <%
} else { } else {
%> %>

View File

@@ -0,0 +1,50 @@
var _uploads = [];
function handle_upload_helper(fileInputElement,
uploadId,
callback,
contextPath)
{
var id = fileInputElement.getAttribute("name");
var d = fileInputElement.ownerDocument;
var iframe = d.createElement("iframe");
iframe.style.display = "none";
iframe.name = id + "upload_frame";
iframe.id = iframe.name;
document.body.appendChild(iframe);
// makes it possible to target the frame properly in ie.
window.frames[iframe.name].name = iframe.name;
_uploads[uploadId] = { path: fileInputElement.value, callback: callback };
var form = d.createElement("form");
d.body.appendChild(form);
form.style.display = "none";
form.method = "post";
form.encoding = "multipart/form-data";
form.enctype = "multipart/form-data";
form.target = iframe.name;
form.action = contextPath + "/uploadFileServlet";
form.appendChild(fileInputElement.cloneNode(true));
var id = document.createElement("input");
form.appendChild(id);
id.type = "hidden";
id.name = "upload-id";
id.value = uploadId;
var rp = document.createElement("input");
form.appendChild(rp);
rp.type = "hidden";
rp.name = "return-page";
rp.value = "javascript:window.parent.upload_complete_helper('" + uploadId + "')";
form.submit();
}
function upload_complete_helper(id)
{
var upload = _uploads[id];
upload.callback(id, upload.path);
}