Skip to content
Snippets Groups Projects
submission-response-parsing.service.ts 6.63 KiB
Newer Older
Giuseppe's avatar
Giuseppe committed
import { Inject, Injectable } from '@angular/core';

import { ResponseParsingService } from '../data/parsing.service';
import { RestRequest } from '../data/request.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { ErrorResponse, RestResponse, SubmissionSuccessResponse } from '../cache/response.models';
Giuseppe's avatar
Giuseppe committed
import { isEmpty, isNotEmpty, isNotNull } from '../../shared/empty.util';
import { ConfigObject } from '../config/models/config.model';
Giuseppe's avatar
Giuseppe committed
import { BaseResponseParsingService } from '../data/base-response-parsing.service';
Giuseppe's avatar
Giuseppe committed
import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface';
import { ObjectCacheService } from '../cache/object-cache.service';
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';
Giuseppe Digilio's avatar
Giuseppe Digilio committed
import { SubmissionObject } from './models/submission-object.model';
Giuseppe Digilio's avatar
Giuseppe Digilio committed
/**
 * Export a function to check if object has same properties of FormFieldMetadataValueObject
 *
 * @param obj
 */
export function isServerFormValue(obj: any): boolean {
  return (typeof obj === 'object'
    && obj.hasOwnProperty('value')
    && obj.hasOwnProperty('language')
    && obj.hasOwnProperty('authority')
Giuseppe Digilio's avatar
Giuseppe Digilio committed
/**
 * Export a function to normalize sections object of the server response
 *
 * @param obj
Giuseppe Digilio's avatar
Giuseppe Digilio committed
 */
export function normalizeSectionData(obj: any, objIndex?: number) {
  let result: any = obj;
  if (isNotNull(obj)) {
    // If is an Instance of FormFieldMetadataValueObject normalize it
    if (typeof obj === 'object' && isServerFormValue(obj)) {
      // If authority property is set normalize as a FormFieldMetadataValueObject object
      /* NOTE: Data received from server could have authority property equal to null, but into form
         field's model is required a FormFieldMetadataValueObject object as field value, so instantiate it */
      result = new FormFieldMetadataValueObject(
        obj.value,
        obj.language,
        obj.authority,
        (obj.display || obj.value),
        obj.confidence,
        obj.otherInformation
      );
    } else if (Array.isArray(obj)) {
      result = [];
      obj.forEach((item, index) => {
        result[index] = normalizeSectionData(item, index);
      });
    } else if (typeof obj === 'object') {
      result = Object.create({});
      Object.keys(obj)
        .forEach((key) => {
          result[key] = normalizeSectionData(obj[key]);
        });
    }
  }
  return result;
}

/**
 * Provides methods to parse response for a submission request.
 */
Giuseppe's avatar
Giuseppe committed
@Injectable()
export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {

  protected toCache = false;

  constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
Giuseppe's avatar
Giuseppe committed
              protected objectCache: ObjectCacheService) {
Giuseppe's avatar
Giuseppe committed
    super();
  }

Giuseppe Digilio's avatar
Giuseppe Digilio committed
  /**
   * Parses data from the workspaceitems/workflowitems endpoints
   *
   * @param {RestRequest} request
   * @param {DSpaceRESTV2Response} data
   * @returns {RestResponse}
   */
Giuseppe's avatar
Giuseppe committed
  parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
    if (isNotEmpty(data.payload)
      && isNotEmpty(data.payload._links)
      && this.isSuccessStatus(data.statusCode)) {
lotte's avatar
lotte committed
      const dataDefinition = this.processResponse<SubmissionObject | ConfigObject>(data.payload, request.href);
Giuseppe's avatar
Giuseppe committed
      return new SubmissionSuccessResponse(dataDefinition, data.statusCode, data.statusText, this.processPageInfo(data.payload));
    } else if (isEmpty(data.payload) && this.isSuccessStatus(data.statusCode)) {
      return new SubmissionSuccessResponse(null, data.statusCode, data.statusText);
Giuseppe's avatar
Giuseppe committed
    } else {
      return new ErrorResponse(
        Object.assign(
          new Error('Unexpected response from server'),
          {statusCode: data.statusCode, statusText: data.statusText}
Giuseppe Digilio's avatar
Giuseppe Digilio committed
  /**
   * Parses response and normalize it
   *
   * @param {DSpaceRESTV2Response} data
   * @param {string} requestHref
   * @returns {any[]}
   */
lotte's avatar
lotte committed
  protected processResponse<ObjectDomain>(data: any, requestHref: string): any[] {
    const dataDefinition = this.process<ObjectDomain>(data, requestHref);
Giuseppe's avatar
Giuseppe committed
    const normalizedDefinition = Array.of();
    const processedList = Array.isArray(dataDefinition) ? dataDefinition : Array.of(dataDefinition);

Giuseppe's avatar
Giuseppe committed

Giuseppe's avatar
Giuseppe committed
      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) {
Giuseppe's avatar
Giuseppe committed
        if (item.sections) {
          const precessedSection = Object.create({});
          // Iterate over all workspaceitem's sections
          Object.keys(item.sections)
            .forEach((sectionId) => {
              if (typeof item.sections[sectionId] === 'object' && (isNotEmpty(item.sections[sectionId]) &&
                // 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)))) {

Giuseppe's avatar
Giuseppe committed
                const normalizedSectionData = 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
Giuseppe Digilio's avatar
Giuseppe Digilio committed
                    if (Array.isArray(entry)) {
Giuseppe's avatar
Giuseppe committed
                      normalizedSectionData[metdadataId] = [];
Giuseppe's avatar
Giuseppe committed
                        // Parse value and normalize it
                        const normValue = normalizeSectionData(valueItem, index);
Giuseppe's avatar
Giuseppe committed
                        if (isNotEmpty(normValue)) {
                          normalizedSectionData[metdadataId].push(normValue);
                        }
                      });
                    } else {
                      normalizedSectionData[metdadataId] = entry;
                    }
                  });
                precessedSection[sectionId] = normalizedSectionData;
              }
            });
          normalizedItem = Object.assign({}, item, { sections: precessedSection });
      normalizedDefinition.push(normalizedItem);
Giuseppe's avatar
Giuseppe committed
    return normalizedDefinition;