Skip to content
Snippets Groups Projects
contentProcess.js 10.47 KiB
import("system.db");
import("system.translate");
import("system.result");
import("system.vars");
import("ObjectRelation_lib");
import("Context_lib");
import("Sql_lib");

var tree = []
var filter = JSON.parse(vars.get("$local.filter"))
var selectedRelationType = null;

if (filter)
{
    if (filter.childs.length > 0)
    {
        selectedRelationType = filter.childs[0].value;
    }
}
var originalObjectId = vars.get("$param.ObjectId_param");

_loadObjectRelationTree(originalObjectId, vars.get("$param.ObjectType_param"), selectedRelationType);

result.object(tree);

function _loadObjectRelationTree(pObjectId, pObjectType, pObjectRelationTypeId, pNodeId, pLayer, pRelationTypeData)
{
    // prevent stack overflows
    if (pLayer > 30)
        return;
    
    if (pLayer == undefined)
        pLayer = 0;
    
    if (pNodeId == undefined)
        pNodeId = null;
        
    var currentObjectId = pObjectId
        
    if (currentObjectId && pObjectType)
    {
        if (pLayer == 0)
        {
            if (pObjectRelationTypeId)
            {
                var relationTypeData = ObjectRelationUtils.getRelationType(pObjectRelationTypeId);
                
                // if hirachy: get most top id else use the current currentObjectId
                if (relationTypeData[4] == "1")
                {
                    // use always reverse-type
                    relationTypeData = ObjectRelationUtils.getRelationType(relationTypeData[8]);
                    currentObjectId = _getRootID(currentObjectId, relationTypeData);
                }
                
                let uids = _insertEntry(tree, [[currentObjectId, "", "", "", "", relationTypeData[7]]], pNodeId, pLayer, pObjectType, selectedRelationType)
                for (let i = 0; i < uids.length; i++) 
                {                    
                    _loadObjectRelationTree(uids[i][0], uids[i][3], relationTypeData[0], uids[i], pLayer+1, relationTypeData);
                }
            }
            else // no ObjectType chosen
            {
                // load all ObjectRelationTypes
                var relationTypes = _getRelationTypes(pObjectType);
                
                for (let i=0; i<relationTypes.length; i++)
                {   
                    var data = _getEntryData(currentObjectId, relationTypes[i][3], relationTypes[i][7], relationTypes[i][8]);
                    
                    // if any subentry: show objectType
                    if (data.length > 0)
                    {
                        // TODO: Icons, BINDATA
                        // var icon = getIcon...
                        let uid = [currentObjectId, i, relationTypes[i]];
                        tree.push([JSON.stringify(uid), translate.text(relationTypes[i][1]), JSON.stringify(pNodeId), true, null, null, "", relationTypes[i][0]]);
                        
                        _loadObjectRelationTree(pObjectId, pObjectType, pObjectRelationTypeId, uid, pLayer+1, relationTypeData);
                    }
                }
            }
        }
        else if (pLayer >= 1)
        {
            // if no relationType given, load from nodeId
            if (!pRelationTypeData)
                pRelationTypeData = pNodeId[2];
            var thisRelationTypeId = pRelationTypeData[0];
            var otherRelationTypeId = pRelationTypeData[10];            
            var hierarchy = pRelationTypeData[4];
            var destObjectType = pRelationTypeData[6];
            var relationType1 = pRelationTypeData[7];
            var relationType2 = pRelationTypeData[8];
            var direction = pRelationTypeData[3];
            
            var relationTypeIdForNew = otherRelationTypeId;
            
            if (hierarchy == "1")
            {
                var myData = _getEntryData(pNodeId[0], direction, relationType1, relationType2)
                
                
                
                // if hierarchy and selected RelationType -> use the selected one
                if (selectedRelationType)
                    relationTypeIdForNew = selectedRelationType
                else
                    relationTypeIdForNew = thisRelationTypeId;
                
                
                let uids = _insertEntry(tree, myData, pNodeId, pLayer, destObjectType, relationTypeIdForNew)
                for (let i = 0; i < uids.length; i++) 
                {                    
                    _loadObjectRelationTree(uids[i][0], uids[i][3], pObjectRelationTypeId, uids[i], pLayer+1, pRelationTypeData);
                }
            }
            else
            {
                // pNodeId[4] is the previous NodeId and pNodeId[4][0] the previous ObjectId
                var prevObjectId;
                if (pNodeId[4] != undefined)
                {
                    prevObjectId = pNodeId[4][0];
                }
                
                var entryData = _getEntryData(pNodeId[0], direction, relationType1, relationType2, prevObjectId, true);

                if (direction == "same")
                    relationTypeIdForNew = thisRelationTypeId

                // add both sides. Only one will succeed, because the prevObjectId will be filtered and it will just return []
                let uids = _insertEntry(tree, entryData, pNodeId, pLayer, destObjectType, thisRelationTypeId, 0);
                if (direction == "same")
                {
                    var otherEntryData = _getEntryData(pNodeId[0], "normal", relationType1, relationType2, prevObjectId, true);
                    uids = uids.concat(_insertEntry(tree, otherEntryData, pNodeId, pLayer, destObjectType, thisRelationTypeId, 1));
                }
                                
                for (let i = 0; i < uids.length; i++) 
                {   
                    _loadObjectRelationTree(uids[i][0], uids[i][3], pObjectRelationTypeId, uids[i], pLayer+1, pRelationTypeData);
                }
            }
        }
    }
}

/**
 * load data for a relation.
 * OBJECT_ROWID, AB_OBJECTRELATIONID, OBJECT_TYPE, RELATION_TITLE, AB_OBJECTRELATIONTYPEID
 * 
 * @param {String} pObjectId
 * @param {String} pDirection
 * @param {String} pRelationType1
 * @param {String} pRelationType2
 * @param {String} pPrevId Id of the previous node to exclude it
 * @param {Boolean} [pNoRecursion=false] if false: select for direction "same" the other direction, if result is empty.
 * 
 * @return {[][]}
 */
function _getEntryData(pObjectId, pDirection, pRelationType1, pRelationType2, pPrevId, pNoRecursion)
{
    if (pRelationType1 == undefined || pRelationType2 == undefined) 
        return [];
 
    var myNum;
    var otherNum;
        
    if (pDirection == "normal") 
    {
        otherNum = 1;
        myNum = 2;
    }
    else
    {
        otherNum = 2;
        myNum = 1;
    }
        
    var cond = SqlCondition.begin()
                           .andPrepare("AB_OBJECTRELATION.AB_OBJECTRELATIONTYPE1", pRelationType1)
                           .andPrepare("AB_OBJECTRELATION.AB_OBJECTRELATIONTYPE2", pRelationType2)
                           .andPrepare("AB_OBJECTRELATION.OBJECT" + myNum + "_ROWID", pObjectId);
    
    // exclude previous node
    if (!pPrevId)
        cond.and("AB_OBJECTRELATION.OBJECT" + otherNum + "_ROWID is not null");
    else
    {
        cond.andPrepare("AB_OBJECTRELATION.OBJECT" + otherNum + "_ROWID", pPrevId, "# <> ?");
    }
        
    // TODO: BINDATA?
    // var image = getImageObject("Beziehung");

    var data = db.table(cond.buildSql(
                "select OBJECT" + otherNum + "_ROWID, AB_OBJECTRELATIONID, OBJECT_TYPE, RELATION_TITLE, INFO, AB_OBJECTRELATIONTYPEID \n\
                 from AB_OBJECTRELATION \n\
                 join AB_OBJECTRELATIONTYPE on AB_OBJECTRELATIONTYPEID = AB_OBJECTRELATIONTYPE" + myNum + " and ","1=2", "", false));

    if (data.length == 0 && pDirection == "same" && !pNoRecursion)
    {
         return _getEntryData(pObjectId, "normal", pRelationType1, pRelationType2, pPrevId, true)
    }
    
    // TODO: BINDATA?
    //for ( var i = 0; i < data.length; i++)  data[i][2] = image[data[i][2]] == undefined ? "" : image[data[i][2]];
    return data;
}

function _getRelationTypes(pObjectType)
{
    // TODO: load from entity when possible
    return ObjectRelationUtils.getPossibleRelationTypes(pObjectType, true);
}

/**
 * insert a new Entry
 * 
 * @param {Array} pTree
 * @param {Array[][]} pEntryData
 * @param {Array[][]} pNodeId id of the parent
 * @param {Integer} pLayer layernumber
 * @param {String} pObjectType
 * @param {String} pNewRelationTypeId the RelationType, a new relation should have, if this node is selected.
 * @param {Integer} [pNum=undefined] optional number added to the key. Needed, if the key would not be unique.
 * 
 * @return {Array[][]} the uids of the inserted data. Consists of [ObjectId, pEntryData-Index, AB_OBJECTRELATIONTYPEID, pObjectType, pNodeId, objectrelationid, objecttype
 */
function _insertEntry(pTree, pEntryData, pNodeId, pLayer, pObjectType, pNewRelationTypeId, pNum)
{
    var expanded = true;
    if (pLayer > 10) expanded = false;
    // TODO: display address (tooltip wird denke ich nicht benötigt, da preview vorhanden)
    var uids = [];
    for(let i = 0; i < pEntryData.length; i++)
    {
        var display = db.cell(ContextUtils.getNameSql(pObjectType, pEntryData[i][0]));
        // TODO: Icon                       
        var uid = [pEntryData[i][0], i, pEntryData[i][5], pObjectType, pNodeId, pEntryData[i][2], pEntryData[i][1]]
        if (pNum)
            uid.push(pNum);
        uids.push(uid);
        pTree.push([JSON.stringify(uid), display, JSON.stringify(pNodeId), expanded, pEntryData[i][0], pObjectType, pEntryData[i][4], pNewRelationTypeId]);
    }
    return uids;
}

/*
* get most top root of a node
*
* @param {String} pObjectId
* @param {String[]} pObjectRelationTypeData
*
* @return {String} RootObjectId        
*/
function _getRootID(pObjectId, pObjectRelationTypeData) 
{
    var sourceid = pObjectId;
    var max = 100;
    do
    {
        var rootid = sourceid;
        max--;
        sourceid = db.cell(SqlCondition.begin()
                                       .andPrepare("AB_OBJECTRELATION.OBJECT2_ROWID", sourceid)
                                       .andPrepare("AB_OBJECTRELATION.AB_OBJECTRELATIONTYPE1", pObjectRelationTypeData[7])
                                       .andPrepare("AB_OBJECTRELATION.AB_OBJECTRELATIONTYPE2", pObjectRelationTypeData[8])
                                       .buildSql("select OBJECT1_ROWID from AB_OBJECTRELATION", "1=2"))
    }
    while( sourceid != "" && max > 0 );
    return rootid; 
    return currentObjectId;
}