<commit_before>import {Injectable} from '@angular/core';
import {Document, NewDocument, NewResource, Query, Resource} from 'idai-components-2';
import {TypeUtility} from '../../model/type-utility';
import {Validator} from '../../model/validator';
import {Validations} from '../../model/validations';
import {ImportErrors as E} from './import-errors';
import {ValidationErrors} from '../../model/validation-errors';
import {DocumentDatastore} from '../../datastore/document-datastore';
import {includedIn, is, isNot, isnt, on} from 'tsfun';
import {INPUT_TYPES, ResourceId} from '../../../c';
import {HIERARCHICAL_RELATIONS, PARENT} from '../../model/relation-constants';
import RECORDED_IN = HIERARCHICAL_RELATIONS.RECORDED_IN;
import LIES_WITHIN = HIERARCHICAL_RELATIONS.LIES_WITHIN;
import {ProjectConfiguration} from '../../configuration/project-configuration';


@Injectable()
/**
 * Validates against data model of ProjectConfiguration and TypeUtility and contents of Database
 *
 * Errors thrown are of type
 *   ImportError.* if specified in ImportValidator itself and of type
 *   ValidationError.* if coming from the Validator
 *
 * @author <NAME>
 * @author <NAME>
 */
export class ImportValidator extends Validator {


    constructor(projectConfiguration: ProjectConfiguration,
                private datastore: DocumentDatastore,
                typeUtility: TypeUtility) {

        super(projectConfiguration, (q: Query) => datastore.find(q), typeUtility);
    }


    public assertIsAllowedRelationDomainType(domainTypeName: string,
                                             rangeTypeName: string,
                                             relationName: string,
                                             identifier: string) {

        if (!this.projectConfiguration.isAllowedRelationDomainType(domainTypeName, rangeTypeName, relationName)) {

            throw [
                E.TARGET_TYPE_RANGE_MISMATCH,
                identifier,
                [LIES_WITHIN, RECORDED_IN].includes(relationName) ? PARENT : relationName,
                rangeTypeName
            ];
        }
    }


    public async assertLiesWithinCorrectness(resources: Array<Resource>) {

        for (let resource of resources) {

            const type = this.projectConfiguration.getTypesList().find(on('name', is(resource.type)));
            if (!type) {
                console.error("resource type not found", resource.type);
                continue;
            }
            if (!type.mustLieWithin) continue;

            const recordedIn = resource.relations[RECORDED_IN];
            const liesWithin = resource.relations[LIES_WITHIN];

            if (recordedIn && recordedIn.length > 0 && (!liesWithin || liesWithin.length === 0)) {

                throw [E.MUST_LIE_WITHIN_OTHER_NON_OPERATON_RESOURCE, resource.type, resource.identifier];
            }
        }
    }
<commit_msg>Add todo<commit_after>import {Injectable} from '@angular/core';
import {Document, NewDocument, NewResource, Query, Resource} from 'idai-components-2';
import {TypeUtility} from '../../model/type-utility';
import {Validator} from '../../model/validator';
import {Validations} from '../../model/validations';
import {ImportErrors as E} from './import-errors';
import {ValidationErrors} from '../../model/validation-errors';
import {DocumentDatastore} from '../../datastore/document-datastore';
import {includedIn, is, isNot, isnt, on} from 'tsfun';
import {INPUT_TYPES, ResourceId} from '../../../c';
import {HIERARCHICAL_RELATIONS, PARENT} from '../../model/relation-constants';
import RECORDED_IN = HIERARCHICAL_RELATIONS.RECORDED_IN;
import LIES_WITHIN = HIERARCHICAL_RELATIONS.LIES_WITHIN;
import {ProjectConfiguration} from '../../configuration/project-configuration';


@Injectable()
/**
 * Validates against data model of ProjectConfiguration and TypeUtility and contents of Database
 *
 * Errors thrown are of type
 *   ImportError.* if specified in ImportValidator itself and of type
 *   ValidationError.* if coming from the Validator
 *
 * @author <NAME>
 * @author <NAME>
 */
export class ImportValidator extends Validator {


    constructor(projectConfiguration: ProjectConfiguration,
                private datastore: DocumentDatastore,
                typeUtility: TypeUtility) {

        super(projectConfiguration, (q: Query) => datastore.find(q), typeUtility);
    }


    public assertIsAllowedRelationDomainType(domainTypeName: string,
                                             rangeTypeName: string,
                                             relationName: string,
                                             identifier: string) {

        if (!this.projectConfiguration.isAllowedRelationDomainType(domainTypeName, rangeTypeName, relationName)) {

            throw [
                E.TARGET_TYPE_RANGE_MISMATCH,
                identifier,
                [LIES_WITHIN, RECORDED_IN].includes(relationName) ? PARENT : relationName, // TODO do this mapping at the proper level, namely in default-import, where isChildOf gets replaced with liesWithin
                rangeTypeName
            ];
        }
    }


    public async assertLiesWithinCorrectness(resources: Array<Resource>) {

        for (let resource of resources) {

            const type = this.projectConfiguration.getTypesList().find(on('name', is(resource.type)));
            if (!type) {
                console.error("resource type not found", resource.type);
                continue;
            }
            if (!type.mustLieWithin) continue;

            const recordedIn = resource.relations[RECORDED_IN];
            const liesWithin = resource.relations[LIES_WITHIN];

            if (recordedIn && recordedIn.length > 0 && (!liesWithin || liesWithin.length === 0)) {

                throw [E.MUST_LIE_WITHIN_OTHER_NON_OPERATON_RESOURCE, resource.type, resource.identifier];
            }
        }
    }

{'fraction_non_alphanumeric': 0.10868830290736985, 'fraction_numerical': 0.0010141987829614604, 'mean_word_length': 2.6101281269066505, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1675993', 'n_tokens_mistral': 1564, 'n_tokens_neox': 1504, 'n_words': 382}