removed remaining normalized models and related services

This commit is contained in:
Art Lowel
2020-02-14 18:06:17 +01:00
parent 884e94a08b
commit bc7c92f44c
104 changed files with 397 additions and 1343 deletions

View File

@@ -5,7 +5,6 @@ import { By } from '@angular/platform-browser';
import { Store } from '@ngrx/store';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
@@ -63,7 +62,6 @@ describe('PublicationComponent', () => {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: NotificationsService, useValue: {} },

View File

@@ -5,7 +5,6 @@ import { By } from '@angular/platform-browser';
import { Store } from '@ngrx/store';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
@@ -67,7 +66,6 @@ export function getItemPageFieldsTest(mockItem: Item, component) {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: HttpClient, useValue: {} },

View File

@@ -10,7 +10,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
import { ResponseParsingService } from '../data/parsing.service';
import { RestRequest } from '../data/request.models';
import { AuthStatus } from './models/auth-status.model';
import { NormalizedObject } from '../cache/models/normalized-object.model';
@Injectable()
export class AuthResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
@@ -24,7 +23,7 @@ export class AuthResponseParsingService extends BaseResponseParsingService imple
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === 200)) {
const response = this.process<NormalizedObject<AuthStatus>>(data.payload, request);
const response = this.process<AuthStatus>(data.payload, request);
return new AuthStatusResponse(response, data.statusCode, data.statusText);
} else {
return new AuthStatusResponse(data.payload as AuthStatus, data.statusCode, data.statusText);

View File

@@ -8,101 +8,34 @@ import { HALResource } from '../../shared/hal-resource.model';
import { CacheableObject, TypedObject } from '../object-cache.reducer';
import { ResourceType } from '../../shared/resource-type';
const mapsToMetadataKey = Symbol('mapsTo');
const relationshipKey = Symbol('relationship');
const resolvedLinkKey = Symbol('resolvedLink');
const relationshipMap = new Map();
const resolvedLinkMap = new Map();
const typeMap = new Map();
const dataServiceMap = new Map();
const linkMap = new Map();
/**
* Decorator function to map a normalized class to it's not-normalized counter part class
* It will also maps a type to the matching class
* @param value The not-normalized class to map to
* Decorator function to map a ResourceType to its class
* @param value The ResourceType to map
*/
export function mapsTo(value: GenericConstructor<TypedObject>) {
return function decorator(objectConstructor: GenericConstructor<TypedObject>) {
Reflect.defineMetadata(mapsToMetadataKey, value, objectConstructor);
mapsToType((value as any).type, objectConstructor);
}
}
/**
* Decorator function to map a normalized class to it's not-normalized counter part class
* It will also maps a type to the matching class
* @param value The not-normalized class to map to
*/
// export function resourceType(target: any, key: string) {
// typeMap.set(target.key.value, target.constructor);
// }
export function resourceType(value: ResourceType) {
return function decorator(objectConstructor: GenericConstructor<TypedObject>) {
typeMap.set(value.value, objectConstructor);
}
}
/**
* Maps a type to the matching class
* @param value The resourse type
* @param objectConstructor The class to map to
*/
function mapsToType(value: ResourceType, objectConstructor: GenericConstructor<TypedObject>) {
if (!objectConstructor || !value) {
return;
}
typeMap.set(value.value, objectConstructor);
}
/**
* Returns the mapped class for the given normalized class
* @param target The normalized class
*/
export function getMapsTo(target: any) {
return Reflect.getOwnMetadata(mapsToMetadataKey, target);
}
/**
* Returns the mapped class for the given type
* @param type The resource type
*/
export function getMapsToType(type: string | ResourceType) {
export function getClassForType(type: string | ResourceType) {
if (typeof(type) === 'object') {
type = (type as ResourceType).value;
}
return typeMap.get(type);
}
export function relationship<T extends CacheableObject>(value: GenericConstructor<T>, isList: boolean = false, shouldAutoResolve: boolean = true): any {
return function r(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
if (!target || !propertyKey) {
return;
}
const metaDataList: string[] = relationshipMap.get(target.constructor) || [];
if (metaDataList.indexOf(propertyKey) === -1) {
metaDataList.push(propertyKey);
}
relationshipMap.set(target.constructor, metaDataList);
return Reflect.metadata(relationshipKey, {
resourceType: (value as any).type.value,
isList,
shouldAutoResolve
}).apply(this, arguments);
};
}
export function getRelationMetadata(target: any, propertyKey: string) {
return Reflect.getMetadata(relationshipKey, target, propertyKey);
}
export function getRelationships(target: any) {
return relationshipMap.get(target);
}
export function dataService(resourceType: ResourceType): any {
return (target: any) => {
if (hasNoValue(resourceType)) {

View File

@@ -55,13 +55,15 @@ export class LinkService {
/**
* Remove any resolved links that the model may have.
*/
public removeResolvedLinks<T extends HALResource>(model: T) {
public removeResolvedLinks<T extends HALResource>(model: T): T {
const result = Object.assign(new (model.constructor as GenericConstructor<T>)(), model);
const linkDefs = getLinkDefinitions(model.constructor as GenericConstructor<T>);
if (isNotEmpty(linkDefs)) {
linkDefs.forEach((linkDef: LinkDefinition<T>) => {
model[linkDef.propertyName] = undefined;
result[linkDef.propertyName] = undefined;
});
}
return result;
}
}

View File

@@ -1,48 +0,0 @@
import { Injectable } from '@angular/core';
import { NormalizedObject } from '../models/normalized-object.model';
import { getMapsToType, getRelationships } from './build-decorators';
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
import { CacheableObject, TypedObject } from '../object-cache.reducer';
/**
* Return true if halObj has a value for `_links.self`
*
* @param {any} halObj The object to test
*/
export function isRestDataObject(halObj: any): boolean {
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
}
/**
* Return true if halObj has a value for `page` and `_embedded`
*
* @param {any} halObj The object to test
*/
export function isRestPaginatedList(halObj: any): boolean {
return hasValue(halObj.page) && hasValue(halObj._embedded);
}
/**
* A service to turn domain models in to their normalized
* counterparts.
*/
@Injectable()
export class NormalizedObjectBuildService {
/**
* Returns the normalized model that corresponds to the given domain model
*
* @param {TDomain} domainModel a domain model
*/
normalize<T extends CacheableObject>(domainModel: T): NormalizedObject<T> {
const normalizedConstructor = getMapsToType((domainModel as any).type);
const relationships = getRelationships(normalizedConstructor) || [];
const normalizedModel = Object.assign({}, domainModel) as any;
relationships.forEach((key: string) => {
if (hasValue(normalizedModel[key])) {
normalizedModel[key] = normalizedModel._links[key];
}
});
return normalizedModel;
}
}

View File

@@ -24,11 +24,9 @@ import {
getResourceLinksFromResponse
} from '../../shared/operators';
import { PageInfo } from '../../shared/page-info.model';
import { NormalizedObject } from '../models/normalized-object.model';
import { CacheableObject } from '../object-cache.reducer';
import { ObjectCacheService } from '../object-cache.service';
import { DSOSuccessResponse, ErrorResponse } from '../response.models';
import { getMapsTo, getRelationMetadata, getRelationships } from './build-decorators';
import { LinkService } from './link.service';
@Injectable()
@@ -84,8 +82,8 @@ export class RemoteDataBuildService {
}
}),
hasValueOperator(),
map((normalized: NormalizedObject<T>) => {
return this.build<T>(normalized, ...linksToFollow);
map((obj: T) => {
return this.build<T>(obj, ...linksToFollow);
}),
startWith(undefined),
distinctUntilChanged()
@@ -138,9 +136,9 @@ export class RemoteDataBuildService {
getResourceLinksFromResponse(),
switchMap((resourceUUIDs: string[]) => {
return this.objectCache.getList(resourceUUIDs).pipe(
map((normList: Array<NormalizedObject<T>>) => {
return normList.map((normalized: NormalizedObject<T>) => {
return this.build<T>(normalized, ...linksToFollow);
map((objs: Array<T>) => {
return objs.map((obj: T) => {
return this.build<T>(obj, ...linksToFollow);
});
}));
}),
@@ -170,76 +168,9 @@ export class RemoteDataBuildService {
return this.toRemoteDataObservable(requestEntry$, payload$);
}
build<T extends CacheableObject>(normalized: NormalizedObject<T>, ...linksToFollow: Array<FollowLinkConfig<T>>): T {
const halLinks: any = {};
const relationships = getRelationships(normalized.constructor) || [];
relationships.forEach((relationship: string) => {
let result;
if (hasValue(normalized[relationship])) {
const { resourceType, isList, shouldAutoResolve } = getRelationMetadata(normalized, relationship);
const objectList = normalized[relationship].page || normalized[relationship];
if (shouldAutoResolve) {
if (typeof objectList !== 'string') {
objectList.forEach((href: string) => {
const request = new GetRequest(this.requestService.generateRequestId(), href);
if (!this.requestService.isCachedOrPending(request)) {
this.requestService.configure(request)
}
});
const rdArr = [];
objectList.forEach((href: string) => {
rdArr.push(this.buildSingle(href));
});
if (isList) {
result = this.aggregate(rdArr);
} else if (rdArr.length === 1) {
result = rdArr[0];
}
} else {
const request = new GetRequest(this.requestService.generateRequestId(), objectList);
if (!this.requestService.isCachedOrPending(request)) {
this.requestService.configure(request)
}
// The rest API can return a single URL to represent a list of resources (e.g. /items/:id/bitstreams)
// in that case only 1 href will be stored in the normalized obj (so the isArray above fails),
// but it should still be built as a list
if (isList) {
result = this.buildList(objectList);
} else {
result = this.buildSingle(objectList);
}
}
if (hasValue(normalized[relationship].page)) {
halLinks[relationship] = this.toPaginatedList(result, normalized[relationship].pageInfo);
} else {
halLinks[relationship] = result;
}
} else {
if (hasNoValue(halLinks._links)) {
halLinks._links = {};
}
halLinks._links[relationship] = {
href: objectList
};
}
}
});
let domainModel;
const domainModelConstructor = getMapsTo(normalized.constructor);
if(hasValue(domainModelConstructor) && domainModelConstructor !== normalized.constructor) {
domainModel = Object.assign(new domainModelConstructor(), normalized, halLinks);
} else {
domainModel = normalized;
}
this.linkService.resolveLinks(domainModel, ...linksToFollow);
return domainModel;
build<T extends CacheableObject>(model: T, ...linksToFollow: Array<FollowLinkConfig<T>>): T {
this.linkService.resolveLinks(model, ...linksToFollow);
return model;
}
aggregate<T>(input: Array<Observable<RemoteData<T>>>): Observable<RemoteData<T[]>> {

View File

@@ -1,73 +0,0 @@
import { autoserializeAs, deserializeAs, autoserialize } from 'cerialize';
import { DSpaceObject } from '../../shared/dspace-object.model';
import { HALLink } from '../../shared/hal-link.model';
import { MetadataMap, MetadataMapSerializer } from '../../shared/metadata.models';
import { ResourceType } from '../../shared/resource-type';
import { NormalizedObject } from './normalized-object.model';
import { TypedObject } from '../object-cache.reducer';
/**
* An model class for a DSpaceObject.
*/
export class NormalizedDSpaceObject<T extends DSpaceObject> extends NormalizedObject<T> implements TypedObject {
/**
* The link to the rest endpoint where this object can be found
*
* Repeated here to make the serialization work,
* inheritSerialization doesn't seem to work for more than one level
*/
@deserializeAs(String)
self: string;
/**
* The human-readable identifier of this DSpaceObject
*
* Currently mapped to uuid but left in to leave room
* for a shorter, more user friendly type of id
*/
@autoserializeAs(String, 'uuid')
id: string;
/**
* The universally unique identifier of this DSpaceObject
*/
@autoserializeAs(String)
uuid: string;
/**
* The type of the object
*/
@autoserialize
type: ResourceType;
/**
* All metadata of this DSpaceObject
*/
@autoserializeAs(MetadataMapSerializer)
metadata: MetadataMap;
/**
* An array of DSpaceObjects that are direct parents of this DSpaceObject
*/
@deserializeAs(String)
parents: string[];
/**
* The DSpaceObject that owns this DSpaceObject
*/
@deserializeAs(String)
owner: string;
/**
* The links to all related resources returned by the rest api.
*
* Repeated here to make the serialization work,
* inheritSerialization doesn't seem to work for more than one level
*/
@deserializeAs(Object)
_links: {
self: HALLink,
[name: string]: HALLink
}
}

View File

@@ -1,26 +0,0 @@
import { HALLink } from '../../shared/hal-link.model';
import { CacheableObject, TypedObject } from '../object-cache.reducer';
import { autoserialize, deserialize } from 'cerialize';
import { ResourceType } from '../../shared/resource-type';
/**
* An abstract model class for a NormalizedObject.
*/
export abstract class NormalizedObject<T extends TypedObject> implements CacheableObject {
/**
* The link to the rest endpoint where this object can be found
*/
@deserialize
self: string;
@deserialize
_links: {
self: HALLink,
[name: string]: HALLink
};
/**
* A string representing the kind of object
*/
@deserialize
type: ResourceType;
}

View File

@@ -11,7 +11,6 @@ import { RestRequestMethod } from '../data/rest-request-method';
import { selfLinkFromUuidSelector } from '../index/index.selectors';
import { GenericConstructor } from '../shared/generic-constructor';
import { LinkService } from './builders/link.service';
import { NormalizedObject } from './models/normalized-object.model';
import {
AddPatchObjectCacheAction,
AddToObjectCacheAction,
@@ -21,7 +20,7 @@ import {
import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer';
import { AddToSSBAction } from './server-sync-buffer.actions';
import { getMapsToType } from './builders/build-decorators';
import { getClassForType } from './builders/build-decorators';
/**
* The base selector function to select the object cache in the store
@@ -55,16 +54,16 @@ export class ObjectCacheService {
/**
* Add an object to the cache
*
* @param objectToCache
* @param object
* The object to add
* @param msToLive
* The number of milliseconds it should be cached for
* @param requestUUID
* The UUID of the request that resulted in this object
*/
add(objectToCache: CacheableObject, msToLive: number, requestUUID: string): void {
this.linkService.removeResolvedLinks(objectToCache); // Ensure the object we're storing has no resolved links
this.store.dispatch(new AddToObjectCacheAction(objectToCache, new Date().getTime(), msToLive, requestUUID));
add(object: CacheableObject, msToLive: number, requestUUID: string): void {
object = this.linkService.removeResolvedLinks(object); // Ensure the object we're storing has no resolved links
this.store.dispatch(new AddToObjectCacheAction(object, new Date().getTime(), msToLive, requestUUID));
}
/**
@@ -82,14 +81,14 @@ export class ObjectCacheService {
*
* @param uuid
* The UUID of the object to get
* @return Observable<NormalizedObject<T>>
* An observable of the requested object in normalized form
* @return Observable<T>
* An observable of the requested object
*/
getObjectByUUID<T extends CacheableObject>(uuid: string):
Observable<NormalizedObject<T>> {
Observable<T> {
return this.store.pipe(
select(selfLinkFromUuidSelector(uuid)),
mergeMap((selfLink: string) => this.getObjectBySelfLink(selfLink)
mergeMap((selfLink: string) => this.getObjectBySelfLink<T>(selfLink)
)
)
}
@@ -99,10 +98,10 @@ export class ObjectCacheService {
*
* @param selfLink
* The selfLink of the object to get
* @return Observable<NormalizedObject<T>>
* An observable of the requested object in normalized form
* @return Observable<T>
* An observable of the requested object
*/
getObjectBySelfLink<T extends CacheableObject>(selfLink: string): Observable<NormalizedObject<T>> {
getObjectBySelfLink<T extends CacheableObject>(selfLink: string): Observable<T> {
return this.getBySelfLink(selfLink).pipe(
map((entry: ObjectCacheEntry) => {
if (isNotEmpty(entry.patches)) {
@@ -115,11 +114,11 @@ export class ObjectCacheService {
}
),
map((entry: ObjectCacheEntry) => {
const type: GenericConstructor<NormalizedObject<T>> = getMapsToType((entry.data as any).type);
const type: GenericConstructor<T> = getClassForType((entry.data as any).type);
if (typeof type !== 'function') {
throw new Error(`${type} is not a valid constructor for ${JSON.stringify(entry.data)}`);
}
return Object.assign(new type(), entry.data) as NormalizedObject<T>
return Object.assign(new type(), entry.data) as T
})
);
}
@@ -188,7 +187,7 @@ export class ObjectCacheService {
* The type of the objects to get
* @return Observable<Array<T>>
*/
getList<T extends CacheableObject>(selfLinks: string[]): Observable<Array<NormalizedObject<T>>> {
getList<T extends CacheableObject>(selfLinks: string[]): Observable<Array<T>> {
return observableCombineLatest(
selfLinks.map((selfLink: string) => this.getObjectBySelfLink<T>(selfLink))
);

View File

@@ -7,8 +7,8 @@ import { PaginatedList } from '../data/paginated-list';
import { ConfigRequest } from '../data/request.models';
import { PageInfo } from '../shared/page-info.model';
import { ConfigResponseParsingService } from './config-response-parsing.service';
import { NormalizedSubmissionDefinitionModel } from './models/normalized-config-submission-definition.model';
import { NormalizedSubmissionSectionModel } from './models/normalized-config-submission-section.model';
import { SubmissionDefinitionModel } from './models/config-submission-definition.model';
import { SubmissionSectionModel } from './models/config-submission-section.model';
describe('ConfigResponseParsingService', () => {
let service: ConfigResponseParsingService;
@@ -172,7 +172,7 @@ describe('ConfigResponseParsingService', () => {
self: 'https://rest.api/config/submissiondefinitions/traditional/sections'
});
const definitions =
Object.assign(new NormalizedSubmissionDefinitionModel(), {
Object.assign(new SubmissionDefinitionModel(), {
isDefault: true,
name: 'traditional',
type: 'submissiondefinition',
@@ -182,7 +182,7 @@ describe('ConfigResponseParsingService', () => {
},
self: 'https://rest.api/config/submissiondefinitions/traditional',
sections: new PaginatedList(pageinfo, [
Object.assign(new NormalizedSubmissionSectionModel(), {
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.describe.stepone',
mandatory: true,
sectionType: 'submission-form',
@@ -197,7 +197,7 @@ describe('ConfigResponseParsingService', () => {
},
self: 'https://rest.api/config/submissionsections/traditionalpageone',
}),
Object.assign(new NormalizedSubmissionSectionModel(), {
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.describe.steptwo',
mandatory: true,
sectionType: 'submission-form',
@@ -212,7 +212,7 @@ describe('ConfigResponseParsingService', () => {
},
self: 'https://rest.api/config/submissionsections/traditionalpagetwo',
}),
Object.assign(new NormalizedSubmissionSectionModel(), {
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.upload',
mandatory: false,
sectionType: 'upload',
@@ -227,7 +227,7 @@ describe('ConfigResponseParsingService', () => {
},
self: 'https://rest.api/config/submissionsections/upload',
}),
Object.assign(new NormalizedSubmissionSectionModel(), {
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.license',
mandatory: true,
sectionType: 'license',

View File

@@ -1,8 +1,10 @@
import { inheritSerialization } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { SubmissionDefinitionModel } from './config-submission-definition.model';
import { ResourceType } from '../../shared/resource-type';
@resourceType(SubmissionDefinitionsModel.type)
@inheritSerialization(SubmissionDefinitionModel)
export class SubmissionDefinitionsModel extends SubmissionDefinitionModel {
static type = new ResourceType('submissiondefinitions');

View File

@@ -1,3 +1,4 @@
import { inheritSerialization } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { SubmissionFormModel } from './config-submission-form.model';
import { ResourceType } from '../../shared/resource-type';
@@ -6,6 +7,7 @@ import { ResourceType } from '../../shared/resource-type';
* A model class for a NormalizedObject.
*/
@resourceType(SubmissionFormsModel.type)
@inheritSerialization(SubmissionFormModel)
export class SubmissionFormsModel extends SubmissionFormModel {
static type = new ResourceType('submissionforms');
}

View File

@@ -1,8 +1,10 @@
import { inheritSerialization } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { SubmissionSectionModel } from './config-submission-section.model';
import { ResourceType } from '../../shared/resource-type';
@resourceType(SubmissionSectionsModel.type)
@inheritSerialization(SubmissionSectionModel)
export class SubmissionSectionsModel extends SubmissionSectionModel {
static type = new ResourceType('submissionsections');
}

View File

@@ -1,3 +1,4 @@
import { autoserialize } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { ConfigObject } from './config.model';
import { AccessConditionOption } from './config-access-condition-option.model';
@@ -10,15 +11,19 @@ export class SubmissionUploadsModel extends ConfigObject {
/**
* A list of available bitstream access conditions
*/
@autoserialize
accessConditionOptions: AccessConditionOption[];
/**
* An object representing the configuration describing the bistream metadata form
*/
@autoserialize
metadata: SubmissionFormsModel;
@autoserialize
required: boolean;
@autoserialize
maxSize: number;
}

View File

@@ -1,25 +0,0 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { PaginatedList } from '../../data/paginated-list';
import { SubmissionDefinitionModel } from './config-submission-definition.model';
import { SubmissionSectionModel } from './config-submission-section.model';
import { NormalizedConfigObject } from './normalized-config.model';
/**
* Normalized class for the configuration describing the submission
*/
@inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionDefinitionModel extends NormalizedConfigObject<SubmissionDefinitionModel> {
/**
* A boolean representing if this submission definition is the default or not
*/
@autoserialize
isDefault: boolean;
/**
* A list of SubmissionSectionModel that are present in this submission definition
*/
@autoserializeAs(SubmissionSectionModel)
sections: PaginatedList<SubmissionSectionModel>;
}

View File

@@ -1,11 +0,0 @@
import { inheritSerialization } from 'cerialize';
import { NormalizedConfigObject } from './normalized-config.model';
import { SubmissionDefinitionsModel } from './config-submission-definitions.model';
import { NormalizedSubmissionDefinitionModel } from './normalized-config-submission-definition.model';
/**
* Normalized class for the configuration describing the submission
*/
@inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionDefinitionsModel extends NormalizedSubmissionDefinitionModel {
}

View File

@@ -1,16 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { NormalizedConfigObject } from './normalized-config.model';
import { FormRowModel, SubmissionFormModel } from './config-submission-form.model';
/**
* Normalized class for the configuration describing the submission form
*/
@inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionFormModel extends NormalizedConfigObject<SubmissionFormModel> {
/**
* An array of [FormRowModel] that are present in this form
*/
@autoserialize
rows: FormRowModel[];
}

View File

@@ -1,9 +0,0 @@
import { inheritSerialization } from 'cerialize';
import { NormalizedSubmissionFormModel } from './normalized-config-submission-form.model';
/**
* Normalized class for the configuration describing the submission form
*/
@inheritSerialization(NormalizedSubmissionFormModel)
export class NormalizedSubmissionFormsModel extends NormalizedSubmissionFormModel {
}

View File

@@ -1,38 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { SectionsType } from '../../../submission/sections/sections-type';
import { NormalizedConfigObject } from './normalized-config.model';
import {
SubmissionSectionModel,
SubmissionSectionVisibility
} from './config-submission-section.model';
/**
* Normalized class for the configuration describing the submission section
*/
@inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionSectionModel extends NormalizedConfigObject<SubmissionSectionModel> {
/**
* The header for this section
*/
@autoserialize
header: string;
/**
* A boolean representing if this submission section is the mandatory or not
*/
@autoserialize
mandatory: boolean;
/**
* A string representing the kind of section object
*/
@autoserialize
sectionType: SectionsType;
/**
* The [SubmissionSectionVisibility] object for this section
*/
@autoserialize
visibility: SubmissionSectionVisibility
}

View File

@@ -1,10 +0,0 @@
import { inheritSerialization } from 'cerialize';
import { SubmissionSectionsModel } from './config-submission-sections.model';
import { NormalizedSubmissionSectionModel } from './normalized-config-submission-section.model';
/**
* Normalized class for the configuration describing the submission section
*/
@inheritSerialization(NormalizedSubmissionSectionModel)
export class NormalizedSubmissionSectionsModel extends NormalizedSubmissionSectionModel {
}

View File

@@ -1,30 +0,0 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { AccessConditionOption } from './config-access-condition-option.model';
import { SubmissionFormsModel } from './config-submission-forms.model';
import { NormalizedConfigObject } from './normalized-config.model';
import { SubmissionUploadsModel } from './config-submission-uploads.model';
/**
* Normalized class for the configuration describing the submission upload section
*/
@inheritSerialization(NormalizedConfigObject)
export class NormalizedSubmissionUploadsModel extends NormalizedConfigObject<SubmissionUploadsModel> {
/**
* A list of available bitstream access conditions
*/
@autoserialize
accessConditionOptions: AccessConditionOption[];
/**
* An object representing the configuration describing the bistream metadata form
*/
@autoserializeAs(SubmissionFormsModel)
metadata: SubmissionFormsModel;
@autoserialize
required: boolean;
@autoserialize
maxSize: number;
}

View File

@@ -1,42 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { NormalizedObject } from '../../cache/models/normalized-object.model';
import { CacheableObject } from '../../cache/object-cache.reducer';
import { HALLink } from '../../shared/hal-link.model';
import { ResourceType } from '../../shared/resource-type';
import { excludeFromEquals } from '../../utilities/equals.decorators';
/**
* Normalized abstract class for a configuration object
*/
@inheritSerialization(NormalizedObject)
export abstract class NormalizedConfigObject<T extends CacheableObject> implements CacheableObject {
/**
* The name for this configuration
*/
@autoserialize
public name: string;
/**
* The object type
*/
@excludeFromEquals
@autoserialize
type: ResourceType;
/**
* The links to all related resources returned by the rest api.
*/
@autoserialize
public _links: {
self: HALLink,
[name: string]: HALLink
};
/**
* The link to the rest endpoint where this config object can be found
*/
@autoserialize
self: string;
}

View File

@@ -38,7 +38,6 @@ import { AuthInterceptor } from './auth/auth.interceptor';
import { AuthenticatedGuard } from './auth/authenticated.guard';
import { AuthStatus } from './auth/models/auth-status.model';
import { BrowseService } from './browse/browse.service';
import { NormalizedObjectBuildService } from './cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
import { ObjectCacheService } from './cache/object-cache.service';
import { ConfigResponseParsingService } from './config/config-response-parsing.service';
@@ -194,7 +193,6 @@ const PROVIDERS = [
ResourcePolicyService,
RegistryService,
BitstreamFormatDataService,
NormalizedObjectBuildService,
RemoteDataBuildService,
EndpointMapResponseParsingService,
FacetValueResponseParsingService,

View File

@@ -7,11 +7,33 @@ import { ObjectCacheService } from '../cache/object-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface';
import { GenericConstructor } from '../shared/generic-constructor';
import { PaginatedList } from './paginated-list';
import { isRestDataObject, isRestPaginatedList } from '../cache/builders/normalized-object-build.service';
import { getMapsToType } from '../cache/builders/build-decorators';
import { getClassForType } from '../cache/builders/build-decorators';
import { RestRequest } from './request.models';
/* tslint:disable:max-classes-per-file */
/**
* Return true if halObj has a value for `_links.self`
*
* @param {any} halObj The object to test
*/
export function isRestDataObject(halObj: any): boolean {
return isNotEmpty(halObj._links) && hasValue(halObj._links.self);
}
/**
* Return true if halObj has a value for `page` with properties
* `size`, `totalElements`, `totalPages`, `number`
*
* @param {any} halObj The object to test
*/
export function isRestPaginatedList(halObj: any): boolean {
return hasValue(halObj.page) &&
hasValue(halObj.page.size) &&
hasValue(halObj.page.totalElements) &&
hasValue(halObj.page.totalPages) &&
hasValue(halObj.page.number);
}
export abstract class BaseResponseParsingService {
protected abstract EnvConfig: GlobalConfig;
protected abstract objectCache: ObjectCacheService;
@@ -89,7 +111,7 @@ export abstract class BaseResponseParsingService {
protected deserialize<ObjectDomain>(obj): any {
const type: string = obj.type;
if (hasValue(type)) {
const normObjConstructor = getMapsToType(type) as GenericConstructor<ObjectDomain>;
const normObjConstructor = getClassForType(type) as GenericConstructor<ObjectDomain>;
if (hasValue(normObjConstructor)) {
const serializer = new this.serializerConstructor(normObjConstructor);

View File

@@ -7,7 +7,6 @@ import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -37,7 +36,6 @@ export class BitstreamDataService extends DataService<Bitstream> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected cds: CommunityDataService,
protected objectCache: ObjectCacheService,

View File

@@ -8,7 +8,6 @@ import { cold, getTestScheduler, hot } from 'jasmine-marbles';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { BitstreamFormat } from '../shared/bitstream-format.model';
import { async } from '@angular/core/testing';
@@ -48,14 +47,12 @@ describe('BitstreamFormatDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
const rdbService = {} as RemoteDataBuildService;
function initTestService(halService) {
return new BitstreamFormatDataService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -13,7 +13,6 @@ import { BitstreamFormatRegistryState } from '../../+admin/admin-registries/bits
import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RestResponse } from '../cache/response.models';
@@ -50,7 +49,6 @@ export class BitstreamFormatDataService extends DataService<BitstreamFormat> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -3,11 +3,11 @@ import { Inject, Injectable } from '@angular/core';
import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface';
import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { ErrorResponse, GenericSuccessResponse, 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 { DSpaceObject } from '../shared/dspace-object.model';
import { BaseResponseParsingService } from './base-response-parsing.service';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
@@ -34,7 +34,7 @@ export class BrowseItemsResponseParsingService extends BaseResponseParsingServic
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._embedded)
&& Array.isArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]])) {
const serializer = new DSpaceSerializer(NormalizedDSpaceObject);
const serializer = new DSpaceSerializer(DSpaceObject);
const items = serializer.deserializeArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]]);
return new GenericSuccessResponse(items, data.statusCode, data.statusText, this.processPageInfo(data.payload));
} else if (hasValue(data.payload) && hasValue(data.payload.page)) {

View File

@@ -7,7 +7,6 @@ import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -31,12 +30,10 @@ import { RequestService } from './request.service';
@dataService(BUNDLE)
export class BundleDataService extends DataService<Bundle> {
protected linkPath = 'bundles';
protected forceBypassCache = false;
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -11,7 +11,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { SearchParam } from '../cache/models/search-param.model';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -58,7 +57,6 @@ export class CollectionDataService extends ComColDataService<Collection> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected cds: CommunityDataService,
protected objectCache: ObjectCacheService,

View File

@@ -6,9 +6,7 @@ import { TestScheduler } from 'rxjs/testing';
import { GlobalConfig } from '../../../config';
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Community } from '../shared/community.model';
@@ -23,16 +21,11 @@ import { RequestService } from './request.service';
const LINK_NAME = 'test';
/* tslint:disable:max-classes-per-file */
class NormalizedTestObject extends NormalizedObject<Item> {
}
class TestService extends ComColDataService<any> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected EnvConfig: GlobalConfig,
protected cds: CommunityDataService,
@@ -52,8 +45,6 @@ class TestService extends ComColDataService<any> {
}
}
/* tslint:enable:max-classes-per-file */
describe('ComColDataService', () => {
let scheduler: TestScheduler;
let service: TestService;
@@ -68,7 +59,6 @@ describe('ComColDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
const options = Object.assign(new FindListOptions(), {
@@ -115,7 +105,6 @@ describe('ComColDataService', () => {
return new TestService(
requestService,
rdbService,
dataBuildService,
store,
EnvConfig,
cds,

View File

@@ -7,7 +7,6 @@ import { filter, switchMap, take } from 'rxjs/operators';
import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -31,7 +30,6 @@ export class CommunityDataService extends ComColDataService<Community> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -1,43 +1,36 @@
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngrx/store';
import { compare, Operation } from 'fast-json-patch';
import { Observable, of as observableOf } from 'rxjs';
import * as uuidv4 from 'uuid/v4';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { DataService } from './data.service';
import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { CoreState } from '../core.reducers';
import { Store } from '@ngrx/store';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Observable, of as observableOf } from 'rxjs';
import { FindListOptions } from './request.models';
import { SortDirection, SortOptions } from '../cache/models/sort-options.model';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { compare, Operation } from 'fast-json-patch';
import { DSpaceObject } from '../shared/dspace-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Item } from '../shared/item.model';
import { ChangeAnalyzer } from './change-analyzer';
import { DataService } from './data.service';
import { FindListOptions } from './request.models';
import { RequestService } from './request.service';
import { HttpClient } from '@angular/common/http';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { Item } from '../shared/item.model';
import * as uuidv4 from 'uuid/v4';
import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
const endpoint = 'https://rest.api/core';
// tslint:disable:max-classes-per-file
class NormalizedTestObject extends NormalizedObject<Item> {
}
class TestService extends DataService<any> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected linkPath: string,
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: ChangeAnalyzer<NormalizedTestObject>
protected comparator: ChangeAnalyzer<Item>
) {
super();
}
@@ -47,8 +40,8 @@ class TestService extends DataService<any> {
}
}
class DummyChangeAnalyzer implements ChangeAnalyzer<NormalizedTestObject> {
diff(object1: NormalizedTestObject, object2: NormalizedTestObject): Operation[] {
class DummyChangeAnalyzer implements ChangeAnalyzer<Item> {
diff(object1: Item, object2: Item): Operation[] {
return compare((object1 as any).metadata, (object2 as any).metadata);
}
@@ -63,9 +56,6 @@ describe('DataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = new DummyChangeAnalyzer() as any;
const dataBuildService = {
normalize: (object) => object
} as NormalizedObjectBuildService;
const objectCache = {
addPatch: () => {
/* empty */
@@ -80,7 +70,6 @@ describe('DataService', () => {
return new TestService(
requestService,
rdbService,
dataBuildService,
store,
endpoint,
halService,

View File

@@ -18,10 +18,8 @@ import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.uti
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { getMapsToType } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { getClassForType } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { SearchParam } from '../cache/models/search-param.model';
import { CacheableObject } from '../cache/object-cache.reducer';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -55,7 +53,6 @@ import { RestRequestMethod } from './rest-request-method';
export abstract class DataService<T extends CacheableObject> {
protected abstract requestService: RequestService;
protected abstract rdbService: RemoteDataBuildService;
protected abstract dataBuildService: NormalizedObjectBuildService;
protected abstract store: Store<CoreState>;
protected abstract linkPath: string;
protected abstract halService: HALEndpointService;
@@ -333,8 +330,7 @@ export abstract class DataService<T extends CacheableObject> {
map((endpoint: string) => parentUUID ? `${endpoint}?parent=${parentUUID}` : endpoint)
);
const normalizedObject: NormalizedObject<T> = this.dataBuildService.normalize<T>(dso);
const serializedDso = new DSpaceSerializer(getMapsToType((dso as any).type)).serialize(normalizedObject);
const serializedDso = new DSpaceSerializer(getClassForType((dso as any).type)).serialize(dso);
const request$ = endpoint$.pipe(
take(1),

View File

@@ -1,8 +1,7 @@
import { Injectable } from '@angular/core';
import { compare } from 'fast-json-patch';
import { Operation } from 'fast-json-patch/lib/core';
import { getMapsToType } from '../cache/builders/build-decorators';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { getClassForType } from '../cache/builders/build-decorators';
import { CacheableObject } from '../cache/object-cache.reducer';
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
import { ChangeAnalyzer } from './change-analyzer';
@@ -20,14 +19,14 @@ export class DefaultChangeAnalyzer<T extends CacheableObject> implements ChangeA
* Compare the metadata of two CacheableObject and return the differences as
* a JsonPatch Operation Array
*
* @param {NormalizedObject} object1
* @param {CacheableObject} object1
* The first object to compare
* @param {NormalizedObject} object2
* @param {CacheableObject} object2
* The second object to compare
*/
diff(object1: T, object2: T): Operation[] {
const serializer1 = new DSpaceSerializer(getMapsToType(object1.type));
const serializer2 = new DSpaceSerializer(getMapsToType(object2.type));
const serializer1 = new DSpaceSerializer(getClassForType(object1.type));
const serializer2 = new DSpaceSerializer(getClassForType(object2.type));
return compare(serializer1.serialize(object1), serializer2.serialize(object2));
}
}

View File

@@ -1,7 +1,6 @@
import { Operation } from 'fast-json-patch/lib/core';
import { compare } from 'fast-json-patch';
import { ChangeAnalyzer } from './change-analyzer';
import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model';
import { Injectable } from '@angular/core';
import { DSpaceObject } from '../shared/dspace-object.model';

View File

@@ -7,7 +7,6 @@ import { RequestService } from './request.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { DsoRedirectDataService } from './dso-redirect-data.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
@@ -31,7 +30,6 @@ describe('DsoRedirectDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
const objectCache = {} as ObjectCacheService;
let setup;
beforeEach(() => {
@@ -68,7 +66,6 @@ describe('DsoRedirectDataService', () => {
service = new DsoRedirectDataService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -1,35 +1,32 @@
import { DataService } from './data.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { HttpClient } from '@angular/common/http';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestService } from './request.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { FindListOptions, FindByIDRequest, IdentifierType } from './request.models';
import { Observable } from 'rxjs';
import { RemoteData } from './remote-data';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { Injectable } from '@angular/core';
import { filter, take, tap } from 'rxjs/operators';
import { hasValue } from '../../shared/empty.util';
import { getFinishedRemoteData } from '../shared/operators';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { take, tap } from 'rxjs/operators';
import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { getFinishedRemoteData } from '../shared/operators';
import { DataService } from './data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { RemoteData } from './remote-data';
import { FindByIDRequest, IdentifierType } from './request.models';
import { RequestService } from './request.service';
@Injectable()
export class DsoRedirectDataService extends DataService<any> {
// Set the default link path to the identifier lookup endpoint.
protected linkPath = 'pid';
protected forceBypassCache = false;
private uuidEndpoint = 'dso';
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -3,7 +3,6 @@ import { Inject, Injectable } from '@angular/core';
import { ObjectCacheService } from '../cache/object-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface';
import { GLOBAL_CONFIG } from '../../../config';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { RestResponse, DSOSuccessResponse } from '../cache/response.models';
import { RestRequest } from './request.models';
@@ -30,7 +29,7 @@ export class DSOResponseParsingService extends BaseResponseParsingService implem
if (hasValue(data.payload) && hasValue(data.payload.page) && data.payload.page.totalElements === 0) {
processRequestDTO = { page: [] };
} else {
processRequestDTO = this.process<NormalizedObject<DSpaceObject>>(data.payload, request);
processRequestDTO = this.process<DSpaceObject>(data.payload, request);
}
let objectList = processRequestDTO;

View File

@@ -9,8 +9,6 @@ import { DSpaceObjectDataService } from './dspace-object-data.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
describe('DSpaceObjectDataService', () => {
let scheduler: TestScheduler;
let service: DSpaceObjectDataService;
@@ -46,12 +44,10 @@ describe('DSpaceObjectDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
service = new DSpaceObjectDataService(
requestService,
rdbService,
dataBuildService,
objectCache,
halService,
notificationsService,

View File

@@ -4,7 +4,6 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -23,7 +22,6 @@ class DataServiceImpl extends DataService<DSpaceObject> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -47,13 +45,12 @@ export class DSpaceObjectDataService {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DSOChangeAnalyzer<DSpaceObject>) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
}
findById(uuid: string): Observable<RemoteData<DSpaceObject>> {

View File

@@ -5,7 +5,6 @@ import { Observable } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -25,7 +24,6 @@ class DataServiceImpl extends DataService<ItemType> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -44,14 +42,13 @@ export class ItemTypeDataService {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<ItemType>) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
}
/**

View File

@@ -3,7 +3,6 @@ import { DataService } from './data.service';
import { ExternalSource } from '../shared/external-source.model';
import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -31,7 +30,6 @@ export class ExternalSourceService extends DataService<ExternalSource> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -6,7 +6,6 @@ import { TestScheduler } from 'rxjs/testing';
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { BrowseService } from '../browse/browse.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RestResponse } from '../cache/response.models';
import { CoreState } from '../core.reducers';
@@ -66,7 +65,6 @@ describe('ItemDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
const itemEndpoint = 'https://rest.api/core/items';
const ScopedItemEndpoint = `https://rest.api/core/items/${scopeID}`;
@@ -83,7 +81,6 @@ describe('ItemDataService', () => {
return new ItemDataService(
requestService,
rdbService,
dataBuildService,
store,
bs,
objectCache,

View File

@@ -7,7 +7,6 @@ import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.uti
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { BrowseService } from '../browse/browse.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { GenericSuccessResponse, RestResponse } from '../cache/response.models';
@@ -50,7 +49,6 @@ export class ItemDataService extends DataService<Item> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
private bs: BrowseService,
protected objectCache: ObjectCacheService,

View File

@@ -5,7 +5,6 @@ import { Observable } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -25,7 +24,6 @@ class DataServiceImpl extends DataService<License> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -44,14 +42,13 @@ export class LicenseDataService {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<License>) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
}
findByHref(href: string, ...linksToFollow: Array<FollowLinkConfig<License>>): Observable<RemoteData<License>> {

View File

@@ -3,7 +3,6 @@ import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -23,7 +22,6 @@ class DataServiceImpl extends DataService<MetadataSchema> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -50,9 +48,8 @@ export class MetadataSchemaDataService {
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,
protected comparator: DefaultChangeAnalyzer<MetadataSchema>,
protected dataBuildService: NormalizedObjectBuildService,
protected http: HttpClient,
protected notificationsService: NotificationsService) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
}
}

View File

@@ -1,10 +1,10 @@
import { Injectable } from '@angular/core';
import { RestResponse, SearchSuccessResponse } from '../cache/response.models';
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
import { DSOResponseParsingService } from './dso-response-parsing.service';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { NormalizedObjectSerializer } from '../dspace-rest-v2/normalized-object.serializer';
import { hasValue } from '../../shared/empty.util';
import { SearchQueryResponse } from '../../shared/search/search-query-response.model';
import { MetadataMap, MetadataValue } from '../shared/metadata.models';
@@ -57,7 +57,7 @@ export class MyDSpaceResponseParsingService implements ResponseParsingService {
_embedded: this.filterEmbeddedObjects(object)
}));
payload.objects = objects;
const deserialized = new NormalizedObjectSerializer(SearchQueryResponse).deserialize(payload);
const deserialized = new DSpaceSerializer(SearchQueryResponse).deserialize(payload);
return new SearchSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(payload));
}

View File

@@ -9,7 +9,6 @@ import { isNotUndefined } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { followLink } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -37,7 +36,6 @@ export class RelationshipTypeService extends DataService<RelationshipType> {
constructor(protected itemService: ItemDataService,
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,

View File

@@ -20,7 +20,6 @@ import { NameVariantListState } from '../../shared/form/builder/ds-dynamic-form-
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { SearchParam } from '../cache/models/search-param.model';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -67,7 +66,6 @@ export class RelationshipService extends DataService<Relationship> {
constructor(protected itemService: ItemDataService,
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected halService: HALEndpointService,
protected objectCache: ObjectCacheService,

View File

@@ -6,7 +6,7 @@ import { catchError, filter, flatMap, map, take } from 'rxjs/operators';
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { StoreActionTypes } from '../../store.actions';
import { getMapsToType } from '../cache/builders/build-decorators';
import { getClassForType } from '../cache/builders/build-decorators';
import { ErrorResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
@@ -45,7 +45,7 @@ export class RequestEffects {
flatMap((request: RestRequest) => {
let body;
if (isNotEmpty(request.body)) {
const serializer = new DSpaceSerializer(getMapsToType(request.body.type));
const serializer = new DSpaceSerializer(getClassForType(request.body.type));
body = serializer.serialize(request.body);
}
return this.restApi.request(request.method, request.href, body, request.options).pipe(

View File

@@ -2,12 +2,10 @@ import { HttpClient } from '@angular/common/http';
import { cold, getTestScheduler } from 'jasmine-marbles';
import { TestScheduler } from 'rxjs/testing';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { ResourcePolicy } from '../shared/resource-policy.model';
import { GetRequest } from './request.models';
import { RequestService } from './request.service';
import { ResourcePolicyService } from './resource-policy.service';
@@ -42,12 +40,10 @@ describe('ResourcePolicyService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
service = new ResourcePolicyService(
requestService,
rdbService,
dataBuildService,
objectCache,
halService,
notificationsService,

View File

@@ -17,7 +17,6 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RESOURCE_POLICY } from '../shared/resource-policy.resource-type';
import { ChangeAnalyzer } from './change-analyzer';
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
@@ -30,7 +29,6 @@ class DataServiceImpl extends DataService<ResourcePolicy> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -53,13 +51,12 @@ export class ResourcePolicyService {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected http: HttpClient,
protected comparator: DefaultChangeAnalyzer<ResourcePolicy>) {
this.dataService = new DataServiceImpl(requestService, rdbService, dataBuildService, null, objectCache, halService, notificationsService, http, comparator);
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
}
findByHref(href: string, ...linksToFollow: Array<FollowLinkConfig<ResourcePolicy>>): Observable<RemoteData<ResourcePolicy>> {

View File

@@ -8,7 +8,6 @@ import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { of as observableOf } from 'rxjs';
import { RestResponse } from '../cache/response.models';
@@ -63,12 +62,10 @@ describe('SiteDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {} as NormalizedObjectBuildService;
service = new SiteDataService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -5,7 +5,6 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -30,7 +29,6 @@ export class SiteDataService extends DataService<Site> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -0,0 +1,154 @@
import { autoserialize, autoserializeAs, deserialize } from 'cerialize';
import { HALLink } from '../shared/hal-link.model';
import { HALResource } from '../shared/hal-resource.model';
import { DSpaceSerializer } from './dspace.serializer';
class TestModel implements HALResource {
@autoserialize
id: string;
@autoserialize
name: string;
@deserialize
_links: {
self: HALLink;
parents: HALLink;
}
}
const testModels = [
{
id: 'd4466d54-d73b-4d8f-b73f-c702020baa14',
name: 'Model 1',
_links: {
self: {
href: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60'
},
parents: {
href: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60/parents'
}
}
},
{
id: '752a1250-949a-46ad-9bea-fbc45f0b656d',
name: 'Model 2',
_links: {
self: {
href: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad'
},
parents: {
href: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad/parents'
}
}
}
];
const testResponses = [
{
_links: {
self: {
href: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60'
},
parents: {
href: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60/parents'
}
},
id: '9e32a2e2-6b91-4236-a361-995ccdc14c60',
type: 'testModels',
name: 'A Test Model'
},
{
_links: {
self: {
href: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad'
},
parents: {
href: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad/parents'
}
},
id: '598ce822-c357-46f3-ab70-63724d02d6ad',
type: 'testModels',
name: 'Another Test Model'
}
];
describe('DSpaceSerializer', () => {
describe('serialize', () => {
it('should turn a model in to a valid document', () => {
const serializer = new DSpaceSerializer(TestModel);
const doc = serializer.serialize(testModels[0]);
expect(testModels[0].id).toBe(doc.id);
expect(testModels[0].name).toBe(doc.name);
expect(testModels[0]._links).toBeUndefined();
});
});
describe('serializeArray', () => {
it('should turn an array of models in to a valid document', () => {
const serializer = new DSpaceSerializer(TestModel);
const doc = serializer.serializeArray(testModels);
expect(testModels[0].id).toBe(doc[0].id);
expect(testModels[0].name).toBe(doc[0].name);
expect(testModels[0]._links).toBeUndefined();
expect(testModels[1].id).toBe(doc[1].id);
expect(testModels[1].name).toBe(doc[1].name);
expect(testModels[1]._links).toBeUndefined();
});
});
describe('deserialize', () => {
it('should turn a valid document describing a single entity in to a valid model', () => {
const serializer = new DSpaceSerializer(TestModel);
const model = serializer.deserialize(testResponses[0]);
expect(model.id).toBe(testResponses[0].id);
expect(model.name).toBe(testResponses[0].name);
});
it('should throw an error when dealing with a document describing an array', () => {
const serializer = new DSpaceSerializer(TestModel);
expect(() => {
serializer.deserialize(testResponses);
}).toThrow();
});
});
describe('deserializeArray', () => {
it('should throw an error when dealing with a document describing a single model', () => {
const serializer = new DSpaceSerializer(TestModel);
const doc = {
_embedded: testResponses[0]
};
expect(() => {
serializer.deserializeArray(doc);
}).toThrow();
});
it('should turn an array of responses in to valid models', () => {
const serializer = new DSpaceSerializer(TestModel);
const output = serializer.deserializeArray(testResponses);
expect(testResponses[0].id).toBe(output[0].id);
expect(testResponses[0].name).toBe(output[0].name);
expect(testResponses[0]._links.self.href).toBe(output[0]._links.self.href);
expect(testResponses[0]._links.parents.href).toBe(output[0]._links.parents.href);
expect(testResponses[1].id).toBe(output[1].id);
expect(testResponses[1].name).toBe(output[1].name);
expect(testResponses[1]._links.self.href).toBe(output[1]._links.self.href);
expect(testResponses[1]._links.parents.href).toBe(output[1]._links.parents.href);
});
});
});

View File

@@ -1,194 +0,0 @@
import { autoserialize, autoserializeAs } from 'cerialize';
import { NormalizedObjectSerializer } from './normalized-object.serializer';
class TestModel {
@autoserialize
id: string;
@autoserialize
name: string;
@autoserializeAs(TestModel)
parents?: TestModel[];
}
const testModels = [
{
id: 'd4466d54-d73b-4d8f-b73f-c702020baa14',
name: 'Model 1',
},
{
id: '752a1250-949a-46ad-9bea-fbc45f0b656d',
name: 'Model 2',
}
];
const testResponses = [
{
_links: {
self: '/testmodels/9e32a2e2-6b91-4236-a361-995ccdc14c60',
parents: [
{ href: '/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78' },
{ href: '/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5' }
]
},
id: '9e32a2e2-6b91-4236-a361-995ccdc14c60',
type: 'testModels',
name: 'A Test Model'
},
{
_links: {
self: '/testmodels/598ce822-c357-46f3-ab70-63724d02d6ad',
parents: [
{ href: '/testmodels/be8325f7-243b-49f4-8a4b-df2b793ff3b5' },
{ href: '/testmodels/21539b1d-9ef1-4eda-9c77-49565b5bfb78' }
]
},
id: '598ce822-c357-46f3-ab70-63724d02d6ad',
type: 'testModels',
name: 'Another Test Model'
}
];
const parentHrefRegex = /^\/testmodels\/(.+)$/g;
describe('NormalizedObjectSerializer', () => {
describe('serialize', () => {
it('should turn a model in to a valid document', () => {
const serializer = new NormalizedObjectSerializer(TestModel);
const doc = serializer.serialize(testModels[0]);
expect(testModels[0].id).toBe(doc.id);
expect(testModels[0].name).toBe(doc.name);
});
});
describe('serializeArray', () => {
it('should turn an array of models in to a valid document', () => {
const serializer = new NormalizedObjectSerializer(TestModel);
const doc = serializer.serializeArray(testModels);
expect(testModels[0].id).toBe(doc[0].id);
expect(testModels[0].name).toBe(doc[0].name);
expect(testModels[1].id).toBe(doc[1].id);
expect(testModels[1].name).toBe(doc[1].name);
});
});
describe('deserialize', () => {
it('should turn a valid document describing a single entity in to a valid model', () => {
const serializer = new NormalizedObjectSerializer(TestModel);
const model = serializer.deserialize(testResponses[0]);
expect(model.id).toBe(testResponses[0].id);
expect(model.name).toBe(testResponses[0].name);
});
// TODO: cant implement/test this yet - depends on how relationships
// will be handled in the rest api
// it('should retain relationship information', () => {
// const serializer = new NormalizedObjectSerializer(TestModel);
// const doc = {
// '_embedded': testResponses[0],
// };
//
// const model = serializer.deserialize(doc);
//
// console.log(model);
//
// const modelParentIds = model.parents.map(parent => parent.id).sort();
// const responseParentIds = doc._embedded._links.parents
// .map(parent => parent.href)
// .map(href => href.replace(parentHrefRegex, '$1'))
// .sort();
//
// expect(modelParentIds).toEqual(responseParentIds);
// });
// TODO enable once validation is enabled in the serializer
// it('should throw an error when dealing with an invalid document', () => {
// const serializer = new NormalizedObjectSerializer(TestModel);
// const doc = testResponses[0];
//
// expect(() => {
// serializer.deserialize(doc);
// }).toThrow();
// });
it('should throw an error when dealing with a document describing an array', () => {
const serializer = new NormalizedObjectSerializer(TestModel);
expect(() => {
serializer.deserialize(testResponses);
}).toThrow();
});
});
describe('deserializeArray', () => {
// TODO: rewrite to incorporate normalisation.
// it('should turn a valid document describing a collection of objects in to an array of valid models', () => {
// const serializer = new NormalizedObjectSerializer(TestModel);
// const doc = {
// '_embedded': testResponses
// };
//
// const models = serializer.deserializeArray(doc);
//
// expect(models[0].id).toBe(doc._embedded[0].id);
// expect(models[0].name).toBe(doc._embedded[0].name);
// expect(models[1].id).toBe(doc._embedded[1].id);
// expect(models[1].name).toBe(doc._embedded[1].name);
// });
// TODO: cant implement/test this yet - depends on how relationships
// will be handled in the rest api
// it('should retain relationship information', () => {
// const serializer = new NormalizedObjectSerializer(TestModel);
// const doc = {
// '_embedded': testResponses,
// };
//
// const models = serializer.deserializeArray(doc);
//
// models.forEach((model, i) => {
// const modelParentIds = model.parents.map(parent => parent.id).sort();
// const responseParentIds = doc._embedded[i]._links.parents
// .map(parent => parent.href)
// .map(href => href.replace(parentHrefRegex, '$1'))
// .sort();
//
// expect(modelParentIds).toEqual(responseParentIds);
// });
// });
// TODO enable once validation is enabled in the serializer
// it('should throw an error when dealing with an invalid document', () => {
// const serializer = new NormalizedObjectSerializer(TestModel);
// const doc = testResponses[0];
//
// expect(() => {
// serializer.deserializeArray(doc);
// }).toThrow();
// });
it('should throw an error when dealing with a document describing a single model', () => {
const serializer = new NormalizedObjectSerializer(TestModel);
const doc = {
_embedded: testResponses[0]
};
expect(() => {
serializer.deserializeArray(doc);
}).toThrow();
});
});
});

View File

@@ -1,95 +0,0 @@
import { Deserialize, Serialize } from 'cerialize';
import { deprecate } from 'util';
import { Serializer } from '../serializer';
import { GenericConstructor } from '../shared/generic-constructor';
/**
* This Serializer turns responses from v2 of DSpace's REST API
* to normalized models and vice versa
*
* @deprecated use DSpaceSerializer instead
*/
export class NormalizedObjectSerializer<T> implements Serializer<T> {
/**
* Create a new NormalizedObjectSerializer instance
*
* @param modelType a class or interface to indicate
* the kind of model this serializer should work with
*/
constructor(private modelType: GenericConstructor<T>) {
}
/**
* Convert a model in to the format expected by the backend
*
* @param model The model to serialize
* @returns An object to send to the backend
*/
serialize(model: T): any {
return Serialize(model, this.modelType);
}
/**
* Convert an array of models in to the format expected by the backend
*
* @param models The array of models to serialize
* @returns An object to send to the backend
*/
serializeArray(models: T[]): any {
return Serialize(models, this.modelType);
}
/**
* Convert a response from the backend in to a model.
*
* @param response An object returned by the backend
* @returns a model of type T
*/
deserialize(response: any): T {
// TODO enable validation, once rest data stabilizes
// new DSpaceRESTv2Validator(response).validate();
if (Array.isArray(response)) {
throw new Error('Expected a single model, use deserializeArray() instead');
}
const normalized = Object.assign({}, response, this.normalizeLinks(response._links));
return Deserialize(normalized, this.modelType) as T;
}
/**
* Convert a response from the backend in to an array of models
*
* @param response An object returned by the backend
* @returns an array of models of type T
*/
deserializeArray(response: any): T[] {
// TODO: enable validation, once rest data stabilizes
// new DSpaceRESTv2Validator(response).validate();
if (!Array.isArray(response)) {
throw new Error('Expected an Array, use deserialize() instead');
}
const normalized = response.map((resource) => {
return Object.assign({}, resource, this.normalizeLinks(resource._links));
});
return Deserialize(normalized, this.modelType) as T[];
}
private normalizeLinks(links: any): any {
const normalizedLinks = {};
for (const link in links) {
if (links.hasOwnProperty(link)) {
if (Array.isArray(links[link])) {
normalizedLinks[link] = links[link].map((linkedResource) => {
return linkedResource.href;
});
} else {
normalizedLinks[link] = links[link].href;
}
}
}
return normalizedLinks;
}
}

View File

@@ -3,7 +3,6 @@ import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -23,7 +22,6 @@ export class EPersonDataService extends DataService<EPerson> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -6,7 +6,6 @@ import { Observable } from 'rxjs';
import { filter, map, take } from 'rxjs/operators';
import { DataService } from '../data/data.service';
import { EPersonDataService } from './eperson-data.service';
import { RequestService } from '../data/request.service';
import { FindListOptions } from '../data/request.models';
import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -18,7 +17,6 @@ import { SearchParam } from '../cache/models/search-param.model';
import { RemoteData } from '../data/remote-data';
import { PaginatedList } from '../data/paginated-list';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
/**
@@ -33,7 +31,6 @@ export class GroupDataService extends DataService<Group> {
constructor(
protected comparator: DSOChangeAnalyzer<Group>,
protected dataBuildService: NormalizedObjectBuildService,
protected http: HttpClient,
protected notificationsService: NotificationsService,
protected requestService: RequestService,

View File

@@ -46,6 +46,9 @@ export class AuthorityValue extends IntegrationModel implements MetadataValueInt
@autoserialize
language: string;
/**
* The HALLinks for this AuthorityValue
*/
@deserialize
_links: {
self: HALLink,

View File

@@ -31,7 +31,6 @@ import { createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { AuthService } from '../auth/auth.service';
import { BrowseService } from '../browse/browse.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -166,7 +165,6 @@ describe('MetadataService', () => {
{ provide: AuthService, useValue: {} },
{ provide: NotificationsService, useValue: {} },
{ provide: HttpClient, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: DSOChangeAnalyzer, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: DefaultChangeAnalyzer, useValue: {} },

View File

@@ -1,16 +1,24 @@
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 { relationship } from '../cache/builders/build-decorators';
import { link } from '../cache/builders/build-decorators';
export class RegistryBitstreamformatsResponse {
@deserialize
@relationship(BitstreamFormat, true)
bitstreamformats: BitstreamFormat[];
@autoserialize
page: PageInfo;
@autoserialize
self: string;
/**
* The HALLinks for this RegistryBitstreamformatsResponse
*/
@deserialize
_links: {
self: HALLink;
bitstreamformats: HALLink;
};
@link(BITSTREAM_FORMAT)
bitstreamformats?: BitstreamFormat[];
}

View File

@@ -1,5 +1,5 @@
import { autoserialize, deserialize } from 'cerialize';
import { relationship, resourceType } from '../cache/builders/build-decorators';
import { resourceType } 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';
@@ -25,7 +25,6 @@ export class RegistryMetadatafieldsResponse {
* List of metadata fields in the response
*/
@deserialize
@relationship(MetadataField, true)
metadatafields: MetadataField[];
/**
@@ -40,8 +39,8 @@ export class RegistryMetadatafieldsResponse {
@autoserialize
self: string;
@deserialize
_links: {
self: HALLink,
schema: HALLink
}
}

View File

@@ -1,11 +1,9 @@
import { PageInfo } from '../shared/page-info.model';
import { autoserialize, deserialize } from 'cerialize';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { relationship } from '../cache/builders/build-decorators';
export class RegistryMetadataschemasResponse {
@deserialize
@relationship(MetadataSchema, true)
metadataschemas: MetadataSchema[];
@autoserialize

View File

@@ -56,7 +56,7 @@ import { HttpHeaders } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { MetadataField } from '../metadata/metadata-field.model';
import { getMapsToType } from '../cache/builders/build-decorators';
import { getClassForType } from '../cache/builders/build-decorators';
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema);
@@ -399,7 +399,7 @@ export class RegistryService {
distinctUntilChanged()
);
const serializedSchema = new DSpaceSerializer(getMapsToType(MetadataSchema.type)).serialize(schema);
const serializedSchema = new DSpaceSerializer(getClassForType(MetadataSchema.type)).serialize(schema);
const request$ = endpoint$.pipe(
take(1),

View File

@@ -10,7 +10,6 @@ import { ResourceType } from './resource-type';
/**
* Class object representing a browse entry
* This class is not normalized because browse entries do not have self links
*/
@resourceType(BrowseEntry.type)
export class BrowseEntry extends ListableObject implements TypedObject {

View File

@@ -52,6 +52,9 @@ export class ExternalSourceEntry extends ListableObject {
@autoserializeAs(MetadataMapSerializer)
metadata: MetadataMap;
/**
* The HALLinks for this ExternalSourceEntry
*/
@deserialize
_links: {
self: HALLink;

View File

@@ -38,6 +38,9 @@ export class ExternalSource extends CacheableObject {
@autoserialize
hierarchical: boolean;
/**
* The HALLinks for this ExternalSource
*/
@deserialize
_links: {
self: HALLink;

View File

@@ -38,6 +38,9 @@ export class ItemType implements CacheableObject {
@deserializeAs(new IDToUUIDSerializer(ItemType.type.value), 'id')
uuid: string;
/**
* The HALLinks for this ItemType
*/
@deserialize
_links: {
self: HALLink,

View File

@@ -48,6 +48,9 @@ export class ResourcePolicy implements CacheableObject {
@deserializeAs(new IDToUUIDSerializer('resource-policy'), 'id')
uuid: string;
/**
* The HALLinks for this ResourcePolicy
*/
@deserialize
_links: {
self: HALLink,

View File

@@ -1,43 +0,0 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
import { SubmissionObjectError } from './submission-object.model';
import { DSpaceObject } from '../../shared/dspace-object.model';
/**
* An abstract model class for a NormalizedSubmissionObject.
*/
@inheritSerialization(NormalizedDSpaceObject)
export class NormalizedSubmissionObject<T extends DSpaceObject> extends NormalizedDSpaceObject<T> {
/**
* The workspaceitem/workflowitem identifier
*/
@autoserialize
id: string;
/**
* The workspaceitem/workflowitem identifier
*/
@autoserializeAs(String, 'id')
uuid: string;
/**
* The workspaceitem/workflowitem last modified date
*/
@autoserialize
lastModified: Date;
/**
* The workspaceitem/workflowitem last sections data
*/
@autoserialize
sections: WorkspaceitemSectionsObject;
/**
* The workspaceitem/workflowitem last sections errors
*/
@autoserialize
errors: SubmissionObjectError[];
}

View File

@@ -1,45 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { relationship } from '../../cache/builders/build-decorators';
import { WorkflowItem } from './workflowitem.model';
import { NormalizedSubmissionObject } from './normalized-submission-object.model';
import { Collection } from '../../shared/collection.model';
import { Item } from '../../shared/item.model';
import { SubmissionDefinitionsModel } from '../../config/models/config-submission-definitions.model';
import { EPerson } from '../../eperson/models/eperson.model';
/**
* An model class for a NormalizedWorkflowItem.
*/
@inheritSerialization(NormalizedSubmissionObject)
export class NormalizedWorkflowItem extends NormalizedSubmissionObject<WorkflowItem> {
/**
* The collection this workflowitem belonging to
*/
@autoserialize
@relationship(Collection, false)
collection: string;
/**
* The item created with this workflowitem
*/
@autoserialize
@relationship(Item, false)
item: string;
/**
* The configuration object that define this workflowitem
*/
@autoserialize
@relationship(SubmissionDefinitionsModel, false)
submissionDefinition: string;
/**
* The EPerson who submit this workflowitem
*/
@autoserialize
@relationship(EPerson, false)
submitter: string;
}

View File

@@ -1,46 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { WorkspaceItem } from './workspaceitem.model';
import { NormalizedSubmissionObject } from './normalized-submission-object.model';
import { relationship } from '../../cache/builders/build-decorators';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { Item } from '../../shared/item.model';
import { Collection } from '../../shared/collection.model';
import { SubmissionDefinitionModel } from '../../config/models/config-submission-definition.model';
import { EPerson } from '../../eperson/models/eperson.model';
/**
* An model class for a NormalizedWorkspaceItem.
*/
@inheritSerialization(NormalizedDSpaceObject)
@inheritSerialization(NormalizedSubmissionObject)
export class NormalizedWorkspaceItem extends NormalizedSubmissionObject<WorkspaceItem> {
/**
* The collection this workspaceitem belonging to
*/
@autoserialize
@relationship(Collection, false)
collection: string;
/**
* The item created with this workspaceitem
*/
@autoserialize
@relationship(Item, false)
item: string;
/**
* The configuration object that define this workspaceitem
*/
@autoserialize
@relationship(SubmissionDefinitionModel, false)
submissionDefinition: string;
/**
* The EPerson who submit this workspaceitem
*/
@autoserialize
@relationship(EPerson, false)
submitter: string;
}

View File

@@ -12,13 +12,12 @@ import { BaseResponseParsingService } from '../data/base-response-parsing.servic
import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface';
import { ObjectCacheService } from '../cache/object-cache.service';
import { NormalizedObjectSerializer } from '../dspace-rest-v2/normalized-object.serializer';
import { Serializer } from '../serializer';
import { GenericConstructor } from '../shared/generic-constructor';
import { NormalizedWorkspaceItem } from './models/normalized-workspaceitem.model';
import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model';
import { FormFieldMetadataValueObject } from '../../shared/form/builder/models/form-field-metadata-value.model';
import { SubmissionObject } from './models/submission-object.model';
import { WorkflowItem } from './models/workflowitem.model';
import { WorkspaceItem } from './models/workspaceitem.model';
/**
* Export a function to check if object has same properties of FormFieldMetadataValueObject
@@ -81,8 +80,6 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
protected toCache = false;
protected shouldDirectlyAttachEmbeds = true;
protected serializerConstructor: GenericConstructor<Serializer<any>> = NormalizedObjectSerializer;
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
protected objectCache: ObjectCacheService,
protected dsoParser: DSOResponseParsingService
@@ -125,15 +122,15 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
*/
protected processResponse<ObjectDomain>(data: any, request: RestRequest): any[] {
const dataDefinition = this.process<ObjectDomain>(data, request);
const normalizedDefinition = Array.of();
const definition = Array.of();
const processedList = Array.isArray(dataDefinition) ? dataDefinition : Array.of(dataDefinition);
processedList.forEach((item) => {
let normalizedItem = Object.assign({}, item);
// In case data is an Instance of NormalizedWorkspaceItem normalize field value of all the section of type form
if (item instanceof NormalizedWorkspaceItem
|| item instanceof NormalizedWorkflowItem) {
item = Object.assign({}, item);
// In case data is an Instance of WorkspaceItem normalize field value of all the section of type form
if (item instanceof WorkspaceItem
|| item instanceof WorkflowItem) {
if (item.sections) {
const precessedSection = Object.create({});
// Iterate over all workspaceitem's sections
@@ -143,35 +140,35 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
// When Upload section is disabled, add to submission only if there are files
(!item.sections[sectionId].hasOwnProperty('files') || isNotEmpty((item.sections[sectionId] as any).files)))) {
const normalizedSectionData = Object.create({});
const sectiondata = Object.create({});
// Iterate over all sections property
Object.keys(item.sections[sectionId])
.forEach((metdadataId) => {
const entry = item.sections[sectionId][metdadataId];
// If entry is not an array, for sure is not a section of type form
if (Array.isArray(entry)) {
normalizedSectionData[metdadataId] = [];
sectiondata[metdadataId] = [];
entry.forEach((valueItem, index) => {
// Parse value and normalize it
const normValue = normalizeSectionData(valueItem, index);
if (isNotEmpty(normValue)) {
normalizedSectionData[metdadataId].push(normValue);
sectiondata[metdadataId].push(normValue);
}
});
} else {
normalizedSectionData[metdadataId] = entry;
sectiondata[metdadataId] = entry;
}
});
precessedSection[sectionId] = normalizedSectionData;
precessedSection[sectionId] = sectiondata;
}
});
normalizedItem = Object.assign({}, item, { sections: precessedSection });
item = Object.assign({}, item, { sections: precessedSection });
}
}
normalizedDefinition.push(normalizedItem);
definition.push(item);
});
return normalizedDefinition;
return definition;
}
}

View File

@@ -10,7 +10,6 @@ import { RequestService } from '../data/request.service';
import { WorkflowItem } from './models/workflowitem.model';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { FindListOptions } from '../data/request.models';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
@@ -26,7 +25,6 @@ export class WorkflowItemDataService extends DataService<WorkflowItem> {
constructor(
protected comparator: DSOChangeAnalyzer<WorkflowItem>,
protected dataBuildService: NormalizedObjectBuildService,
protected halService: HALEndpointService,
protected http: HttpClient,
protected notificationsService: NotificationsService,

View File

@@ -9,7 +9,6 @@ import { DataService } from '../data/data.service';
import { RequestService } from '../data/request.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { FindListOptions } from '../data/request.models';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
@@ -26,7 +25,6 @@ export class WorkspaceitemDataService extends DataService<WorkspaceItem> {
constructor(
protected comparator: DSOChangeAnalyzer<WorkspaceItem>,
protected dataBuildService: NormalizedObjectBuildService,
protected halService: HALEndpointService,
protected http: HttpClient,
protected notificationsService: NotificationsService,

View File

@@ -6,7 +6,6 @@ import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service-stub';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { CoreState } from '../core.reducers';
import { ClaimedTaskDataService } from './claimed-task-data.service';
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
@@ -22,9 +21,6 @@ describe('ClaimedTaskDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {
normalize: (object) => object
} as NormalizedObjectBuildService;
const objectCache = {
addPatch: () => {
/* empty */
@@ -39,7 +35,6 @@ describe('ClaimedTaskDataService', () => {
return new ClaimedTaskDataService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -5,8 +5,6 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -37,7 +35,7 @@ export class ClaimedTaskDataService extends TasksService<ClaimedTask> {
*
* @param {RequestService} requestService
* @param {RemoteDataBuildService} rdbService
* @param {NormalizedObjectBuildService} dataBuildService
* @param {NormalizedObjectBuildService} linkService
* @param {Store<CoreState>} store
* @param {ObjectCacheService} objectCache
* @param {HALEndpointService} halService
@@ -48,7 +46,6 @@ export class ClaimedTaskDataService extends TasksService<ClaimedTask> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -1,4 +1,6 @@
import { inheritSerialization } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { DSpaceObject } from '../../shared/dspace-object.model';
import { CLAIMED_TASK } from './claimed-task-object.resource-type';
import { TaskObject } from './task-object.model';
@@ -6,6 +8,7 @@ import { TaskObject } from './task-object.model';
* A model class for a ClaimedTask.
*/
@resourceType(ClaimedTask.type)
@inheritSerialization(DSpaceObject)
export class ClaimedTask extends TaskObject {
static type = CLAIMED_TASK;
}

View File

@@ -1,53 +0,0 @@
import { NormalizedTaskObject } from './normalized-task-object.model';
import { relationship } from '../../cache/builders/build-decorators';
import { autoserialize, inheritSerialization } from 'cerialize';
import { ClaimedTask } from './claimed-task-object.model';
import { EPerson } from '../../eperson/models/eperson.model';
import { Group } from '../../eperson/models/group.model';
import { WorkflowItem } from '../../submission/models/workflowitem.model';
/**
* A normalized model class for a ClaimedTask.
*/
@inheritSerialization(NormalizedTaskObject)
export class NormalizedClaimedTask extends NormalizedTaskObject<ClaimedTask> {
/**
* The task identifier
*/
@autoserialize
id: string;
/**
* The workflow step
*/
@autoserialize
step: string;
/**
* The task action type
*/
@autoserialize
action: string;
/**
* The eperson object for this task
*/
@autoserialize
@relationship(EPerson, false)
eperson: string;
/**
* The group object for this task
*/
@autoserialize
@relationship(Group, false)
group: string;
/**
* The workflowitem object whom this task is related
*/
@autoserialize
@relationship(WorkflowItem, false)
workflowitem: string;
}

View File

@@ -1,44 +0,0 @@
import { NormalizedTaskObject } from './normalized-task-object.model';
import { PoolTask } from './pool-task-object.model';
import { autoserialize, inheritSerialization } from 'cerialize';
import { relationship } from '../../cache/builders/build-decorators';
import { Group } from '../../eperson/models/group.model';
import { WorkflowItem } from '../../submission/models/workflowitem.model';
/**
* A normalized model class for a PoolTask.
*/
@inheritSerialization(NormalizedTaskObject)
export class NormalizedPoolTask extends NormalizedTaskObject<PoolTask> {
/**
* The task identifier
*/
@autoserialize
id: string;
/**
* The workflow step
*/
@autoserialize
step: string;
/**
* The task action type
*/
@autoserialize
action: string;
/**
* The group object for this task
*/
@autoserialize
@relationship(Group, false)
group: string;
/**
* The workflowitem object whom this task is related
*/
@autoserialize
@relationship(WorkflowItem, false)
workflowitem: string;
}

View File

@@ -1,54 +0,0 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { relationship } from '../../cache/builders/build-decorators';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { TaskObject } from './task-object.model';
import { DSpaceObject } from '../../shared/dspace-object.model';
import { Group } from '../../eperson/models/group.model';
import { EPerson } from '../../eperson/models/eperson.model';
import { WorkflowItem } from '../../submission/models/workflowitem.model';
/**
* An abstract normalized model class for a TaskObject.
*/
@inheritSerialization(NormalizedDSpaceObject)
export class NormalizedTaskObject<T extends DSpaceObject> extends NormalizedDSpaceObject<T> {
/**
* The task identifier
*/
@autoserialize
id: string;
/**
* The workflow step
*/
@autoserialize
step: string;
/**
* The task action type
*/
@autoserialize
action: string;
/**
* The eperson object for this task
*/
@autoserialize
@relationship(EPerson, false)
eperson: string;
/**
* The group object for this task
*/
@autoserialize
@relationship(Group, false)
group: string;
/**
* The workflowitem object whom this task is related
*/
@autoserialize
@relationship(WorkflowItem, false)
workflowitem: string;
}

View File

@@ -1,3 +1,4 @@
import { inheritSerialization } from 'cerialize';
import { resourceType } from '../../cache/builders/build-decorators';
import { POOL_TASK } from './pool-task-object.resource-type';
import { TaskObject } from './task-object.model';
@@ -6,6 +7,7 @@ import { TaskObject } from './task-object.model';
* A model class for a PoolTask.
*/
@resourceType(PoolTask.type)
@inheritSerialization(TaskObject)
export class PoolTask extends TaskObject {
static type = POOL_TASK;
}

View File

@@ -1,3 +1,4 @@
import { autoserialize, deserialize, inheritSerialization } from 'cerialize';
import { Observable } from 'rxjs';
import { link, resourceType } from '../../cache/builders/build-decorators';
@@ -16,24 +17,39 @@ import { TASK_OBJECT } from './task-object.resource-type';
* An abstract model class for a TaskObject.
*/
@resourceType(TaskObject.type)
@inheritSerialization(DSpaceObject)
export class TaskObject extends DSpaceObject implements CacheableObject {
static type = TASK_OBJECT;
/**
* The task identifier
*/
@autoserialize
id: string;
/**
* The workflow step
*/
@autoserialize
step: string;
/**
* The task action type
*/
@autoserialize
action: string;
/**
* The HALLinks for this TaskObject
*/
@deserialize
_links: {
self: HALLink;
eperson: HALLink;
group: HALLink;
workflowitem: HALLink;
};
/**
* The EPerson for this task
* Will be undefined unless the eperson HALLink has been resolved.
@@ -55,11 +71,4 @@ export class TaskObject extends DSpaceObject implements CacheableObject {
@link(WorkflowItem.type)
workflowitem?: Observable<RemoteData<WorkflowItem>> | WorkflowItem;
_links: {
self: HALLink,
eperson: HALLink,
group: HALLink,
workflowitem: HALLink,
}
}

View File

@@ -6,7 +6,6 @@ import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service-stub';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { CoreState } from '../core.reducers';
import { PoolTaskDataService } from './pool-task-data.service';
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
@@ -22,9 +21,6 @@ describe('PoolTaskDataService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = {} as any;
const dataBuildService = {
normalize: (object) => object
} as NormalizedObjectBuildService;
const objectCache = {
addPatch: () => {
/* empty */
@@ -39,7 +35,6 @@ describe('PoolTaskDataService', () => {
return new PoolTaskDataService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -5,8 +5,6 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
@@ -37,7 +35,7 @@ export class PoolTaskDataService extends TasksService<PoolTask> {
*
* @param {RequestService} requestService
* @param {RemoteDataBuildService} rdbService
* @param {NormalizedObjectBuildService} dataBuildService
* @param {NormalizedObjectBuildService} linkService
* @param {Store<CoreState>} store
* @param {ObjectCacheService} objectCache
* @param {HALEndpointService} halService
@@ -48,7 +46,6 @@ export class PoolTaskDataService extends TasksService<PoolTask> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,

View File

@@ -9,7 +9,6 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service-stub';
import { TaskObject } from './models/task-object.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service';
@@ -18,7 +17,6 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
import { ChangeAnalyzer } from '../data/change-analyzer';
import { compare, Operation } from 'fast-json-patch';
import { NormalizedTaskObject } from './models/normalized-task-object.model';
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
const LINK_NAME = 'test';
@@ -33,7 +31,6 @@ class TestService extends TasksService<TestTask> {
constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected dataBuildService: NormalizedObjectBuildService,
protected store: Store<CoreState>,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
@@ -44,11 +41,8 @@ class TestService extends TasksService<TestTask> {
}
}
class NormalizedTestTaskObject extends NormalizedTaskObject<TestTask> {
}
class DummyChangeAnalyzer implements ChangeAnalyzer<NormalizedTestTaskObject> {
diff(object1: NormalizedTestTaskObject, object2: NormalizedTestTaskObject): Operation[] {
class DummyChangeAnalyzer implements ChangeAnalyzer<TestTask> {
diff(object1: TestTask, object2: TestTask): Operation[] {
return compare((object1 as any).metadata, (object2 as any).metadata);
}
@@ -66,9 +60,6 @@ describe('TasksService', () => {
const notificationsService = {} as NotificationsService;
const http = {} as HttpClient;
const comparator = new DummyChangeAnalyzer() as any;
const dataBuildService = {
normalize: (object) => object
} as NormalizedObjectBuildService;
const objectCache = {
addPatch: () => {
/* empty */
@@ -83,7 +74,6 @@ describe('TasksService', () => {
return new TestService(
requestService,
rdbService,
dataBuildService,
store,
objectCache,
halService,

View File

@@ -6,7 +6,6 @@ import { Store } from '@ngrx/store';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/internal/Observable';
import { GenericItemPageFieldComponent } from '../../../../+item-page/simple/field-components/specific-field/generic/generic-item-page-field.component';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
@@ -80,7 +79,6 @@ describe('JournalComponent', () => {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: HttpClient, useValue: {} },

View File

@@ -7,7 +7,6 @@ import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { NormalizedObjectBuildService } from '../../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
@@ -111,7 +110,6 @@ describe('OrgUnitSearchResultListSubmissionElementComponent', () => {
{ provide: ObjectCacheService, useValue: {} },
{ provide: UUIDService, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: HttpClient, useValue: {} },

View File

@@ -7,7 +7,6 @@ import { Store } from '@ngrx/store';
import { TranslateService } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { NormalizedObjectBuildService } from '../../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
@@ -105,7 +104,6 @@ describe('PersonSearchResultListElementSubmissionComponent', () => {
{ provide: ObjectCacheService, useValue: {} },
{ provide: UUIDService, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: HttpClient, useValue: {} },

View File

@@ -1,7 +1,6 @@
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { NormalizedObject } from '../../core/cache/models/normalized-object.model';
import { PaginatedList } from '../../core/data/paginated-list';
import { RemoteData } from '../../core/data/remote-data';
import { RequestEntry } from '../../core/data/request.reducer';
@@ -22,7 +21,7 @@ export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observab
}
},
buildSingle: (href$: string | Observable<string>) => createSuccessfulRemoteDataObject$({}),
build: (normalized: NormalizedObject<any>) => Object.create({}),
build: (obj: any) => Object.create({}),
buildList: (href$: string | Observable<string>) => {
if (hasValue(buildList$)) {
return buildList$;
@@ -47,7 +46,7 @@ export function getMockRemoteDataBuildServiceHrefMap(toRemoteDataObservable$?: O
}
},
buildSingle: (href$: string | Observable<string>) => createSuccessfulRemoteDataObject$({}),
build: (normalized: NormalizedObject<any>) => Object.create({}),
build: (obj: any) => Object.create({}),
buildList: (href$: string | Observable<string>) => {
if (typeof href$ === 'string') {
if (hasValue(buildListHrefMap$[href$])) {

View File

@@ -7,7 +7,6 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
@@ -103,7 +102,6 @@ describe('ItemDetailPreviewComponent', () => {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: NotificationsService, useValue: {} },

View File

@@ -4,7 +4,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Store } from '@ngrx/store';
import { of as observableOf } from 'rxjs';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { CommunityDataService } from '../../../../core/data/community-data.service';
@@ -63,7 +62,6 @@ describe('CollectionSearchResultGridElementComponent', () => {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: NotificationsService, useValue: {} },

View File

@@ -4,7 +4,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Store } from '@ngrx/store';
import { of as observableOf } from 'rxjs';
import { NormalizedObjectBuildService } from '../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../core/cache/object-cache.service';
import { CommunityDataService } from '../../../../core/data/community-data.service';
@@ -63,7 +62,6 @@ describe('CommunitySearchResultGridElementComponent', () => {
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: NotificationsService, useValue: {} },

View File

@@ -6,7 +6,6 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/internal/Observable';
import { of as observableOf } from 'rxjs/internal/observable/of';
import { NormalizedObjectBuildService } from '../../../../../core/cache/builders/normalized-object-build.service';
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../../../../core/cache/object-cache.service';
import { BitstreamDataService } from '../../../../../core/data/bitstream-data.service';
@@ -109,7 +108,6 @@ export function getEntityGridElementTestComponent(component, searchResultWithMet
{ provide: UUIDService, useValue: {} },
{ provide: Store, useValue: {} },
{ provide: RemoteDataBuildService, useValue: {} },
{ provide: NormalizedObjectBuildService, useValue: {} },
{ provide: CommunityDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: HttpClient, useValue: {} },

View File

@@ -1,9 +1,11 @@
import { autoserialize, autoserializeAs } from 'cerialize';
import { autoserialize, autoserializeAs, deserialize } from 'cerialize';
import { HALLink } from '../../core/shared/hal-link.model';
import { HALResource } from '../../core/shared/hal-resource.model';
/**
* Class representing possible values for a certain filter
*/
export class FacetValue {
export class FacetValue implements HALResource {
/**
* The display label of the facet value
*/
@@ -23,8 +25,11 @@ export class FacetValue {
count: number;
/**
* The REST url to add this filter value
* The HALLinks for this FacetValue
*/
@autoserialize
search: string;
@deserialize
_links: {
self: HALLink
search: HALLink
}
}

View File

@@ -23,7 +23,7 @@ export class SearchAuthorityFilterComponent extends SearchFacetFilterComponent i
* Retrieve facet value from search link
*/
protected getFacetValue(facet: FacetValue): string {
const search = facet.search;
const search = facet._links.search.href;
const hashes = search.slice(search.indexOf('?') + 1).split('&');
const params = {};
hashes.map((hash) => {

View File

@@ -113,7 +113,7 @@ export class SearchFacetOptionComponent implements OnInit, OnDestroy {
*/
private getFacetValue(): string {
if (this.filterConfig.type === FilterType.authority) {
const search = this.filterValue.search;
const search = this.filterValue._links.search.href;
const hashes = search.slice(search.indexOf('?') + 1).split('&');
const params = {};
hashes.map((hash) => {

Some files were not shown because too many files have changed in this diff Show More