Files
Unify/framework/server/core.js
2025-12-25 11:16:59 +01:00

1015 lines
17 KiB
JavaScript

/*
Copyright (c) 2020, 2023, The Unified Company.
This code is part of Unify.
This program is free software; you can redistribute it and/or modify
it under the terms of the ESA Software Community License - Strong Copyleft LICENSE,
as published by the ESA.
See the ESA Software Community License - Strong Copyleft LICENSE, for more details.
https://unifyjs.org
*/
import tableManager from '../server/tableManager.js';
import datatype from '../unify/datatype.js';
import tools from '../unify/tools.js';
import unify from '../unify/unify.js';
import collection from '../unify/collection.js';
import permissions from '../unify/permissionManager.js';
import moduleLoader from './moduleLoader.js';
import Console from './console.js';
import deepclone from '../unify/clonedeep.js';
import consoleColors from '../unify/consoleColors.js';
export default class core{
__className = "core";
tableManager = new tableManager();
root = false;
client = false;
propertyNames = new Array();
setUserObjects( user, client ) {
var root = client.application;
var userInstance = new global.user();
this.user = userInstance;
this.extendDefaultObject( userInstance );
userInstance.id = user.id;
userInstance.get();
userInstance.userType = "currentUser";
userInstance.parent = false;
this.setUserObjectsChildren( userInstance, client, root );
}
removeObject( className, id, client ) {
if( !this.classObjects ) {
return false;
}
if( this.classObjects ) {
var clientClassObjects = this.classObjects;
} else {
var clientClassObjects = client.classObjects;
}
if( className && id ) {
var classObjects = this.classObjects[ className ];
if( classObjects ) {
var object = classObjects[ id ];
if( object ) {
// todo bug This causes an infinity loop error
//this.removeChildren( object );
delete client.classObjects[ className ][ id ];
}
}
}
}
setUserObjectsChildren( user, client, object ) {
if( object && object.getChildren ) {
var objects = object.getChildren();
for ( var i = 0; i < objects.length; i++ ) {
if( user ) {
objects[i].user = user;
} else {
objects[i].user = false;
}
if( objects[i].permission ) {
objects[i].permissionManager.permissions = new Array();
var clone = tools.structuredClone( objects[i] );
objects[i].permission( clone );
}
this.setUserObjectsChildren( user, client, objects[i] );
}
}
}
extendDefaultObject( object ) {
if( unify.extend( object ) ) {
return true;
} else {
return false;
}
}
prepareObject( object, client ) {
object.permissionManager = new permissions();
if( this.user && client ) {
object.user = client.user;
}
if( object.permission ) {
object.permissionManager.permissions = new Array();
var clone = tools.structuredClone(object);
object.permission( clone );
}
if( object.prepare ) {
object.prepare();
}
}
addObject( object, client ) {
if( client ) {
client.objects.push( object );
if( !this.getObjectByclassName( object.getClassName(), client ) ) {
client.classObjects[ object.getClassName() ] = object;
}
}
}
parseClient( object, objects ) {
objects.push( object );
var children = object.getChildren();
for( var c = 0; c<children.length; c++ ) {
var child = children[c];
var className = child.getClassName();
this.parseClientChild( child, objects );
}
}
parseClientChild( child, objects ) {
var className = child.getClassName();
switch( className ) {
case "renderCollection":
//this.parseClient( child.object, objects );
break;
case "collection":
break;
default:
this.parseClient( child, objects );
}
}
isClass( obj ) {
if(!obj) {
return false;
}
if( Array.isArray( obj ) ) {
return true;
}
const isCtorClass = obj.constructor
&& obj.constructor.toString().substring(0, 5) === 'class'
if(obj.prototype === undefined) {
return isCtorClass
}
const isPrototypeCtorClass = obj.prototype.constructor
&& obj.prototype.constructor.toString
&& obj.prototype.constructor.toString().substring(0, 5) === 'class'
return isCtorClass || isPrototypeCtorClass
}
getTables( object, tableStorage ) {
var className = tools.getClassName( object );
if( object.type == "table" ) {
tableStorage[className] = tools.getTableFromObject( object );
}
var children = tools.getChildren( object );
for( var c = 0; c<children.length; c++ ) {
var child = children[c];
this.getTables( child, tableStorage );
}
}
removeCollectionObject( object, parentClassName, collectionStorage ) {
var children = tools.getChildren( object );
var className = tools.getClassName( object );
if( object.permission ){
console.log("this object has a method called permission", className)
}
switch( object.type ) {
case "renderCollection":
if( object.collections ){
//console.log("renderCollection - remove object from collection ", object);
collectionStorage[className] = object.object;
object.object = false;
if( object.collections[0]) {
object.collections[0].object = false;
}
}
break;
case "collection":
//console.log("parsing collection ", parentClassName);
collectionStorage[parentClassName] = object.object;
object.object = false;
break;
}
for( var c = 0; c<children.length; c++ ) {
var child = children[c];
this.removeCollectionObject( child, className, collectionStorage );
}
}
prepareClone( object, removedMethods ) {
var nodeMethodsString = object.__nodeMethods;
var className = tools.getClassName( object );
if(!removedMethods[className]) {
removedMethods[className] = new Array();
}
if( nodeMethodsString ) {
var nodeMethods = nodeMethodsString.split(",");
for (var i = 0; i < nodeMethods.length; i++) {
var nodeMethodName = nodeMethods[i]
removedMethods[className][nodeMethodName] = object[nodeMethodName];
}
}
//console.log("className", tools.getClassName( object ), object.type)
var properties = Object.getOwnPropertyNames( object );
var propertiesFiltered = properties.filter( prop => prop !== "constructor" );
for ( const prop of propertiesFiltered ) {
try{
structuredClone( object[prop] )
} catch{
if( !this.isClass( object[prop] ) ) {
removedMethods[className][prop] = object[prop];
delete object[prop];
//console.log("---------", prop);
}
}
}
var methods = tools.getAllFuncs( object );
var skip = new Array("hasOwnProperty", "isPrototypeOf", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "length")
for (var i = 0; i < methods.length; i++) {
var method = methods[i]
if( skip.includes( method ) ){
continue;
}
try{
structuredClone( object[method] )
} catch{
if( !this.isClass( object[method] ) ) {
//console.log("??????", method);
removedMethods[className][method] = object[method];
delete object[method];
}
}
}
var extendedInstance = new object.constructor();
var prototype = Object.getPrototypeOf( extendedInstance );
var propertyNames = Object.getOwnPropertyNames( prototype );
propertyNames.forEach( methodName => {
if( !this.isClass( object[methodName] ) ) {
//console.log("---------", methodName);
removedMethods[className][methodName] = object[methodName];
delete object[methodName];
}
});
var properties = tools.getProperties( object );
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
if( tools.isCSSProperty( property.name ) ) {
delete object[property.name];
}
}
if( object.type == "table" ) {
//console.log("get table", tools.getTableFromObject( object ));
var table = tools.getTableFromObject( object );
if( table ) {
object.tableName = tools.getClassName( table );
}
//object.tableName = tools.getClassName( );
}
if( object.type == "collectionQuery") {
//console.log("collectionQuery", className);
return true;
}
var children = tools.getChildren( object );
for( var c = 0; c<children.length; c++ ) {
var child = children[c];
if( child.queryChildren ) {
//console.log("prepareClone queryChildren");
this.prepareClone( child.queryChildren, removedMethods );
this.prepareClone( child.queryRoot, removedMethods );
}
this.prepareClone( child, removedMethods );
}
}
fastParse( object, client, parent ){
var className = tools.getClassName( object );
client.objects.push( object );
if( !this.getObjectByclassName( className, client ) ) {
client.classObjects[ className ] = object;
}
object.permissionManager = new permissions();
if( object.type == "renderCollection" ) {
if( object.collections && object.collections[0] ) {
var collection = object.collections[0];
// collection.parent = object;
// collection.parentName = tools.getClassName(object)
this.fastParse( collection, client );
this.fastParse( collection.queryChildren, client );
this.fastParse( collection.queryRoot, client );
}
}
if( object.type == "collection" ) {
//object.parent = parent;
this.fastParse( object.queryChildren, client );
this.fastParse( object.queryRoot, client );
}
if( object.type == "collectionQuery" ) {
return true;
}
var children = tools.getChildren( object );
for( var c = 0; c < children.length; c++ ) {
var child = children[c];
child.parent = object;
this.fastParse( child, client, object );
}
}
collectObjects( object, client ) {
client.objects.push( object );
var className = tools.getClassName( object );
if( !this.getObjectByclassName( className, client ) ) {
client.classObjects[ className ] = object;
}
if( object.type == "renderCollection" ) {
if( object.collections && object.collections[0] ) {
var collection = object.collections[0];
//collection.parent = object;
this.collectObjects( collection, client );
}
}
var children = tools.getChildren( object );
for( var c = 0; c < children.length; c++ ) {
var child = children[c];
child.parent = object;
this.collectObjects( child, client );
}
}
fastParse( object, client, ultra = false ){
//if( !this.extendDefaultObject( object ) ) {
// return false;
//}
if( !this.root ) {
this.root = object;
}
//this.prepareObject( object, client );
client.objects.push( object );
if( !this.getObjectByclassName( tools.getClassName(object), client ) ) {
client.classObjects[ tools.getClassName(object) ] = object;
}
if( object.type == "renderCollection" ) {
if( object.collections && object.collections[0] ) {
var collection = object.collections[0];
//collection.parent = object;
this.fastParse( collection, client );
// this should only be enabled on ultra fast parse
// but commented on fast parse.
if( ultra ) {
this.fastParse( collection.queryChildren, client );
this.fastParse( collection.queryRoot, client );
}
}
}
this.prepareObject( object, client );
if( object.type == "collectionQuery" ) {
return true;
}
var children = tools.getChildren( object );
for( var c = 0; c < children.length; c++ ) {
var child = children[c];
child.parent = object;
this.fastParse( child, client, ultra );
}
}
parse( object, client ) {
this.parseServer( object, client );
}
parseServer( object, client ){
if( !this.extendDefaultObject( object ) ) {
return false;
}
if( typeof object == "boolean" ) {
return false;
}
if( !this.root ) {
this.root = object;
}
this.tableManager.parse( object );
this.prepareObject( object, client );
this.addObject( object, client );
if( object.parent ) {
this.prepareCollection( object.parent, object );
}
var children = object.getChildren();
for( var c = 0; c < children.length; c++ ) {
var child = children[c];
this.parseChild( child, client );
}
}
findDuplicates( object ) {
this.extendDefaultObject( object );
for (var i = 0; i < this.propertyNames.length; i++) {
var propertyName = this.propertyNames[i];
if( propertyName == object.propertyName ) {
//tools.logError("Object dublicate not allowed: " + object.getClassName() );
}
}
this.propertyNames.push( object.getClassName() );
if( object.getChildren ) {
var children = object.getChildren();
for(var c = 0; c<children.length; c++) {
var child = children[c];
this.findDuplicates( child );
}
}
}
parseRenderCollection( child, client ) {
if( child.object ) {
var object = child.object;
var instance = new object();
this.parseServer( instance, client );
}
this.parseServer( child, client );
}
parseCollection( child, client, propertyName ) {
this.parseServer( child, client );
if( propertyName != "collection" ) {
this.parseInstance( child, client );
}
}
parseChild( child, client, parseRenderCollection ) {
var propertyName = child.propertyName;
unify.extend( child );
var className = tools.getClassName( child );
switch( child.type ) {
case "renderCollection":
this.parseRenderCollection( child, client );
break;
case "collection":
this.parseCollection( child, client, propertyName );
break;
default:
this.parseServer( child, client );
}
}
parseInstance( object, client ){
var instance = object.createInstance();
var className = tools.getClassName( instance );
if( !this.getObjectByclassName( className, client ) ) {
this.parseServer( instance, client );
}
}
mapExtendedDependencies( currentClass, extendObjects, client ) {
for ( var i = 0; i < extendObjects.length; i++ ) {
var extendName = extendObjects[i];
if( !client.dependencieMap[ extendName ] ) {
client.dependencieMap[ extendName ] = new Array();
}
//console.log(currentClass.getClassName(), "to", extendName );
client.dependencieMap[ extendName ].push( currentClass );
}
}
createDependencyMap( client ) {
var classObjects = client.objects;
client.dependencieMap = new Array();
for (var i = 0; i < classObjects.length; i++) {
var currentClass = classObjects[i];
var extendObjects = currentClass.getExtends();
extendObjects = tools.removeDuplicates( extendObjects );
this.mapExtendedDependencies( currentClass, extendObjects, client );
}
//console.log("map for input", client.dependencieMap["input"].length);
}
getObjectByclassName( className, client ) {
if( !client ) {
return true;
}
var objects = client.classObjects[ tools.validateString( className ) ];
if( objects ) {
return objects;
} else {
return false;
}
}
prepareCollection( object, property ) {
if( object.table ) {
this.prepareStorageCollection( object, property );
}
}
prepareStorageCollection( parentObject, object ) {
var tableObject = parentObject.table;
var tableProperty = tableObject[ object.propertyName ];
if( tableProperty ) {
if( tableProperty.object ) {
var tableName = tools.getClassName( new tableProperty.object() );
var parentName = tools.getClassName( tableObject );
if( object.storageCollection ) {
object.storageCollection.propertyName = object.propertyName;
object.storageCollection.tableName = tableName;
object.storageCollection.parentName = parentName;
object.storageCollection.enabled = true;
}
}
}
}
getObjectByclassNameClone( className ) {
return deepclone( this.getObjectByclassName( className ) );
}
}