UNPKG

@knora/core

Version:
1,021 lines (984 loc) 119 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@knora/api'), require('moment'), require('json2typescript'), require('rxjs'), require('@angular/common/http'), require('rxjs/internal/observable/throwError'), require('rxjs/operators')) : typeof define === 'function' && define.amd ? define('@knora/core', ['exports', '@angular/core', '@knora/api', 'moment', 'json2typescript', 'rxjs', '@angular/common/http', 'rxjs/internal/observable/throwError', 'rxjs/operators'], factory) : (global = global || self, factory((global.knora = global.knora || {}, global.knora.core = {}), global.ng.core, global.api, global.momentImported, global.json2typescript, global.rxjs, global.ng.common.http, global.rxjs['internal/observable/throwError'], global.rxjs.operators)); }(this, (function (exports, core, api, momentImported, json2typescript, rxjs, http, throwError, operators) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __exportStar(m, exports) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } function __values(o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result.default = mod; return result; } function __importDefault(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } // config for knora-api-js-lib (@knora/api) var KnoraApiConfigToken = new core.InjectionToken('Knora api configuration'); // connection config for knora-api-js-lib (@knora/api) var KnoraApiConnectionToken = new core.InjectionToken('Knora api connection configuration'); // config for knora-ui (@knora/action, @knora/search, @knora/viewer) var KuiConfigToken = new core.InjectionToken('Main configuration for knora-ui modules'); var KuiCoreModule = /** @class */ (function () { function KuiCoreModule() { } KuiCoreModule_1 = KuiCoreModule; KuiCoreModule.forRoot = function (kuiConfig) { // get the app environment configuration here // console.log('KuiCoreModule - forRoot - config: ', config); return { ngModule: KuiCoreModule_1, providers: [ { provide: KuiConfigToken, useValue: kuiConfig } ] }; }; var KuiCoreModule_1; KuiCoreModule = KuiCoreModule_1 = __decorate([ core.NgModule({ imports: [], declarations: [], exports: [] }) ], KuiCoreModule); return KuiCoreModule; }()); var KuiConfig = /** @class */ (function () { function KuiConfig(knora, app) { this.knora = knora; this.app = app; } return KuiConfig; }()); var moment = momentImported; var SessionService = /** @class */ (function () { function SessionService(knoraApiConnection, knoraApiConfig) { this.knoraApiConnection = knoraApiConnection; this.knoraApiConfig = knoraApiConfig; /** * max session time in milliseconds * default value (24h): 86400000 * */ this.MAX_SESSION_TIME = 86400000; // 1d = 24 * 60 * 60 * 1000 } /** * set the session by using the json web token (jwt) and the user object; * it will be used in the login process * * @param jwt * @param username */ SessionService.prototype.setSession = function (jwt, identifier, identifierType) { var _this = this; var session; this.updateKnoraApiConnection(jwt); // get user information this.knoraApiConnection.admin.usersEndpoint.getUser(identifierType, identifier).subscribe(function (response) { var e_1, _a; var sysAdmin = false; var projectAdmin = []; // get permission inforamation: a) is user sysadmin? b) get list of project iris where user is project admin var groupsPerProjectKeys = Object.keys(response.body.user.permissions.groupsPerProject); try { for (var groupsPerProjectKeys_1 = __values(groupsPerProjectKeys), groupsPerProjectKeys_1_1 = groupsPerProjectKeys_1.next(); !groupsPerProjectKeys_1_1.done; groupsPerProjectKeys_1_1 = groupsPerProjectKeys_1.next()) { var key = groupsPerProjectKeys_1_1.value; if (key === api.Constants.SystemProjectIRI) { sysAdmin = response.body.user.permissions.groupsPerProject[key].indexOf(api.Constants.SystemAdminGroupIRI) > -1; } if (response.body.user.permissions.groupsPerProject[key].indexOf(api.Constants.ProjectAdminGroupIRI) > -1) { projectAdmin.push(key); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (groupsPerProjectKeys_1_1 && !groupsPerProjectKeys_1_1.done && (_a = groupsPerProjectKeys_1.return)) _a.call(groupsPerProjectKeys_1); } finally { if (e_1) throw e_1.error; } } // store session information in browser's localstorage session = { id: _this.setTimestamp(), user: { name: response.body.user.username, jwt: jwt, lang: response.body.user.lang, sysAdmin: sysAdmin, projectAdmin: projectAdmin } }; // update localStorage localStorage.setItem('session', JSON.stringify(session)); }, function (error) { localStorage.removeItem('session'); console.error(error); }); }; /** * Validate intern session and check knora api credentials if necessary. * If a json web token exists, it doesn't mean, that the knora api credentials are still valid. * * @returns boolean */ SessionService.prototype.validateSession = function () { var _this = this; // mix of checks with session.validation and this.authenticate var session = JSON.parse(localStorage.getItem('session')); var tsNow = this.setTimestamp(); if (session) { this.updateKnoraApiConnection(session.user.jwt); // check if the session is still valid: if (session.id + this.MAX_SESSION_TIME <= tsNow) { // the internal (knora-ui) session has expired // check if the api credentails are still valid // console.error('session is not valid; check knora api credentials'); this.knoraApiConnection.v2.auth.checkCredentials().subscribe(function (response) { // the knora api credentials are still valid // console.log('knora api credentials', response); // refresh the jwt in @knora/api _this.updateKnoraApiConnection(session.user.jwt); // update the session.id session.id = tsNow; localStorage.setItem('session', JSON.stringify(session)); // console.log('knora api credentials are valid; return', true); return true; }, function (error) { // a user is not authenticated anymore! // console.error('session.service -- validateSession -- authenticate: the session expired on API side'); _this.destroySession(); // console.warn('knora api credentials are not valid; return', false); return false; }); } else { // the internal (knora-ui) session is still valid // console.log('session is valid; return', true); return true; } } else { // no session found; update knora api connection with empty jwt this.updateKnoraApiConnection(); // console.warn('session is not valid; return', false); return false; } }; /** * update the session storage * @param jwt * @param username * * @returns boolean */ SessionService.prototype.updateSession = function (jwt, username) { if (jwt && username) { this.setSession(jwt, username, 'username'); return true; } else { return false; } }; /** * Destroy session by removing the session from local storage * */ SessionService.prototype.destroySession = function () { localStorage.removeItem('session'); }; /** * Update the knora-api-config and knora-api-connection of @knora/api * * @param {string} jwt? */ SessionService.prototype.updateKnoraApiConnection = function (jwt) { this.knoraApiConfig.jsonWebToken = (jwt ? jwt : ''); this.knoraApiConnection = new api.KnoraApiConnection(this.knoraApiConfig); }; /** * Convert a timestamp in a number * @returns number */ SessionService.prototype.setTimestamp = function () { return (moment().add(0, 'second')).valueOf(); }; SessionService.ctorParameters = function () { return [ { type: api.KnoraApiConnection, decorators: [{ type: core.Inject, args: [KnoraApiConnectionToken,] }] }, { type: api.KnoraApiConfig, decorators: [{ type: core.Inject, args: [KnoraApiConfigToken,] }] } ]; }; SessionService.ngInjectableDef = core.ɵɵdefineInjectable({ factory: function SessionService_Factory() { return new SessionService(core.ɵɵinject(KnoraApiConnectionToken), core.ɵɵinject(KnoraApiConfigToken)); }, token: SessionService, providedIn: "root" }); SessionService = __decorate([ core.Injectable({ providedIn: 'root' }), __param(0, core.Inject(KnoraApiConnectionToken)), __param(1, core.Inject(KnoraApiConfigToken)), __metadata("design:paramtypes", [api.KnoraApiConnection, api.KnoraApiConfig]) ], SessionService); return SessionService; }()); /** * @deprecated Use ApiResponseData from `@knora/api` (github:dasch-swiss/knora-api-js-lib) instead * Result class used as API url response in ApiService */ var ApiServiceResult = /** @class */ (function () { function ApiServiceResult() { /** * Status number */ this.status = 0; /** * Status text */ this.statusText = ''; /** * API url */ this.url = ''; } /** * Gets the result body as instance of classObject. * @param classObject * @returns {any} * @throws */ ApiServiceResult.prototype.getBody = function (classObject) { // console.log(this.body); return ApiServiceResult.jsonConvert.deserialize(this.body, classObject); }; ApiServiceResult.jsonConvert = new json2typescript.JsonConvert(json2typescript.OperationMode.ENABLE, json2typescript.ValueCheckingMode.ALLOW_NULL); return ApiServiceResult; }()); /** * @deprecated Use ApiResponseError from `@knora/api` (github:dasch-swiss/knora-api-js-lib) instead * * Error class used as API response in ApiService */ var ApiServiceError = /** @class */ (function () { function ApiServiceError() { /** * Status number */ this.status = 0; /** * Status text */ this.statusText = ''; /** * API url */ this.url = ''; /** * Additional error info */ this.errorInfo = ''; } return ApiServiceError; }()); var KnoraConstants = /** @class */ (function () { function KnoraConstants() { } // The following version of Knora is needed to work properly with this module KnoraConstants.KnoraVersion = '12.0.0'; KnoraConstants.KnoraApi = 'http://api.knora.org/ontology/knora-api'; KnoraConstants.PathSeparator = '#'; // Simple KnoraConstants.KnoraApiV2SimplePath = KnoraConstants.KnoraApi + '/simple/v2' + KnoraConstants.PathSeparator; KnoraConstants.resourceSimple = KnoraConstants.KnoraApiV2SimplePath + 'Resource'; KnoraConstants.dateSimple = KnoraConstants.KnoraApiV2SimplePath + 'Date'; KnoraConstants.intervalSimple = KnoraConstants.KnoraApiV2SimplePath + 'Interval'; KnoraConstants.geomSimple = KnoraConstants.KnoraApiV2SimplePath + 'Geom'; KnoraConstants.colorSimple = KnoraConstants.KnoraApiV2SimplePath + 'Color'; KnoraConstants.geonameSimple = KnoraConstants.KnoraApiV2SimplePath + 'Geoname'; KnoraConstants.fileSimple = KnoraConstants.KnoraApiV2SimplePath + 'File'; KnoraConstants.listNodeSimple = KnoraConstants.KnoraApiV2SimplePath + 'ListNode'; // comparison operators --> TODO: should be moved to search-module!? KnoraConstants.EqualsComparisonOperator = '='; KnoraConstants.EqualsComparisonLabel = 'is equal to'; KnoraConstants.NotEqualsComparisonOperator = '!='; KnoraConstants.NotEqualsComparisonLabel = 'is not equal to'; KnoraConstants.GreaterThanComparisonOperator = '>'; KnoraConstants.GreaterThanComparisonLabel = 'is greater than'; KnoraConstants.GreaterThanEqualsComparisonOperator = '>='; KnoraConstants.GreaterThanEqualsComparisonLabel = 'is greater than equals to'; KnoraConstants.LessThanComparisonOperator = '<'; KnoraConstants.LessThanComparisonLabel = 'is less than'; KnoraConstants.LessThanEqualsComparisonOperator = '<='; KnoraConstants.LessThanQualsComparisonLabel = 'is less than equals to'; KnoraConstants.ExistsComparisonOperator = 'E'; KnoraConstants.ExistsComparisonLabel = 'exists'; KnoraConstants.LikeComparisonOperator = 'regex'; KnoraConstants.LikeComparisonLabel = 'is like'; KnoraConstants.MatchComparisonOperator = 'contains'; KnoraConstants.MatchComparisonLabel = 'matches'; KnoraConstants.MatchFunction = KnoraConstants.KnoraApi + '/v2' + KnoraConstants.PathSeparator + 'match'; return KnoraConstants; }()); // Knora Schema (function (KnoraSchema) { KnoraSchema[KnoraSchema["complex"] = 0] = "complex"; KnoraSchema[KnoraSchema["simple"] = 1] = "simple"; })(exports.KnoraSchema || (exports.KnoraSchema = {})); /** * @deprecated since v10.0.0 * * Will be replaced by `@knora/api` (github:knora-api-js-lib) * * Represents the parameters of an extended search. */ var ExtendedSearchParams = /** @class */ (function () { /** * * @param generateGravsearch a function that generates a Gravsearch query. * * The function takes the offset * as a parameter and returns a Gravsearch query string. * Returns false if not set correctly (init state). */ function ExtendedSearchParams(generateGravsearch) { this.generateGravsearch = generateGravsearch; } return ExtendedSearchParams; }()); var SearchParamsService = /** @class */ (function () { function SearchParamsService() { // init with a dummy function that returns false // if the application is reloaded, this will be returned this._currentSearchParams = new rxjs.BehaviorSubject(new ExtendedSearchParams(function (offset) { return false; })); } /** * Updates the parameters of an extended search. * * @param {ExtendedSearchParams} searchParams * @returns void */ SearchParamsService.prototype.changeSearchParamsMsg = function (searchParams) { this._currentSearchParams.next(searchParams); }; /** * Gets the search params of an extended search. * * @returns ExtendedSearchParams - search parameters */ SearchParamsService.prototype.getSearchParams = function () { return this._currentSearchParams.getValue(); }; SearchParamsService.ngInjectableDef = core.ɵɵdefineInjectable({ factory: function SearchParamsService_Factory() { return new SearchParamsService(); }, token: SearchParamsService, providedIn: "root" }); SearchParamsService = __decorate([ core.Injectable({ providedIn: 'root' }) /** * @deprecated since v10.0.0 * * Will be replaced by `@knora/api` (github:knora-api-js-lib) * Temporarily stores the parameters of an extended search. */ , __metadata("design:paramtypes", []) ], SearchParamsService); return SearchParamsService; }()); /** * @deprecated Use new service from `@knora/api` (github:dasch-swiss/knora-api-js-lib) instead * * Create GravSearch queries from provided parameters. */ var GravsearchGenerationService = /** @class */ (function () { function GravsearchGenerationService(_searchParamsService) { this._searchParamsService = _searchParamsService; } GravsearchGenerationService_1 = GravsearchGenerationService; /** * @deprecated since v10.0.0 * * Will be replaced by `@knora/api` (github:knora-api-js-lib) * * Generates a Gravsearch query from the provided arguments. * * @param {PropertyWithValue[]} properties the properties specified by the user. * @param {string} [mainResourceClassOption] the class of the main resource, if specified. * @param {number} offset the offset to be used (nth page of results). * @returns string - a KnarQL query string. */ GravsearchGenerationService.prototype.createGravsearchQuery = function (properties, mainResourceClassOption, offset) { if (offset === void 0) { offset = 0; } // class restriction for the resource searched for var mainResourceClass = ''; // if given, create the class restriction for the main resource if (mainResourceClassOption !== undefined) { mainResourceClass = "?mainRes a <" + mainResourceClassOption + "> ."; } // criteria for the order by statement var orderByCriteria = []; // statements to be returned in query results var returnStatements = []; // loop over given properties and create statements and filters from them var props = properties.map(function (propWithVal, index) { // represents the object of a statement var propValue; if (!propWithVal.property.isLinkProperty || propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Exists') { // it is not a linking property, create a variable for the value (to be used by a subsequent FILTER) // OR the comparison operator Exists is used in which case we do not need to specify the object any further propValue = "?propVal" + index; } else { // it is a linking property and the comparison operator is not Exists, use its IRI propValue = propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex); } // generate statement var statement = "?mainRes <" + propWithVal.property.id + "> " + propValue + " ."; // check if it is a linking property that has to be wrapped in a FILTER NOT EXISTS (comparison operator NOT_EQUALS) to negate it if (propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') { // do not include statement in results, because the query checks for the absence of this statement statement = "FILTER NOT EXISTS {\n" + statement + "\n\n\n}"; } else { // TODO: check if statement should be returned returned in results (Boolean flag from checkbox) returnStatements.push(statement); statement = "\n" + statement + "\n\n\n"; } // generate restricting expression (e.g., a FILTER) if comparison operator is not Exists var restriction = ''; // only create a FILTER if the comparison operator is not EXISTS and it is not a linking property if (!propWithVal.property.isLinkProperty && propWithVal.valueLiteral.comparisonOperator.getClassName() !== 'Exists') { // generate variable for value literal var propValueLiteral = propValue + "Literal"; if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Like') { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // use regex function for LIKE restriction += "FILTER regex(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex) + ", \"i\")"; } else if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'Match') { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // use contains function for MATCH restriction += "FILTER <" + KnoraConstants.MatchFunction + ">(" + propValueLiteral + ", " + propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex) + ")"; } else if (propWithVal.property.objectType === api.Constants.DateValue) { // handle date property restriction = "FILTER(knora-api:toSimpleDate(" + propValue + ") " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex) + ")"; } else if (propWithVal.property.objectType === api.Constants.ListValue) { // handle list node restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex) + '\n'; // check for comparison operator "not equals" if (propWithVal.valueLiteral.comparisonOperator.getClassName() === 'NotEquals') { restriction = "FILTER NOT EXISTS {\n " + restriction + "\n }"; } } else { // generate statement to value literal restriction = propValue + " <" + GravsearchGenerationService_1.complexTypeToProp[propWithVal.property.objectType] + "> " + propValueLiteral + '\n'; // generate filter expression restriction += "FILTER(" + propValueLiteral + " " + propWithVal.valueLiteral.comparisonOperator.type + " " + propWithVal.valueLiteral.value.toSparql(exports.KnoraSchema.complex) + ")"; } } // check if current value is a sort criterion if (propWithVal.isSortCriterion) orderByCriteria.push(propValue); return statement + "\n" + restriction + "\n"; }); var orderByStatement = ''; if (orderByCriteria.length > 0) { orderByStatement = "\nORDER BY " + orderByCriteria.join(' ') + "\n"; } // template of the Gravsearch query with dynamic components var gravsearchTemplate = "\nPREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>\nCONSTRUCT {\n\n?mainRes knora-api:isMainResource true .\n\n" + returnStatements.join('\n') + "\n\n} WHERE {\n\n?mainRes a knora-api:Resource .\n\n" + mainResourceClass + "\n\n" + props.join('') + "\n\n}\n" + orderByStatement; // offset component of the Gravsearch query var offsetTemplate = "\nOFFSET " + offset + "\n"; // function that generates the same KnarQL query with the given offset var generateGravsearchQueryWithCustomOffset = function (localOffset) { var offsetCustomTemplate = "\nOFFSET " + localOffset + "\n"; return gravsearchTemplate + offsetCustomTemplate; }; if (offset === 0) { // store the function so another KnarQL query can be created with an increased offset this._searchParamsService.changeSearchParamsMsg(new ExtendedSearchParams(generateGravsearchQueryWithCustomOffset)); } return gravsearchTemplate + offsetTemplate; }; var GravsearchGenerationService_1; /** * @ignore * * Map of complex knora-api value types to simple ones. * Use computed property name: http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer. */ GravsearchGenerationService.typeConversionComplexToSimple = { 'http://api.knora.org/ontology/knora-api/v2#IntValue': api.Constants.XsdInteger, 'http://api.knora.org/ontology/knora-api/v2#DecimalValue': api.Constants.XsdDecimal, 'http://api.knora.org/ontology/knora-api/v2#BooleanValue': api.Constants.XsdBoolean, 'http://api.knora.org/ontology/knora-api/v2#TextValue': api.Constants.XsdString, 'http://api.knora.org/ontology/knora-api/v2#UriValue': api.Constants.XsdAnyUri, 'http://api.knora.org/ontology/knora-api/v2#DateValue': KnoraConstants.dateSimple, 'http://api.knora.org/ontology/knora-api/v2#IntervalValue': KnoraConstants.intervalSimple, 'http://api.knora.org/ontology/knora-api/v2#GeomValue': KnoraConstants.geomSimple, 'http://api.knora.org/ontology/knora-api/v2#ColorValue': KnoraConstants.colorSimple, 'http://api.knora.org/ontology/knora-api/v2#GeonameValue': KnoraConstants.geonameSimple, 'http://api.knora.org/ontology/knora-api/v2#StillImageFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#FileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#MovingImageFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#DDDFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#AudioFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#DocumentFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#TextFileValue': KnoraConstants.fileSimple, 'http://api.knora.org/ontology/knora-api/v2#ListValue': KnoraConstants.listNodeSimple }; GravsearchGenerationService.complexTypeToProp = { 'http://api.knora.org/ontology/knora-api/v2#IntValue': api.Constants.IntValueAsInt, 'http://api.knora.org/ontology/knora-api/v2#DecimalValue': api.Constants.DecimalValueAsDecimal, 'http://api.knora.org/ontology/knora-api/v2#BooleanValue': api.Constants.BooleanValueAsBoolean, 'http://api.knora.org/ontology/knora-api/v2#TextValue': api.Constants.ValueAsString, 'http://api.knora.org/ontology/knora-api/v2#UriValue': api.Constants.UriValueAsUri, 'http://api.knora.org/ontology/knora-api/v2#ListValue': api.Constants.ListValueAsListNode }; GravsearchGenerationService.ctorParameters = function () { return [ { type: SearchParamsService } ]; }; GravsearchGenerationService.ngInjectableDef = core.ɵɵdefineInjectable({ factory: function GravsearchGenerationService_Factory() { return new GravsearchGenerationService(core.ɵɵinject(SearchParamsService)); }, token: GravsearchGenerationService, providedIn: "root" }); GravsearchGenerationService = GravsearchGenerationService_1 = __decorate([ core.Injectable({ providedIn: 'root' }), __metadata("design:paramtypes", [SearchParamsService]) ], GravsearchGenerationService); return GravsearchGenerationService; }()); var Equals = /** @class */ (function () { function Equals() { this.type = KnoraConstants.EqualsComparisonOperator; this.label = KnoraConstants.EqualsComparisonLabel; } Equals.prototype.getClassName = function () { return 'Equals'; }; return Equals; }()); var NotEquals = /** @class */ (function () { function NotEquals() { this.type = KnoraConstants.NotEqualsComparisonOperator; this.label = KnoraConstants.NotEqualsComparisonLabel; } NotEquals.prototype.getClassName = function () { return 'NotEquals'; }; return NotEquals; }()); var GreaterThanEquals = /** @class */ (function () { function GreaterThanEquals() { this.type = KnoraConstants.GreaterThanEqualsComparisonOperator; this.label = KnoraConstants.GreaterThanEqualsComparisonLabel; } GreaterThanEquals.prototype.getClassName = function () { return 'GreaterThanEquals'; }; return GreaterThanEquals; }()); var GreaterThan = /** @class */ (function () { function GreaterThan() { this.type = KnoraConstants.GreaterThanComparisonOperator; this.label = KnoraConstants.GreaterThanComparisonLabel; } GreaterThan.prototype.getClassName = function () { return 'GreaterThan'; }; return GreaterThan; }()); var LessThan = /** @class */ (function () { function LessThan() { this.type = KnoraConstants.LessThanComparisonOperator; this.label = KnoraConstants.LessThanComparisonLabel; } LessThan.prototype.getClassName = function () { return 'LessThan'; }; return LessThan; }()); var LessThanEquals = /** @class */ (function () { function LessThanEquals() { this.type = KnoraConstants.LessThanEqualsComparisonOperator; this.label = KnoraConstants.LessThanQualsComparisonLabel; } LessThanEquals.prototype.getClassName = function () { return 'LessThanEquals'; }; return LessThanEquals; }()); var Exists = /** @class */ (function () { function Exists() { this.type = KnoraConstants.ExistsComparisonOperator; this.label = KnoraConstants.ExistsComparisonLabel; } Exists.prototype.getClassName = function () { return 'Exists'; }; return Exists; }()); var Like = /** @class */ (function () { function Like() { this.type = KnoraConstants.LikeComparisonOperator; this.label = KnoraConstants.LikeComparisonLabel; } Like.prototype.getClassName = function () { return 'Like'; }; return Like; }()); var Match = /** @class */ (function () { function Match() { this.type = KnoraConstants.MatchComparisonOperator; this.label = KnoraConstants.MatchComparisonLabel; } Match.prototype.getClassName = function () { return 'Match'; }; return Match; }()); /** * Combination of a comparison operator and a value literal or an IRI. * In case the comparison operator is 'Exists', no value is given. */ var ComparisonOperatorAndValue = /** @class */ (function () { function ComparisonOperatorAndValue(comparisonOperator, value) { this.comparisonOperator = comparisonOperator; this.value = value; } return ComparisonOperatorAndValue; }()); /** * Represents a property's value as a literal with the indication of its type. */ var ValueLiteral = /** @class */ (function () { /** * Constructs a [ValueLiteral]. * * @param {string} value the literal representation of the value. * @param {string} type the type of the value (making use of xsd). */ function ValueLiteral(value, type) { this.value = value; this.type = type; } /** * Creates a type annotated value literal to be used in a SPARQL query. * * @param schema indicates the Knora schema to be used. * @returns {string} */ ValueLiteral.prototype.toSparql = function (schema) { var literalType; // check if a Knora schema conversion is necessary, e.g., knora-api:dateValue (complex) to knora-api:date (simple). // xsd types will remain unchanged if (schema === exports.KnoraSchema.simple && GravsearchGenerationService.typeConversionComplexToSimple[this.type] !== undefined) { // convert to simple schema literalType = GravsearchGenerationService.typeConversionComplexToSimple[this.type]; } else { // do not convert literalType = this.type; } return "\"" + this.value + "\"^^<" + literalType + ">"; }; return ValueLiteral; }()); /** * Represents an IRI. */ var IRI = /** @class */ (function () { /** * Constructs an [IRI]. * * @param {string} iri the IRI of a resource instance. */ function IRI(iri) { this.iri = iri; } /** * Creates a SPARQL representation of the IRI. * * @param schema indicates the Knora schema to be used. * @returns {string} */ IRI.prototype.toSparql = function (schema) { // this is an instance Iri and does not have to be converted. return "<" + this.iri + ">"; }; return IRI; }()); /** * Represents a property, the specified comparison operator, and value. */ var PropertyWithValue = /** @class */ (function () { /** * Constructs a [PropertyWithValue]. * * @param {Property} property the specified property. * @param {ComparisonOperatorAndValue} valueLiteral the specified comparison operator and value. * @param isSortCriterion indicates if the property is used as a sort criterion. */ function PropertyWithValue(property, valueLiteral, isSortCriterion) { this.property = property; this.valueLiteral = valueLiteral; this.isSortCriterion = isSortCriterion; } return PropertyWithValue; }()); /** * Collection of useful utility functions. */ // @dynamic var Utils = /** @class */ (function () { function Utils() { } /** * Given a Knora entity IRI, gets the ontology Iri. * * @param {string} entityIri an entity Iri. * @return {string} the ontology IRI */ Utils.getOntologyIriFromEntityIri = function (entityIri) { // split class Iri on "#" var segments = entityIri.split(KnoraConstants.PathSeparator); if (segments.length !== 2) console.error("Error: " + entityIri + " is not a valid entity IRI."); return segments[0]; }; /** * Converts a complex knora-api entity Iri to a knora-api simple entity Iri. * * @param {string} complexEntityIri * @returns {string} */ Utils.convertComplexKnoraApiEntityIritoSimple = function (complexEntityIri) { // split entity Iri on "#" var segments = complexEntityIri.split('v2' + KnoraConstants.PathSeparator); if (segments.length !== 2) console.error("Error: " + complexEntityIri + " is not a valid entity IRI."); // add 'simple' to base path return segments[0] + 'simple/v2' + KnoraConstants.PathSeparator + segments[1]; }; /** * A regex to validate Email address. * * @type {RegExp} */ Utils.RegexEmail = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; /** * A regex to validate Username. * * @type {RegExp} */ Utils.RegexUsername = /^[a-zA-Z0-9]+$/; /** * A regex to validate URLs. * * @type {RegExp} */ Utils.RegexUrl = /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$/i; /** * A regex to validate Passwords * * @type {RegExp} */ Utils.RegexPassword = /^(?=.*\d)(?=.*[a-zA-Z]).{8,}$/i; /** * A regex to validate Hexadecimal values * * @type {RegExp} */ Utils.RegexHex = /^[0-9A-Fa-f]+$/; /** * A regex to validate shortname in projects * * @type {RegExp} */ Utils.RegexShortname = /^[a-zA-Z]+\S*$/; /** * Lambda function eliminating duplicates in a collection to be passed to [[filter]]. * * @param elem element of an Array that is currently being looked at. * @param index current elements index. * @param self reference to the whole Array. * @returns {boolean} true if the same element does not already exist in the Array. */ Utils.filterOutDuplicates = function (elem, index, self) { // https://stackoverflow.com/questions/16747798/delete-duplicate-elements-from-an-array // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter?v=example // returns true if the element's index equals the index of the leftmost element // -> this means that there is no identical element before this index, hence it is not a duplicate // for all other elements, false is returned return index === self.indexOf(elem); }; return Utils; }()); /** * Represents a region. * Contains a reference to the resource representing the region and its geometries.