/* DialogUploadAgent.java
Purpose:
Description:
History:
Jun 19, 2012 Created by pao
Copyright (C) 2011 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zats.mimic.impl.operation;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.text.MessageFormat;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.util.IO;
import org.zkoss.lang.Strings;
import org.zkoss.zats.common.util.MultiPartOutputStream;
import org.zkoss.zats.mimic.AgentException;
import org.zkoss.zats.mimic.ComponentAgent;
import org.zkoss.zats.mimic.DesktopAgent;
import org.zkoss.zats.mimic.impl.ClientCtrl;
import org.zkoss.zats.mimic.impl.EventDataManager;
import org.zkoss.zats.mimic.impl.OperationAgentBuilder;
import org.zkoss.zats.mimic.impl.Util;
import org.zkoss.zats.mimic.operation.UploadAgent;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.sys.DesktopCtrl;
/**
* The builder implementation of dialog upload agent
* @author pao
* @since 1.1.0
*/
public class DialogUploadAgentBuilder implements OperationAgentBuilder<DesktopAgent, UploadAgent> {
private final static Logger logger = Logger.getLogger(DialogUploadAgentBuilder.class.getName());
public Class<UploadAgent> getOperationClass() {
return UploadAgent.class;
}
public UploadAgent getOperation(DesktopAgent target) {
return new UploadAgentImpl(target);
}
class UploadAgentImpl extends AgentDelegator<DesktopAgent> implements UploadAgent {
private int sid; // serial ID. for next file
public UploadAgentImpl(DesktopAgent target) {
super(target);
}
public void upload(File file, String contentType) {
if (file == null)
throw new NullPointerException("file can't be null.");
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
upload(file.getName(), is, contentType);
} catch (IOException e) {
throw new AgentException(e.getMessage(), e);
} finally {
Util.close(is);
}
}
public void upload(String fileName, InputStream content, String contentType) {
if (fileName == null)
throw new NullPointerException("file name can't be null.");
if (content == null)
throw new NullPointerException("content stream can't be null.");
// find upload dialog
DesktopAgent desktop = target;
ComponentAgent dialog = desktop.query("uploaddlg");
ComponentAgent fileupload = desktop.query("uploaddlg fileupload");
if (dialog == null || fileupload == null)
throw new AgentException("There is no dialog for uploading.");
OutputStream os = null;
InputStream is = null;
try {
// parameters
String param = "?uuid={0}&dtid={1}&sid={2}&maxsize=undefined";
param = MessageFormat.format(param, fileupload.getUuid(), desktop.getId(), String.valueOf(sid));
// open connection
String boundary = Util.generateRandomString(); // boundary for multipart
ClientCtrl cc = (ClientCtrl) getClient();
HttpURLConnection conn = cc.getConnection("/zkau/upload" + param, "POST");
conn.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.setDoInput(true);
conn.setDoOutput(true);
os = conn.getOutputStream();
MultiPartOutputStream multipartStream = new MultiPartOutputStream(os, boundary);
if (logger.isLoggable(Level.FINEST)) {
logger.finest("desktop: " + desktop.getId());
logger.finest("upload URL: " + conn.getURL().toString());
}
// additional headers
String contentDisposition = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"";
contentDisposition = MessageFormat.format(contentDisposition, fileName);
String[] headers = new String[] { contentDisposition };
// upload multipart data
multipartStream.startPart(contentType != null ? contentType : "application/octet-stream", headers); // default content type
int b;
while ((b = content.read()) >= 0)
multipartStream.write(b);
Util.close(multipartStream); // close before get input stream
// read response
String respMsg = conn.getResponseMessage();
is = conn.getInputStream();
String resp = IO.toString(is);
if (logger.isLoggable(Level.FINEST)) {
logger.finest("response message: " + respMsg);
logger.finest("response content: " + resp);
}
} catch (IOException e) {
throw new AgentException(e.getMessage(), e);
} finally {
Util.close(os);
Util.close(is);
}
// get the correct key
int key = ((DesktopCtrl) desktop.getDelegatee()).getNextKey() - 1;
String contentId = Strings.encode(new StringBuffer(12).append("z__ul_"), key).toString(); // copy from AuUploader
// perform AU
String cmd = "updateResult";
String desktopId = desktop.getId();
Event event = new Event(cmd, (Component) fileupload.getDelegatee());
Map<String, Object> data = EventDataManager.getInstance().build(event);
data.put("wid", fileupload.getUuid());
data.put("contentId", contentId);
data.put("sid", String.valueOf(sid++)); // increase sid
((ClientCtrl) getClient()).postUpdate(desktopId, fileupload.getUuid(), cmd, data, false);
((ClientCtrl) getClient()).flush(desktopId);
}
public void finish() {
// find upload dialog
DesktopAgent desktop = target;
ComponentAgent dialog = desktop.query("uploaddlg");
if (dialog == null)
throw new AgentException("There is no dialog for uploading.");
// perform AU to close dialog
String desktopId = desktop.getId();
Event event = new Event(Events.ON_CLOSE, (Component) dialog.getDelegatee());
Map<String, Object> data = EventDataManager.getInstance().build(event);
data.put("", true);
((ClientCtrl) getClient()).postUpdate(desktopId, dialog.getUuid(), Events.ON_CLOSE, data, false);
((ClientCtrl) getClient()).flush(desktopId);
// reset
sid = 0;
}
}
}