예제 #1
0
        private void UpdateLowerLevels(IExpressionNode myNode, LevelKey myCurrentLevelKey, IEnumerable<LevelKey> myLowerLevelKeys, IExpressionGraph myGraph)
        {
            if (myCurrentLevelKey.Level > 0)
            {
                lock (myGraph)
                {
                    //iterate the next lower LevelKeys
                    foreach (var aLowerLevelKey in myLowerLevelKeys)
                    {
                        #region data

                        //get next lower attribute (might be more than one step away)
                        int levelDistance = myCurrentLevelKey.Level - aLowerLevelKey.Level;
                        //GraphDBType currentType = null;
                        EdgeKey myCurrentBackwardEdgekey = null;
                        TypeAttribute currentAttribute = null;
                        SettingInvalidReferenceHandling invalidReferenceSetting = null;

                        #endregion

                        if (levelDistance >= 1)
                        {
                            if (myCurrentLevelKey.Level > 1)
                            {
                                myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[myCurrentLevelKey.Level - 1];
                            }
                            else
                            {
                                myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[0];
                            }
                        }
                        else
                        {
                            throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "Distances below 1 are not valid."));
                        }

                        IEnumerable<ObjectUUID> referencedUUIDs = null;
                        GraphDBType referencedType = null;
                        currentAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myCurrentBackwardEdgekey.TypeUUID).GetTypeAttributeByUUID(myCurrentBackwardEdgekey.AttrUUID);

                        if (currentAttribute.IsBackwardEdge)
                        {
                            var backwardEdgeTypeInfo = currentAttribute.BackwardEdgeDefinition.GetTypeAndAttributeInformation(_DBContext.DBTypeManager);

                            var dbObjectStream = myNode.GetDBObjectStream(_DBObjectCache, backwardEdgeTypeInfo.Item1.UUID);

                            referencedType = backwardEdgeTypeInfo.Item2.GetDBType(_DBContext.DBTypeManager);

                            if (dbObjectStream.HasAttribute(backwardEdgeTypeInfo.Item2.UUID, backwardEdgeTypeInfo.Item1))
                            {
                                referencedUUIDs = GetUUIDsForAttribute(dbObjectStream, backwardEdgeTypeInfo.Item2, backwardEdgeTypeInfo.Item1);
                            }
                        }
                        else
                        {
                            referencedType = currentAttribute.GetRelatedType(_DBContext.DBTypeManager);

                            if (myNode.BackwardEdges.ContainsKey(aLowerLevelKey.LastEdge))
                            {
                                //take the edges that are already available

                                referencedUUIDs = myNode.BackwardEdges[aLowerLevelKey.LastEdge].Select(item => item.Destination);
                            }
                            else
                            {
                                //load the backward edge stream
                                var currentBackwardEdgeStream = _DBObjectCache.LoadDBBackwardEdgeStream(currentAttribute.GetDBType(_DBContext.DBTypeManager), myNode.GetObjectUUID());

                                if (currentBackwardEdgeStream.Failed())
                                {
                                    throw new GraphDBException(new Error_CouldNotLoadBackwardEdge(myNode.GetDBObjectStream(_DBObjectCache, currentAttribute.GetRelatedType(_DBContext.DBTypeManager).UUID), currentAttribute, currentBackwardEdgeStream.IErrors));
                                }

                                if (currentBackwardEdgeStream.Value.ContainsBackwardEdge(myCurrentBackwardEdgekey))
                                {
                                    referencedUUIDs = currentBackwardEdgeStream.Value.GetBackwardEdgeUUIDs(myCurrentBackwardEdgekey);
                                }

                            }
                        }

                        if (referencedUUIDs != null)
                        {
                            var lowerLevelKeys = ExtractLowerLevelKeys(GetPreviousLevel(aLowerLevelKey.Level, myGraph.Levels), aLowerLevelKey, myGraph);

                            EdgeKey edgeKeyForBackwardEdge = null;
                            //get edgeKey for backwardEdge
                            if (myCurrentLevelKey.Level == 1)
                            {
                                edgeKeyForBackwardEdge = aLowerLevelKey.LastEdge;
                            }
                            else
                            {
                                edgeKeyForBackwardEdge = aLowerLevelKey.Edges[aLowerLevelKey.Level - 1];
                            }

                            Exceptional<DBObjectStream> referencedDBObject = null;

                            foreach (var aReferenceObjectUUID in referencedUUIDs)
                            {
                                referencedDBObject = _DBObjectCache.LoadDBObjectStream(referencedType, aReferenceObjectUUID);

                                if (!referencedDBObject.Success())
                                {
                                    #region error

                                    if (invalidReferenceSetting == null)
                                    {
                                        invalidReferenceSetting = (SettingInvalidReferenceHandling)_DBContext.DBSettingsManager.GetSetting(SettingInvalidReferenceHandling.UUID, _DBContext, Enums.TypesSettingScope.ATTRIBUTE, referencedType, currentAttribute).Value;
                                    }

                                    switch (invalidReferenceSetting.Behaviour)
                                    {
                                        case BehaviourOnInvalidReference.ignore:
                                            #region ignore

                                            //set lower levelKeys to null because it is not possible to go any lower
                                            AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, null, myGraph);
                                            myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null);

                                            #endregion
                                            break;
                                        case BehaviourOnInvalidReference.log:

                                            AddWarning(new Warning_EdgeToNonExistingNode(myNode.GetDBObjectStream(_DBObjectCache, referencedType.UUID), currentAttribute.GetDBType(_DBContext.DBTypeManager), currentAttribute, referencedDBObject.IErrors));

                                            break;

                                        default:

                                            throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace()));
                                    }

                                    #endregion

                                }
                                else
                                {
                                    AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, lowerLevelKeys, myGraph);
                                    myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        private void RemoveReferenceFromUpperLevel(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph)
        {
            #region remove reference from upper level

            if (myGraph.Levels.ContainsKey(mylevelKey.Level + 1))
            {
                foreach (var aForwardEdgeSet in myExpressionNode.ForwardEdges)
                {
                    var forwardLevelKey = GetForwardLevelKey(mylevelKey, aForwardEdgeSet.Key, _DBContext.DBTypeManager);

                    if (myGraph.ContainsLevelKey(forwardLevelKey))
                    {
                        //go to every object the forwardEdge points to and remove the backward reference
                        foreach (var aForwardEdge in aForwardEdgeSet.Value)
                        {
                            if (myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.ContainsKey(aForwardEdge.Destination))
                            {
                                myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].RemoveBackwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID());

                                if (!myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].BackwardEdges.Exists(item => item.Value.Count > 0))
                                {
                                    //the current object has no backward Edges... delete it

                                    //remove upper references
                                    RemoveReferenceFromUpperLevel(myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination], forwardLevelKey, myGraph);

                                    //remove the node itself
                                    myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.Remove(aForwardEdge.Destination);
                                }
                            }
                        }
                    }
                }
            }

            #endregion
        }
예제 #3
0
 private void MergeNodeIntoGraph(IExpressionGraph destinationGraph, LevelKey levelKey, IExpressionNode aNode, IExpressionGraph sourceGraph)
 {
     if (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes.ContainsKey(aNode.GetObjectUUID()))
     {
         if (levelKey.Level != 0)
         {
             //check if the node has backward edes
             if ((aNode.BackwardEdges.Count != 0) || (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes[aNode.GetObjectUUID()].BackwardEdges.Count != 0))
             {
                 //check if the node has backward edes
                 destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode);
             }
         }
         else
         {
             //nothing has to be checked
             destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode);
         }
     }
     else
     {
         //the node does not exist
         if (levelKey.Level != 0)
         {
             if (aNode.BackwardEdges.Exists(item => item.Value.Count != 0))
             {
                 //check if the node has backward edes
                 destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode);
             }
             else
             {
                 //remove the backward edge from the upper level
                 RemoveReferenceFromUpperLevel(aNode, levelKey, sourceGraph);
             }
         }
         else
         {
             //nothing has to be checked
             destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode);
         }
     }
 }
예제 #4
0
        private void RemoveNodeReferncesFromGraph(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph, HashSet<LevelKey> integratedByAnOtherGraph)
        {
            #region remove complex connection

            foreach (var aComplexConnection in myExpressionNode.ComplexConnection)
            {
                var expressionLevelEntry = myGraph.Levels[aComplexConnection.Key.Level].ExpressionLevels[aComplexConnection.Key];

                foreach (var aReference in aComplexConnection.Value)
                {
                    if (expressionLevelEntry.Nodes.ContainsKey(aReference))
                    {
                        expressionLevelEntry.Nodes[aReference].RemoveComplexConnection(mylevelKey, myExpressionNode.GetObjectUUID());
                        RemoveNodeReferncesFromGraph(expressionLevelEntry.Nodes[aReference], aComplexConnection.Key, myGraph, integratedByAnOtherGraph);
                    }

                    if (myGraph.Levels.ContainsKey(aComplexConnection.Key.Level - 1))
                    {
                        foreach (var aBackwardEdgeSet in expressionLevelEntry.Nodes[aReference].BackwardEdges)
                        {
                            //go to every object the backwardEdge points to and remove the forward reference

                            var backwardLevelKey = GetBackwardLevelKey(aComplexConnection.Key, aBackwardEdgeSet.Key, _DBContext.DBTypeManager);

                            if (myGraph.ContainsLevelKey(backwardLevelKey))
                            {
                                foreach (var aBackwardEdge in aBackwardEdgeSet.Value)
                                {
                                    if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination))
                                    {
                                        myGraph.Levels[backwardLevelKey.Level].RemoveNode(backwardLevelKey, aBackwardEdge.Destination);
                                    }
                                }
                            }
                        }
                    }

                    myGraph.Levels[aComplexConnection.Key.Level].RemoveNode(aComplexConnection.Key, aReference);
                }
            }

            #endregion

            #region remove reference from lower level

            if (mylevelKey.Level != 0)
            {
                if (myGraph.Levels.ContainsKey(mylevelKey.Level - 1))
                {
                    foreach (var aBackwardEdgeSet in myExpressionNode.BackwardEdges)
                    {
                        //go to every object the backwardEdge points to and remove the forward reference

                        var backwardLevelKey = GetBackwardLevelKey(mylevelKey, aBackwardEdgeSet.Key, _DBContext.DBTypeManager);

                        if (myGraph.ContainsLevelKey(backwardLevelKey))
                        {
                            foreach (var aBackwardEdge in aBackwardEdgeSet.Value)
                            {
                                if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination))
                                {
                                    myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes[aBackwardEdge.Destination].RemoveForwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID());
                                }
                            }
                        }
                    }
                }
            }

            #endregion

            RemoveReferenceFromUpperLevel(myExpressionNode, mylevelKey, myGraph);
        }
예제 #5
0
        public void AddNode(LevelKey levelKey, IExpressionNode expressionNode)
        {
            lock (_Content)
            {
                if (_Content.ContainsKey(levelKey))
                {
                    var tempObjectUUID = expressionNode.GetObjectUUID();

                    if (_Content[levelKey].Nodes.ContainsKey(tempObjectUUID))
                    {
                        //the node already exist, so update its edges
                        foreach (var aBackwardEdge in expressionNode.BackwardEdges)
                        {
                            _Content[levelKey].Nodes[tempObjectUUID].AddBackwardEdges(aBackwardEdge.Value);
                        }

                        foreach (var aForwardsEdge in expressionNode.ForwardEdges)
                        {
                            _Content[levelKey].Nodes[tempObjectUUID].AddForwardEdges(aForwardsEdge.Value);
                        }
                    }
                    else
                    {
                        _Content[levelKey].Nodes.Add(tempObjectUUID, expressionNode);
                    }
                }
                else
                {
                    _Content.Add(levelKey, new ExpressionLevelEntry(levelKey));
                    _Content[levelKey].Nodes.Add(expressionNode.GetObjectUUID(), expressionNode);
                }
            }
        }