1(function (window) { 2 'use strict'; 3 4 window.fileTransferService = fileTransferService; 5 fileTransferService.$inject = ['$q', 'Healthspace']; 6 return window; 7 8 function fileTransferService($q, Healthspace) { 9 var BYTES_PER_CHUNK = 45000; 10 var MAX_FILE_SIZE_BYTES = 6291456; // 6 MB 11 12 // from Hciactive.Healthspace.TransferTypes 13 var TransferTypes = { 14 Download: 'Download', 15 UploadNewDoc: 'UploadNewDoc', 16 UploadReplace: 'UploadReplace', 17 UploadNewVersion: 'UploadNewVersion', 18 UploadTranslation: 'UploadTranslation' 19 }; 20 21 // from Hciactive.Healthspace.DocumentTypes 22 var DocumentTypes = { 23 Template: 'W', 24 MergeReport: 'C', 25 Attached: 'A', 26 Merged: 'M', 27 Floating: 'F', 28 Original: 'O' 29 }; 30 31 // from Hciactive.Healthspace.StorageTypes 32 var StorageTypes = { 33 Database: 1, 34 WebServer: 2, 35 FileServer: 3 36 }; 37 38 var OPID = { 39 EnrollmentService_AttachMemberDocumentChunk: 'BenefitModule.EnrollmentService.AttachMemberDocumentChuck', 40 PrincipalDocumentService_UploadDocChunk: 'PrincipalDocumentService.UploadDocChunk' 41 }; 42 43 var service = this; 44 45 angular.extend(service, { 46 AttachMemberDocument: attachMemberDocument, 47 UploadPrincipalDocument: uploadPrincipalDocument 48 }); 49 50 Object.defineProperty(service, "MaxFileSizeBytes", { 51 get: function () { 52 return MAX_FILE_SIZE_BYTES; 53 } 54 }); 55 56 function FileUploadAtrributes(source) { 57 var self = this; 58 59 angular.extend(self, { 60 Name: '', 61 FileName: '', 62 Notes: '' 63 }); 64 65 // Id 66 var _Id = null; 67 Object.defineProperty(self, "Id", { 68 get: function () { 69 return _Id; 70 }, 71 set: function (value) { 72 _Id = hci.utils.parseGuid(value); 73 } 74 }); 75 76 // PrincipalId 77 var _PrincipalId = null; 78 Object.defineProperty(self, "PrincipalId", { 79 get: function () { 80 return _PrincipalId; 81 }, 82 set: function (value) { 83 _PrincipalId = hci.utils.parseGuid(value); 84 } 85 }); 86 87 // ProjectId 88 var _ProjectId = null; 89 Object.defineProperty(self, "ProjectId", { 90 get: function () { 91 return _ProjectId; 92 }, 93 set: function (value) { 94 _ProjectId = hci.utils.parseGuid(value); 95 } 96 }); 97 98 // TempVersionId 99 var _TempVersionId = null; 100 Object.defineProperty(self, "TempVersionId", { 101 get: function () { 102 return _TempVersionId; 103 }, 104 set: function (value) { 105 _TempVersionId = hci.utils.parseGuid(value); 106 } 107 }); 108 109 // DocumentType 110 var _DocumentType = null; 111 Object.defineProperty(self, "DocumentType", { 112 get: function () { 113 return _DocumentType; 114 }, 115 set: function (value) { 116 for (var prop in DocumentTypes) { 117 if (DocumentTypes.hasOwnProperty(prop) && DocumentTypes[prop] === value) { 118 _DocumentType = DocumentTypes[prop]; 119 return; 120 } 121 } 122 } 123 }); 124 125 // TransferType 126 var _TransferType = null; 127 Object.defineProperty(self, "TransferType", { 128 get: function () { 129 return _TransferType; 130 }, 131 set: function (value) { 132 for (var prop in TransferTypes) { 133 if (TransferTypes.hasOwnProperty(prop) && TransferTypes[prop] === value) { 134 _TransferType = TransferTypes[prop]; 135 return; 136 } 137 } 138 } 139 }); 140 141 // IsProjectRelated 142 var _IsProjectRelated = null; 143 Object.defineProperty(self, "IsProjectRelated", { 144 get: function () { 145 return _IsProjectRelated; 146 }, 147 set: function (value) { 148 _IsProjectRelated = hci.utils.parseBool(value); 149 } 150 }); 151 152 update(source); 153 154 return self; 155 156 function update(source) { 157 if (typeof source != 'undefined' && source !== null) { 158 self.Id = source['Id']; 159 self.PrincipalId = source['PrincipalId']; 160 self.ProjectId = source['ProjectId']; 161 self.TempVersionId = source['TempVersionId']; 162 self.DocumentType = source['DocumentType']; 163 self.TransferType = source['TransferType']; 164 self.Name = source['Name']; 165 self.FileName = source['FileName']; 166 self.Notes = source['Notes']; 167 self.IsProjectRelated = source['IsProjectRelated']; 168 } 169 } 170 } 171 172 function attachMemberDocument(principalId, projectId, documentId, file, notes, onSuccess, onError, onProgressUpdate) { 173 return uploadDocument(OPID.EnrollmentService_AttachMemberDocumentChunk, principalId, projectId, documentId, file, notes, onSuccess, onError, onProgressUpdate); 174 } 175 176 function uploadPrincipalDocument(principalId, projectId, documentId, file, notes, onSuccess, onError, onProgressUpdate) { 177 return uploadDocument(OPID.PrincipalDocumentService_UploadDocChunk, principalId, projectId, documentId, file, notes, onSuccess, onError, onProgressUpdate); 178 } 179 180 // Helper functions 181 182 function uploadDocument(fileUploadServiceOperation, principalId, projectId, documentId, file, notes, onSuccess, onError, onProgressUpdate) { 183 return readFile(file).then(function (result) { 184 var deferred = $q.defer(); 185 186 var fileContent = new Uint8Array(result); 187 188 var fileAttributes = new FileUploadAtrributes(); 189 if (hci.utils.parseGuid(documentId) !== null) { 190 fileAttributes.Id = documentId; 191 fileAttributes.TransferType = TransferTypes.UploadReplace; 192 } 193 else { 194 fileAttributes.TransferType = TransferTypes.UploadNewDoc; 195 } 196 fileAttributes.PrincipalId = principalId; 197 fileAttributes.ProjectId = projectId; 198 fileAttributes.DocumentType = DocumentTypes.Attached; 199 fileAttributes.Name = file.name.replace(/\.[^/.]+$/, ''); // file name without extension 200 fileAttributes.FileName = file.name; 201 fileAttributes.Notes = notes; 202 203 return uploadDocumentChunk(deferred, fileContent, 0, fileAttributes, fileUploadServiceOperation).then(function (documentId) { 204 if (typeof onSuccess == 'function') { 205 onSuccess(documentId); 206 } 207 }, function (errorMessage) { 208 if (typeof onError == 'function') { 209 onError(errorMessage); 210 } 211 }, function (update) { 212 if (typeof onProgressUpdate == 'function') { 213 onProgressUpdate(update.BytesUploaded, update.FileSize); 214 } 215 }); 216 }) 217 .catch(function (error) { 218 if (console !== undefined) { 219 console.error("FileReader error occured in FileTransfer.uploadDocument: " + error.code); 220 } 221 222 var msg = getFileReaderErrorMessage(error); 223 if (typeof onError == 'function') { 224 onError(msg); 225 } 226 }); 227 } 228 229 function uploadDocumentChunk(deferred, fileContent, offset, fileAttributes, fileUploadServiceOperation) { 230 if (typeof deferred == 'undefined') { 231 deferred = $q.defer(); 232 } 233 234 // determine chunk size 235 var fileLength = fileContent.length; 236 var chunkOffsetEnd; 237 var moreChunks = "True"; 238 var fileHash = null; 239 240 if (offset + BYTES_PER_CHUNK >= fileLength) { 241 // upload the remaining bytes 242 chunkOffsetEnd = fileLength; 243 moreChunks = "False"; 244 245 // generate SHA1 hash for server-side file verification 246 var wordArray = CryptoJS.lib.WordArray.create(fileContent); 247 fileHash = CryptoJS.enc.Base64.stringify(CryptoJS.SHA1(wordArray)); 248 } 249 else { 250 // upload the next chunk of bytes 251 chunkOffsetEnd = offset + BYTES_PER_CHUNK; 252 } 253 254 var chunk = fileContent.buffer.slice(offset, chunkOffsetEnd); 255 256 var dto = { 257 Id: fileAttributes.Id, 258 PrincipalId: fileAttributes.PrincipalId, 259 ProjectId: fileAttributes.ProjectId, 260 TempVersionId: fileAttributes.TempVersionId, 261 DocumentType: fileAttributes.DocumentType, 262 TransferType: fileAttributes.TransferType, 263 Name: fileAttributes.Name, 264 FileName: fileAttributes.FileName, 265 Notes: fileAttributes.Notes, 266 Offset: offset, 267 MoreChunks: moreChunks, 268 SHA1Hash: fileHash 269 }; 270 271 $q.when( 272 Healthspace.executePostFileJS(fileUploadServiceOperation, chunk, dto, 'File') 273 ).then(function (response) { 274 var data = Healthspace.getDataFromHSResponse(response, 'File'); 275 if (data.length > 0) { 276 data = data[0]; 277 } 278 else { 279 data = {}; 280 } 281 282 if (data.hasOwnProperty("MoreChunks")) { 283 // report file upload progress 284 deferred.notify({ 285 BytesUploaded: chunkOffsetEnd, 286 FileSize: fileLength 287 }); 288 289 if (hci.utils.parseBool(data.MoreChunks) === true) { 290 // upload the next chunk of data 291 fileAttributes.Id = data.Id; 292 fileAttributes.TempVersionId = data.TempVersionId; 293 294 return uploadDocumentChunk(deferred, fileContent, chunkOffsetEnd, fileAttributes, fileUploadServiceOperation); 295 } 296 else { 297 // report success 298 deferred.resolve(data.Id); 299 } 300 } 301 else { 302 if (console !== undefined) { 303 console.error("No data returned from serviceOp: " + fileUploadServiceOperation); 304 } 305 306 deferred.reject("File transfer incomplete. Please try again"); 307 } 308 }) 309 .catch(function (fault) { 310 var message = !!(fault.UserMessage) ? fault.UserMessage : fault.ExceptionMessage; 311 if (console !== undefined) { 312 console.error(message); 313 } 314 315 deferred.reject(message); 316 }); 317 318 return deferred.promise; 319 } 320 321 function readFile(file) { 322 var reader = new FileReader(); 323 var deferred = $q.defer(); 324 325 reader.onloadend = function (event) { 326 if (event.target.readyState == FileReader.DONE) { 327 deferred.resolve(event.target.result); 328 } 329 }; 330 331 reader.onerror = function (event) { 332 deferred.reject(event.target.error); 333 }; 334 335 reader.readAsArrayBuffer(file); 336 337 return deferred.promise; 338 } 339 340 function getFileReaderErrorMessage(domError) { 341 var msg = ''; 342 343 // FileReader.DOMError 344 switch (domError.code) { 345 case domError.NOT_FOUND_ERR: 346 msg = 'File not found!'; 347 break; 348 349 case domError.NOT_READABLE_ERR: 350 msg = 'File not readable!'; 351 break; 352 353 case domError.ABORT_ERR: 354 msg = 'Read operation was aborted!'; 355 break; 356 357 case domError.SECURITY_ERR: 358 msg = 'File is in a locked state!'; 359 break; 360 361 case domError.ENCODING_ERR: 362 msg = 'File is too large to encode in a "data://" URL.'; 363 break; 364 365 default: 366 msg = 'Unknown read error.'; 367 break; 368 } 369 370 return msg; 371 } 372 } 373}(this)); 374//#sourceURL=fileTransferService.js
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.