webgme-engine
Version:
WebGME server and Client API without a GUI
1,230 lines (1,086 loc) • 117 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: client/gmeNodeSetter.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: client/gmeNodeSetter.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/*globals define*/
/*eslint-env browser*/
/**
* @author kecso / https://github.com/kecso
* @author pmeijer / https://github.com/pmeijer
*/
define([], function () {
'use strict';
function gmeNodeSetter(logger, state, saveRoot, storeNode, printCoreError) {
function _logDeprecated(oldFn, newFn, isGetter, comment) {
var typeToUse = isGetter ? 'gmeNode.' : 'gmeClient.',
commentStr = comment ? comment : '';
//eslint-disable-next-line no-console
console.warn('"gmeClient.' + oldFn + '" is deprecated and will eventually be removed, use "' +
typeToUse + newFn + '" instead.' + commentStr);
}
function _getNode(path) {
if (state.core && state.nodes[path] && typeof state.nodes[path].node === 'object') {
return state.nodes[path].node;
}
}
function _setAttrAndRegistry(node, desc) {
var name;
desc = desc || {};
if (desc.attributes) {
for (name in desc.attributes) {
if (Object.hasOwn(desc.attributes, name)) {
state.core.setAttribute(node, name, desc.attributes[name]);
}
}
}
if (desc.registry) {
for (name in desc.registry) {
if (Object.hasOwn(desc.registry, name)) {
state.core.setRegistry(node, name, desc.registry[name]);
}
}
}
}
function _copyMultipleNodes(paths, parentNode, resultAsArray) {
var copiedNodes, result = {},
resultArray = [],
i, originalNodes = [],
checkPaths = function () {
var i,
result = true;
for (i = 0; i < paths.length; i += 1) {
result = result && (state.nodes[paths[i]] &&
typeof state.nodes[paths[i]].node === 'object');
}
return result;
};
if (parentNode && checkPaths()) {
for (i = 0; i < paths.length; i += 1) {
originalNodes.push(state.nodes[paths[i]].node);
}
copiedNodes = state.core.copyNodes(originalNodes, parentNode);
if (copiedNodes instanceof Error) {
return copiedNodes;
}
for (i = 0; i < paths.length; i += 1) {
result[paths[i]] = copiedNodes[i];
resultArray.push(storeNode(copiedNodes[i]));
}
}
return resultAsArray ? resultArray : result;
}
/**
* @description Method to set an attribute of a given node.
* @memberOf Client
* @instance
* @param {string} path - The path of the node in question.
* @param {string} name - The name of the attribute.
* @param {any} value - The value of the attribute to be set.
* @param {string} msg - The message that should be attached to the commit that covers this update.
*/
function setAttribute(path, name, value, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.setAttribute(node, name, value);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ?
msg : 'setAttribute(' + path + ',' + name + ',' + JSON.stringify(value) + ')');
}
}
/**
* @description Method to remove an attribute from a given node.
* @memberOf Client
* @instance
* @param {string} path - The path of the node in question.
* @param {string} name - The name of the attribute.
* @param {string} msg - The message that should be attached to the commit that covers this update.
*/
function delAttribute(path, name, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.delAttribute(node, name);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'delAttribute(' + path + ',' + name + ')');
}
}
/**
* @description Method to set a registry entry of a given node.
* @memberOf Client
* @instance
* @param {string} path - The path of the node in question.
* @param {string} name - The name of the registry.
* @param {any} value - The value of the registry to be set.
* @param {string} msg - The message that should be attached to the commit that covers this update.
*/
function setRegistry(path, name, value, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.setRegistry(node, name, value);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ?
msg : 'setRegistry(' + path + ',' + name + ',' + JSON.stringify(value) + ')');
}
}
/**
* @description Method to remove a registry entry of a given node.
* @memberOf Client
* @instance
* @param {string} path - The path of the node in question.
* @param {string} name - The name of the registry.
* @param {string} msg - The message that should be attached to the commit that covers this update.
*/
function delRegistry(path, name, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.delRegistry(node, name);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'delRegistry(' + path + ',' + name + ')');
}
}
/**
* @example
*
* var nodeCopy1 = client.copyNode('/4', '');
* var nodeCopy2 = client.copyNode('/4', '', {
* attributes: {
* name: 'CopiedNode'
* },
* registry: {
* position: {x: 100, y: 100}
* }
* }, 'Created node with specific name and position.');
*
* @description Copies the given node into parent
* (does not enforce meta-rules and requires all participating nodes to be loaded in the client)
* @function copyNode
* @memberOf Client
* @param {string} path - the id/path of the node to copy
* @param {string} parentId - the id/path of the parent where the new copy should be created
* @param {object} [desc={}] - named attributes and/or registries to set for the new node (see example)
* @param {object} [desc.attributes={}] - named attributes to set for the new node
* @param {object} [desc.registry={}] - named registries to set for the new node
* @param {string} [msg] - optional commit message, if not supplied a default one
* with the function name and input parameters will be used
* @returns {GMENode|undefined} - the newly created node if it could be copied
* @instance
*/
function copyNode(path, parentPath, desc, msg) {
var node = _getNode(path),
parentNode = _getNode(parentPath),
newNode, newPath;
if (node && parentNode) {
newNode = state.core.copyNode(node, parentNode);
if (newNode instanceof Error) {
printCoreError(newNode);
return;
}
_setAttrAndRegistry(newNode, desc);
newPath = storeNode(newNode);
saveRoot(typeof msg === 'string' ?
msg : 'copyNode(' + path + ', ' + parentPath + ', ' + JSON.stringify(desc) + ')');
return newPath;
}
}
/**
* @example
*
* client.copyMoreNodes({
* parentId: '',
* '/4': {},
* '/5': {
* attributes: {
* name: 'MyNamedCopy'
* },
* registry: {
* position: {x: 100, y:100}
* }
* }
* }, 'Copied two nodes with some additional init data.');
*
* @description Copies the given nodes into the parent (does not enforce meta-rules
* and requires all participating nodes to be loaded in the client)
* @function copyMoreNodes
* @memberOf Client
* @param {object} parameters - the parameters holding parentId and nodes to be copied
* indexed by their ids/paths (see example)
* @param {string} parameters.parentId - the id/path of the parent where the new copies should be created
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function copyMoreNodes(parameters, msg) {
var pathsToCopy = [],
parentNode = _getNode(parameters.parentId),
nodePath,
newNodes;
if (parentNode) {
for (nodePath in parameters) {
if (Object.hasOwn(parameters, nodePath) && nodePath !== 'parentId') {
pathsToCopy.push(nodePath);
}
}
msg = typeof msg === 'string' ?
msg : 'copyMoreNodes(' + JSON.stringify(pathsToCopy) + ',' + parameters.parentId + ')';
if (pathsToCopy.length < 1) {
// empty on purpose
} else if (pathsToCopy.length === 1) {
copyNode(pathsToCopy[0], parameters.parentId, parameters[pathsToCopy[0]], msg);
} else {
newNodes = _copyMultipleNodes(pathsToCopy, parentNode);
if (newNodes instanceof Error) {
printCoreError(newNodes);
return;
}
for (nodePath in newNodes) {
if (Object.hasOwn(newNodes, nodePath) && parameters[nodePath]) {
_setAttrAndRegistry(newNodes[nodePath], parameters[nodePath]);
}
}
saveRoot(msg);
}
} else {
state.logger.error('wrong parameters for copy operation - denied -');
}
}
/**
* @example
*
* client.moveMoreNodes({
* parentId: '',
* '/4': {},
* '/5': {
* attributes: {
* name: 'MyNamedCopy'
* },
* registry: {
* position: {x: 100, y:100}
* }
* }
* }, 'Copied two nodes with some additional init data.');
*
* @description Moves the given nodes into the parent (does not enforce meta-rules
* and requires all participating nodes to be loaded in the client)
* @function moveMoreNodes
* @memberOf Client
* @param {object} parameters - the parameters holding parentId and nodes to be copied
* indexed by their ids/paths (see example)
* @param {string} parameters.parentId - the id/path of the parent where the new copies should be created
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function moveMoreNodes(parameters, msg) {
var pathsToMove = [],
returnParams = {},
i,
newNode;
for (i in parameters) {
if (Object.hasOwn(parameters, i)) {
if (i !== 'parentId') {
pathsToMove.push(i);
}
}
}
if (pathsToMove.length > 0 &&
typeof parameters.parentId === 'string' &&
state.nodes[parameters.parentId] &&
typeof state.nodes[parameters.parentId].node === 'object') {
for (i = 0; i < pathsToMove.length; i += 1) {
if (state.nodes[pathsToMove[i]] &&
typeof state.nodes[pathsToMove[i]].node === 'object') {
newNode = state.core.moveNode(state.nodes[pathsToMove[i]].node,
state.nodes[parameters.parentId].node);
returnParams[pathsToMove[i]] = state.core.getPath(newNode);
_setAttrAndRegistry(newNode, parameters[pathsToMove[i]]);
delete state.nodes[pathsToMove[i]];
storeNode(newNode, true);
}
}
}
saveRoot(typeof msg === 'string' ? msg : 'moveMoreNodes(' + JSON.stringify(returnParams) + ')');
return returnParams;
}
/**
* @example
*
* client.createChildren({
* parentId: '',
* '/4': {},
* '/5': {
* attributes: {
* name: 'MyVeryOwnName'
* },
* registry: {
* position: {x: 100, y:100}
* }
* }
* }, 'Created new children of the root based on the list of existing nodes.');
*
* @description Creates instances as children of the parent node based on the list
* of nodes among the parameters (does not enforce meta-rules
* and requires all participating nodes to be loaded in the client).
* @function createChildren
* @memberOf Client
* @param {object} parameters - the parameters holding parentId and nodes to be instantiated
* indexed by their ids/paths (see example)
* @param {string} parameters.parentId - the id/path of the parent where the new nodes should be created
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function createChildren(parameters, msg) {
//TODO we also have to check out what is happening with the sets!!!
var result = {},
paths = [],
nodes = [],
node,
parent = state.nodes[parameters.parentId].node,
names, i, j, index, pointer,
newChildren = [],
relations = [];
//to allow 'meaningfull' instantiation of multiple objects
// we have to recreate the internal relations - except the base
paths = Object.keys(parameters);
paths.splice(paths.indexOf('parentId'), 1);
for (i = 0; i < paths.length; i++) {
node = state.nodes[paths[i]].node;
nodes.push(node);
pointer = {};
names = state.core.getPointerNames(node);
index = names.indexOf('base');
if (index !== -1) {
names.splice(index, 1);
}
for (j = 0; j < names.length; j++) {
index = paths.indexOf(state.core.getPointerPath(node, names[j]));
if (index !== -1) {
pointer[names[j]] = index;
}
}
relations.push(pointer);
}
//now the instantiation
for (i = 0; i < nodes.length; i++) {
newChildren.push(state.core.createNode({parent: parent, base: nodes[i]}));
}
//now for the storage and relation setting
for (i = 0; i < paths.length; i++) {
_setAttrAndRegistry(newChildren[i], parameters[paths[i]]);
//relations
names = Object.keys(relations[i]);
for (j = 0; j < names.length; j++) {
state.core.setPointer(newChildren[i], names[j], newChildren[relations[i][names[j]]]);
}
//store
result[paths[i]] = storeNode(newChildren[i]);
}
msg = typeof msg === 'string' ? msg : 'createChildren(' + JSON.stringify(result) + ')';
saveRoot(msg);
return result;
}
/**
* @description Delete the given node.
* @function deleteNode
* @memberOf Client
* @param {string} path - the path/id of the node to be deleted from the model.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function deleteNode(path, msg) {
var node = _getNode(path);
if (node) {
state.core.deleteNode(node);
saveRoot(typeof msg === 'string' ? msg : 'deleteNode(' + path + ')');
}
}
/**
* @description Delete the given node.
* @function deleteNodes
* @memberOf Client
* @param {string[]} paths - the path/id list of the nodes to be deleted from the model.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function deleteNodes(paths, msg) {
var didDelete = false,
i,
node;
for (i = 0; i < paths.length; i++) {
node = _getNode(paths[i]);
if (node) {
state.core.deleteNode(node);
didDelete = true;
}
}
if (didDelete) {
saveRoot(typeof msg === 'string' ? msg : 'deleteNodes(' + paths + ')');
}
}
/**
* @example
*
* client.createNode({
* parentId: '',
* baseId:'/1',
* guid:,
* relid:'/aaa'
* },
* {
* attributes: {
* name: 'MyVeryOwnName'
* },
* registry: {
* position: {x: 100, y:100}
* }
* },
* 'Created new node as the child of the root and instance of the FCO.');
*
* @description Creates a new node based on the given parameters.
* @function createNode
* @memberOf Client
* @param {object} parameters - the parameters holding necessary information for the creation.
* @param {string} parameters.parentId - the path/id of the container of the new node.
* @param {string} parameters.baseId - the path/id of the prototype of the new node.
* @param {string} parameters.parentId - the id/path of the parent where the new nodes should be created
* @param {string} [parameters.guid] - the unique identifier of the node we will create.
* @param {string} [parameters.relid] - the relative id of the node we will create.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function createNode(parameters, desc, msg) {
var parentNode = _getNode(parameters.parentId),
baseNode = _getNode(parameters.baseId),
newNode,
newID;
if (parentNode) {
newNode = state.core.createNode({
parent: parentNode,
base: baseNode,
guid: parameters.guid,
relid: parameters.relid
});
if (newNode instanceof Error) {
printCoreError(newNode);
return;
}
// By default the position will be {100, 100}
desc = desc || {};
desc.registry = desc.registry || {};
desc.registry.position = desc.registry.position || {};
desc.registry.position.x = (typeof desc.registry.position.x === 'number' ||
Number(desc.registry.position.x) + '' === desc.registry.position.x) ?
Number(desc.registry.position.x) : 100;
desc.registry.position.y = (typeof desc.registry.position.y === 'number' ||
Number(desc.registry.position.y) + '' === desc.registry.position.y) ?
Number(desc.registry.position.y) : 100;
_setAttrAndRegistry(newNode, desc);
storeNode(newNode);
newID = state.core.getPath(newNode);
saveRoot(typeof msg === 'string' ? msg :
'createNode(' + parameters.parentId + ',' + parameters.baseId + ',' + newID + ')');
}
return newID;
}
/**
* @description Sets the value of the pointer of the given node.
* @function setPointer
* @memberOf Client
* @param {string} path - the path/id of the node that we will modify.
* @param {string} name - the name of the pointer to set.
* @param {string|null} target - the id/path of the target node of the pointer. If
* the value is null, there will be no target for the pointer.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setPointer(path, name, target, msg) {
var node = _getNode(path),
targetNode;
if (node) {
if (target === null) {
state.core.setPointer(node, name, target);
} else {
targetNode = _getNode(target);
state.core.setPointer(node, name, targetNode);
}
saveRoot(typeof msg === 'string' ? msg : 'setPointer(' + path + ',' + name + ',' + target + ')');
}
}
/**
* @description Removes the pointer of the given node.
* Setting a pointer to null and deleting it is different!
* (one is a value, the other means the absence of value)
* @function delPointer
* @memberOf Client
* @param {string} path - the path/id of the node that we will modify.
* @param {string} name - the name of the pointer to set.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delPointer(path, name, msg) {
var node = _getNode(path);
if (node) {
state.core.delPointer(node, name);
saveRoot(typeof msg === 'string' ? msg : 'delPointer(' + path + ',' + name + ')');
}
}
// Mixed argument methods - START
/**
* @description Add a new member node to the given set of the
* specified node.
* @function addMember
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set to expand.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function addMember(path, memberPath, setId, msg) {
// FIXME: This will have to break due to switched arguments
var node = _getNode(path),
memberNode = _getNode(memberPath);
if (node && memberNode) {
state.core.addMember(node, setId, memberNode);
saveRoot(typeof msg === 'string' ? msg : 'addMember(' + path + ',' + memberPath + ',' + setId + ')');
}
}
/**
* @description Removes a member node from the given set of the
* specified node.
* @function removeMember
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set to expand.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function removeMember(path, memberPath, setId, msg) {
// FIXME: This will have to break due to switched arguments (sort of)
var node = _getNode(path);
if (node) {
state.core.delMember(node, setId, memberPath);
saveRoot(typeof msg === 'string' ? msg : 'removeMember(' + path + ',' + memberPath + ',' + setId + ')');
}
}
/**
* @description Set the given attribute value that is connected to the membership
* (not the member node, so it only has a meaning in the context of the membership).
* @function setMemberAttribute
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set where the member exists.
* @param {string} name - the name of the attribute.
* @param {object|string|null} value - the value of the attribute.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setMemberAttribute(path, memberPath, setId, name, value, msg) {
// FIXME: This will have to break due to switched arguments
var node = _getNode(path);
if (node) {
state.core.setMemberAttribute(node, setId, memberPath, name, value);
saveRoot(typeof msg === 'string' ?
msg : 'setMemberAttribute(' + [path, memberPath, setId, name, value].join(',') + ')');
}
}
/**
* @description Removes the given attribute that is connected to the membership
* from the node.
* @function delMemberAttribute
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set to expand.
* @param {string} name - the name of the attribute.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delMemberAttribute(path, memberPath, setId, name, msg) {
// FIXME: This will have to break due to switched arguments
var node = _getNode(path);
if (node) {
state.core.delMemberAttribute(node, setId, memberPath, name);
saveRoot(typeof msg === 'string' ?
msg : 'delMemberAttribute(' + [path, memberPath, setId, name].join(',') + ')');
}
}
/**
* @description Set the given registry value that is connected to the membership
* (not the member node, so it only has a meaning in the context of the membership).
* @function setMemberRegistry
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set to expand.
* @param {string} name - the name of the registry.
* @param {object|string|null} value - the value of the registry.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setMemberRegistry(path, memberPath, setId, name, value, msg) {
// FIXME: This will have to break due to switched arguments
var node = _getNode(path);
if (node) {
state.core.setMemberRegistry(node, setId, memberPath, name, value);
saveRoot(typeof msg === 'string' ?
msg : 'setMemberRegistry(' + path + ',' + memberPath + ',' + setId + ',' + name + ',' +
JSON.stringify(value) + ')');
}
}
/**
* @description Removes the given registry that is connected to the membership
* from the node.
* @function delMemberRegistry
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} memberPath - the path/id of the member node.
* @param {string} setId - the name of the set to expand.
* @param {string} name - the name of the registry.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delMemberRegistry(path, memberPath, setId, name, msg) {
// FIXME: This will have to break due to switched arguments
var node = _getNode(path);
if (node) {
state.core.delMemberRegistry(node, setId, memberPath, name);
saveRoot(typeof msg === 'string' ?
msg : 'delMemberRegistry(' + path + ',' + memberPath + ',' + setId + ',' + name + ')');
}
}
// Mixed argument methods - END
/**
* @description Set the given attribute value of the set of the node
* (the value is connected to the node, but only in the context of the set).
* @function setSetAttribute
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setName - the name of the set where the member exists.
* @param {string} attrName - the name of the attribute.
* @param {object|string|null} attrValue - the value of the attribute.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setSetAttribute(path, setName, attrName, attrValue, msg) {
var node = _getNode(path);
if (node) {
state.core.setSetAttribute(node, setName, attrName, attrValue);
saveRoot(typeof msg === 'string' ?
msg : 'setSetAttribute(' + path + ',' + setName + ',' + attrName + ',' +
JSON.stringify(attrValue) + ')');
}
}
/**
* @description Removes the given attribute that is connected to set of the node.
* @function delSetAttribute
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setName - the name of the set to change.
* @param {string} attrName - the name of the attribute.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delSetAttribute(path, setName, attrName, msg) {
var node = _getNode(path);
if (node) {
state.core.delSetAttribute(node, setName, attrName);
saveRoot(typeof msg === 'string' ?
msg : 'delSetAttribute(' + path + ',' + setName + ',' + attrName + ')');
}
}
/**
* @description Set the given registry value of the set of the node
* (the value is connected to the node, but only in the context of the set).
* @function setSetRegistry
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setName - the name of the set where the member exists.
* @param {string} regName - the name of the registry.
* @param {object|string|null} regValue - the value of the registry.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setSetRegistry(path, setName, regName, regValue, msg) {
var node = _getNode(path);
if (node) {
state.core.setSetRegistry(node, setName, regName, regValue);
saveRoot(typeof msg === 'string' ?
msg : 'setSetRegistry(' + [path, setName, regName, JSON.stringify(regValue)].join(',') + ')');
}
}
/**
* @description Removes the given registry that is connected to set of the node.
* @function delSetRegistry
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setName - the name of the set to change.
* @param {string} attrName - the name of the registry.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delSetRegistry(path, setName, regName, msg) {
var node = _getNode(path);
if (node) {
state.core.delSetRegistry(node, setName, regName);
saveRoot(typeof msg === 'string' ?
msg : 'delSetRegistry(' + path + ',' + setName + ',' + regName + ')');
}
}
/**
* @description Creates a set that belongs to the node.
* @function createSet
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setId - the name of the set.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function createSet(path, setId, msg) {
var node = _getNode(path);
if (node) {
state.core.createSet(node, setId);
saveRoot(typeof msg === 'string' ? msg : 'createSet(' + path + ',' + setId + ')');
}
}
/**
* @description Removes a set that belongs to the node.
* @function delSet
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} setId - the name of the set.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delSet(path, setId, msg) {
var node = _getNode(path),
error;
if (node) {
error = state.core.delSet(node, setId);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'delSet(' + path + ',' + setId + ')');
}
}
/**
* @description Changes the prototype node of the node.
* This function should only be used with care!
* @function setBase
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} basePath - the path/id of the new prototype node.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setBase(path, basePath, msg) {
var node = _getNode(path),
baseNode = _getNode(basePath),
error;
if (node && baseNode) {
error = state.core.setBase(node, baseNode);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'setBase(' + path + ',' + basePath + ')');
}
}
/**
* @description Moves a node into a new container.
* @function moveNode
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} parentPath - the path/id of the new container node.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function moveNode(path, parentPath, msg) {
var node = _getNode(path),
parentNode = _getNode(parentPath),
movedPath;
if (node && parentNode) {
movedPath = storeNode(state.core.moveNode(node, parentNode));
saveRoot(typeof msg === 'string' ? msg : 'moveNode(' + path + ',' + parentPath + ')');
}
return movedPath;
}
/**
* @description Removes teh prototype ofd the node. Do not use this function
* as it is very dangerous!
* @function delBase
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delBase(path, msg) {
var node = _getNode(path),
error;
if (node) {
error = state.core.setBase(node, null);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'delBase(' + path + ')');
}
}
// META functions
/**
* @description Returns the JSON based meta description of the node.
* @function getMeta
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function getMeta(path) {
var node = _getNode(path),
meta = {children: {}, attributes: {}, pointers: {}, aspects: {}};
if (!node) {
return null;
}
meta = state.core.getJsonMeta(node);
return meta;
}
/**
* @description Set all the meta rules of a node based on a JSON.
* It has no effect on the inherited rules!
* @function setMeta
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {object} meta - the directory of rules to be set.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function setMeta(path, meta, msg) {
var node = _getNode(path),
otherNode,
name,
i,
error;
if (node) {
state.core.clearMetaRules(node);
//children
if (meta.children && meta.children.items && meta.children.items.length > 0) {
error = state.core.setChildrenMetaLimits(node, meta.children.min, meta.children.max);
if (error instanceof Error) {
printCoreError(error);
return;
}
for (i = 0; i < meta.children.items.length; i += 1) {
otherNode = _getNode(meta.children.items[i]);
if (otherNode) {
error = state.core.setChildMeta(node,
otherNode,
meta.children.minItems[i],
meta.children.maxItems[i]);
if (error instanceof Error) {
printCoreError(error);
return;
}
}
}
}
//attributes
if (meta.attributes) {
for (i in meta.attributes) {
error = state.core.setAttributeMeta(node, i, meta.attributes[i]);
if (error instanceof Error) {
printCoreError(error);
return;
}
}
}
//pointers and sets
if (meta.pointers) {
for (name in meta.pointers) {
if (meta.pointers[name].items && meta.pointers[name].items.length > 0) {
error = state.core.setPointerMetaLimits(node,
name,
meta.pointers[name].min,
meta.pointers[name].max);
if (error instanceof Error) {
printCoreError(error);
return;
}
for (i = 0; i < meta.pointers[name].items.length; i += 1) {
otherNode = _getNode(meta.pointers[name].items[i]);
if (otherNode) {
error = state.core.setPointerMetaTarget(node,
name,
otherNode,
meta.pointers[name].minItems[i],
meta.pointers[name].maxItems[i]);
if (error instanceof Error) {
printCoreError(error);
return;
}
}
}
}
}
}
//aspects
if (meta.aspects) {
for (name in meta.aspects) {
for (i = 0; i < meta.aspects[name].length; i += 1) {
otherNode = _getNode(meta.aspects[name][i]);
if (otherNode) {
error = state.core.setAspectMetaTarget(node, name, otherNode);
if (error instanceof Error) {
printCoreError(error);
return;
}
}
}
}
}
//constraints
if (meta.constraints) {
for (name in meta.constraints) {
if (typeof meta.constraints[name] === 'object') {
error = state.core.setConstraint(node, name, meta.constraints[name]);
if (error instanceof Error) {
printCoreError(error);
return;
}
}
}
}
saveRoot(typeof msg === 'string' ? msg : 'setMeta(' + path + ')');
}
}
/**
* @description Removes all Meta rules from the node (does not have effect on the inherited rules).
* @function clearMetaRules
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function clearMetaRules(path, msg) {
var node = _getNode(path);
if (node) {
state.core.clearMetaRules(node);
saveRoot(typeof msg === 'string' ? msg : 'clearMetaRules(' + path + ')');
}
}
/**
* @description Creates a mixin connection to the node.
* @function addMixin
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} addMixin - the path/id of the mixin node.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function addMixin(path, mixinPath, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.addMixin(node, mixinPath);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'addMixin(' + path + ',' + mixinPath + ')');
}
}
/**
* @description Removes a mixin connection from the node.
* @function delMixin
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} addMixin - the path/id of the mixin node.
* @param {string} [msg] - optional commit message, if not supplied a default one with the
* function name and input parameters will be used
* @instance
*/
function delMixin(path, mixinPath, msg) {
var error,
node = _getNode(path);
if (node) {
error = state.core.delMixin(node, mixinPath);
if (error instanceof Error) {
printCoreError(error);
return;
}
saveRoot(typeof msg === 'string' ? msg : 'delMixin(' + path + ',' + mixinPath + ')');
}
}
//TODO add function description
function setChildrenMetaAttribute(path, attrName, value, msg) {
if (attrName !== 'items') {
var rawMeta = getMeta(path);
rawMeta.children[attrName] = value;
setMeta(path, rawMeta, msg);
}
}
/**
* @description Creates a containment rule for the node.
* @function setChildMeta
* @memberOf Client
* @param {string} path - the path/id of the node that will be modified.
* @param {string} childPath - the path/id of the child node.
* @param {number} min - the minimum allowed number of children of this type.
* -1 means that there is no lower limit.
* @param {number} max - the maximum allowed number of children of this type.
* -1 ,eams there is no upper limit.