/******************************************************************************** | |
* Copyright (c) 2015-2018 Contributors to the Eclipse Foundation | |
* | |
* See the NOTICE file(s) distributed with this work for additional | |
* information regarding copyright ownership. | |
* | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v. 2.0 which is available at | |
* http://www.eclipse.org/legal/epl-2.0. | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
********************************************************************************/ | |
import { Injectable} from '@angular/core'; | |
import { Http, Headers, RequestMethod, ResponseContentType} from '@angular/http'; | |
import { plainToClass } from 'class-transformer'; | |
import { map, tap, concatMap } from 'rxjs/operators'; | |
import { from } from 'rxjs'; | |
import { MDMNotificationService } from '@core/mdm-notification.service'; | |
import { HttpErrorHandler } from '@core/http-error-handler'; | |
import { PropertyService } from '@core/property.service'; | |
import { Node, MDMLink, FileSize } from '@navigator/node'; | |
import { FileUploadRow } from '../model/file-explorer.model'; | |
@Injectable() | |
export class FilesAttachableService { | |
public static readonly MDM_LINKS = 'MDMLinks'; | |
private contextUrl: string; | |
constructor (private http: Http, | |
private httpErrorHandler: HttpErrorHandler, | |
private notificationService: MDMNotificationService, | |
private _prop: PropertyService) { | |
this.contextUrl = _prop.getUrl('mdm/environments'); | |
} | |
public getFilesEndpoint(node: Node) { | |
const urlType = this.typeToUrl(node.sourceType); | |
return this.contextUrl | |
+ '/' + node.sourceName | |
+ '/' + urlType | |
+ '/' + node.id | |
+ '/files'; | |
} | |
// loads file for fileatachable from server, returns file as blob. | |
public loadFile(remotePath: string, node: Node) { | |
const headers = new Headers({}); | |
const endpoint = this.getFilesEndpoint(node) + '/' + this.escapeUrlCharacters(remotePath); | |
return this.http.get(endpoint, { method: RequestMethod.Get, | |
responseType: ResponseContentType.Blob, | |
headers: headers }) | |
.pipe( | |
map(res => res.blob()) | |
) | |
.catch(this.httpErrorHandler.handleError); | |
} | |
// loads file size from server for file with given remote path | |
public loadFileSize(remotePath: string, node: Node) { | |
const endpoint = this.getFilesEndpoint(node) + '/size/' + this.escapeUrlCharacters(remotePath); | |
return this.http.get(endpoint) | |
.pipe( | |
map(res => plainToClass(FileSize, res.json() as FileSize)) | |
) | |
.catch(this.httpErrorHandler.handleError); | |
} | |
// loads file sizes from server for all files attached to given entity | |
public loadFileSizes(node: Node) { | |
const endpoint = this.getFilesEndpoint(node) + '/sizes'; | |
return this.http.get(endpoint) | |
.pipe( | |
map(res => plainToClass(FileSize, res.json() as FileSize[])) | |
) | |
.catch(this.httpErrorHandler.handleError); | |
} | |
// Uploads multiple files. Http requests are chained to avoid concurrency in server side update process. | |
public uploadFiles(node: Node, files: FileUploadRow[]) { | |
return from(files).pipe( | |
concatMap(file => this.uploadFile(node, file)) | |
); | |
} | |
// upload file | |
public uploadFile(node: Node, fileData: FileUploadRow) { | |
const fd = new FormData(); | |
fd.append('file', fileData.file, fileData.file.name); | |
// fd.append('size', fileData.file.size.toString()); | |
fd.append('mimeType', fileData.file.type); | |
fd.append('description', fileData.description); | |
const endpoint = this.getFilesEndpoint(node); | |
return this.http.post(endpoint , fd) | |
.pipe( | |
map(res => plainToClass(MDMLink, res.json() as MDMLink)), | |
tap(link => this.notificationService.notifySuccess( | |
'File created.', | |
'The file ' + link.remotePath.substring(link.remotePath.lastIndexOf('/') + 1) | |
+ ' has been successfully created.' | |
)) | |
) | |
.catch(this.httpErrorHandler.handleError); | |
} | |
// delete file from server | |
public deleteFile(remotePath: string, node: Node) { | |
const endpoint = this.getFilesEndpoint(node) + '/' + this.escapeUrlCharacters(remotePath); | |
return this.http.delete(endpoint) | |
.pipe( | |
map(res => plainToClass(MDMLink, res.json() as MDMLink)), | |
tap(link => this.notificationService.notifySuccess( | |
'File deleted.', | |
'The file ' + link.remotePath.substring(link.remotePath.lastIndexOf('/') + 1) | |
+ ' has been successfully deleted from file system.' | |
)) | |
) | |
.catch(this.httpErrorHandler.handleError); | |
} | |
// helping function to map sourceType to proper url for endpoint. | |
private typeToUrl(type: string) { | |
if (type != undefined) { | |
switch (type) { | |
case 'MeaResult': | |
return 'measurements'; | |
default: | |
return type.toLowerCase() + 's'; | |
} | |
} | |
} | |
// replaces / by %2F to not break url | |
private escapeUrlCharacters(urlString: string) { | |
return urlString.replace(/\//g, '%2F').replace(/\./g, '%2E'); | |
} | |
} |