/*globals define*/
/*eslint-env node, browser*/
/**
* This class defines the public API of the WebGME-Core
*
* @author kecso / https://github.com/kecso
* @module Core
*/
/**
* @typedef {object} Node - the object that represents the atomic element of the containment hierarchy.
*/
/**
* @typedef {object} DataObject - Inner data of {@link module:Core~Node} that can be serialized
* and saved in the storage.
*/
/**
* @typedef {object} GmePersisted - the result object of a persist which contains information about the newly
* created data objects.
* @prop {module:Core~ObjectHash} rootHash - Hash of the root node.
* @prop {object.<module:Core~ObjectHash, module:Core~DataObject>} objects - Hash of the root node.
*/
/**
* @typedef {string} ObjectHash - Unique SHA-1 hash for the node object.
* @example
* '#5496cf226542fcceccf89056f0d27564abc88c99'
*/
/**
* @typedef {string} GUID - Globally unique identifier. A formatted string containing hexadecimal characters. If some
* projects share some GUIDs that can only be because the node with the given identification represents the same
* concept.
* @example
* 'cd891e7b-e2ea-e929-f6cd-9faf4f1fc045'
*/
/**
* @typedef {object} Constraint - An object that represents some additional rule regarding some node of the project.
* @prop {string} script - The script which checks if the constraint is met.
* @prop {string} info - Short description of the constraint.
* @prop {string} priority - Gives instructions on how to deal with violations of the constraint.
*/
/**
* @typedef {object} DefinitionInfo - Contains the owner and the target of the meta-rule that makes the
* relationship between the given node and related node a valid one. There can be multiple meta-rules that make
* the relationship valid, but this is the first one that answers the question isValidChildOf, isValidTargetOf etc.
* @prop {Core~Node} ownerNode - The meta-node where the meta-rule is stored.
* @prop {Core~Node} targetNode - The meta-node the meta-rule is targeting.
*/
/**
* @typedef {object} RelationRule - An object that represents a relational type rule-set (pointer/set).
* @prop {integer} [min] - The minimum amount of target necessary for the relationship (if not present or '-1'
* then there is no minimum rule that applies)
* @prop {integer} [max] - The minimum amount of target necessary for the relationship (if not present or '-1'
* then there is no minimum rule that applies)
* @prop {object} [absolutePathOfTarget] - special rules regarding the given type (if the object is empty, it still
* represents that the type is a valid target of the relationship)
* @prop {integer} [absolutePathOfTarget.min] - The minimum amount of target necessary for the relationship
* from the given type (if not present or '-1' then there is no minimum rule that applies)
* @prop {integer} [absolutePathOfTarget.max] - The minimum amount of target necessary for the relationship
* from the given type (if not present or '-1' then there is no minimum rule that applies)
* @example
* '{
* 'min': 1,
* 'max': -1,
* 'any/path/of/node':{
* 'min':-1,
* 'max':2
* },
* 'any/other/valid/path':{
* }
* }'
*/
/**
* @typedef {object} MixinViolation - An object that has information about a mixin violation in the given node.
* @prop {string} [severity] - The severity of the given error ('error','warning').
* @prop {string} [type] - 'missing', 'attribute collision', 'set collision',
* 'pointer collision', 'containment collision', 'aspect collision', 'constraint collision'
* @prop {string|undefined} [ruleName] - The name of the affected rule definition (if available).
* @prop {string|undefined} [targetInfo] - The path of the target of the violation (if available).
* @prop {module:Core~Node|undefined} [targetNode] - The target node of the violation (if available).
* @prop {string[]} [collisionPaths] - The list of paths of colliding nodes (if any).
* @prop {module:Core~Node[]} [collisionNodes] - The colliding mixin nodes (if any).
* @prop {string} [message] - The description of the violation.
* @prop {string} [hint] - Hint on how to resolve the issue.
* @example
* '{
* 'severity': 'error',
* 'type': 'missing',
* 'targetInfo': '/E/b',
* 'message': '[MyObject]: mixin node "E/b" is missing from the Meta',
* 'hint': 'Remove mixin or add to the Meta'
* }'
* @example
* '{
* 'severity': 'warning',
* 'type': 'attribute collision',
* 'ruleName': 'value',
* 'collisionPaths': ['/E/a','/E/Z'],
* 'collisionNodes': [Object,Object],
* 'message':'[MyObject]: inherits attribute definition "value" from [TypeA] and [TypeB]',
* 'hint': 'Remove one of the mixin relations'
* }'
*/
define([
'common/core/corerel',
'common/core/setcore',
'common/core/guidcore',
'common/core/nullpointercore',
'common/core/coreunwrap',
'common/core/coretype',
'common/core/constraintcore',
'common/core/coretree',
'common/core/metacore',
'common/core/coretreeloader',
'common/core/corediff',
'common/core/metacachecore',
'common/core/mixincore',
'common/core/metaquerycore',
'common/regexp',
'common/core/librarycore',
'common/core/CoreIllegalArgumentError',
'common/core/CoreIllegalOperationError',
'common/core/constants'
], function (CoreRel,
Set,
Guid,
NullPtr,
UnWrap,
Type,
Constraint,
CoreTree,
MetaCore,
TreeLoader,
CoreDiff,
MetaCacheCore,
MixinCore,
MetaQueryCore,
REGEXP,
LibraryCore,
CoreIllegalArgumentError,
CoreIllegalOperationError,
CONSTANTS) {
'use strict';
var isValidNode,
isValidPath;
function ensureType(input, nameOfInput, type, isAsync) {
var error;
if (typeof input !== type) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not of type ' + type + '.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureValue(input, nameOfInput, isAsync) {
var error;
if (input === undefined) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' cannot be undefined.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureInstanceOf(input, nameOfInput, type, isAsync) {
var error;
if (input instanceof type === false) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not of type ' + type + '.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensurePath(input, nameOfInput, isAsync) {
var error;
if (isValidPath(input) === false) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not a valid path.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureNode(input, nameOfInput, isAsync) {
var error;
if (isValidNode(input) === false) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not a valid node.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureHash(input, nameOfInput, isAsync) {
var error;
if (REGEXP.DB_HASH.test(input) === false) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not a valid hash.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureGuid(input, nameOfInput, isAsync) {
var error;
if (REGEXP.GUID.test(input) === false) {
error = new CoreIllegalArgumentError('Parameter \'' + nameOfInput + '\' is not a valid GUID.');
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureMinMax(input, nameOfInput, isAsync) {
var error;
if (input === null || input === undefined) {
return;
}
if (typeof input === 'number' && Number.isSafeInteger(input) && input >= -1) {
return;
}
error = new CoreIllegalArgumentError('Parameter ' + nameOfInput + ' is not a safe integer from [-1,∞).');
if (error) {
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureRelationName(input, nameOfInput, isAsync) {
var error,
reserved = [
CONSTANTS.BASE_POINTER,
CONSTANTS.OVERLAYS_PROPERTY,
CONSTANTS.MEMBER_RELATION
];
if (typeof input !== 'string') {
error = new CoreIllegalArgumentError('Parameter ' + nameOfInput + ' is not of type string.');
} else {
if (input.indexOf('_') === 0 ||
reserved.indexOf(input) !== -1) {
error = new CoreIllegalArgumentError('Parameter ' + nameOfInput + ' cannot start with \'_\'' +
', or be equal with any of the reserved ' + reserved + ' words.');
}
}
if (error) {
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function ensureMongoCompatibleKey(input, nameOfInput, hiddenIsFine, isAsync) {
var error = null,
realInput = input;
if (hiddenIsFine === true && input[0] === '_') {
realInput = input.substr(1);
}
if (REGEXP.DOCUMENT_KEY.test(realInput) === false) {
error = new CoreIllegalArgumentError('Parameter ' + nameOfInput +
' is not a valid key (cannot contain "." or "$"' +
(hiddenIsFine ? '' : ', or start with "_"') + ').');
}
if (error) {
if (isAsync) {
return error;
} else {
throw error;
}
}
}
function getCommonAncestor(node1, node2, getter) {
function getChain(node) {
var ancestors = [];
while (node) {
ancestors.push(node);
node = getter(node);
}
return ancestors;
}
var ancestors2 = getChain(node2),
i;
while (node1) {
for (i = 0; i < ancestors2.length; i += 1) {
if (node1 === ancestors2[i]) {
return node1;
}
}
node1 = getter(node1);
}
return null;
}
/**
* @param {ProjectInterface} project - project connected to storage
* @param {object} options - contains logging information
* @param {object} options.logger - gmeLogger
* @param {object} options.globConf - gmeConfig
* @alias Core
* @description The Core defines the main API for model manipulation and traversal. It is important to note, that
* all 'Path' function must be used with caution as the returned information is just an estimate and does not
* guarantee that the actual node will exist (as in certain scenarios they might become invalid and need to
* be removed, but said removal can only take place during their load). Try to always 'Load' every
* node before depending on their paths.
* @constructor
*/
function Core(project, options) {
var core,
coreLayers = [];
coreLayers.push(CoreRel);
coreLayers.push(NullPtr);
coreLayers.push(Type);
coreLayers.push(NullPtr);
coreLayers.push(Set);
coreLayers.push(Guid);
coreLayers.push(Constraint);
coreLayers.push(MetaCore);
coreLayers.push(MetaCacheCore);
coreLayers.push(MixinCore);
coreLayers.push(MetaQueryCore);
coreLayers.push(CoreDiff);
coreLayers.push(TreeLoader);
coreLayers.push(LibraryCore);
// TODO check how we should handle the TASYNC error handling...
// if (options.usertype !== 'tasync') {
// coreLayers.push(UnWrap);
// }
coreLayers.push(UnWrap);
core = coreLayers.reduce(function (inner, Class) {
return new Class(inner, options);
}, new CoreTree(project, options));
isValidNode = core.isValidNode;
isValidPath = core.isValidPath;
/**
* Returns the parent of the node.
* @param {module:Core~Node} node - the node in question
*
* @return {module:Core~Node|null} Returns the parent of the node or NULL if it has no parent.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getParent = function (node) {
ensureNode(node, 'node');
return core.getParent(node);
};
/**
* Returns the common parent node of all supplied nodes. Note that if a node and its parent are passed,
* the method will return the parent of the parent.
* @param {...module:Core~Node} nodes - a variable number of nodes to compare
*
* @return {module:Core~Node|null} The common parent. Will be null whenever the root-node is passed in.
* @example
* core.getCommonParent(node1, node2, node3);
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getCommonParent = function () {
var nodesArr = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)),
result,
i;
nodesArr.forEach(function (node, idx) {
ensureNode(node, 'arguments[' + idx + ']');
});
result = nodesArr[0];
for (i = 1; i < nodesArr.length; i += 1) {
result = getCommonAncestor(result, nodesArr[i], core.getParent);
}
if (result && nodesArr.indexOf(result) > -1) {
result = core.getParent(result);
}
return result || null;
};
/**
* Returns the parent-relative identifier of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string|null} Returns the last segment of the node path.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getRelid = function (node) {
ensureNode(node, 'node');
return core.getRelid(node);
};
/**
* Returns the root node of the containment tree that node is part of.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~Node} Returns the root of the containment hierarchy (it can be the node itself).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getRoot = function (node) {
ensureNode(node, 'node');
return core.getRoot(node);
};
/**
* Returns the complete path of the node in the containment hierarchy.
* @param {module:Core~Node} node - the node in question.
*
* @return {string} Returns a path string where each portion is a relative id and they are separated by '/'.
* The path can be empty as well if the node in question is the root itself, otherwise it should be a chain
* of relative ids from the root of the containment hierarchy.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getPath = function (node) {
ensureNode(node, 'node');
return core.getPath(node);
};
/**
* Retrieves the child of the input node at the given relative id. It is not an asynchronous load
* and it automatically creates the child under the given relative id if no child was there beforehand.
* @param {module:Core~Node} node - the node in question.
* @param {string} relativeId - the relative id which our child in question has.
*
* @return {module:Core~Node} Return an empty node if it was created as a result of the function or
* return the already existing and loaded node if it found.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getChild = function (node, relativeId) {
ensureNode(node, 'node');
ensureType(relativeId, 'relativeId', 'string');
return core.getChild(node, relativeId);
};
/**
* Checks if the node in question has some actual data.
* @param {module:Core~Node} node - the node in question.
*
* @return {bool} Returns true if the node is 'empty' meaning that it is not reserved by real data.
* Returns false if the node is exists and have some meaningful value.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isEmpty = function (node) {
ensureNode(node, 'node');
return core.isEmpty(node);
};
/**
* Returns the calculated hash and database id of the data for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~ObjectHash} Returns the hash value of the data for the given node.
* An empty string is returned when the node was mutated and not persisted.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getHash = function (node) {
ensureNode(node, 'node');
return core.getHash(node);
};
/**
* Persists the changes made in memory and computed the data blobs that needs to be saved into the database
* to make the change and allow other users to see the new state of the project.
* @param {module:Core~Node} node - some node element of the modified containment hierarchy (usually the root).
*
* @return {module:Core~GmePersisted} The function returns an object which collects all the changes
* on data level and necessary to update the database on server side. Keys of the returned object are 'rootHash'
* and 'objects'. The values of these should be passed to project.makeCommit.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.persist = function (node) {
ensureNode(node, 'node');
return core.persist(node);
};
/**
* Loads the data object with the given hash and makes it a root of a containment hierarchy.
* @param {module:Core~ObjectHash} hash - the hash of the data object we like to load as root.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node} callback.node - the resulting root node
*
* @return {external:Promise} If no callback is given, the result will be provided in
* a promiselike manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadRoot = function (hash, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureHash(hash, 'hash', true);
if (error) {
callback(error);
} else {
core.loadRoot(hash, callback);
}
};
/**
* Loads the child of the given parent pointed by the relative id. Behind the scenes, it means
* that it actually loads the data pointed by a hash stored inside the parent under the given id
* and wraps it in a node object which will be connected to the parent as a child in the containment
* hierarchy. If there is no such relative id reserved, the call will return with null.
* @param {module:Core~Node} parent - the container node in question.
* @param {string} relativeId - the relative id of the child in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node} callback.node - the resulting child
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadChild = function (node, relativeId, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensureType(relativeId, 'relativeId', 'string', true);
if (error) {
callback(error);
} else {
core.loadChild(node, relativeId, callback);
}
};
/**
* From the given starting node, it loads the path given as a series of relative ids (separated by '/')
* and returns the node it finds at the ends of the path. If there is no node, the function will return null.
* @param {module:Core~Node} node - the starting node of our search.
* @param {string} relativePath - the relative path - built by relative ids - of the node in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node} callback.node - the resulting node
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadByPath = function (node, relativePath, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensurePath(relativePath, 'relativePath', true);
if (error) {
callback(error);
} else {
core.loadByPath(node, relativePath, callback);
}
};
/**
* Loads all the children of the given parent. As it first checks the already reserved relative ids of
* the parent, it only loads the already existing children (so no on-demand empty node creation).
* @param {module:Core~Node} node - the container node in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node[]} callback.children - the resulting children
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadChildren = function (node, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadChildren(node, callback);
}
};
/**
* Loads all the children of the given parent that has some data and not just inherited. As it first checks
* the already reserved relative ids of the parent, it only loads the already existing children
* (so no on-demand empty node creation).
* @param {module:Core~Node} node - the container node in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node[]} callback.node - the resulting children
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadOwnChildren = function (node, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadOwnChildren(node, callback);
}
};
/**
* Loads the target of the given pointer of the given node. In the callback the node can have three values:
* if the node is valid, then it is the defined target of a valid pointer,
* if the returned value is null, then it means that the pointer is defined, but has no real target,
* finally if the returned value is undefined than there is no such pointer defined for the given node.
* @param {module:Core~Node} node - the source node in question.
* @param {string} pointerName - the name of the pointer.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node} callback.node - the resulting target
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadPointer = function (node, pointerName, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensureType(pointerName, 'pointerName', 'string', true);
if (error) {
callback(error);
} else {
core.loadPointer(node, pointerName, callback);
}
};
/**
* Loads all the source nodes that has such a pointer and its target is the given node.
* @param {module:Core~Node} node - the target node in question.
* @param {string} pointerName - the name of the pointer of the sources.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node[]} callback.node - the resulting sources
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadCollection = function (node, pointerName, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensureType(pointerName, 'pointerName', 'string', true);
if (error) {
callback(error);
} else {
core.loadCollection(node, pointerName, callback);
}
};
/**
* Loads a complete sub-tree of the containment hierarchy starting from the given node.
* @param {module:Core~Node} node - the node that is the root of the sub-tree in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node[]} callback.nodes - the resulting sources
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadSubTree = function (node, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadSubTree(node, callback);
}
};
/**
* Loads a complete sub-tree of the containment hierarchy starting from the given node, but load only those
* children that has some additional data and not purely inherited.
* @param {module:Core~Node} node - the container node in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution
* @param {module:Core~Node[]} callback.nodes - the resulting sources
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadOwnSubTree = function (node, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadOwnSubTree(node, callback);
}
};
/**
* Loads a complete containment hierarchy using the data object - pointed by the given hash -
* as the root.
* @param {module:Core~ObjectHash} hash - hash of the root node.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution.
* @param {module:Core~Node[]} callback.nodes - the resulting nodes.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadTree = function (hash, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureHash(hash, 'hash', true);
if (error) {
callback(error);
} else {
core.loadTree(hash, callback);
}
};
/**
* Collects the relative ids of all the children of the given node.
* @param {module:Core~Node} node - the container node in question.
*
* @return {string[]} The function returns an array of the relative ids.
*/
this.getChildrenRelids = function (node) {
ensureNode(node, 'node');
return core.getChildrenRelids(node);
};
/**
* Collects the relative ids of all the children of the given node that has some data and not just inherited.
* N.B. Do not mutate the returned array!
* @param {module:Core~Node} node - the container node in question.
*
* @return {string[]} The function returns an array of the relative ids.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnChildrenRelids = function (node) {
ensureNode(node, 'node');
return core.getOwnChildrenRelids(node);
};
/**
* Collects the paths of all the children of the given node.
* @param {module:Core~Node} node - the container node in question.
*
*@return {string[]} The function returns an array of the absolute paths of the children.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getChildrenPaths = function (node) {
ensureNode(node, 'node');
return core.getChildrenPaths(node);
};
/**
* Collects the paths of all the children of the given node that has some data as well and not just inherited.
* @param {module:Core~Node} parent - the container node in question.
*
*@return {string[]} The function returns an array of the absolute paths of the children.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnChildrenPaths = function (node) {
ensureNode(node, 'node');
return core.getOwnChildrenPaths(node);
};
/**
* Creates a node according to the given parameters.
* @param {object} [parameters] - the details of the creation.
* @param {module:Core~Node|null} [parameters.parent] - the parent of the node to be created.
* @param {module:Core~Node|null} [parameters.base] - the base of the node to be created.
* @param {string} [parameters.relid] - the relative id of the node to be created (if reserved, the function
* returns the node behind the relative id)
* @param {module:Core~GUID} [parameters.guid] - the GUID of the node to be created
*
*
* @return {module:Core~Node} The function returns the created node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.createNode = function (parameters) {
if (parameters) {
ensureType(parameters, 'parameters', 'object');
if (Object.hasOwn(parameters, 'parent') &&
parameters.parent !== null && parameters.parent !== undefined) {
ensureNode(parameters.parent, 'parameters.parent');
}
if (Object.hasOwn(parameters, 'base') &&
parameters.base !== null && parameters.base !== undefined) {
ensureNode(parameters.base, 'parameters.base');
}
if (Object.hasOwn(parameters, 'guid') && parameters.guid !== undefined) {
ensureGuid(parameters.guid, 'parameters.guid');
}
}
return core.createNode(parameters);
};
/**
* Creates a child, with base as provided, inside the provided node.
* @param {module:Core~Node} node - the parent of the node to be created.
* @param {module:Core~Node} base - the base of the node to be created.
*
* @return {module:Core~Node} The function returns the created child node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.createChild = function (node, base) {
ensureNode(node, 'node');
ensureNode(base, 'base');
return core.createNode({parent: node, base: base});
};
/**
* Removes a node from the containment hierarchy.
* @param {module:Core~Node} node - the node to be removed.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.deleteNode = function (node) {
ensureNode(node, 'node');
if (core.getParent(node) === null) {
throw new CoreIllegalOperationError('Not allowed to delete node without a parent.');
}
return core.deleteNode(node, false);
};
/**
* Copies the given node into parent.
* @param {module:Core~Node} node - the node to be copied.
* @param {module:Core~Node} parent - the parent node of the copy.
*
* @return {module:Core~Node} The function returns the copied node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.copyNode = function (node, parent) {
ensureNode(node, 'node');
ensureNode(parent, 'parent');
return core.copyNode(node, parent);
};
/**
* Copies the given nodes into parent.
* @param {module:Core~Node[]} nodes - the nodes to be copied.
* @param {module:Core~Node} parent - the parent node of the copy.
*
* @return {module:Core~Node[]} The function returns an array of the copied nodes. The order follows
* the order of originals.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.copyNodes = function (nodes, parent) {
var i;
ensureInstanceOf(nodes, 'nodes', Array);
for (i = 0; i < nodes.length; i += 1) {
ensureNode(nodes[i], 'nodes[' + i + ']');
}
ensureNode(parent, 'parent');
return core.copyNodes(nodes, parent);
};
/**
* Checks if parent can be the new parent of node.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} parent - the new parent.
*
* @return {boolean} True if the supplied parent is a valid parent for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidNewParent = function (node, parent) {
ensureNode(node, 'node');
ensureNode(parent, 'parent');
return core.isValidNewParent(node, parent);
};
/**
* Moves the given node under the given parent.
* @param {module:Core~Node} node - the node to be moved.
* @param {module:Core~Node} parent - the parent node of the copy.
*
* @return {module:Core~Node} The function returns the node after the move.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.moveNode = function (node, parent) {
ensureNode(node, 'node');
ensureNode(parent, 'parent');
return core.moveNode(node, parent);
};
/**
* Returns the names of the defined attributes of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the attributes of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAttributeNames = function (node) {
ensureNode(node, 'node');
return core.getAttributeNames(node);
};
/**
* Retrieves the value of the given attribute of the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
*
* @return {string|number|bool|object|undefined} The function returns the value of the attribute of the node.
* If the value is undefined that means the node do not have
* such attribute defined.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAttribute = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getAttribute(node, name));
};
/**
* Sets the value of the given attribute of the given node. It defines the attribute on demand, means that it
* will set the given attribute even if was ot defined for the node beforehand.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
* @param {string|number|bool|object} value - the new of the attribute, undefined is not allowed.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setAttribute = function (node, name, value) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureMongoCompatibleKey(name, 'name', true);
ensureValue(value, 'value');
return core.setAttribute(node, name, value);
};
/**
* Removes the given attributes from the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delAttribute = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.delAttribute(node, name);
};
/**
* Returns the names of the defined registry entries of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the registry entries of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getRegistryNames = function (node) {
ensureNode(node, 'node');
return core.getRegistryNames(node);
};
/**
* Retrieves the value of the given registry entry of the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} The function returns the value of the registry entry
* of the node. The value can be an object or any primitive type. If the value is undefined that means
* the node do not have such attribute defined.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getRegistry = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getRegistry(node, name));
};
/**
* Sets the value of the given registry entry of the given node. It defines the registry entry on demand,
* means that it will set the given registry entry even if was ot defined for the node beforehand.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the registry entry.
* @param {string|number|bool|object} value - the new of the registry entry. Can be any primitive
* type or object. Undefined is not allowed.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setRegistry = function (node, name, value) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureMongoCompatibleKey(name, 'name', true);
ensureValue(value, 'value');
return core.setRegistry(node, name, value);
};
/**
* Removes the given registry entry from the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the registry entry.
*
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delRegistry = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.delRegistry(node, name);
};
/**
* Retrieves a list of the defined pointer names of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the pointers of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getPointerNames = function (node) {
ensureNode(node, 'node');
return core.getPointerNames(node);
};
/**
* Retrieves the path of the target of the given pointer of the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer in question.
*
* @return {string|null|undefined} The function returns the absolute path of the target node
* if there is a valid target. It returns null if though the pointer is defined it does not have any
* valid target. Finally, it return undefined if there is no pointer defined for the node under the given name.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getPointerPath = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getPointerPath(node, name);
};
/**
* Removes the pointer from the node. (Aliased deletePointer.)
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer in question.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delPointer = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.deletePointer(node, name);
};
/**
* Removes the pointer from the node. (Aliased delPointer.)
* @function
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer in question.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.deletePointer = this.delPointer;
/**
* Sets the target of the pointer of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer in question.
* @param {module:Core~Node|null} target - the new target of the pointer.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setPointer = function (node, name, target) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureMongoCompatibleKey(name, 'name', true);
if (target !== null) {
ensureNode(target, 'target');
}
return core.setPointer(node, name, target);
};
/**
* Retrieves a list of the defined pointer names that has the node as target.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the pointers pointing to the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getCollectionNames = function (node) {
ensureNode(node, 'node');
return core.getCollectionNames(node);
};
/**
* Retrieves a list of absolute paths of nodes that has a given pointer which points to the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer.
*
* @return {string[]} The function returns an array of absolute paths of nodes that
* has the pointer pointing to the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getCollectionPaths = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getCollectionPaths(node, name);
};
/**
* Collects the data hash values of the children of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {Object<string, module:Core~ObjectHash>} The function returns a dictionary of
* {@link module:Core~ObjectHash} that stored in pair with the relative id of the corresponding
* child of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getChildrenHashes = function (node) {
ensureNode(node, 'node');
return core.getChildrenHashes(node);
};
/**
* Returns the base node.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~Node|null} Returns the base of the given node or null if there is no such node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getBase = function (node) {
ensureNode(node, 'node');
return core.getBase(node);
};
/**
* Returns the common base node of all supplied nodes. Note that if a node and its base are passed,
* the method will return the base of the base.
* @param {...module:Core~Node} nodes - a variable number of nodes to compare
*
* @return {module:Core~Node|null} The common base or null if e.g. the root node was passed or the fco.
* @example
* core.getCommonBase(node1, node2, node3);
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getCommonBase = function () {
var nodesArr = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)),
result,
i;
nodesArr.forEach(function (node, idx) {
ensureNode(node, 'arguments[' + idx + ']');
});
result = nodesArr[0];
for (i = 1; i < nodesArr.length; i += 1) {
result = getCommonAncestor(result, nodesArr[i], core.getBase);
}
if (result && nodesArr.indexOf(result) > -1) {
result = core.getBase(result);
}
return result || null;
};
/**
* Returns the root of the inheritance chain of the given node.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~Node} Returns the root of the inheritance chain (usually the FCO).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getBaseRoot = function (node) {
ensureNode(node, 'node');
return core.getBaseRoot(node);
};
/**
* Returns the names of the attributes of the node that have been first defined for the node and not for its
* bases.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the own attributes of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnAttributeNames = function (node) {
ensureNode(node, 'node');
return core.getOwnAttributeNames(node);
};
/**
* Returns the names of the registry enrties of the node that have been first defined for the node
* and not for its bases.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of the names of the own registry entries of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnRegistryNames = function (node) {
ensureNode(node, 'node');
return core.getOwnRegistryNames(node);
};
/**
* Returns the value of the attribute defined for the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
*
* @return {string|number|bool|object|undefined} Returns the value of the attribute defined specifically for
* the node. If undefined then it means that there is no such attribute defined directly for the node, meaning
* that it either inherits some value or there is no such attribute at all.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnAttribute = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getOwnAttribute(node, name));
};
/**
* Returns the value of the registry entry defined for the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} Returns the value of the registry entry defined specifically
* for the node. If undefined then it means that there is no such registry entry defined directly for the node,
* meaning that it either inherits some value or there is no such registry entry at all.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnRegistry = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getOwnRegistry(node, name));
};
/**
* Returns the list of the names of the pointers that were defined specifically for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} Returns an array of names of pointers defined specifically for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnPointerNames = function (node) {
ensureNode(node, 'node');
return core.getOwnPointerNames(node);
};
/**
* Returns the absolute path of the target of the pointer specifically defined for the node.
* @param {module:Core~Node} node - the node in question
* @param {string} name - the name of the pointer
*
* @return {string|null|undefined} Returns the absolute path. If the path is null, then it means that
* 'no-target' was defined specifically for this node for the pointer. If undefined it means that the node
* either inherits the target of the pointer or there is no pointer defined at all.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnPointerPath = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getOwnPointerPath(node, name);
};
/**
* Checks if base can be the new base of node.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node|null|undefined} base - the new base.
*
* @return {boolean} True if the supplied base is a valid base for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidNewBase = function (node, base) {
ensureNode(node, 'node');
if (base !== null) {
ensureNode(base, 'base');
}
return core.isValidNewBase(node, base);
};
/**
* Sets the base node of the given node. The function doesn't touch the properties or the children of the node
* so it can cause META rule violations that needs to be corrected manually.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node|null} base - the new base.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setBase = function (node, base) {
ensureNode(node, 'node');
if (base !== null) {
ensureNode(base, 'base');
}
core.setBase(node, base);
};
/**
* Returns the root of the inheritance chain (cannot be the node itself).
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~Node|null} Returns the root of the inheritance chain of the node. If returns null,
* that means the node in question is the root of the chain.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getTypeRoot = function (node) {
ensureNode(node, 'node');
return core.getTypeRoot(node);
};
/**
* Returns the names of the sets of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} Returns an array of set names that the node has.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetNames = function (node) {
ensureNode(node, 'node');
return core.getSetNames(node);
};
/**
* Returns the names of the sets created specifically at the node.
* N.B. When adding a member to a set of a node, the set is automatically created at the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} Returns an array of set names that were specifically created at the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnSetNames = function (node) {
ensureNode(node, 'node');
return core.getOwnSetNames(node);
};
/**
* Creates a set for the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.createSet = function (node, name) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
ensureMongoCompatibleKey(name, 'name', false);
core.createSet(node, name);
};
/**
* Removes a set from the node. (Aliased deleteSet.)
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delSet = function (node, name) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
core.deleteSet(node, name);
};
/**
* Removes a set from the node. (Aliased delSet.)
* @function
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.deleteSet = this.delSet;
/**
* Return the names of the attribute entries for the set.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns the array of names of attribute entries in the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetAttributeNames = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.getSetAttributeNames(node, name);
};
/**
* Return the names of the attribute entries specifically set for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns the array of names of attribute entries defined in the set at the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnSetAttributeNames = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.getOwnSetAttributeNames(node, name);
};
/**
* Get the value of the attribute entry in the set.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} attrName - the name of the attribute entry.
*
* @return {string|number|bool|object|undefined} Return the value of the attribute. If it is undefined,
* then there is no such attribute at the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetAttribute = function (node, setName, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.copyIfObject(core.getSetAttribute(node, setName, attrName));
};
/**
* Get the value of the attribute entry specifically set for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} attrName - the name of the attribute entry.
*
* @return {string|number|bool|object|undefined} Return the value of the attribute. If it is undefined,
* then there is no such attribute at the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnSetAttribute = function (node, setName, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.copyIfObject(core.getOwnSetAttribute(node, setName, attrName));
};
/**
* Sets the attribute entry value for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} attrName - the name of the attribute entry.
* @param {string|number|bool|object} value - the new value of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setSetAttribute = function (node, setName, attrName, value) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(attrName, 'attrName', 'string');
ensureMongoCompatibleKey(attrName, 'attrName', true);
ensureValue(value, 'value');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
core.setSetAttribute(node, setName, attrName, value);
};
/**
* Removes the attribute entry for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} attrName - the name of the attribute entry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delSetAttribute = function (node, setName, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
core.delSetAttribute(node, setName, attrName);
};
//Regs
/**
* Return the names of the registry entries for the set.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns the array of names of registry entries in the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetRegistryNames = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.getSetRegistryNames(node, name);
};
/**
* Return the names of the registry entries specifically set for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns the array of names of registry entries defined in the set at the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnSetRegistryNames = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.getOwnSetRegistryNames(node, name);
};
/**
* Get the value of the registry entry in the set.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} regName - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} Return the value of the registry. If it is undefined,
* then there is no such registry at the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetRegistry = function (node, setName, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.copyIfObject(core.getSetRegistry(node, setName, regName));
};
/**
* Get the value of the registry entry specifically set for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} regName - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} Return the value of the registry. If it is undefined,
* then there is no such registry at the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnSetRegistry = function (node, setName, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
return core.copyIfObject(core.getOwnSetRegistry(node, setName, regName));
};
/**
* Sets the registry entry value for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} regName - the name of the registry entry.
* @param {string|number|bool|object} value - the new value of the registry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setSetRegistry = function (node, setName, regName, value) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(regName, 'regName', 'string');
ensureMongoCompatibleKey(regName, 'regName', true);
ensureValue(value, 'value');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
core.setSetRegistry(node, setName, regName, value);
};
/**
* Removes the registry entry for the set at the node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} regName - the name of the registry entry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delSetRegistry = function (node, setName, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of unknown set.');
}
core.delSetRegistry(node, setName, regName);
};
/**
* Returns the list of absolute paths of the members of the given set of the given node.
* @param {module:Core~Node} node - the set owner.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns an array of absolute path strings of the member nodes of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberPaths = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node).concat(core.getValidSetNames(node));
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
return core.getMemberPaths(node, name);
};
/**
* Returns the list of absolute paths of the members of the given set of the given node that not simply
* inherited.
* @param {module:Core~Node} node - the set owner.
* @param {string} name - the name of the set.
*
* @return {string[]} Returns an array of absolute path strings of the member nodes of the set that has
* information on the node's inheritance level.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnMemberPaths = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getSetNames(node).concat(core.getValidSetNames(node));
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
return core.getOwnMemberPaths(node, name);
};
/**
* Removes a member from the set. The functions doesn't remove the node itself.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {string} path - the absolute path of the member to be removed.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delMember = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
core.delMember(node, name, path);
};
/**
* Adds a member to the given set.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {module:Core~Node} member - the new member of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.addMember = function (node, name, member) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureRelationName(name, 'name');
ensureMongoCompatibleKey(name, 'name', false);
ensureNode(member, 'member');
core.addMember(node, name, member);
};
/**
* Return the names of the attributes defined for the set membership to the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {string} path - the absolute path of the member.
*
* @return {string[]} Returns the array of names of attributes that represents some property of the membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberAttributeNames = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, name);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
return core.getMemberAttributeNames(node, name, path);
};
/**
* Return the names of the attributes defined for the set membership specifically defined to the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {string} path - the absolute path of the member.
*
* @return {string[]} Returns the array of names of attributes that represents some property of the membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberOwnAttributeNames = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, name);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
return core.getMemberOwnAttributeNames(node, name, path);
};
/**
* Get the value of the attribute in relation with the set membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} attrName - the name of the attribute.
*
* @return {string|number|bool|object|undefined} Return the value of the attribute. If it is undefined,
* then there is no such attributed connected to the given set membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberAttribute = function (node, setName, path, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
return core.copyIfObject(core.getMemberAttribute(node, setName, path, attrName));
};
/**
* Get the value of the attribute for the set membership specifically defined to the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} attrName - the name of the attribute.
*
* @return {string|number|bool|object|undefined} Return the value of the attribute. If it is undefined,
* then there is no such attributed connected to the given set membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberOwnAttribute = function (node, setName, path, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
return core.copyIfObject(core.getMemberOwnAttribute(node, setName, path, attrName));
};
/**
* Sets the attribute value which represents a property of the membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} attrName - the name of the attribute.
* @param {string|number|bool|object} value - the new value of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setMemberAttribute = function (node, setName, path, attrName, value) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(attrName, 'attrName', 'string');
ensureMongoCompatibleKey(attrName, 'attrName', true);
ensureValue(value, 'value');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
core.setMemberAttribute(node, setName, path, attrName, value);
};
/**
* Removes an attribute which represented a property of the given set membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} memberPath - the absolute path of the member node.
* @param {string} attrName - the name of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delMemberAttribute = function (node, setName, memberPath, attrName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(memberPath, 'memberPath');
ensureType(attrName, 'attrName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(memberPath) === -1) {
throw new CoreIllegalOperationError('Cannot access attributes of an unknown member.');
}
core.delMemberAttribute(node, setName, memberPath, attrName);
};
/**
* Return the names of the registry entries defined for the set membership to the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {string} path - the absolute path of the member.
*
* @return {string[]} Returns the array of names of registry entries that represents some property of the
* membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberRegistryNames = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, name);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
return core.getMemberRegistryNames(node, name, path);
};
/**
* Return the names of the registry entries defined for the set membership specifically defined to
* the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} name - the name of the set.
* @param {string} path - the absolute path of the member.
*
* @return {string[]} Returns the array of names of registry entries that represents some property of the
* membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberOwnRegistryNames = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, name);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
return core.getMemberOwnRegistryNames(node, name, path);
};
/**
* Get the value of the registry entry in relation with the set membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} regName - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} Return the value of the registry. If it is undefined,
* then there is no such registry connected to the given set membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberRegistry = function (node, setName, path, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
return core.copyIfObject(core.getMemberRegistry(node, setName, path, regName));
};
/**
* Get the value of the registry entry for the set membership specifically defined to the member node.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} regName - the name of the registry entry.
*
* @return {string|number|bool|object|undefined} Return the value of the registry. If it is undefined,
* then there is no such registry connected to the given set membership.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMemberOwnRegistry = function (node, setName, path, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
return core.copyIfObject(core.getMemberOwnRegistry(node, setName, path, regName));
};
/**
* Sets the registry entry value which represents a property of the membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} regName - the name of the registry entry.
* @param {string|number|bool|object} value - the new value of the registry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setMemberRegistry = function (node, setName, path, regName, value) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(regName, 'regName', 'string');
ensureMongoCompatibleKey(regName, 'regName', true);
ensureValue(value, 'value');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
core.setMemberRegistry(node, setName, path, regName, value);
};
/**
* Removes a registry entry which represented a property of the given set membership.
* @param {module:Core~Node} node - the owner of the set.
* @param {string} setName - the name of the set.
* @param {string} path - the absolute path of the member node.
* @param {string} regName - the name of the registry entry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delMemberRegistry = function (node, setName, path, regName) {
ensureNode(node, 'node');
ensureType(setName, 'setName', 'string');
ensurePath(path, 'path');
ensureType(regName, 'regName', 'string');
var names = core.getSetNames(node);
if (names.indexOf(setName) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
var paths = core.getMemberPaths(node, setName);
if (paths.indexOf(path) === -1) {
throw new CoreIllegalOperationError('Cannot access registry of an unknown member.');
}
core.delMemberRegistry(node, setName, path, regName);
};
/**
* Returns all membership information of the given node.
* @param {module:Core~Node} node - the node in question
*
* @return {object} Returns a dictionary where every the key of every entry is an absolute path of a set owner
* node. The value of each entry is an array with the set names in which the node can be found as a member.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isMemberOf = function (node) {
ensureNode(node, 'node');
return core.isMemberOf(node);
};
/**
* Get the GUID of a node.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~GUID} Returns the globally unique identifier.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getGuid = function (node) {
ensureNode(node, 'node');
return core.getGuid(node);
};
//TODO this is only used in import - export use-cases, probably could be removed...
/**
* Set the GUID of a node. As the Core itself do not checks whether the GUID already exists. The use of
* this function is only advised during the creation of the node.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~GUID} guid - the new globally unique identifier.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreIllegalOperationError|CoreInternalError|null} callback.error - the
* result of the execution.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.setGuid = function (node, guid, callback) {
var error = null;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensureGuid(guid, 'guid', true);
if (error) {
callback(error);
} else {
core.setGuid(node, guid, callback);
}
};
/**
* Gets a constraint object of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the constraint.
*
* @return {module:Core~Constraint|null} Returns the defined constraint or null if it was not
* defined for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example
* {
* script: "function (core, node, callback) {callback(null, {hasViolation: false, message: ''});}",
* priority: 1,
* info: "Should check unique name"
* }
*/
this.getConstraint = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getConstraint(node, name);
};
/**
* Sets a constraint object of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the constraint.
* @param {module:Core~Constraint} constraint - the constraint to be set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setConstraint = function (node, name, constraint) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureMongoCompatibleKey(name, 'name', false);
ensureType(constraint, 'constraint', 'object');
core.setConstraint(node, name, constraint);
};
/**
* Removes a constraint from the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the constraint.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delConstraint = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
core.delConstraint(node, name);
};
/**
* Retrieves the list of constraint names defined for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} Returns the array of names of constraints available for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getConstraintNames = function (node) {
ensureNode(node, 'node');
return core.getConstraintNames(node);
};
/**
* Retrieves the list of constraint names defined specifically for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} Returns the array of names of constraints for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnConstraintNames = function (node) {
ensureNode(node, 'node');
return core.getOwnConstraintNames(node);
};
/**
* Checks if the given node in any way inherits from the typeNode. In addition to checking if the node
* "isInstanceOf" of typeNode, this methods also takes mixins into account.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node|string} typeNodeOrPath - the type node we want to check or its path.
*
* @return {bool} The function returns true if the typeNodeOrPath represents a base node,
* or a mixin of any of the base nodes, of the node.
* Every node is considered to be a type of itself.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isTypeOf = function (node, typeNodeOrPath) {
ensureNode(node, 'node');
if (typeof typeNodeOrPath === 'string') {
ensurePath(typeNodeOrPath, 'typeNodeOrPath');
} else {
ensureNode(typeNodeOrPath, 'typeNodeOrPath');
}
return core.isTypeOf(node, typeNodeOrPath);
};
/**
* Checks if according to the META rules the given node can be a child of the parent.
* @param {module:Core~Node} node - the node in question
* @param {module:Core~Node} parent - the parent we like to test.
*
* @return {bool} The function returns true if according to the META rules the node can be a child of the
* parent. The check does not cover multiplicity (so if the parent can only have twi children and it already
* has them, this function will still returns true).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidChildOf = function (node, parent) {
ensureNode(node, 'node');
ensureNode(parent, 'parent');
return core.isValidChildOf(node, parent);
};
/**
* Returns the list of the META defined pointer names of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the pointer names that are defined among the META rules
* of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidPointerNames = function (node) {
ensureNode(node, 'node');
return core.getValidPointerNames(node);
};
/**
* Returns the list of the META defined pointer names of the node that were specifically defined for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the pointer names that are defined among the META
* rules of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidPointerNames = function (node) {
ensureNode(node, 'node');
return core.getOwnValidPointerNames(node);
};
/**
* Returns the list of the META defined set names of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the set names that are defined among the META rules of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidSetNames = function (node) {
ensureNode(node, 'node');
return core.getValidSetNames(node);
};
/**
* Returns the list of the META defined set names of the node that were specifically defined for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the set names that are defined among the META rules of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidSetNames = function (node) {
ensureNode(node, 'node');
return core.getOwnValidSetNames(node);
};
/**
* Checks if the node can be a target of a pointer of the source node in accordance with the META rules.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} source - the source to test.
* @param {string} name - the name of the pointer.
*
* @return {bool} The function returns true if according to the META rules, the given node is a valid
* target of the given pointer of the source.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidTargetOf = function (node, source, name) {
ensureNode(node, 'node');
ensureNode(source, 'source');
ensureType(name, 'name', 'string');
return core.isValidTargetOf(node, source, name);
};
/**
* Checks if the node can be a member of the given set at the provided set-owner node. This does not take
* cardinality rules into account.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} setOwner - the owner of the set.
* @param {string} name - the name of the set.
*
* @return {bool} The function returns true if according to the META rules, the given node is a valid
* member of set of the given set-owner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidSetMemberOf = function (node, setOwner, name) {
ensureNode(node, 'node');
ensureNode(setOwner, 'setOwner');
ensureType(name, 'name', 'string');
// This is not a typo - the isValidTargetOf method can be reused.
return core.isValidTargetOf(node, setOwner, name);
};
/**
* Returns the list of the META defined attribute names of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the attribute names that are defined among the META rules of the
* node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidAttributeNames = function (node) {
ensureNode(node, 'node');
return core.getValidAttributeNames(node);
};
/**
* Returns the list of the META defined attribute names of the node that were specifically defined for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns the attribute names that are defined specifically for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidAttributeNames = function (node) {
ensureNode(node, 'node');
return core.getOwnValidAttributeNames(node);
};
/**
* Checks if the given value is of the necessary type, according to the META rules.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
* @param {string|number|bool|object} value - the value to test.
*
* @return {bool} Returns true if the value matches the META definitions.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidAttributeValueOf = function (node, name, value) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureValue(value, 'value');
if (core.getValidAttributeNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not a valid attribute name [' + name + '] of the node.');
}
return core.isValidAttributeValueOf(node, name, value);
};
/**
* Returns the list of the META defined aspect names of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns all the aspect names that are defined among the META rules of the
* node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidAspectNames = function (node) {
ensureNode(node, 'node');
return core.getValidAspectNames(node);
};
/**
* Returns the list of the META defined aspect names of the node that were specifically defined for the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns the aspect names that are specifically defined for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidAspectNames = function (node) {
ensureNode(node, 'node');
return core.getOwnValidAspectNames(node);
};
/**
* Returns the list of valid children types of the given aspect.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspect.
*
* @return {string[]} The function returns a list of absolute paths of nodes that are valid children of the node
* and fits to the META rules defined for the aspect. Any children, visible under the given aspect of the node
* must be an instance of at least one node represented by the absolute paths.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAspectMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getAspectMeta(node, name);
};
/**
* Gives a JSON representation of the META rules of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {object} Returns an object that represents all the META rules of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example
* {
* children: {
* items: [ "/1", "/c" ],
* minItems: [ -1, -1 ],
* maxItems: [ -1, -1 ]
* },
* attributes: {
* name: { type: "string" },
* level: { type: "integer"}
* },
* pointers: {
* ptr: {
* min: 1,
* max: 1,
* items: [ "/1" ],
* minItems: [ -1 ],
* maxItems: [ 1 ]
* },
* set: {
* min: -1,
* max: -1,
* items: [ "/c" ],
* minItems: [ -1 ],
* maxItems: [ -1 ]
* }
* },
* aspects: {
* filter: [ "/8", "/c" ]
* },
* constraints: {
* myConstraint: {
* script: "function (core, node, callback) {callback(null, {hasViolation: false, message: ''});}",
* priority: 1,
* info: "Should check unique name"
* }
* }
* }
* @example
* {
* children: {},
* attributes: {
* name: { type: "string" },
* },
* pointers: {},
* aspects: {},
* constraints: {}
*/
this.getJsonMeta = function (node) {
ensureNode(node, 'node');
return core.getJsonMeta(node);
};
/**
* Returns the META rules specifically defined for the given node.
* @param {module:Core~Node} node - the node in question.
*
* @return {object} The function returns an object that represent the META rules that were defined
* specifically for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnJsonMeta = function (node) {
ensureNode(node, 'node');
return core.getOwnJsonMeta(node);
};
/**
* Removes all META rules defined at the node. Note that it does not clear any rules from other meta-nodes
* where the node if referenced.
* @param {module:Core~Node} node - the node in question.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.clearMetaRules = function (node) {
ensureNode(node, 'node');
core.clearMetaRules(node);
};
/**
* Sets the META rules of the attribute of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
* @param {object} rule - the rules that defines the attribute
* @param {'string'|'integer'|'float'|'boolean'|'asset'} rule.type - the type of the attribute (valid types see
* CONSTANTS.ATTRIBUTE_TYPES).
* @param {string[]} [rule.enum] - if the attribute is an enumeration, this array contains the possible values
* @param {string|number|boolean} [rule.default] - The value the attribute should have at the node. If not given
* it should be set at some point.
* @param {boolean} [rule.multiline] - if true, than the attribute represents a multiline string,
* for example code snipet.
* @param {string} [rule.multilineType] - describing the type of the multiline (like java or c++)
* suggesting syntax highlighting.
* @param {boolean} [rule.isPassword] - shows if the string attribute should be handled
* sensitively on the user interface.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setAttributeMeta = function (node, name, rule) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureMongoCompatibleKey(name, 'name', false);
ensureType(rule, 'rule', 'object');
ensureType(rule.type, 'rule.type', 'string');
core.setAttributeMeta(node, name, rule);
};
/**
* Removes an attribute definition from the META rules of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delAttributeMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
core.delAttributeMeta(node, name);
};
/**
* Returns the definition object of an attribute from the META rules of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute.
*
* @return {object} The function returns the definition object, where type is always defined.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example
* {
* type: "string"
* }
* @example
* {
* type: "string",
* regexp: "^win"
* }
* @example
* {
* type: "string",
* enum: [ "value1", "value2" ]
* }
* @example
* {
* type: "boolean"
* }
* @example
* {
* type: "integer"
* }
* @example
* {
* type: "integer",
* min: 0,
* max: 10
* }
* @example
* {
* type: "integer",
* enum: [ 3, 8 ]
* }
* @example
* {
* type: "float",
* min: 0,
* max: 9.9
* }
* @example
* {
* type: "asset"
* }
*/
this.getAttributeMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getAttributeMeta(node, name));
};
/**
* Returns the list of absolute path of the valid children types of the node.
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The function returns an array of absolute paths of the nodes that was defined as valid
* children for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidChildrenPaths = function (node) {
ensureNode(node, 'node');
return core.getValidChildrenPaths(node);
};
/**
* Return a JSON representation of the META rules regarding the valid children of the given node.
* @param {module:Core~Node} node - the node in question.
*
* @return {module:Core~RelationRule} The function returns a detailed JSON structure that represents the META
* rules regarding the possible children of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example
* {
* '/5': { max: 1, min: -1 },
* '/c': { max: -1, min: 2 },
* max: 10,
* min: undefined
* }
* @func
*/
this.getChildrenMeta = function (node) {
ensureNode(node, 'node');
return core.getChildrenMeta(node);
};
/**
* Sets the given child as a valid children type for the node.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} child - the valid child node.
* @param {integer} [min] - the allowed minimum number of children from this given node type (if not given or
* -1 is set, then there will be no minimum rule according this child type)
* @param {integer} [max] - the allowed maximum number of children from this given node type (if not given or
* -1 is set, then there will be no minimum rule according this child type)
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setChildMeta = function (node, child, min, max) {
ensureNode(node, 'node');
ensureNode(child, 'child');
ensureMinMax(min, 'min');
ensureMinMax(max, 'max');
core.setChildMeta(node, child, min, max);
};
/**
* Removes the given child rule from the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} path - the absolute path of the child which rule is to be removed from the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delChildMeta = function (node, path) {
ensureNode(node, 'node');
ensurePath(path, 'path');
core.delChildMeta(node, path);
};
/**
* Sets the global containment limits for the node.
* @param {module:Core~Node} node - the node in question.
* @param {integer} [min] - the allowed minimum number of children (if not given or
* -1 is set, then there will be no minimum rule according children)
* @param {integer} [max] - the allowed maximum number of children (if not given or
* -1 is set, then there will be no maximum rule according children)
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setChildrenMetaLimits = function (node, min, max) {
ensureNode(node, 'node');
ensureMinMax(min, 'min');
ensureMinMax(max, 'max');
core.setChildrenMetaLimits(node, min, max);
};
/**
* Sets the given target as a valid target type for the pointer/set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer/set.
* @param {module:Core~Node} target - the valid target/member node.
* @param {integer} [min] - the allowed minimum number of target/member from this given node type (if not
* given or -1 is set, then there will be no minimum rule according this target type)
* @param {integer} [max] - the allowed maximum number of target/member from this given node type (if not
* given or -1 is set, then there will be no minimum rule according this target type)
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setPointerMetaTarget = function (node, name, target, min, max) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
ensureMongoCompatibleKey(name, 'name', false);
ensureNode(target, 'target');
ensureMinMax(min, 'min');
ensureMinMax(max, 'max');
core.setPointerMetaTarget(node, name, target, min, max);
};
/**
* Removes a possible target type from the pointer/set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer/set
* @param {string} path - the absolute path of the possible target type.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If node is read-only, or definition does not exist.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delPointerMetaTarget = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getValidPointerNames(node).concat(core.getValidSetNames(node));
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access definition of unknown pointer.');
}
core.delPointerMetaTarget(node, name, path);
};
/**
* Sets the global target limits for pointer/set of the node. On META level the only distinction between
* pointer and sets is the global multiplicity which has to maximize the number of possible targets to 1 in
* case of 'pure' pointer definitions.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer/set.
* @param {integer} [min] - the allowed minimum number of children (if not given or
* -1 is set, then there will be no minimum rule according targets)
* @param {integer} [max] - the allowed maximum number of children (if not given or
* -1 is set, then there will be no maximum rule according targets)
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setPointerMetaLimits = function (node, name, min, max) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
ensureMinMax(min, 'min');
ensureMinMax(max, 'max');
core.setPointerMetaLimits(node, name, min, max);
};
/**
* Removes the complete META rule regarding the given pointer/set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer/set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delPointerMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
core.delPointerMeta(node, name);
};
/**
* Return a JSON representation of the META rules regarding the given pointer/set of the given node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer/set.
*
* @return {module:Core~RelationRule|undefined} The function returns a detailed JSON structure that
* represents the META rules regarding the given pointer/set of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example
* pointer
* {
* '/a': { max: 1, min: -1 },
* max: 1,
* min: 1
* }
* @example
* set
* {
* '/G': { max: -1, min: -1},
* '/i': { max: -1, min: -1},
* max: -1
* min: -1
* }
*/
this.getPointerMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getPointerMeta(node, name);
};
/**
* Sets a valid type for the given aspect of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspect.
* @param {module:Core~Node} target - the valid type for the aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.setAspectMetaTarget = function (node, name, target) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
ensureMongoCompatibleKey(name, 'name', false);
ensureNode(target, 'target');
core.setAspectMetaTarget(node, name, target);
};
/**
* Removes a valid type from the given aspect of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspect.
* @param {string} path - the absolute path of the valid type of the aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delAspectMetaTarget = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getValidAspectNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot change definition of unknown aspect.');
}
core.delAspectMetaTarget(node, name, path);
};
/**
* Removes the given aspect rule of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delAspectMeta = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
core.delAspectMeta(node, name);
};
/**
* Returns the meta-node of the node in question, that is the first base node that is part of the meta.
* (Aliased getBaseType).
* @param {module:Core~Node} node - the node in question
*
* @return {module:Core~Node|null} Returns the first node (including itself) among the inheritance chain
* that is a META node. It returns null if it does not find such node (ideally the only node with this result
* is the ROOT).
*
* @throws {CoreIllegalArgumentError} If node is not a Node
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMetaType = function (node) {
ensureNode(node, 'node');
return core.getBaseType(node);
};
/**
* Returns the meta-node of the node in question, that is the first base node that is part of the meta.
* (Aliased getMetaType).
* @function
* @param {module:Core~Node} node - the node in question
*
* @return {module:Core~Node|null} Returns the first node (including itself) among the inheritance chain
* that is a META node. It returns null if it does not find such node (ideally the only node with this result
* is the ROOT).
*
* @throws {CoreIllegalArgumentError} If node is not a Node
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getBaseType = this.getMetaType;
/**
* Checks if the node is an instance of base.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node|string} baseNodeOrPath - a potential base node (or its path) of the node
*
* @return {bool} Returns true if the base is on the inheritance chain of node.
* A node is considered to be an instance of itself here.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isInstanceOf = function (node, baseNodeOrPath) {
var noPath;
ensureNode(node, 'node');
if (typeof baseNodeOrPath === 'string') {
noPath = ensurePath(baseNodeOrPath, 'baseNodeOrPath', true);
if (noPath) {
return core.isInstanceOfDeprecated(node, baseNodeOrPath);
}
} else {
ensureNode(baseNodeOrPath, 'baseNodeOrPath');
}
return core.isInstanceOf(node, baseNodeOrPath);
};
/**
* Generates a differential tree among the two states of the project that contains the necessary changes
* that can modify the source to be identical to the target. The result is in form of a json object.
* @param {module:Core~Node} sourceRoot - the root node of the source state.
* @param {module:Core~Node} targetRoot - the root node of the target state.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the status of the exectuion.
* @param {object} callback.treeDiff - the difference between the two containment hierarchies in
* a special JSON object
*
* @return {external:Promise} if the callback is not defined, the result is provided in a promise
* like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.generateTreeDiff = function (sourceRoot, targetRoot, callback) {
var error;
ensureType(callback, 'callback', 'function');
error = ensureNode(sourceRoot, 'sourceRoot', true);
error = error || ensureNode(targetRoot, 'targetRoot', true);
if (error) {
callback(error);
} else {
core.generateTreeDiff(sourceRoot, targetRoot, callback);
}
};
/**
* Apply changes to the current project.
* @param {module:Core~Node} node - the root of the containment hierarchy where we wish to apply the changes
* @param {object} patch - the tree structured collection of changes represented with a special JSON object
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the result of the execution.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.applyTreeDiff = function (node, patch, callback) {
var error;
ensureType(callback, 'callback', 'function');
error = ensureNode(node, 'node', true);
error = error || ensureType(patch, 'patch', 'object', true);
if (error) {
callback(error);
} else {
core.applyTreeDiff(node, patch, callback);
}
};
/**
* Tries to merge two patch object. The patches ideally represents changes made by two parties. They represents
* changes from the same source ending in different states. Our aim is to generate a single patch that could
* cover the changes of both party.
* @param {object} mine - the tree structured JSON patch that represents my changes.
* @param {object} theirs - the tree structured JSON patch that represents the changes of the other party.
*
* @return {object} The function returns with an object that contains the conflicts (if any) and the merged
* patch.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.tryToConcatChanges = function (mine, theirs) {
ensureType(mine, 'mine', 'object');
ensureType(theirs, 'theirs', 'object');
return core.tryToConcatChanges(mine, theirs);
};
/**
* When our attempt to merge two patches ended in some conflict, then we can modify that result highlighting
* that in case of every conflict, which side we prefer (mine vs. theirs). If we give that object as an input
* to this function, it will finish the merge resolving the conflict according our settings and present a final
* patch.
* @param {object} conflict - the object that represents our settings for every conflict and the so-far-merged
* patch.
*
* @return {object} The function results in a tree structured patch object that contains the changesthat cover
* both parties modifications (and the conflicts are resolved according the input settings).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.applyResolution = function (conflict) {
ensureType(conflict, 'conflict', 'object');
return core.applyResolution(conflict);
};
/**
* Checks if the node is abstract.
* @param {module:Core~Node} node - the node in question.
*
* @return {bool} The function returns true if the registry entry 'isAbstract' of the node if true hence
* the node is abstract.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isAbstract = function (node) {
ensureNode(node, 'node');
return core.isAbstract(node);
};
/**
* Check is the node is a connection-like node.
* @param {module:Core~Node} node - the node in question.
*
* @return {bool} Returns true if both the 'src' and 'dst' pointer are defined as valid for the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isConnection = function (node) {
ensureNode(node, 'node');
return core.isConnection(node);
};
/**
* Retrieves the valid META nodes that can be base of a child of the node.
* @param {object} parameters - the input parameters of the query.
* @param {module:Core~Node} parameters.node - the node in question.
* @param {bool} [parameters.sensitive=false] - if true, the query filters out the abstract and connection-like
* nodes.
* @param {bool} [parameters.multiplicity=false] - if true, the query tries to filter out even more
* nodes according to the multiplicity rules.
* @param {module:Core~Node[]} [parameters.children=[]] - the current children of the node in question
* (must be passed if multiplicity=true)
* @param {string|null} [parameters.aspect=undefined] - if given, the query filters to contain only types that
* are visible in the given aspect.
* @return {module:Core~Node[]} The function returns a list of valid nodes that can be instantiated as a
* child of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidChildrenMetaNodes = function (parameters) {
ensureType(parameters, 'parameters', 'object');
ensureNode(parameters.node, 'parameters.node');
if (Object.hasOwn(parameters, 'children') && parameters.children !== undefined) {
ensureInstanceOf(parameters.children, 'parameters.children', Array);
for (var i = 0; i < parameters.children.length; i += 1) {
ensureNode(parameters.children[i], 'parameters.children[i]');
}
}
if (Object.hasOwn(parameters, 'sensitive') && parameters.sensitive !== undefined) {
ensureType(parameters.sensitive, 'parameters.sensitive', 'boolean');
}
if (Object.hasOwn(parameters, 'multiplicity')) {
ensureType(parameters.multiplicity, 'parameters.multiplicity', 'boolean');
}
if (Object.hasOwn(parameters, 'aspect') && parameters.aspect !== undefined && parameters.aspect !== null) {
ensureType(parameters.aspect, 'parameters.aspect', 'string');
}
return core.getValidChildrenMetaNodes(parameters);
};
/**
* Retrieves the valid META nodes that can be base of a member of the set of the node.
* @param {object} parameters - the input parameters of the query.
* @param {module:Core~Node} parameters.node - the node in question.
* @param {string} parameters.name - the name of the set.
* @param {bool} [parameters.sensitive=false] - if true, the query filters out the abstract and connection-like
* nodes.
* @param {bool} [parameters.multiplicity=false] - if true, the query tries to filter out even more nodes
* according to the multiplicity rules (the check is only meaningful if all the members were passed)
* @param {module:Core~Node[]} [parameters.members=[]] - the current members of the set of the node in question.
*
* @return {module:Core~Node[]} The function returns a list of valid nodes that can be instantiated as a
* member of the set of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidSetElementsMetaNodes = function (parameters) {
ensureType(parameters, 'parameters', 'object');
ensureNode(parameters.node, 'parameters.node');
ensureType(parameters.name, 'parameters.name', 'string');
if (Object.hasOwn(parameters, 'members')) {
ensureInstanceOf(parameters.members, 'parameters.members', Array);
for (var i = 0; i < parameters.members.length; i += 1) {
ensureNode(parameters.members[i], 'parameters.members[i]');
}
}
if (Object.hasOwn(parameters, 'sensitive')) {
ensureType(parameters.sensitive, 'parameters.sensitive', 'boolean');
}
if (Object.hasOwn(parameters, 'multiplicity')) {
ensureType(parameters.multiplicity, 'parameters.multiplicity', 'boolean');
}
return core.getValidSetElementsMetaNodes(parameters);
};
/**
* Returns all META nodes.
* @param {module:Core~Node} node - any node of the containment hierarchy.
*
* @return {Object<string, module:Core~Node>} The function returns a dictionary. The keys of the dictionary
* are the absolute paths of the META nodes of the project. Every value of the dictionary
* is a {@link module:Core~Node}.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAllMetaNodes = function (node) {
ensureNode(node, 'node');
return core.getAllMetaNodes(node);
};
/**
* Checks if the node is a META node.
* @param {module:Core~Node} node - the node to test.
*
* @return {bool} Returns true if the node is a member of the METAAspectSet of the ROOT node hence can be
* seen as a META node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isMetaNode = function (node) {
ensureNode(node, 'node');
return core.isMetaNode(node);
};
/**
* Checks if the member is completely overridden in the set of the node.
* @param {module:Core~Node} node - the node to test.
* @param {string} name - the name of the set of the node.
* @param {string} path - the path of the member in question.
*
* @return {bool} Returns true if the member exists in the base of the set, but was
* added to the given set as well, which means a complete override. If the set does not exist
* or the member do not have a 'base' member or just some property was overridden, the function returns
* false.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isFullyOverriddenMember = function (node, name, path) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensurePath(path, 'path');
var names = core.getSetNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot access member information of unknown set.');
}
return core.isFullyOverriddenMember(node, name, path);
};
/**
* Checks if the mixins allocated with the node can be used.
* Every mixin node should be on the Meta.
* Every rule (attribute/pointer/set/aspect/containment/constraint) should be defined only in one mixin.
*
* @param {module:Core~Node} node - the node to test.
*
* @return {module:Core~MixinViolation[]} Returns the array of violations. If the array is empty,
* there is no violation.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMixinErrors = function (node) {
ensureNode(node, 'node');
return core.getMixinErrors(node);
};
/**
* Gathers the paths of the mixin nodes defined directly at the node.
*
* @param {module:Core~Node} node - the node in question.
*
* @return {string[]} The paths of the mixins in an array ordered by their order of use (which is important
* in case of some collision among definitions would arise).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMixinPaths = function (node) {
ensureNode(node, 'node');
return core.getMixinPaths(node);
};
/**
* Gathers the mixin nodes defined directly at the node.
*
* @param {module:Core~Node} node - the node in question.
*
* @return {Object<string, module:Core~Node>} The dictionary of the mixin nodes keyed by their paths.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getMixinNodes = function (node) {
ensureNode(node, 'node');
return core.getMixinNodes(node);
};
/**
* Removes a mixin from the mixin set of the node.
*
* @param {module:Core~Node} node - the node in question.
* @param {string} path - the path of the mixin node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.delMixin = function (node, path) {
ensureNode(node, 'node');
ensurePath(path, 'path');
return core.delMixin(node, path);
};
/**
* Adds a mixin to the mixin set of the node.
*
* @param {module:Core~Node} node - the node in question.
* @param {string} path - the path of the mixin node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.addMixin = function (node, path) {
ensureNode(node, 'node');
ensurePath(path, 'path');
return core.addMixin(node, path);
};
/**
* Removes all mixins for a given node.
*
* @param {module:Core~Node} node - the node in question.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.clearMixins = function (node) {
ensureNode(node, 'node');
return core.clearMixins(node);
};
/**
* Searches for the closest META node of the node in question and the direct mixins of that node.
* @param {module:Core~Node} node - the node in question
*
* @return {module:Core~Node[]} Returns the closest Meta node that is a base of the given node
* plus it returns all the mixin nodes associated with the base.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getBaseTypes = function (node) {
ensureNode(node, 'node');
return core.getBaseTypes(node);
};
/**
* Checks if the given path can be added as a mixin to the given node.
*
* @param {module:Core~Node} node - the node in question.
* @param {string} path - the path of the mixin node.
* @return {object} Returns an object with isOk set to true if the given path can be added as a
* mixin to the given node. If it cannot, the reason will be reported under reason.
*
* @example
* result = core.canSetAsMixin(node, core.getPath(aValidMixinNode));
* // result = { isOk: true, reason: '' }
* result = core.canSetAsMixin(node, core.getPath(node));
* // result = { isOk: false, reason: 'Node cannot be mixin of itself!' }
* result = core.canSetAsMixin(node, core.getPath(nonMetaNode));
* // result = { isOk: false, reason: 'Mixin must be on the Meta!!' }
* result = core.canSetAsMixin(node, core.getPath(FCO));
* // result = { isOk: false, reason: 'Base of node cannot be its mixin as well!' }
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.canSetAsMixin = function (node, path) {
ensureNode(node, 'node');
ensurePath(path, 'path');
return core.canSetAsMixin(node, path);
};
//library function TODO checking everything and adding all new functions
/**
* It adds a project as library to your project by copying it over. The library will be a node
* with the given name directly under your project's ROOT. It becomes a read-only portion of your project.
* You will only be able to manipulate it with library functions, but cannot edit the individual nodes inside.
* However you will be able to instantiate or copy the nodes into other places of your project. Every node
* that was part of the META in the originating project becomes part of your project's meta.
* @param {module:Core~Node} node - any regular node in your project.
* @param {string} name - the name of the library you wish to use as a namespace in your project.
* @param {string} libraryRootHash - the hash of your library's root
* (must exist in the project's collection at the time of call).
* @param {object} [libraryInfo] - information about your project.
* @param {string} [libraryInfo.projectId] - the projectId of your library.
* @param {string} [libraryInfo.branchName] - the branch that your library follows in the origin project.
* @param {string} [libraryInfo.commitHash] - the version of your library.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreIllegalOperationError|CoreInternalError|null} callback.error - the
* result of the execution.
*
* @return {external:Promise} If no callback is given, the result is provided in a promise like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.addLibrary = function (node, name, libraryRootHash, libraryInfo, callback) {
ensureType(callback, 'callback', 'function');
var error = ensureNode(node, 'node', true);
error = error || ensureType(name, 'name', 'string', true);
error = error || ensureHash(libraryRootHash, 'libraryRootHash', true);
if (libraryInfo) {
error = error || ensureType(libraryInfo, 'libraryInfo', 'object', true);
if (Object.hasOwn(libraryInfo, 'projectId') && libraryInfo.projectId !== undefined) {
error = error || ensureType(libraryInfo.projectId, 'libraryInfo.projectId', 'string', true);
}
if (Object.hasOwn(libraryInfo, 'branchName') && libraryInfo.branchName !== undefined) {
error = error || ensureType(libraryInfo.branchName, 'libraryInfo.branchName', 'string', true);
}
if (Object.hasOwn(libraryInfo, 'commitHash') && libraryInfo.commitHash !== undefined) {
error = error || ensureHash(libraryInfo.commitHash, 'libraryInfo.commitHash', true);
}
}
if (error) {
callback(error);
} else {
core.addLibrary(node, name, libraryRootHash, libraryInfo, callback);
}
};
/**
* It updates a library in your project based on the input information. It will 'replace' the old
* version, keeping as much information as possible regarding the instances.
* @param {module:Core~Node} node - any regular node in your project.
* @param {string} name - the name of the library you want to update.
* @param {string} libraryRootHash - the hash of your library's new root
* (must exist in the project's collection at the time of call).
* @param {object} [libraryInfo] - information about your project.
* @param {string} [libraryInfo.projectId] - the projectId of your library.
* @param {string} [libraryInfo.branchName] - the branch that your library follows in the origin project.
* @param {string} [libraryInfo.commitHash] - the version of your library.
* @param updateInstructions - not yet used parameter.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreIllegalOperationError|CoreInternalError|null} callback.error - the
* status of the execution.
*
* @return {external:Promise} If no callback is given, the result is presented in a promise like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.updateLibrary = function (node, name, libraryRootHash, libraryInfo, updateInstructions, callback) {
ensureType(callback, 'callback', 'function');
var error = ensureNode(node, 'node', true);
error = error || ensureType(name, 'name', 'string', true);
error = error || ensureHash(libraryRootHash, 'libraryRootHash', true);
if (libraryInfo) {
error = error || ensureType(libraryInfo, 'libraryInfo', 'object', true);
if (Object.hasOwn(libraryInfo, 'projectId') && libraryInfo.projectId !== undefined) {
error = error || ensureType(libraryInfo.projectId, 'libraryInfo.projectId', 'string', true);
}
if (Object.hasOwn(libraryInfo, 'branchName') && libraryInfo.branchName !== undefined) {
error = error || ensureType(libraryInfo.branchName, 'libraryInfo.branchName', 'string', true);
}
if (Object.hasOwn(libraryInfo, 'commitHash') && libraryInfo.commitHash !== undefined) {
error = error || ensureHash(libraryInfo.commitHash, 'libraryInfo.commitHash', true);
}
}
if (error) {
callback(error);
} else {
core.updateLibrary(node, name, libraryRootHash, libraryInfo, callback);
}
};
/**
* Gives back the list of libraries in your project.
*
* @param {module:Core~Node} node - any node in your project.
*
* @return {string[]} Returns the fully qualified names of all the libraries in your project
* (even embedded ones).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getLibraryNames = function (node) {
ensureNode(node, 'node');
return core.getLibraryNames(node);
};
/**
* Return the root of the inheritance chain of your Meta nodes.
*
* @param {module:Core~Node} node - any node in your project.
*
* @return {module:Core~Node} Returns the acting FCO of your project.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getFCO = function (node) {
ensureNode(node, 'node');
return core.getFCO(node);
};
/**
* Returns true if the node in question is a library root..
*
* @param {module:Core~Node} node - the node in question.
*
* @return {bool} Returns true if your node is a library root (even if it is embedded in other library),
* false otherwise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isLibraryRoot = function (node) {
ensureNode(node, 'node');
return core.isLibraryRoot(node);
};
/**
* Returns true if the node in question is a library element..
*
* @param {module:Core~Node} node - the node in question.
*
* @return {bool} Returns true if your node is a library element, false otherwise.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isLibraryElement = function (node) {
ensureNode(node, 'node');
return core.isLibraryElement(node);
};
/**
* Returns the resolved namespace for the node. If node is not in a library it returns the
* empty string. If the node is in a library of a library -
* the full name space is the library names joined together by dots.
*
* @param {module:Core~Node} node - the node in question.
*
* @return {string} Returns the name space of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example NS1.NS2
*/
this.getNamespace = function (node) {
ensureNode(node, 'node');
return core.getNamespace(node);
};
/**
* Returns the fully qualified name of the node, which is the list of its namespaces separated
* by dot and followed by the name of the node.
*
* @param {module:Core~Node} node - the node in question.
*
* @return {string} Returns the fully qualified name of the node,
* i.e. its namespaces and name join together by dots.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*
* @example NS1.NS2.name
*/
this.getFullyQualifiedName = function (node) {
ensureNode(node, 'node');
return core.getFullyQualifiedName(node);
};
/**
* Removes a library from your project. It will also remove any remaining instances of the specific library.
*
* @param {module:Core~Node} node - any node in your project.
* @param {string} name - the name of your library.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.removeLibrary = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
var names = core.getLibraryNames(node);
if (names.indexOf(name) === -1) {
throw new CoreIllegalOperationError('Cannot remove unknown library');
}
return core.removeLibrary(node, name);
};
/**
* Returns the origin GUID of any library node. (If name is not provided the returned GUID will be the same
* across all projects where the library node is contained - regardless of library hierarchy.)
* @param {module:Core~Node} node - the node in question.
* @param {undefined|string} [name] - name of the library where we want to compute the GUID from.
* If not given, then the GUID is computed from the direct library root of the node.
*
* @return {module:Core~GUID} Returns the origin GUID of the node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getLibraryGuid = function (node, name) {
ensureNode(node, 'node');
if (name !== undefined && name !== null) {
ensureType(name, 'name', 'string');
}
return core.getLibraryGuid(node, name);
};
/**
* Rename a library in your project.
*
* @param {module:Core~Node} node - any node in your project.
* @param {string} oldName - the current name of the library.
* @param {string} newName - the new name of the project.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renameLibrary = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
core.renameLibrary(node, oldName, newName);
};
/**
* Returns the info associated with the library.
*
* @param {module:Core~Node} node - any node in the project.
* @param {string} name - the name of the library.
*
* @return {object} Returns the information object, stored alongside the library (that basically
* carries metaData about the library).
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getLibraryInfo = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.copyIfObject(core.getLibraryInfo(node, name));
};
/**
* Returns the root node of the given library.
*
* @param {module:Core~Node} node - any node in the project.
* @param {string} name - the name of the library.
*
* @return {module:Core~Node|null} Returns the library root node or null, if the library is unknown.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getLibraryRoot = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
return core.getLibraryRoot(node, name);
};
/**
* Returns all the Meta nodes within the given library.
* By default it will include nodes defined in any library within the given library.
*
* @param {module:Core~Node} node - any node of your project.
* @param {string} name - name of your library.
* @param {bool} [onlyOwn=false] - if true only returns with Meta nodes defined in the library itself.
*
* @return {module:Core~Node[]} Returns an array of core nodes that are part of your meta from
* the given library.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getLibraryMetaNodes = function (node, name, onlyOwn) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
if (onlyOwn !== null && onlyOwn !== undefined) {
ensureType(onlyOwn, 'onlyOwn', 'boolean');
}
return core.getLibraryMetaNodes(node, name, onlyOwn);
};
/**
* The function traverses the sub-tree of the project starting with the given root and calls the
* visit function for every node.
*
* @param {module:Core~Node} root - the root node of the sub-tree that needs to be traversed.
* @param {object} options - parameters to control the traversing.
* @param {bool} [options.excludeRoot=false] - controls whether the root should be excluded from visit.
* @param {'BFS'|'DFS'} [options.order='BFS'] - controls if the traversal order should be breadth first
* or depth first.
* @param {integer} [options.maxParallelLoad=100]- the maximum number of parallel loads allowed.
* @param {bool} [options.stopOnError=true]- controls if the traverse should stop in case of error.
* @param {function} visitFn - the visitation function that will be called for
* every node in the sub-tree, the second parameter of the function is a callback that should be called to
* note to the traversal function that the visitation for a given node finished.
* @param {module:Core~Node} visitFn.node - the node that is being visited.
* @param {function} visitFn.next - the callback function of the visit function that marks the end
* of visitation.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the status of the execution.
*
* @return {external:Promise} If no callback is given, the end of traverse is marked in a promise like
* manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.traverse = function (root, options, visitFn, callback) {
ensureType(callback, 'callback', 'function');
var error = ensureNode(root, 'root', true);
if (options) {
error = error || ensureType(options, 'options', 'object');
if (Object.hasOwn(options, 'excludeRoot')) {
error = error || ensureType(options.excludeRoot, 'options.excludeRoot', 'boolean', true);
}
if (Object.hasOwn(options, 'order')) {
error = error || ensureType(options.order, 'options.order', 'string', true);
if (options.order !== 'BFS' && options.order !== 'DFS') {
error = error ||
new CoreIllegalArgumentError('Parameter options.order must be either \'BFS\' or \'DFS\'.');
}
}
if (Object.hasOwn(options, 'stopOnError')) {
error = error || ensureType(options.stopOnError, 'options.stopOnError', 'boolean', true);
}
}
error = error || ensureType(visitFn, 'visitFn', 'function');
if (error) {
callback(error);
} else {
core.traverse(root, options, visitFn, callback);
}
};
/**
* Collects the necessary information to export the set of input nodes and use it in other
* - compatible - projects.
* @private
*
* @param {module:Core~Node[]} nodes - the set of nodes that we want to export
*
* @return {object} If the closure is available for export, the returned special JSON object
* will contain information about the necessary data that needs to be exported as well as relations
* that will need to be recreated in the destination project to preserve the structure of nodes.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getClosureInformation = function (nodes) {
ensureInstanceOf(nodes, 'nodes', Array);
for (var i = 0; i < nodes.length; i += 1) {
ensureNode(nodes[i], 'nodes[i]');
}
return core.getClosureInformation(nodes);
};
/**
* Imports the set of nodes in the closureInformation - that has the format created by
* [getClosureInformation]{@link Core#getClosureInformation} - as direct children of the parent node.
* All data necessary for importing the closure has to be imported beforehand!
* @private
*
* @param {module:Core~Node} node - the parent node where the closure will be imported.
* @param {object} closureInformation - the information about the closure.
*
* @return {object} If the closure cannot be imported the resulting error highlights the causes,
* otherwise a specific object will be returned that holds information about the closure.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.importClosure = function (node, closureInformation) {
ensureNode(node, 'node');
ensureType(closureInformation, 'closureInformation', 'object');
return core.importClosure(node, closureInformation);
};
/**
* Collects the paths of all the instances of the given node.
* @param {module:Core~Node} node - the node in question.
*
*@return {string[]} The function returns an array of the absolute paths of the instances.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getInstancePaths = function (node) {
ensureNode(node, 'node');
return core.getInstancePaths(node);
};
/**
* Loads all the instances of the given node.
* @param {module:Core~Node} node - the node in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the status of the execution.
* @param {module:Core~Node[]} callback.nodes - the found instances of the node.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise
* like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadInstances = function (node, callback) {
ensureType(callback, 'callback', 'function');
var error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadInstances(node, callback);
}
};
/**
* Loads all the members of the given set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} setName - the name of the set in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the status of the execution.
* @param {module:Core~Node[]} callback.nodes - the found members of the set of the node.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise
* like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadMembers = function (node, setName, callback) {
ensureType(setName, 'setName', 'string');
ensureType(callback, 'callback', 'function');
var error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadMembers(node, setName, callback);
}
};
/**
* Loads all the own members of the given set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} setName - the name of the set in question.
* @param {function} [callback]
* @param {Error|CoreIllegalArgumentError|CoreInternalError|null} callback.error - the status of the execution.
* @param {module:Core~Node[]} callback.nodes - the found own members of the set of the node.
*
* @return {external:Promise} If no callback is given, the result will be provided in a promise
* like manner.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
*/
this.loadOwnMembers = function (node, setName, callback) {
ensureType(setName, 'setName', 'string');
ensureType(callback, 'callback', 'function');
var error = ensureNode(node, 'node', true);
if (error) {
callback(error);
} else {
core.loadOwnMembers(node, setName, callback);
}
};
/**
* Renames the given pointer of the node if its target is not inherited.
* @param {module:Core~Node} node - the node in question.
* @param {string} oldName - the current name of the pointer in question.
* @param {string} newName - the new name of the pointer.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renamePointer = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnPointerPath(node, oldName) === undefined) {
throw new CoreIllegalOperationError('Only pointers with values can be renamed.');
}
core.renamePointer(node, oldName, newName);
};
/**
* Renames the given attribute of the node if its value is not inherited.
* @param {module:Core~Node} node - the node in question.
* @param {string} oldName - the current name of the attribute in question.
* @param {string} newName - the new name of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renameAttribute = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnAttribute(node, oldName) === undefined) {
throw new CoreIllegalOperationError('Only attributes with own values can be renamed.');
}
core.renameAttribute(node, oldName, newName);
};
/**
* Renames the given registry of the node if its value is not inherited.
* @param {module:Core~Node} node - the node in question.
* @param {string} oldName - the current name of the registry in question.
* @param {string} newName - the new name of the registry.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renameRegistry = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnRegistry(node, oldName) === undefined) {
throw new CoreIllegalOperationError('Only registry entries with own values can be renamed.');
}
core.renameRegistry(node, oldName, newName);
};
/**
* Renames the given set of the node if its is not inherited.
* @param {module:Core~Node} node - the node in question.
* @param {string} oldName - the current name of the set in question.
* @param {string} newName - the new name of the set.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renameSet = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnSetNames(node).indexOf(oldName) === -1) {
throw new CoreIllegalOperationError('Cannot rename nonexistent/inherited set [' + oldName + ']');
}
core.renameSet(node, oldName, newName);
};
/**
* Returns the meta node that introduces the given attribute.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the attribute in question.
*
* @return {module:Core~Node} The meta-node that defines the attribute and makes it valid attribute for the
* given node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAttributeDefinitionOwner = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
if (core.getValidAttributeNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not a valid attribute name [' + name + '] of the node.');
}
return core.getAttributeDefinitionOwner(node, name);
};
/**
* Returns the meta nodes that introduce the given pointer relationship.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the pointer in question.
* @param {module:Core~Node} target - the target node.
*
* @return {module:Core~DefinitionInfo} The owner and the target of the pointer meta-rule that makes target a
* valid target of the named pointer of node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getPointerDefinitionInfo = function (node, name, target) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureNode(target, 'target');
if (core.getValidPointerNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not valid pointer name [' + name + '] of the node.');
}
if (core.isValidTargetOf(target, node, name) !== true) {
throw new CoreIllegalOperationError('Not a valid target node of [' + name + '] pointer.');
}
return core.getPointerDefinitionInfo(node, name, target);
};
/**
* Returns the meta nodes that introduce the given set relationship.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the set in question.
* @param {module:Core~Node} member - the member.
*
* @return {module:Core~DefinitionInfo} The owner and the target of the set meta-rule that makes member a
* valid member of the named set of node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getSetDefinitionInfo = function (node, name, member) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureNode(member, 'member');
if (core.getValidSetNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not valid set name [' + name + '] of the node.');
}
if (core.isValidTargetOf(member, node, name) !== true) {
throw new CoreIllegalOperationError('Not a valid member of [' + name + '] set.');
}
return core.getSetDefinitionInfo(node, name, member);
};
/**
* Returns the meta nodes that introduce the given containment relationship.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} child - the child.
*
* @return {module:Core~DefinitionInfo} The owner and the target of the containment meta-rule that makes child a
* valid child of node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getChildDefinitionInfo = function (node, child) {
ensureNode(node, 'node');
ensureNode(child, 'child');
if (core.isValidChildOf(child, node) !== true) {
throw new CoreIllegalOperationError('Not a valid child.');
}
return core.getChildDefinitionInfo(node, child);
};
/**
* Returns the meta nodes that introduce the given aspect relationship.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the set in question.
* @param {module:Core~Node} member - the child.
*
* @return {module:Core~DefinitionInfo} The owner and the target of the aspect meta-rule that makes member a
* valid member of the named aspect of node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAspectDefinitionInfo = function (node, name, member) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
ensureNode(member, 'member');
if (core.getValidAspectNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not valid aspect name [' + name + '] of the node.');
}
if (core.isValidAspectMemberOf(member, node, name) !== true) {
throw new CoreIllegalOperationError('Not a valid member of [' + name + '] aspect.');
}
return core.getAspectDefinitionInfo(node, name, member);
};
/**
* Returns the paths of the meta nodes that are valid target members of the given aspect.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspec in question.
*
* @return {string[]} The paths of the meta nodes whose instances could be members of the aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidAspectTargetPaths = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
if (core.getValidAspectNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not a valid aspect [' + name + '] of the node.');
}
return core.getValidAspectTargetPaths(node, name);
};
/**
* Returns the paths of the meta nodes that are valid target members of the given aspect
* specifically defined for the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the aspec in question.
*
* @return {string[]} The paths of the meta nodes whose instances could be members of the aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidAspectTargetPaths = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
if (core.getValidAspectNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not a valid aspect [' + name + '] of the node.');
}
return core.getOwnValidAspectTargetPaths(node, name);
};
/**
* Returns the meta node that introduces the given aspect.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of the set in question.
*
* @return {module:Core~Node} The meta-node that defines the aspect and makes a valid aspect for the given node.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getAspectDefinitionOwner = function (node, name) {
ensureNode(node, 'node');
ensureType(name, 'name', 'string');
if (core.getValidAspectNames(node).indexOf(name) === -1) {
throw new CoreIllegalOperationError('Not valid aspect name [' + name + '] of the node.');
}
return core.getAspectDefinitionOwner(node, name);
};
/**
* Moves an own member of the set over to another set of the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} memberPath - the path of the memberNode that should be moved.
* @param {string} oldSetName - the name of the set where the member is currently reside.
* @param {string} newSetName - the name of the target set where the member should be moved to.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.moveMember = function (node, memberPath, oldSetName, newSetName) {
ensureNode(node, 'node');
ensureType(memberPath, 'memberPath', 'string');
ensurePath(memberPath, 'memberPath');
ensureType(oldSetName, 'oldSetName', 'string');
ensureType(newSetName, 'newSetName', 'string');
ensureMongoCompatibleKey(newSetName, 'newSetName', true);
if (core.getSetNames(node).indexOf(oldSetName) === -1) {
throw new CoreIllegalOperationError('Source set [' + oldSetName + '] does not exists.');
}
if (core.getOwnMemberPaths(node, oldSetName).indexOf(memberPath) === -1) {
throw new CoreIllegalOperationError('Not own member of the set therefore cannot be moved.');
}
core.moveMember(node, memberPath, oldSetName, newSetName);
};
/**
* Renames the given attribute definition of the node. It also renames the default value of the definition!
* As a result of this operation, all instances of node will have the new attribute, but if they have
* overriden the old attribute it will remain under that name (and become meta invalid).
* @param {module:Core~Node} node - the node in question.
* @param {string} oldName - the current name of the attribute definition in question.
* @param {string} newName - the new name of the attribute.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.renameAttributeMeta = function (node, oldName, newName) {
ensureNode(node, 'node');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getValidAttributeNames(node).indexOf(oldName) === -1) {
throw new CoreIllegalOperationError('Unknown definition [' + oldName + '] cannot be renamed.');
}
core.renameAttributeMeta(node, oldName, newName);
};
/**
* Moves the given target definition over to a new pointer or set.
* Note this does not alter the actual pointer target or set members.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} target - the target that should be moved among definitions.
* @param {string} oldName - the current name of the pointer/set definition in question.
* @param {string} newName - the new name of the relation towards the target.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.movePointerMetaTarget = function (node, target, oldName, newName) {
ensureNode(node, 'node');
ensureNode(target, 'target');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnValidPointerNames(node).indexOf(oldName) === -1 &&
core.getOwnValidSetNames(node).indexOf(oldName) === -1) {
throw new CoreIllegalOperationError('Definition [' + oldName + '] does not exists for the node.');
}
if (core.getOwnValidTargetPaths(node, oldName).indexOf(core.getPath(target)) === -1) {
throw new CoreIllegalOperationError('Not a valid target of [' + oldName + '] defined for the node.');
}
core.movePointerMetaTarget(node, target, oldName, newName);
};
/**
* Moves the given target definition over to a new aspect. As actual values in case of
* relation definitions vary quite a bit from the meta-targets, this function does not deals with
* the actual pointer/set target/members.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} target - the target that should be moved among definitions.
* @param {string} oldName - the current name of the aspect that has the target.
* @param {string} newName - the new aspect name where the target should be moved over.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreIllegalOperationError} If the context of the operation is not allowed.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.moveAspectMetaTarget = function (node, target, oldName, newName) {
ensureNode(node, 'node');
ensureNode(target, 'target');
ensureType(oldName, 'oldName', 'string');
ensureType(newName, 'newName', 'string');
ensureMongoCompatibleKey(newName, 'newName', true);
if (core.getOwnValidAspectNames(node).indexOf(oldName) === -1) {
throw new CoreIllegalOperationError('Aspect [' + oldName + '] doesn\'t exists for the node.');
}
if (core.getOwnValidAspectTargetPaths(node, oldName).indexOf(core.getPath(target)) === -1) {
throw new CoreIllegalOperationError('Not a valid target of [' + oldName + '] defined for the node.');
}
core.moveAspectMetaTarget(node, target, oldName, newName);
};
/**
* Returns if a node could be contained in the given container's aspect.
* @param {module:Core~Node} node - the node in question.
* @param {module:Core~Node} parent - the container node in question.
* @param {string} name - the name of aspect.
*
* @return {bool} The function returns true if the given container could contain the node in the asked aspect.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidAspectMemberOf = function (node, parent, name) {
ensureNode(node, 'node');
ensureNode(parent, 'parent');
ensureType(name, 'name', 'string');
return core.isValidAspectMemberOf(node, parent, name);
};
/**
* Returns the paths of Meta nodes that are possible targets of the given pointer/set introduced by the node.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of pointer/set.
*
* @return {string[]} The function returns the paths of valid nodes.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getOwnValidTargetPaths = function (node, name) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
return core.getOwnValidTargetPaths(node, name);
};
/**
* Returns the paths of Meta nodes that are possible targets of the given pointer/set.
* @param {module:Core~Node} node - the node in question.
* @param {string} name - the name of pointer/set.
*
* @return {string[]} The function returns the paths of valid nodes.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.getValidTargetPaths = function (node, name) {
ensureNode(node, 'node');
ensureRelationName(name, 'name');
return core.getValidTargetPaths(node, name);
};
/**
* Checks if an instance of the given base can be created under the parent. It does not check for
* meta consistency. It only validates if the proposed creation would cause any loops in the
* combined containment inheritance trees.
* @param {module:Core~Node|null} parentNode - the parent in question.
* @param {module:Core~Node|null} baseNode - the intended type of the node.
*
* @return {boolean} True if a child of the type can be created.
*
* @throws {CoreIllegalArgumentError} If some of the parameters don't match the input criteria.
* @throws {CoreInternalError} If some internal error took place inside the core layers.
*/
this.isValidNewChild = function (parentNode, baseNode) {
if (parentNode !== null) {
ensureNode(parentNode, 'parentNode');
}
if (baseNode !== null) {
ensureNode(baseNode, 'baseNode');
}
return core.isValidNewChild(parentNode, baseNode);
};
this.CONSTANTS = CONSTANTS;
}
return Core;
});