| /******************************************************************************** |
| * 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 { map, tap, concatMap } from 'rxjs/operators'; |
| import { from } from 'rxjs'; |
| import { plainToClass } from 'class-transformer'; |
| |
| import { HttpErrorHandler } from '@core/http-error-handler'; |
| import { MDMNotificationService } from '@core/mdm-notification.service'; |
| import { PropertyService } from '@core/property.service'; |
| import { MDMLink, FileSize, Node, Attribute, ContextGroup } from '@navigator/node'; |
| import { FileUploadRow } from '../model/file-explorer.model'; |
| import { ContextAttributeIdentifier } from '@details/model/details.model'; |
| |
| @Injectable({ |
| providedIn: 'root' |
| }) |
| export class ContextFilesService { |
| |
| private contextUrl: string; |
| |
| constructor (private http: Http, |
| private httpErrorHandler: HttpErrorHandler, |
| private notificationService: MDMNotificationService, |
| private _prop: PropertyService) { |
| this.contextUrl = _prop.getUrl('mdm/environments'); |
| } |
| |
| public getUrl(ident: ContextAttributeIdentifier, remotePath: string) { |
| return this.getFileEndpoint(ident) + '/' + this.escapeUrlCharacters(remotePath); |
| } |
| |
| private getFileEndpoint(ident: ContextAttributeIdentifier) { |
| return this.contextUrl |
| + '/' + ident.contextComponent.sourceName |
| + '/' + this.contextGroupToUrl(ident.contextGroup) |
| + '/' + ident.contextDescribable.id |
| + '/contexts' |
| + '/' + ident.contextType |
| + '/' + this.escapeUrlCharacters(ident.contextComponent.name) |
| + '/' + this.escapeUrlCharacters(ident.attribute.name) |
| + '/files'; |
| } |
| |
| // loads file size from server for file with given remote path |
| public loadFileSize(link: MDMLink, ident: ContextAttributeIdentifier) { |
| |
| const endpoint = this.getFileEndpoint(ident) |
| + '/size/' + this.escapeUrlCharacters(link.remotePath); |
| |
| return this.http.get(endpoint) |
| .pipe( |
| map(res => plainToClass(FileSize, res.json() as FileSize)) |
| ) |
| .catch(this.httpErrorHandler.handleError); |
| } |
| |
| // loads file in context from server, returns file as blob. |
| public loadFile(link: MDMLink, ident: ContextAttributeIdentifier) { |
| |
| const headers = new Headers({}); |
| const endpoint = this.getFileEndpoint(ident) |
| + '/' + this.escapeUrlCharacters(link.remotePath); |
| |
| return this.http.get(endpoint, { method: RequestMethod.Get, |
| responseType: ResponseContentType.Blob, |
| headers: headers }) |
| .pipe( |
| map(res => res.blob()) |
| ) |
| .catch(this.httpErrorHandler.handleError); |
| } |
| |
| // Uploads multiple files. Http requests are chained to avoid concurrency in server side update process. |
| public uploadFiles(files: FileUploadRow[], ident: ContextAttributeIdentifier) { |
| return from(files).pipe( |
| concatMap(file => this.uploadFile(file, ident)) |
| ); |
| } |
| |
| // upload file |
| public uploadFile(fileData: FileUploadRow, ident: ContextAttributeIdentifier) { |
| |
| const fd = new FormData(); |
| fd.append('file', fileData.file, fileData.file.name); |
| fd.append('mimeType', fileData.file.type); |
| fd.append('description', fileData.description); |
| |
| const endpoint = this.getFileEndpoint(ident); |
| |
| 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(link: MDMLink, ident: ContextAttributeIdentifier) { |
| const endpoint = this.getFileEndpoint(ident) |
| + '/' + this.escapeUrlCharacters(link.remotePath); |
| |
| return this.http.delete(endpoint) |
| .pipe( |
| map(res => plainToClass(MDMLink, res.json() as MDMLink)), |
| tap(flink => this.notificationService.notifySuccess( |
| 'File deleted.', |
| 'The file ' + flink.remotePath.substring(flink.remotePath.lastIndexOf('/') + 1) |
| + ' has been successfully deleted from file system.' |
| )) |
| ) |
| .catch(this.httpErrorHandler.handleError); |
| } |
| |
| private contextGroupToUrl(type: number) { |
| switch (type) { |
| case 0: |
| return 'teststeps'; |
| case 1: |
| return 'measurements'; |
| } |
| } |
| |
| // replaces / by %2F to not break url |
| private escapeUrlCharacters(urlString: string) { |
| return urlString.replace(/\//g, '%2F').replace(/\./g, '%2E').replace(/ /g, '%20'); |
| } |
| } |