001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.input.upload.impl; 029 030import org.opencms.gwt.client.ui.input.upload.CmsFileInfo; 031import org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog; 032 033import com.google.gwt.core.client.JavaScriptObject; 034import com.google.gwt.core.client.JsArray; 035 036/** 037 * File API implementation of the file uploader.<p> 038 */ 039public class CmsUploaderFileApi extends CmsUploaderFormData { 040 041 /** 042 * @see org.opencms.gwt.client.ui.input.upload.impl.CmsUploaderFormData#upload(java.lang.String, java.lang.String, boolean, java.lang.String, com.google.gwt.core.client.JsArray, com.google.gwt.core.client.JavaScriptObject, boolean, org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog) 043 */ 044 @Override 045 protected native void upload( 046 String uploadUri, 047 String targetFolder, 048 boolean isRootPath, 049 String postCreateHandler, 050 JsArray<CmsFileInfo> filesToUpload, 051 JavaScriptObject filesToUnzip, 052 boolean keepFileNames, 053 I_CmsUploadDialog dialog) /*-{ 054 var self = this; 055 056 function addPlainField(requestBody, fieldName, fieldValue) { 057 requestBody += "Content-Disposition: form-data; name=" + fieldName 058 + "\r\n"; 059 requestBody += "Content-Type: text/plain\r\n\r\n"; 060 requestBody += fieldValue + "\r\n"; 061 requestBody += "--" + boundary + "--"; 062 } 063 064 // is executed when there was an error during reading the file 065 function errorHandler(evt) { 066 self.@org.opencms.gwt.client.ui.input.upload.impl.CmsUploaderFileApi::onBrowserError(Lorg/opencms/gwt/client/ui/input/upload/I_CmsUploadDialog;Ljava/lang/String;)(dialog,evt.target.error.code); 067 } 068 069 // is executed when the current file is read completely 070 function loaded(evt) { 071 // get the current file name/override-name and obtain the read file data 072 var fileName = file.overrideFileName ? file.overrideFileName 073 : file.name ? file.name : file.fileName; 074 var fileData = evt.target.result; 075 if (fileData == null) { 076 fileData = ""; 077 } 078 var fileInputName = "file_" + curIndex; 079 addPlainField( 080 body, 081 fileInputName 082 + @org.opencms.gwt.shared.I_CmsUploadConstants::UPLOAD_FILENAME_ENCODED_SUFFIX, 083 encodeURI(fileName)); 084 body += "Content-Disposition: form-data; name=\"" + fileInputName 085 + "\"; filename=\"" + encodeURI(fileName) + "\"\r\n"; 086 body += "Content-Type: application/octet-stream\r\n\r\n"; 087 body += fileData + "\r\n"; 088 body += "--" + boundary + "\r\n"; 089 // are there any more files?, continue reading the next file 090 if (filesToUpload.length > ++curIndex) { 091 file = filesToUpload[curIndex]; 092 this.readAsBinaryString(file); 093 } else { 094 // there are no more files left append the infos to the request body 095 appendInfos(); 096 // create the request and post it 097 var xhr = new XMLHttpRequest(); 098 xhr.open("POST", uri, true); 099 // simulate a file MIME POST request. 100 xhr.setRequestHeader("Content-Type", 101 "multipart/form-data; boundary=" + boundary); 102 xhr.overrideMimeType('text/plain; charset=x-user-defined'); 103 xhr.onreadystatechange = function() { 104 if (xhr.readyState == 4) { 105 if (xhr.status == 200) { 106 dialog.@org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog::parseResponse(Ljava/lang/String;)(xhr.responseText); 107 } else if (xhr.status != 200) { 108 dialog.@org.opencms.gwt.client.ui.input.upload.I_CmsUploadDialog::showErrorReport(Ljava/lang/String;Ljava/lang/String;)(xhr.statusText, null); 109 } 110 } 111 } 112 xhr.sendAsBinary(body); 113 } 114 } 115 116 // appends the infos to the request body 117 // should be called at end of creating the body because the boundary is closed here 118 function appendInfos() { 119 addPlainField(body, @org.opencms.gwt.shared.I_CmsUploadConstants::KEEP_FILE_NAMES, ""+keepFileNames); 120 for (var i = 0; i < filesToUnzip.length; ++i) { 121 var filename = filesToUnzip[i]; 122 addPlainField( 123 body, 124 @org.opencms.gwt.shared.I_CmsUploadConstants::UPLOAD_UNZIP_FILES_FIELD_NAME, 125 encodeURI(filename)); 126 } 127 128 addPlainField( 129 body, 130 @org.opencms.gwt.shared.I_CmsUploadConstants::UPLOAD_TARGET_FOLDER_FIELD_NAME, 131 targetFolder); 132 133 addPlainField( 134 body, 135 @org.opencms.gwt.shared.I_CmsUploadConstants::POST_CREATE_HANDLER, 136 postCreateHandler); 137 138 addPlainField( 139 body, 140 @org.opencms.gwt.shared.I_CmsUploadConstants::UPLOAD_IS_ROOT_PATH_FIELD_NAME, 141 "" + isRootPath); 142 } 143 144 // the uri to call 145 var uri = uploadUri; 146 // the boundary 147 var boundary = "26924190726270"; 148 // the request body with the starting boundary 149 var body = "--" + boundary + "\r\n"; 150 151 // the main procedure 152 if (filesToUpload) { 153 154 var curIndex = 0; 155 var file = filesToUpload[curIndex]; 156 157 var reader = new FileReader(); 158 reader.onloadend = loaded; 159 reader.onerror = errorHandler; 160 // Read file into memory 161 reader.readAsBinaryString(file); 162 } 163 }-*/; 164 165 /** 166 * Switches the error message depending on the given error code.<p> 167 * 168 * The error codes are defined in the W3C file API.<p> 169 * 170 * <a href="http://www.w3.org/TR/FileAPI/#dfn-fileerror">http://www.w3.org/TR/FileAPI/#dfn-fileerror</a> 171 * 172 * @param dialog the upload dialog 173 * @param errorCode the error code as String 174 */ 175 private void onBrowserError(I_CmsUploadDialog dialog, String errorCode) { 176 177 int code = Integer.valueOf(errorCode).intValue(); 178 String errMsg = org.opencms.gwt.client.Messages.get().key(org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_0); 179 180 switch (code) { 181 case 1: // NOT_FOUND_ERR 182 errMsg = org.opencms.gwt.client.Messages.get().key( 183 org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_NOT_FOUND_0); 184 break; 185 case 2: // SECURITY_ERR 186 errMsg = org.opencms.gwt.client.Messages.get().key( 187 org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_SECURITY_0); 188 break; 189 case 3: // ABORT_ERR 190 errMsg = org.opencms.gwt.client.Messages.get().key( 191 org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_ABORT_ERR_0); 192 break; 193 case 4: // NOT_READABLE_ERR 194 errMsg = org.opencms.gwt.client.Messages.get().key( 195 org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_NOT_READABLE_0); 196 break; 197 case 5: // ENCODING_ERR 198 errMsg = org.opencms.gwt.client.Messages.get().key( 199 org.opencms.gwt.client.Messages.ERR_UPLOAD_BROWSER_ENCODING_0); 200 break; 201 default: 202 break; 203 } 204 dialog.showErrorReport(errMsg, null); 205 } 206}