Skip to content
Snippets Groups Projects
config.service.ts 4.92 KiB
Newer Older
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface';
import { ConfigSuccessResponse, EndpointMap, RootSuccessResponse } from '../cache/response-cache.models';
import { ConfigRequest, FindAllOptions, RestRequest, RootEndpointRequest } from '../data/request.models';
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { ConfigObject } from '../shared/config/config.model';

@Injectable()
export abstract class ConfigService {
  protected request: ConfigRequest;
  protected abstract responseCache: ResponseCacheService;
  protected abstract requestService: RequestService;
  protected abstract linkName: string;
  protected abstract EnvConfig: GlobalConfig;
  protected abstract browseEndpoint: string;

  protected getConfig(request: RestRequest): Observable<ConfigObject[]> {
    return this.responseCache.get(request.href)
      .map((entry: ResponseCacheEntry) => entry.response)
      .filter((response: ConfigSuccessResponse) => isNotEmpty(response) && isNotEmpty(response.configDefinition))
      .map((response: ConfigSuccessResponse) =>  response.configDefinition)
      .distinctUntilChanged();
  }

  protected getConfigByIDHref(endpoint, resourceID): string {
    return `${endpoint}/${resourceID}`;
  }

  protected getConfigSearchHref(endpoint, options: FindAllOptions = {}): string {
    let result;
    const args = [];

    if (hasValue(options.scopeID)) {
      result = `${endpoint}/${this.browseEndpoint}`
      args.push(`uuid=${options.scopeID}`);
    } else {
      result = endpoint;
    }

    if (hasValue(options.currentPage) && typeof options.currentPage === 'number') {
      /* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */
      args.push(`page=${options.currentPage - 1}`);
    }

    if (hasValue(options.elementsPerPage)) {
      args.push(`size=${options.elementsPerPage}`);
    }

    if (hasValue(options.sort)) {
      let direction = 'asc';
      if (options.sort.direction === 1) {
        direction = 'desc';
      }
      args.push(`sort=${options.sort.field},${direction}`);
    }

    if (isNotEmpty(args)) {
      result = `${result}?${args.join('&')}`;
    }
    return result;
  }

  protected getEndpointMap(): Observable<EndpointMap> {
    const request = new RootEndpointRequest(this.EnvConfig);
    setTimeout(() => {
      this.requestService.configure(request);
    }, 0);
    return this.responseCache.get(request.href)
      .map((entry: ResponseCacheEntry) => entry.response)
      .filter((response: RootSuccessResponse) => isNotEmpty(response) && isNotEmpty(response.endpointMap))
      .map((response: RootSuccessResponse) => response.endpointMap)
      .distinctUntilChanged();
  }

  public getConfigAll(): Observable<ConfigObject[]> {
    return this.getEndpoint()
      .filter((href: string) => isNotEmpty(href))
      .distinctUntilChanged()
      .map((endpointURL: string) => new ConfigRequest(endpointURL))
      .do((request: RestRequest) => {
        setTimeout(() => {
          this.requestService.configure(request);
        }, 0);
      })
      .flatMap((request: RestRequest) => this.getConfig(request))
      .distinctUntilChanged();
  }

  public getConfigByHref(href: string): Observable<ConfigObject[]> {
    const request = new ConfigRequest(href);
    this.requestService.configure(request);

    return this.getConfig(request);
  }

  public getConfigById(id: string): Observable<ConfigObject[]> {
    return this.getEndpoint()
      .map((endpoint: string) => this.getConfigByIDHref(endpoint, id))
      .filter((href: string) => isNotEmpty(href))
      .distinctUntilChanged()
      .map((endpointURL: string) => new ConfigRequest(endpointURL))
      .do((request: RestRequest) => {
        setTimeout(() => {
          this.requestService.configure(request);
        }, 0);
      })
      .flatMap((request: RestRequest) => this.getConfig(request))
      .distinctUntilChanged();
  }

  public getConfigBySearch(options: FindAllOptions = {}): Observable<ConfigObject[]> {
    return this.getEndpoint()
      .map((endpoint: string) => this.getConfigSearchHref(endpoint, options))
      .filter((href: string) => isNotEmpty(href))
      .distinctUntilChanged()
      .map((endpointURL: string) => new ConfigRequest(endpointURL))
      .do((request: RestRequest) => {
        setTimeout(() => {
          this.requestService.configure(request);
        }, 0);
      })
      .flatMap((request: RestRequest) => this.getConfig(request))
      .distinctUntilChanged();
  }

  public getEndpoint(): Observable<string> {
    return this.getEndpointMap()
      .map((map: EndpointMap) => map[this.linkName])
      .distinctUntilChanged();
  }

}