示例#1
0
        public virtual void AfterPropertiesSet(IBeanContextFactory beanContextFactory)
        {
            ParamChecker.AssertNotNull(RevertChangesHelper, "RevertChangesHelper");
            ParamChecker.AssertNotNull(SharedData, "SharedData");
            ParamChecker.AssertNotNull(SharedDataHandOnExtendable, "SharedDataHandOnExtendable");

            //TODO: inject Uri as bean
#if SILVERLIGHT
            Uri uri = HtmlPage.Document.DocumentUri;
#else
            Uri uri = null;
            if (uri == null)
            {
                throw new NotSupportedException("This code has to be compatible with .NET first");
            }
#endif

            ISet <String> allBeanNames = new HashSet <String>();
            if (BeansToConsume != null)
            {
                allBeanNames.UnionWith(BeansToConsume.Keys);
            }

            IDictionary <String, IModelContainer> data = null;
            if (Token != null)
            {
                data = SharedData.Read(Token);
            }
            if (data == null)
            {
                // Clear token to suppress handsOn in afterStarted()
                Token = null;
                data  = new Dictionary <String, IModelContainer>();
            }
            IModelMultiContainer <Uri> uriList = (IModelMultiContainer <Uri>)DictionaryExtension.ValueOrDefault(data, SourceUriBeanName);
            if (uriList != null)
            {
                //Url-list is avaliable
                uriList.Values.Add(uri);
            }
            allBeanNames.UnionWith(data.Keys);

            if (!allBeanNames.Contains(SourceUriBeanName))
            {
                //Url-list is not avaliable
                beanContextFactory.RegisterBean <ModelMultiContainer <Uri> >(SourceUriBeanName).PropertyValue("Value", uri);
            }

            IdentityHashSet <Object> allProvidedBusinessObjects = new IdentityHashSet <Object>();
            foreach (String nameInOwnContext in allBeanNames)
            {
                //Proecess the input
                IModelContainer dataContainer = DictionaryExtension.ValueOrDefault(data, nameInOwnContext);
                if (dataContainer != null)
                {
                    if (dataContainer is IModelMultiContainer)
                    {
                        IEnumerable businessObjects = ((IModelMultiContainer)dataContainer).ValuesData;
                        if (businessObjects != null)
                        {
                            allProvidedBusinessObjects.AddAll(businessObjects.Cast <object>());
                        }
                    }
                    else if (dataContainer is IModelSingleContainer)
                    {
                        Object businessObject = ((IModelSingleContainer)dataContainer).ValueData;
                        if (businessObject != null)
                        {
                            allProvidedBusinessObjects.Add(businessObject);
                        }
                    }
                    //By copying only the data, listeners are unregistered
                    //beanContextFactory.registerBean(name, dataContainer.GetType()).propertyValue("Data", dataContainer.Data);
                    beanContextFactory.RegisterExternalBean(nameInOwnContext, dataContainer);
                    continue;
                }
                if (!BeansToConsume.ContainsKey(nameInOwnContext))
                {
                    continue;
                }
                //Process default-beans
                String aliasToDefaultBean = BeansToConsume[nameInOwnContext];
                if (aliasToDefaultBean == null)
                {
                    //Mandatory parameter was not present in data
                    throw new Exception("The new Screen has not all mandatory information: \"" + nameInOwnContext + "\" is missing.");
                }
                if (!nameInOwnContext.Equals(aliasToDefaultBean))
                {
                    beanContextFactory.RegisterAlias(nameInOwnContext, aliasToDefaultBean);
                }
            }
            if (allProvidedBusinessObjects.Count > 0)
            {
                IRevertChangesSavepoint savepoint = RevertChangesHelper.CreateSavepoint(allProvidedBusinessObjects);
                beanContextFactory.RegisterExternalBean(savepoint).Autowireable <IRevertChangesSavepoint>();
            }
        }
示例#2
0
        protected virtual void RevertChangesIntern(IRevertChangesSavepoint savepoint, IList <Object> objectsToRevert, bool globally,
                                                   RevertChangesFinishedCallback revertChangesFinishedCallback)
        {
            // Store the RevertChangesFinishedCallback from this thread on the stack and set the property null (for following calls):
            if (objectsToRevert == null || objectsToRevert.Count == 0)
            {
                if (revertChangesFinishedCallback != null)
                {
                    revertChangesFinishedCallback.Invoke(true);
                }
                return;
            }
            if (globally)
            {
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    bool success = false;
                    try
                    {
                        DataChangeEvent dataChange = new DataChangeEvent();
                        dataChange.IsLocalSource   = true;
                        dataChange.Inserts         = new List <IDataChangeEntry>(0);
                        dataChange.Updates         = new List <IDataChangeEntry>();
                        dataChange.Deletes         = new List <IDataChangeEntry>();

                        for (int a = objectsToRevert.Count; a-- > 0;)
                        {
                            Object objectToRevert    = objectsToRevert[a];
                            IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData();
                            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                            if (id == null)
                            {
                                dataChange.Deletes.Add(new DirectDataChangeEntry(objectToRevert));
                                continue;
                            }
                            dataChange.Updates.Add(new DataChangeEntry(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                        }

                        EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                        success = true;
                    }
                    finally
                    {
                        if (revertChangesFinishedCallback != null)
                        {
                            revertChangesFinishedCallback.Invoke(success);
                        }
                    }
                });
            }
            else
            {
                // Commented the following part from Ambeth 0.130 and use the part from Ambeth 0.129 due to a deadlock in the merge process:
                //GuiThreadHelper.InvokeOutOfGui(delegate()
                //{
                //    bool success1 = false;
                //    try
                //    {
                //        IList<IDataChangeEntry> directObjectDeletes = new List<IDataChangeEntry>();
                //        IList<Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null);

                //        IList<IObjRef> orisToRevert = new List<IObjRef>();
                //        ISet<Object> persistedObjectsToRevert = new IdentityHashSet<Object>();
                //        for (int a = initializedObjects.Count; a-- > 0; )
                //        {
                //            Object objectToRevert = initializedObjects[a];
                //            IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objectToRevert.GetType());
                //            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                //            if (id == null)
                //            {
                //                directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert));
                //                continue;
                //            }
                //            persistedObjectsToRevert.Add(objectToRevert);
                //            orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                //        }
                //        IList<Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses);

                //        for (int a = orisToRevert.Count; a-- > 0; )
                //        {
                //            if (hardRefsToRootCacheValues[a] == null)
                //            {
                //                // Object could not be loaded/retrieved any more. So the ori refers to an invalid object
                //                // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will
                //                // be tried to persist in a merge process any time in the future
                //                orisToRevert.RemoveAt(a);
                //            }
                //        }
                //        // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack
                //        // To prohibit GC any potential WeakReferences in the meantime....
                //        GuiThreadHelper.InvokeInGuiAndWait(delegate()
                //        {
                //            IProcessResumeItem processResumeItem = WaitEventToResume();
                //            try
                //            {
                //                bool oldCacheModificationValue = CacheModification.IsActive;
                //                CacheModification.IsActive = true;
                //                bool oldFailEarlyModeActive = AbstractCache<Object>.FailEarlyModeActive;
                //                AbstractCache<Object>.FailEarlyModeActive = true;
                //                try
                //                {
                //                    IList<IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches();
                //                    IList<Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues;

                //                    foreach (IWritableCache firstLevelCache in firstLevelCaches)
                //                    {
                //                        IList<Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly);

                //                        for (int a = persistedObjectsInThisCache.Count; a-- > 0; )
                //                        {
                //                            Object persistedObjectInThisCache = persistedObjectsInThisCache[a];
                //                            if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache))
                //                            {
                //                                continue;
                //                            }
                //                            RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache);
                //                        }
                //                    }
                //                    for (int a = objectsToRevert.Count; a-- > 0; )
                //                    {
                //                        Object objectToRevert = objectsToRevert[a];
                //                        if (objectToRevert is IDataObject)
                //                        {
                //                            // Objects which are specified to be reverted loose their delete flag
                //                            ((IDataObject)objectToRevert).ToBeDeleted = false;
                //                        }
                //                    }
                //                }
                //                finally
                //                {
                //                    AbstractCache<Object>.FailEarlyModeActive = oldFailEarlyModeActive;
                //                    CacheModification.IsActive = oldCacheModificationValue;
                //                }
                //            }
                //            finally
                //            {
                //                if (processResumeItem != null)
                //                {
                //                    processResumeItem.ResumeProcessingFinished();
                //                    processResumeItem = null;
                //                }
                //            }
                //        });
                //        if (directObjectDeletes.Count > 0)
                //        {
                //            DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0);
                //            dataChange.Deletes = directObjectDeletes;

                //            EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                //        }
                //        success1 = true;
                //    }
                //    finally
                //    {
                //        if (revertChangesFinishedCallback != null)
                //        {
                //            revertChangesFinishedCallback.Invoke(success1);
                //        }
                //    }
                //});

                // Here comes the part from Ambeth 0.129:
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    bool success1 = false;
                    bool?success2 = null;
                    bool?success3 = null;
                    try
                    {
                        IList <IDataChangeEntry> directObjectDeletes = new List <IDataChangeEntry>();
                        List <IObjRef> objRefs = new List <IObjRef>();
                        List <ValueHolderRef> valueHolderKeys = new List <ValueHolderRef>();
                        IList <Object> initializedObjects     = MergeController.ScanForInitializedObjects(objectsToRevert, true, null, objRefs, valueHolderKeys);

                        IList <IObjRef> orisToRevert           = new List <IObjRef>();
                        ISet <Object> persistedObjectsToRevert = new IdentityHashSet <Object>();
                        for (int a = initializedObjects.Count; a-- > 0;)
                        {
                            Object objectToRevert    = initializedObjects[a];
                            IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData();
                            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                            if (id == null)
                            {
                                directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert));
                                continue;
                            }
                            persistedObjectsToRevert.Add(objectToRevert);
                            orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                        }
                        IList <Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses);

                        for (int a = orisToRevert.Count; a-- > 0;)
                        {
                            if (hardRefsToRootCacheValues[a] == null)
                            {
                                // Object could not be loaded/retrieved any more. So the ori refers to an invalid object
                                // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will
                                // be tried to persist in a merge process any time in the future
                                orisToRevert.RemoveAt(a);
                            }
                        }
                        // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack
                        // To prohibit GC any potential WeakReferences in the meantime....
                        success2 = false;
                        GuiThreadHelper.InvokeInGui(delegate(Object state)
                        {
                            WaitEventToResume(delegate(IProcessResumeItem processResumeItem)
                            {
                                try
                                {
                                    bool oldCacheModificationValue = CacheModification.Active;
                                    CacheModification.Active       = true;
                                    bool oldFailEarlyModeActive    = AbstractCache.FailInCacheHierarchyModeActive;
                                    AbstractCache.FailInCacheHierarchyModeActive = true;
                                    try
                                    {
                                        IList <IWritableCache> firstLevelCaches      = FirstLevelCacheManager.SelectFirstLevelCaches();
                                        IList <Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues;

                                        foreach (IWritableCache firstLevelCache in firstLevelCaches)
                                        {
                                            IList <Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly);

                                            for (int a = persistedObjectsInThisCache.Count; a-- > 0;)
                                            {
                                                Object persistedObjectInThisCache = persistedObjectsInThisCache[a];
                                                if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache))
                                                {
                                                    continue;
                                                }
                                                RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache, null);
                                            }
                                        }
                                        for (int a = objectsToRevert.Count; a-- > 0;)
                                        {
                                            Object objectToRevert = objectsToRevert[a];
                                            if (objectToRevert is IDataObject)
                                            {
                                                // Objects which are specified to be reverted loose their flags
                                                ((IDataObject)objectToRevert).ToBeDeleted = false;
                                            }
                                        }
                                        if (directObjectDeletes.Count == 0)
                                        {
                                            success2 = true;
                                            return;
                                        }
                                    }
                                    finally
                                    {
                                        AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive;
                                        CacheModification.Active = oldCacheModificationValue;
                                    }
                                }
                                finally
                                {
                                    if (processResumeItem != null)
                                    {
                                        processResumeItem.ResumeProcessingFinished();
                                    }
                                }
                                success3 = false;
                                GuiThreadHelper.InvokeOutOfGui(delegate()
                                {
                                    try
                                    {
                                        DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0);
                                        dataChange.Deletes         = directObjectDeletes;

                                        EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                                        success3 = true;
                                    }
                                    finally
                                    {
                                        if (revertChangesFinishedCallback != null)
                                        {
                                            revertChangesFinishedCallback.Invoke(success3.Value);
                                        }
                                    }
                                });
                                success2 = true;
                            }, delegate(Exception e)
                            {
                                if (revertChangesFinishedCallback != null && success3 == null)
                                {
                                    revertChangesFinishedCallback.Invoke(success2.Value);
                                }
                            });
                        }, null);
                        success1 = true;
                    }
                    finally
                    {
                        if (revertChangesFinishedCallback != null && success2 == null && success3 == null)
                        {
                            revertChangesFinishedCallback.Invoke(success1);
                        }
                    }
                });
            }
        }
示例#3
0
        public virtual void execute()
        {
            long start = Environment.TickCount;

            // Do something for nearly 60 seconds (job gets invoked every 60 seconds
            while (Environment.TickCount - start < 58000)
            {
                IList <TestEntity>  allTestEntities  = null;
                IList <TestEntity2> allTest2Entities = null;

                ICache newCache = CacheProvider.GetCurrentCache();

                CacheContext.ExecuteWithCache <Object>(newCache, delegate()
                {
                    allTestEntities  = HelloWorldService.GetAllTestEntities();
                    allTest2Entities = HelloWorldService.GetAllTest2Entities();
                    return(null);
                });

                if (allTestEntities.Count > 0)
                {
                    IRevertChangesSavepoint savepoint = RevertChangesHelper.CreateSavepoint(allTestEntities);
                    allTestEntities[0].MyString = "Hallo";
                    allTestEntities[0].Version  = -67;
                    allTestEntities[0].Relation = null;

                    savepoint.RevertChanges();
                }


                // Evaluate random type of change ( INSERT / UPDATE / DELETE / NOTHING)
                double randomChange = random.NextDouble();

                bool entity2Change = random.NextDouble() > 0.66;

                // Evaluate entity to change by its index in the result list of existing entities (necessary for UPDATE /
                // DELETE)
                int changeIndex = (int)(random.NextDouble() * allTestEntities.Count);

                // Evaluate entity2 to select its index in the result list of existing entities (necessary for INSERT of
                // entity1)
                int selectEntity2Index = (int)(random.NextDouble() * allTest2Entities.Count);

                // Evaluate new value to change on chosen entity (necessary for INSERT / UPDATE)
                int randomNewValue = (int)(random.NextDouble() * Int32.MaxValue / 2);

                // Map from randomChange to the enum-based operation to execute
                ChangeOperation changeOperation;
                if (randomChange < 0.10) // 10% probability for INSERTs
                {
                    changeOperation = ChangeOperation.INSERT;
                }
                else if (randomChange < 0.20) // 10% probability for DELETEs
                {
                    changeOperation = ChangeOperation.DELETE;
                }
                else if (randomChange < 0.40) // 20% probability for doing NOTHING
                {
                    changeOperation = ChangeOperation.NOTHING;
                }
                else
                // 60% probablity for doing an ordinary UPDATE on an entity
                {
                    changeOperation = ChangeOperation.UPDATE;
                }
                if (entity2Change && allTestEntities.Count > 0)
                {
                    // If there are less than 10 entities, force to insertion of one
                    if (allTest2Entities.Count < 10)// || ChangeOperation.INSERT.Equals(changeOperation))
                    {
                        TestEntity2 newEntity = new TestEntity2();
                        newEntity.MyValue2 = randomNewValue;
                        HelloWorldService.SaveTestEntities2(newEntity);
                        allTest2Entities.Add(newEntity);
                    }
                    //// If there are more than 20 entities, force to deletion of one
                    else if (allTestEntities.Count > 20 || ChangeOperation.DELETE.Equals(changeOperation))
                    {
                        TestEntity2 deleteEntity = allTest2Entities[selectEntity2Index];
                        allTest2Entities.RemoveAt(selectEntity2Index);
                        HelloWorldService.DeleteTestEntities2(deleteEntity);
                    }
                    else if (ChangeOperation.UPDATE.Equals(changeOperation))
                    {
                        TestEntity2 updateEntity = allTest2Entities[selectEntity2Index];
                        updateEntity.MyValue2 = randomNewValue;
                        HelloWorldService.SaveTestEntities2(updateEntity);
                    }
                    else
                    {
                        TestEntity2 noOpEntity = allTest2Entities[selectEntity2Index];
                        // Change nothing, but try to save entity (results in NO-OP)
                        HelloWorldService.SaveTestEntities2(noOpEntity);
                    }
                }
                else
                {
                    // If there are less than 10 entities, force to insertion of one
                    if (allTestEntities.Count < 10)// || ChangeOperation.INSERT.Equals(changeOperation))
                    {
                        TestEntity newEntity = new TestEntity();
                        newEntity.MyValue = randomNewValue;
                        HelloWorldService.SaveTestEntities(newEntity);
                        allTestEntities.Add(newEntity);
                    }
                    // If there are more than 20 entities, force to deletion of one
                    else if (allTestEntities.Count > 20 || ChangeOperation.DELETE.Equals(changeOperation))
                    {
                        TestEntity deleteEntity = allTestEntities[changeIndex];
                        allTestEntities.RemoveAt(changeIndex);
                        HelloWorldService.DeleteTestEntities(deleteEntity);
                    }
                    else if (ChangeOperation.UPDATE.Equals(changeOperation))
                    {
                        TestEntity  updateEntity = allTestEntities[changeIndex];
                        TestEntity2 testEntity2  = allTest2Entities.Count > 0 ? allTest2Entities[selectEntity2Index] : null;
                        updateEntity.MyValue              = randomNewValue;
                        updateEntity.Relation             = testEntity2;
                        updateEntity.EmbeddedObject.Name  = "Name_" + randomNewValue;
                        updateEntity.EmbeddedObject.Value = randomNewValue;
                        HelloWorldService.SaveTestEntities(updateEntity);
                    }
                    else
                    {
                        TestEntity noOpEntity = allTestEntities[changeIndex];
                        // Change nothing, but try to save entity (results in NO-OP)
                        HelloWorldService.SaveTestEntities(noOpEntity);
                    }
                }
                Thread.Sleep(500);
            }
        }