/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.ade.upload.client.ui; import org.opencms.ade.upload.client.Messages; import org.opencms.ade.upload.client.ui.css.I_CmsLayoutBundle; import org.opencms.gwt.client.ui.input.upload.CmsFileInfo; import org.opencms.gwt.client.util.CmsClientStringUtil; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; /** * Provides the upload dialog for file API support.<p> * * @since 8.0.0 */ public class CmsUploadDialogFileApiImpl extends CmsUploadDialogFormDataImpl { /** The maximum upload size in bytes. (50 MB) */ private static final long MAX_UPLOAD_SIZE = 51200000; /** * @see org.opencms.ade.upload.client.ui.CmsUploadDialogFormDataImpl#getFileSizeTooLargeMessage(org.opencms.gwt.client.ui.input.upload.CmsFileInfo) */ @Override public String getFileSizeTooLargeMessage(CmsFileInfo file) { if ((file.getFileSize() > MAX_UPLOAD_SIZE)) { return Messages.get().key( Messages.GUI_UPLOAD_FILE_MAX_SIZE_REACHED_2, formatBytes(file.getFileSize()), formatBytes(new Long(MAX_UPLOAD_SIZE).intValue())); } return super.getFileSizeTooLargeMessage(file); } /** * @see org.opencms.ade.upload.client.ui.A_CmsUploadDialog#isTooLarge(org.opencms.gwt.client.ui.input.upload.CmsFileInfo) */ @Override public boolean isTooLarge(CmsFileInfo cmsFileInfo) { if (super.isTooLarge(cmsFileInfo) || (cmsFileInfo.getFileSize() > MAX_UPLOAD_SIZE)) { return true; } return false; } /** * @see org.opencms.ade.upload.client.ui.A_CmsUploadDialog#submit() */ @Override public void submit() { // create a JsArray containing the files to upload List<String> orderedFilenamesToUpload = new ArrayList<String>(getFilesToUpload().keySet()); Collections.sort(orderedFilenamesToUpload, String.CASE_INSENSITIVE_ORDER); JsArray<CmsFileInfo> filesToUpload = JavaScriptObject.createArray().cast(); for (String filename : orderedFilenamesToUpload) { filesToUpload.push(getFilesToUpload().get(filename)); } // create a array that contains the names of the files that should be unziped JavaScriptObject filesToUnzip = JavaScriptObject.createArray(); for (String filename : getFilesToUnzip(false)) { CmsClientStringUtil.pushArray(filesToUnzip, filename); } upload(getUploadUri(), getTargetFolder(), filesToUpload, filesToUnzip, this); } /** * @see org.opencms.ade.upload.client.ui.A_CmsUploadDialog#updateSummary() */ @Override public void updateSummary() { super.updateSummary(); if (!getFilesToUpload().isEmpty() && (getContentLength() > MAX_UPLOAD_SIZE)) { String message = Messages.get().key( Messages.GUI_UPLOAD_MAX_SIZE_REACHED_2, formatBytes(new Long(getContentLength()).intValue()), formatBytes(new Long(MAX_UPLOAD_SIZE).intValue())); disableOKButton(message); StringBuffer buffer = new StringBuffer(64); buffer.append("<p class=\""); buffer.append(I_CmsLayoutBundle.INSTANCE.uploadCss().dialogMessageImportant()); buffer.append("\">"); buffer.append(message); buffer.append("</p>"); setSummaryHTML(buffer.toString()); } else if (!getFilesToUpload().isEmpty()) { enableOKButton(); } } /** * Switches the error message depending on the given error code.<p> * * The error codes are defined in the W3C file API.<p> * * <a href="http://www.w3.org/TR/FileAPI/#dfn-fileerror">http://www.w3.org/TR/FileAPI/#dfn-fileerror</a> * * @param errorCode the error code as String */ private void onBrowserError(String errorCode) { int code = new Integer(errorCode).intValue(); String errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_0); switch (code) { case 1: // NOT_FOUND_ERR errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_NOT_FOUND_0); break; case 2: // SECURITY_ERR errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_SECURITY_0); break; case 3: // ABORT_ERR errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_ABORT_ERR_0); break; case 4: // NOT_READABLE_ERR errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_NOT_READABLE_0); break; case 5: // ENCODING_ERR errMsg = Messages.get().key(Messages.ERR_UPLOAD_BROWSER_ENCODING_0); break; default: break; } showErrorReport(errMsg, null); } /** * Sends a post request to the upload JSP.<p> * * @param uploadUri the URI of the JSP that performs the upload * @param targetFolder the target folder to upload * @param filesToUpload the file names to upload * @param filesToUnzip the file names that should be unziped * @param dialog this dialog */ private native void upload( String uploadUri, String targetFolder, JsArray<CmsFileInfo> filesToUpload, JavaScriptObject filesToUnzip, CmsUploadDialogFileApiImpl dialog) /*-{ function addPlainField(requestBody, fieldName, fieldValue) { requestBody += "Content-Disposition: form-data; name=" + fieldName + "\r\n"; requestBody += "Content-Type: text/plain\r\n\r\n"; requestBody += fieldValue + "\r\n"; requestBody += "--" + boundary + "--"; } // is executed when there was an error during reading the file function errorHandler(evt) { dialog.@org.opencms.ade.upload.client.ui.CmsUploadDialogFileApiImpl::onBrowserError(Ljava/lang/String;)(evt.target.error.code); } // is executed when the current file is read completely function loaded(evt) { // get the current file name and obtain the read file data var fileName = file.name; var fileData = evt.target.result; if (fileData == null) { fileData = ""; } var fileInputName = "file_" + curIndex; addPlainField( body, fileInputName + @org.opencms.ade.upload.shared.I_CmsUploadConstants::UPLOAD_FILENAME_ENCODED_SUFFIX, encodeURI(fileName)); body += "Content-Disposition: form-data; name=\"" + fileInputName + "\"; filename=\"" + encodeURI(fileName) + "\"\r\n"; body += "Content-Type: application/octet-stream\r\n\r\n"; body += fileData + "\r\n"; body += "--" + boundary + "\r\n"; // are there any more files?, continue reading the next file if (filesToUpload.length > ++curIndex) { file = filesToUpload[curIndex]; this.readAsBinaryString(file); } else { // there are no more files left append the infos to the request body appendInfos(); // create the request and post it var xhr = new XMLHttpRequest(); xhr.open("POST", uri, true); // simulate a file MIME POST request. xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); xhr.overrideMimeType('text/plain; charset=x-user-defined'); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { dialog.@org.opencms.ade.upload.client.ui.CmsUploadDialogFileApiImpl::parseResponse(Ljava/lang/String;)(xhr.responseText); } else if (xhr.status != 200) { dialog.@org.opencms.ade.upload.client.ui.CmsUploadDialogFileApiImpl::showErrorReport(Ljava/lang/String;Ljava/lang/String;)(xhr.statusText, null); } } } xhr.sendAsBinary(body); } } // appends the infos to the request body // should be called at end of creating the body because the boundary is closed here function appendInfos() { for ( var i = 0; i < filesToUnzip.length; ++i) { var filename = filesToUnzip[i]; addPlainField( body, @org.opencms.ade.upload.shared.I_CmsUploadConstants::UPLOAD_UNZIP_FILES_FIELD_NAME, encodeURI(filename)); } addPlainField( body, @org.opencms.ade.upload.shared.I_CmsUploadConstants::UPLOAD_TARGET_FOLDER_FIELD_NAME, targetFolder); } // the uri to call var uri = uploadUri; // the boundary var boundary = "26924190726270"; // the request body with the starting boundary var body = "--" + boundary + "\r\n"; // the main procedure if (filesToUpload) { var curIndex = 0; var file = filesToUpload[curIndex]; var reader = new FileReader(); reader.onloadend = loaded; reader.onerror = errorHandler; // Read file into memory reader.readAsBinaryString(file); } }-*/; }