import { Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ResponseCacheService } from '../cache/response-cache.service'; import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { URLCombiner } from '../url-combiner/url-combiner'; import { PaginatedList } from './paginated-list'; import { RemoteData } from './remote-data'; import { FindAllOptions, FindAllRequest, FindByIDRequest, GetRequest } from './request.models'; import { RequestService } from './request.service'; import { NormalizedObject } from '../cache/models/normalized-object.model'; export abstract class DataService { protected abstract responseCache: ResponseCacheService; protected abstract requestService: RequestService; protected abstract rdbService: RemoteDataBuildService; protected abstract store: Store; protected abstract linkPath: string; protected abstract halService: HALEndpointService; public abstract getScopedEndpoint(scope: string): Observable protected getFindAllHref(endpoint, options: FindAllOptions = {}): Observable { let result: Observable; const args = []; if (hasValue(options.scopeID)) { result = this.getScopedEndpoint(options.scopeID).distinctUntilChanged(); } else { result = Observable.of(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)) { args.push(`sort=${options.sort.field},${options.sort.direction}`); } if (isNotEmpty(args)) { return result.map((href: string) => new URLCombiner(href, `?${args.join('&')}`).toString()); } else { return result; } } findAll(options: FindAllOptions = {}): Observable>> { const hrefObs = this.halService.getEndpoint(this.linkPath).filter((href: string) => isNotEmpty(href)) .flatMap((endpoint: string) => this.getFindAllHref(endpoint, options)); hrefObs .filter((href: string) => hasValue(href)) .take(1) .subscribe((href: string) => { const request = new FindAllRequest(this.requestService.generateRequestId(), href, options); this.requestService.configure(request); }); return this.rdbService.buildList(hrefObs) as Observable>>; } getFindByIDHref(endpoint, resourceID): string { return `${endpoint}/${resourceID}`; } findById(id: string): Observable> { const hrefObs = this.halService.getEndpoint(this.linkPath) .map((endpoint: string) => this.getFindByIDHref(endpoint, id)); hrefObs .filter((href: string) => hasValue(href)) .take(1) .subscribe((href: string) => { const request = new FindByIDRequest(this.requestService.generateRequestId(), href, id); this.requestService.configure(request); }); return this.rdbService.buildSingle(hrefObs); } findByHref(href: string): Observable> { this.requestService.configure(new GetRequest(this.requestService.generateRequestId(), href)); return this.rdbService.buildSingle(href); } // TODO implement, after the structure of the REST server's POST response is finalized // create(dso: DSpaceObject): Observable> { // const postHrefObs = this.getEndpoint(); // // // TODO ID is unknown at this point // const idHrefObs = postHrefObs.map((href: string) => this.getFindByIDHref(href, dso.id)); // // postHrefObs // .filter((href: string) => hasValue(href)) // .take(1) // .subscribe((href: string) => { // const request = new RestRequest(this.requestService.generateRequestId(), href, RestRequestMethod.Post, dso); // this.requestService.configure(request); // }); // // return this.rdbService.buildSingle(idHrefObs, this.normalizedResourceType); // } }