70834: Refactoring registry-service pt1 - removing response-parsing services and using data-services

This commit is contained in:
Kristof De Langhe
2020-05-12 14:54:10 +02:00
parent bb0f28c9c4
commit 101f1a76dd
17 changed files with 107 additions and 600 deletions

View File

@@ -12,6 +12,7 @@ import { NotificationsService } from '../../../shared/notifications/notification
import { Route, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
@Component({
selector: 'ds-metadata-registry',
@@ -57,7 +58,7 @@ export class MetadataRegistryComponent {
* Update the list of schemas by fetching it from the rest api or cache
*/
private updateSchemas() {
this.metadataSchemas = this.registryService.getMetadataSchemas(this.config);
this.metadataSchemas = this.registryService.getMetadataSchemas(toFindListOptions(this.config));
}
/**

View File

@@ -13,6 +13,8 @@ import { NotificationsService } from '../../../shared/notifications/notification
import { TranslateService } from '@ngx-translate/core';
import { MetadataField } from '../../../core/metadata/metadata-field.model';
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
import { getSucceededRemoteData } from '../../../core/shared/operators';
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
@Component({
selector: 'ds-metadata-schema',
@@ -85,9 +87,9 @@ export class MetadataSchemaComponent implements OnInit {
* Update the list of fields by fetching it from the rest api or cache
*/
private updateFields() {
this.metadataSchema.subscribe((schemaData) => {
this.metadataSchema.pipe(getSucceededRemoteData()).subscribe((schemaData) => {
const schema = schemaData.payload;
this.metadataFields = this.registryService.getMetadataFieldsBySchema(schema, this.config);
this.metadataFields = this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config));
this.namespace = {namespace: schemaData.payload.namespace};
});
}

View File

@@ -6,9 +6,6 @@ import { ConfigObject } from '../config/models/config.model';
import { FacetValue } from '../../shared/search/facet-value.model';
import { SearchFilterConfig } from '../../shared/search/search-filter-config.model';
import { IntegrationModel } from '../integration/models/integration.model';
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
import { PaginatedList } from '../data/paginated-list';
import { SubmissionObject } from '../submission/models/submission-object.model';
import { DSpaceObject } from '../shared/dspace-object.model';
@@ -40,48 +37,6 @@ export class DSOSuccessResponse extends RestResponse {
}
}
/**
* A successful response containing a list of MetadataSchemas wrapped in a RegistryMetadataschemasResponse
*/
export class RegistryMetadataschemasSuccessResponse extends RestResponse {
constructor(
public metadataschemasResponse: RegistryMetadataschemasResponse,
public statusCode: number,
public statusText: string,
public pageInfo?: PageInfo
) {
super(true, statusCode, statusText);
}
}
/**
* A successful response containing a list of MetadataFields wrapped in a RegistryMetadatafieldsResponse
*/
export class RegistryMetadatafieldsSuccessResponse extends RestResponse {
constructor(
public metadatafieldsResponse: RegistryMetadatafieldsResponse,
public statusCode: number,
public statusText: string,
public pageInfo?: PageInfo
) {
super(true, statusCode, statusText);
}
}
/**
* A successful response containing a list of BitstreamFormats wrapped in a RegistryBitstreamformatsResponse
*/
export class RegistryBitstreamformatsSuccessResponse extends RestResponse {
constructor(
public bitstreamformatsResponse: RegistryBitstreamformatsResponse,
public statusCode: number,
public statusText: string,
public pageInfo?: PageInfo
) {
super(true, statusCode, statusText);
}
}
/**
* A successful response containing exactly one MetadataSchema
*/

View File

@@ -73,9 +73,6 @@ import { MetadatafieldParsingService } from './data/metadatafield-parsing.servic
import { MetadataschemaParsingService } from './data/metadataschema-parsing.service';
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
import { RegistryBitstreamformatsResponseParsingService } from './data/registry-bitstreamformats-response-parsing.service';
import { RegistryMetadatafieldsResponseParsingService } from './data/registry-metadatafields-response-parsing.service';
import { RegistryMetadataschemasResponseParsingService } from './data/registry-metadataschemas-response-parsing.service';
import { RelationshipTypeService } from './data/relationship-type.service';
import { RelationshipService } from './data/relationship.service';
import { ResourcePolicyService } from './data/resource-policy.service';
@@ -145,6 +142,8 @@ import { Version } from './shared/version.model';
import { VersionHistory } from './shared/version-history.model';
import { WorkflowActionDataService } from './data/workflow-action-data.service';
import { WorkflowAction } from './tasks/models/workflow-action-object.model';
import { MetadataSchemaDataService } from './data/metadata-schema-data.service';
import { MetadataFieldDataService } from './data/metadata-field-data.service';
/**
* When not in production, endpoint responses can be mocked for testing purposes
@@ -201,9 +200,6 @@ const PROVIDERS = [
FacetValueResponseParsingService,
FacetValueMapResponseParsingService,
FacetConfigResponseParsingService,
RegistryMetadataschemasResponseParsingService,
RegistryMetadatafieldsResponseParsingService,
RegistryBitstreamformatsResponseParsingService,
MappedCollectionsReponseParsingService,
DebugResponseParsingService,
SearchResponseParsingService,
@@ -264,6 +260,8 @@ const PROVIDERS = [
LicenseDataService,
ItemTypeDataService,
WorkflowActionDataService,
MetadataSchemaDataService,
MetadataFieldDataService,
// register AuthInterceptor as HttpInterceptor
{
provide: HTTP_INTERCEPTORS,

View File

@@ -0,0 +1,48 @@
import { Injectable } from '@angular/core';
import { dataService } from '../cache/builders/build-decorators';
import { DataService } from './data.service';
import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { HttpClient } from '@angular/common/http';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
import { MetadataField } from '../metadata/metadata-field.model';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { FindListOptions } from './request.models';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { SearchParam } from '../cache/models/search-param.model';
/**
* A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint
*/
@Injectable()
@dataService(METADATA_FIELD)
export class MetadataFieldDataService extends DataService<MetadataField> {
protected linkPath = 'metadatafields';
protected searchBySchemaLinkPath = 'bySchema';
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>,
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,
protected comparator: DefaultChangeAnalyzer<MetadataField>,
protected http: HttpClient,
protected notificationsService: NotificationsService) {
super();
}
findBySchema(schema: MetadataSchema, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>) {
const optionsWithSchema = Object.assign(new FindListOptions(), options, {
searchParams: [new SearchParam('schema', schema.prefix)]
});
return this.searchBy(this.searchBySchemaLinkPath, optionsWithSchema, ...linksToFollow);
}
}

View File

@@ -9,37 +9,17 @@ import { CoreState } from '../core.reducers';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { METADATA_SCHEMA } from '../metadata/metadata-schema.resource-type';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { ChangeAnalyzer } from './change-analyzer';
import { DataService } from './data.service';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { RequestService } from './request.service';
/* tslint:disable:max-classes-per-file */
class DataServiceImpl extends DataService<MetadataSchema> {
protected linkPath = 'metadataschemas';
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: ChangeAnalyzer<MetadataSchema>) {
super();
}
}
/**
* A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint
*/
@Injectable()
@dataService(METADATA_SCHEMA)
export class MetadataSchemaDataService {
private dataService: DataServiceImpl;
export class MetadataSchemaDataService extends DataService<MetadataSchema> {
protected linkPath = 'metadataschemas';
constructor(
protected requestService: RequestService,
@@ -50,6 +30,6 @@ export class MetadataSchemaDataService {
protected comparator: DefaultChangeAnalyzer<MetadataSchema>,
protected http: HttpClient,
protected notificationsService: NotificationsService) {
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
super();
}
}

View File

@@ -1,41 +0,0 @@
import { PageInfo } from '../shared/page-info.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import {
RegistryBitstreamformatsSuccessResponse
} from '../cache/response.models';
import { RegistryBitstreamformatsResponseParsingService } from './registry-bitstreamformats-response-parsing.service';
describe('RegistryBitstreamformatsResponseParsingService', () => {
let service: RegistryBitstreamformatsResponseParsingService;
const mockDSOParser = Object.assign({
processPageInfo: () => new PageInfo()
}) as DSOResponseParsingService;
const data = Object.assign({
payload: {
_embedded: {
bitstreamformats: [
{
uuid: 'uuid-1',
description: 'a description'
},
{
uuid: 'uuid-2',
description: 'another description'
},
]
}
}
}) as DSpaceRESTV2Response;
beforeEach(() => {
service = new RegistryBitstreamformatsResponseParsingService(mockDSOParser);
});
it('should parse the data correctly', () => {
const response = service.parse(null, data);
expect(response.constructor).toBe(RegistryBitstreamformatsSuccessResponse);
});
});

View File

@@ -1,25 +0,0 @@
import { Injectable } from '@angular/core';
import { RegistryBitstreamformatsSuccessResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
@Injectable()
export class RegistryBitstreamformatsResponseParsingService implements ResponseParsingService {
constructor(private dsoParser: DSOResponseParsingService) {
}
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const payload = data.payload;
const bitstreamformats = payload._embedded.bitstreamformats;
payload.bitstreamformats = bitstreamformats;
const deserialized = new DSpaceSerializer(RegistryBitstreamformatsResponse).deserialize(payload);
return new RegistryBitstreamformatsSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload.page));
}
}

View File

@@ -1,68 +0,0 @@
import { PageInfo } from '../shared/page-info.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import {
RegistryMetadatafieldsSuccessResponse
} from '../cache/response.models';
import { RegistryMetadatafieldsResponseParsingService } from './registry-metadatafields-response-parsing.service';
describe('RegistryMetadatafieldsResponseParsingService', () => {
let service: RegistryMetadatafieldsResponseParsingService;
const mockDSOParser = Object.assign({
processPageInfo: () => new PageInfo()
}) as DSOResponseParsingService;
const data = Object.assign({
payload: {
_embedded: {
metadatafields: [
{
id: 1,
element: 'element',
qualifier: 'qualifier',
scopeNote: 'a scope note',
_embedded: {
schema: {
id: 1,
prefix: 'test',
namespace: 'test namespace'
}
}
},
{
id: 2,
element: 'secondelement',
qualifier: 'secondqualifier',
scopeNote: 'a second scope note',
_embedded: {
schema: {
id: 1,
prefix: 'test',
namespace: 'test namespace'
}
}
},
]
}
}
}) as DSpaceRESTV2Response;
const emptyData = Object.assign({
payload: {}
}) as DSpaceRESTV2Response;
beforeEach(() => {
service = new RegistryMetadatafieldsResponseParsingService(mockDSOParser);
});
it('should parse the data correctly', () => {
const response = service.parse(null, data);
expect(response.constructor).toBe(RegistryMetadatafieldsSuccessResponse);
});
it('should not produce an error and parse the data correctly when the data is empty', () => {
const response = service.parse(null, emptyData);
expect(response.constructor).toBe(RegistryMetadatafieldsSuccessResponse);
});
});

View File

@@ -1,34 +0,0 @@
import { Injectable } from '@angular/core';
import { hasValue } from '../../shared/empty.util';
import { RegistryMetadatafieldsSuccessResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
@Injectable()
export class RegistryMetadatafieldsResponseParsingService implements ResponseParsingService {
constructor(private dsoParser: DSOResponseParsingService) {
}
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const payload = data.payload;
let metadatafields = [];
if (hasValue(payload._embedded)) {
metadatafields = payload._embedded.metadatafields;
metadatafields.forEach((field) => {
field.schema = field._embedded.schema;
});
}
payload.metadatafields = metadatafields;
const deserialized = new DSpaceSerializer(RegistryMetadatafieldsResponse).deserialize(payload);
return new RegistryMetadatafieldsSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload));
}
}

View File

@@ -1,50 +0,0 @@
import { RegistryMetadataschemasResponseParsingService } from './registry-metadataschemas-response-parsing.service';
import { PageInfo } from '../shared/page-info.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { RegistryMetadataschemasSuccessResponse } from '../cache/response.models';
describe('RegistryMetadataschemasResponseParsingService', () => {
let service: RegistryMetadataschemasResponseParsingService;
const mockDSOParser = Object.assign({
processPageInfo: () => new PageInfo()
}) as DSOResponseParsingService;
const data = Object.assign({
payload: {
_embedded: {
metadataschemas: [
{
id: 1,
prefix: 'test',
namespace: 'test namespace'
},
{
id: 2,
prefix: 'second',
namespace: 'second test namespace'
}
]
}
}
}) as DSpaceRESTV2Response;
const emptyData = Object.assign({
payload: {}
}) as DSpaceRESTV2Response;
beforeEach(() => {
service = new RegistryMetadataschemasResponseParsingService(mockDSOParser);
});
it('should parse the data correctly', () => {
const response = service.parse(null, data);
expect(response.constructor).toBe(RegistryMetadataschemasSuccessResponse);
});
it('should not produce an error and parse the data correctly when the data is empty', () => {
const response = service.parse(null, emptyData);
expect(response.constructor).toBe(RegistryMetadataschemasSuccessResponse);
});
});

View File

@@ -1,29 +0,0 @@
import { Injectable } from '@angular/core';
import { hasValue } from '../../shared/empty.util';
import { RegistryMetadataschemasSuccessResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
@Injectable()
export class RegistryMetadataschemasResponseParsingService implements ResponseParsingService {
constructor(private dsoParser: DSOResponseParsingService) {
}
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const payload = data.payload;
let metadataschemas = [];
if (hasValue(payload._embedded)) {
metadataschemas = payload._embedded.metadataschemas;
}
payload.metadataschemas = metadataschemas;
const deserialized = new DSpaceSerializer(RegistryMetadataschemasResponse).deserialize(payload);
return new RegistryMetadataschemasSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload));
}
}

View File

@@ -1,24 +0,0 @@
import { autoserialize, deserialize } from 'cerialize';
import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type';
import { HALLink } from '../shared/hal-link.model';
import { PageInfo } from '../shared/page-info.model';
import { BitstreamFormat } from '../shared/bitstream-format.model';
import { link } from '../cache/builders/build-decorators';
export class RegistryBitstreamformatsResponse {
@autoserialize
page: PageInfo;
/**
* The {@link HALLink}s for this RegistryBitstreamformatsResponse
*/
@deserialize
_links: {
self: HALLink;
bitstreamformats: HALLink;
};
@link(BITSTREAM_FORMAT)
bitstreamformats?: BitstreamFormat[];
}

View File

@@ -1,46 +0,0 @@
import { autoserialize, deserialize } from 'cerialize';
import { typedObject } from '../cache/builders/build-decorators';
import { MetadataField } from '../metadata/metadata-field.model';
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
import { HALLink } from '../shared/hal-link.model';
import { PageInfo } from '../shared/page-info.model';
import { ResourceType } from '../shared/resource-type';
import { excludeFromEquals } from '../utilities/equals.decorators';
/**
* Class that represents a response with a registry's metadata fields
*/
@typedObject
export class RegistryMetadatafieldsResponse {
static type = METADATA_FIELD;
/**
* The object type
*/
@excludeFromEquals
@autoserialize
type: ResourceType;
/**
* List of metadata fields in the response
*/
@deserialize
metadatafields: MetadataField[];
/**
* Page info of this response
*/
@autoserialize
page: PageInfo;
/**
* The REST link to this response
*/
@autoserialize
self: string;
@deserialize
_links: {
self: HALLink,
}
}

View File

@@ -1,14 +0,0 @@
import { PageInfo } from '../shared/page-info.model';
import { autoserialize, deserialize } from 'cerialize';
import { MetadataSchema } from '../metadata/metadata-schema.model';
export class RegistryMetadataschemasResponse {
@deserialize
metadataschemas: MetadataSchema[];
@autoserialize
page: PageInfo;
@autoserialize
self: string;
}

View File

@@ -7,32 +7,20 @@ import { PageInfo } from '../shared/page-info.model';
import {
CreateMetadataFieldRequest,
CreateMetadataSchemaRequest,
DeleteRequest,
GetRequest,
RestRequest,
DeleteRequest, FindListOptions,
UpdateMetadataFieldRequest,
UpdateMetadataSchemaRequest
} from '../data/request.models';
import { GenericConstructor } from '../shared/generic-constructor';
import { ResponseParsingService } from '../data/parsing.service';
import { RegistryMetadataschemasResponseParsingService } from '../data/registry-metadataschemas-response-parsing.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestService } from '../data/request.service';
import { RegistryMetadataschemasResponse } from './registry-metadataschemas-response.model';
import {
MetadatafieldSuccessResponse,
MetadataschemaSuccessResponse,
RegistryMetadatafieldsSuccessResponse,
RegistryMetadataschemasSuccessResponse,
RestResponse
} from '../cache/response.models';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RegistryMetadatafieldsResponseParsingService } from '../data/registry-metadatafields-response-parsing.service';
import { RegistryMetadatafieldsResponse } from './registry-metadatafields-response.model';
import { hasNoValue, hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
import { URLCombiner } from '../url-combiner/url-combiner';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { configureRequest, getResponseFromEntry } from '../shared/operators';
import { configureRequest, getFirstSucceededRemoteDataPayload, getResponseFromEntry } from '../shared/operators';
import { createSelector, select, Store } from '@ngrx/store';
import { AppState } from '../../app.reducer';
import { MetadataRegistryState } from '../../+admin/admin-registries/metadata-registry/metadata-registry.reducers';
@@ -57,6 +45,9 @@ import { TranslateService } from '@ngx-translate/core';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { MetadataField } from '../metadata/metadata-field.model';
import { getClassForType } from '../cache/builders/build-decorators';
import { MetadataSchemaDataService } from '../data/metadata-schema-data.service';
import { MetadataFieldDataService } from '../data/metadata-field-data.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema);
@@ -80,211 +71,60 @@ export class RegistryService {
private halService: HALEndpointService,
private store: Store<AppState>,
private notificationsService: NotificationsService,
private translateService: TranslateService) {
private translateService: TranslateService,
private metadataSchemaService: MetadataSchemaDataService,
private metadataFieldService: MetadataFieldDataService) {
}
/**
* Retrieves all metadata schemas
* @param pagination The pagination info used to retrieve the schemas
* @param options The options used to retrieve the schemas
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getMetadataSchemas(pagination: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataSchema>>> {
const requestObs = this.getMetadataSchemasRequestObs(pagination);
const requestEntryObs = requestObs.pipe(
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
);
const rmrObs: Observable<RegistryMetadataschemasResponse> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadataschemasSuccessResponse) => response.metadataschemasResponse)
);
const metadataschemasObs: Observable<MetadataSchema[]> = rmrObs.pipe(
map((rmr: RegistryMetadataschemasResponse) => rmr.metadataschemas)
);
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadataschemasSuccessResponse) => response.pageInfo)
);
const payloadObs = observableCombineLatest(metadataschemasObs, pageInfoObs).pipe(
map(([metadataschemas, pageInfo]) => {
return new PaginatedList(pageInfo, metadataschemas);
})
);
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
public getMetadataSchemas(options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<PaginatedList<MetadataSchema>>> {
return this.metadataSchemaService.findAll(options, ...linksToFollow);
}
/**
* Retrieves a metadata schema by its name
* @param schemaName The name of the schema to find
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getMetadataSchemaByName(schemaName: string): Observable<RemoteData<MetadataSchema>> {
// Temporary pagination to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema
const pagination: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'all-metadatafields-pagination',
pageSize: 10000
public getMetadataSchemaByName(schemaName: string, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<MetadataSchema>> {
// Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema
const options: FindListOptions = Object.assign(new FindListOptions(), {
elementsPerPage: 10000
});
const requestObs = this.getMetadataSchemasRequestObs(pagination);
const requestEntryObs = requestObs.pipe(
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
return this.getMetadataSchemas(options).pipe(
getFirstSucceededRemoteDataPayload(),
map((schemas: PaginatedList<MetadataSchema>) => schemas.page.filter((schema) => schema.prefix === schemaName)[0]),
flatMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, ...linksToFollow))
);
const rmrObs: Observable<RegistryMetadataschemasResponse> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadataschemasSuccessResponse) => response.metadataschemasResponse)
);
const metadataschemaObs: Observable<MetadataSchema> = rmrObs.pipe(
map((rmr: RegistryMetadataschemasResponse) => rmr.metadataschemas),
map((metadataSchemas: MetadataSchema[]) => metadataSchemas.filter((value) => value.prefix === schemaName)[0])
);
return this.rdb.toRemoteDataObservable(requestEntryObs, metadataschemaObs);
}
/**
* retrieves all metadata fields that belong to a certain metadata schema
* @param schema The schema to filter by
* @param pagination The pagination info used to retrieve the fields
* @param options The options info used to retrieve the fields
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getMetadataFieldsBySchema(schema: MetadataSchema, pagination: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataField>>> {
const requestObs = this.getMetadataFieldsBySchemaRequestObs(pagination, schema);
const requestEntryObs = requestObs.pipe(
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
);
const rmrObs: Observable<RegistryMetadatafieldsResponse> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadatafieldsSuccessResponse) => response.metadatafieldsResponse)
);
const metadatafieldsObs: Observable<MetadataField[]> = rmrObs.pipe(
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields)
);
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadatafieldsSuccessResponse) => response.pageInfo)
);
const payloadObs = observableCombineLatest(metadatafieldsObs, pageInfoObs).pipe(
map(([metadatafields, pageInfo]) => {
return new PaginatedList(pageInfo, metadatafields);
})
);
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
public getMetadataFieldsBySchema(schema: MetadataSchema, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
return this.metadataFieldService.findBySchema(schema, options, ...linksToFollow);
}
/**
* Retrieve all existing metadata fields as a paginated list
* @param pagination Pagination options to determine which page of metadata fields should be requested
* When no pagination is provided, all metadata fields are requested in one large page
* @param options Options to determine which page of metadata fields should be requested
* When no options are provided, all metadata fields are requested in one large page
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
* @returns an observable that emits a remote data object with a page of metadata fields
*/
public getAllMetadataFields(pagination?: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataField>>> {
if (hasNoValue(pagination)) {
pagination = {currentPage: 1, pageSize: 10000} as any;
public getAllMetadataFields(options?: FindListOptions, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
if (hasNoValue(options)) {
options = {currentPage: 1, elementsPerPage: 10000} as any;
}
const requestObs = this.getMetadataFieldsRequestObs(pagination);
const requestEntryObs = requestObs.pipe(
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
);
const rmrObs: Observable<RegistryMetadatafieldsResponse> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadatafieldsSuccessResponse) => response.metadatafieldsResponse)
);
const metadatafieldsObs: Observable<MetadataField[]> = rmrObs.pipe(
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields),
/* Make sure to explicitly cast this into a MetadataField object, on first page loads this object comes from the object cache created by the server and its prototype is unknown */
map((metadataFields: MetadataField[]) => metadataFields.map((metadataField: MetadataField) => Object.assign(new MetadataField(), metadataField)))
);
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
getResponseFromEntry(),
map((response: RegistryMetadatafieldsSuccessResponse) => response.pageInfo)
);
const payloadObs = observableCombineLatest(metadatafieldsObs, pageInfoObs).pipe(
map(([metadatafields, pageInfo]) => {
return new PaginatedList(pageInfo, metadatafields);
})
);
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
}
public getMetadataSchemasRequestObs(pagination: PaginationComponentOptions): Observable<RestRequest> {
return this.halService.getEndpoint(this.metadataSchemasPath).pipe(
map((url: string) => {
const args: string[] = [];
args.push(`size=${pagination.pageSize}`);
args.push(`page=${pagination.currentPage - 1}`);
if (isNotEmpty(args)) {
url = new URLCombiner(url, `?${args.join('&')}`).toString();
}
const request = new GetRequest(this.requestService.generateRequestId(), url);
return Object.assign(request, {
getResponseParser(): GenericConstructor<ResponseParsingService> {
return RegistryMetadataschemasResponseParsingService;
}
});
}),
tap((request: RestRequest) => this.requestService.configure(request)),
);
}
private getMetadataFieldsBySchemaRequestObs(pagination: PaginationComponentOptions, schema: MetadataSchema): Observable<RestRequest> {
return this.halService.getEndpoint(this.metadataFieldsPath + '/search/bySchema').pipe(
// return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
map((url: string) => {
const args: string[] = [];
args.push(`schema=${schema.prefix}`);
args.push(`size=${pagination.pageSize}`);
args.push(`page=${pagination.currentPage - 1}`);
if (isNotEmpty(args)) {
url = new URLCombiner(url, `?${args.join('&')}`).toString();
}
const request = new GetRequest(this.requestService.generateRequestId(), url);
return Object.assign(request, {
getResponseParser(): GenericConstructor<ResponseParsingService> {
return RegistryMetadatafieldsResponseParsingService;
}
});
}),
tap((request: RestRequest) => this.requestService.configure(request)),
);
}
private getMetadataFieldsRequestObs(pagination: PaginationComponentOptions): Observable<RestRequest> {
return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
map((url: string) => {
const args: string[] = [];
args.push(`size=${pagination.pageSize}`);
args.push(`page=${pagination.currentPage - 1}`);
if (isNotEmpty(args)) {
url = new URLCombiner(url, `?${args.join('&')}`).toString();
}
const request = new GetRequest(this.requestService.generateRequestId(), url);
return Object.assign(request, {
getResponseParser(): GenericConstructor<ResponseParsingService> {
return RegistryMetadatafieldsResponseParsingService;
}
});
}),
tap((request: RestRequest) => this.requestService.configure(request)),
);
return this.metadataFieldService.findAll(options, ...linksToFollow);
}
public editMetadataSchema(schema: MetadataSchema) {

View File

@@ -0,0 +1,14 @@
import { PaginationComponentOptions } from './pagination-component-options.model';
import { FindListOptions } from '../../core/data/request.models';
/**
* Transform a PaginationComponentOptions object into a FindListOptions object
* @param pagination The PaginationComponentOptions to transform
* @param original An original FindListOptions object to start from
*/
export function toFindListOptions(pagination: PaginationComponentOptions, original?: FindListOptions): FindListOptions {
return Object.assign(new FindListOptions(), original, {
currentPage: pagination.currentPage,
elementsPerPage: pagination.pageSize
});
}