private void SetRel(IEntity source, IEntity target, IEntity rel, Direction direction = Direction.Forward) { IEntityRelationshipCollection <IEntity> relationshipsCol = new EntityRelationshipCollection <IEntity> { target }; source.SetRelationships(rel, relationshipsCol, direction); source.Save( ); }
/// <summary> /// Multi-relationship setter implementation for strong types. /// </summary> /// <typeparam name="T">Type of entity being pointed to.</typeparam> /// <param name="alias">Relationship alias.</param> /// <param name="values">New entities to point to, or null.</param> /// <param name="direction">Relationship direction.</param> protected void SetRelationships <T>(string alias, IEntityCollection <T> values, Direction direction) where T : class, IEntity { IEntityRelationshipCollection <T> converted = null; if (values != null) { converted = new EntityRelationshipCollection <T>(values); } _entity.SetRelationships(alias, converted, direction); }
public void Test_RelationshipInstance(string action, string fromPerms, string toPerms, Direction direction, bool saveBothEnds, bool haveFieldChanges, bool expectAllow) { if (fromPerms == "modify") { fromPerms = "read,modify"; } if (toPerms == "modify") { toPerms = "read,modify"; } // Create schema EntityType fromType = new EntityType(); fromType.Inherits.Add(UserResource.UserResource_Type); fromType.Name = Guid.NewGuid().ToString(); fromType.Save(); EntityType toType = new EntityType(); toType.Inherits.Add(UserResource.UserResource_Type); toType.Name = Guid.NewGuid().ToString(); toType.Save(); Relationship rel = new Relationship(); rel.Name = Guid.NewGuid().ToString(); rel.FromType = fromType; rel.ToType = toType; rel.Cardinality_Enum = CardinalityEnum_Enumeration.ManyToMany; rel.Save(); // Create data IEntity toInst = new Entity(toType); toInst.Save(); IEntity fromInst = new Entity(fromType); if (action != "Create") { fromInst.SetRelationships(rel, new EntityRelationshipCollection <IEntity> { toInst }); } fromInst.Save(); // Create test user UserAccount userAccount = Entity.Create <UserAccount>(); userAccount.Name = Guid.NewGuid().ToString(); userAccount.Save(); // Grant access if (!string.IsNullOrEmpty(fromPerms)) { new AccessRuleFactory().AddAllowByQuery( userAccount.As <Subject>(), fromType.As <SecurableEntity>(), fromPerms.Split(',').Select(pa => new EntityRef(pa)), TestQueries.Entities().ToReport()); } if (!string.IsNullOrEmpty(toPerms)) { new AccessRuleFactory().AddAllowByQuery( userAccount.As <Subject>(), toType.As <SecurableEntity>(), toPerms.Split(',').Select(pa => new EntityRef(pa)), TestQueries.Entities().ToReport()); } // Test bool allowed = false; try { using (new SetUser(userAccount)) { IEntity source = Entity.Get(direction == Direction.Forward ? fromInst.Id : toInst.Id); if (action != "Read") { source = source.AsWritable(); } Func <IEntity> target = () => Entity.Get(direction == Direction.Forward ? toInst.Id : fromInst.Id); IEntityRelationshipCollection <IEntity> relCol = null; switch (action) { case "Read": relCol = source.GetRelationships(rel.Id, direction); IEntity entity = relCol.FirstOrDefault(); allowed = entity != null; break; case "Create": relCol = new EntityRelationshipCollection <IEntity> { target() }; source.SetRelationships(rel, relCol); if (haveFieldChanges) { source.SetField("core:name", Guid.NewGuid().ToString()); } if (saveBothEnds) { Entity.Save(new[] { source, target() }); } else { source.Save(); } allowed = true; break; case "Remove": relCol = source.GetRelationships(rel.Id, direction); relCol.Remove(target()); source.SetRelationships(rel, relCol); if (haveFieldChanges) { source.SetField("core:name", Guid.NewGuid().ToString()); } if (saveBothEnds) { Entity.Save(new[] { source, target() }); } else { source.Save(); } allowed = true; break; case "Clear": relCol = source.GetRelationships(rel.Id, direction); relCol.Clear(); source.SetRelationships(rel, relCol); if (haveFieldChanges) { source.SetField("core:name", Guid.NewGuid().ToString()); } if (saveBothEnds) { Entity.Save(new[] { source, target() }); } else { source.Save(); } allowed = true; break; default: throw new InvalidOperationException("Unknown " + action); } } Assert.That(allowed, Is.EqualTo(expectAllow)); } catch (PlatformSecurityException) { Assert.That(false, Is.EqualTo(expectAllow)); } }
/// <summary> /// Given a update ac /// </summary> /// <param name="activityAs"></param> /// <param name="inputs"></param> /// <param name="entityToUpdate"></param> public static void UpdateEntityFromArgs(EntityWithArgsAndExits activityAs, ActivityInputs inputs, IEntity entityToUpdate) { // This activity may also have its own input arguments (as opposed to those on its type) // and these are grouped so we can update multiple fields, relationships etc. // find the list of base names (indexes) of the argument groups Entity.GetField(activityAs.InputArguments, new EntityRef("core:name")); IOrderedEnumerable <int> argGroups = GetInputArgumentGroups(activityAs); // process each group foreach (var baseName in argGroups.Select(g => g.ToString())) { var arg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName); if (arg == null) { Log("Failed to find input argument for activity {0} with name {1}", activityAs.Name, baseName); continue; } if (!inputs.ContainsKey(arg)) { Log("Failed to input argument expression for activity {0} with name {1}", activityAs.Name, baseName); continue; } var memberEntity = (IEntity)inputs[arg]; if (memberEntity != null) { var fieldEntity = memberEntity.Is <Field>() ? memberEntity.Cast <Field>() : null; var relEntity = memberEntity.Is <Relationship>() ? memberEntity.Cast <Relationship>() : null; if (fieldEntity != null) { var valueArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_value"); if (valueArg == null || !inputs.ContainsKey(valueArg)) { Log("Failed to find input argument for activity {0} with name {1}", activityAs.Name, baseName + "_value"); } else { //Log("Updating field {0} {1} with value {2}", fieldEntity.Id, fieldEntity.Name, // inputs[valueArg]); entityToUpdate.SetField(fieldEntity, inputs[valueArg]); } } else if (relEntity != null) { var reverseArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_reverse"); var replaceArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_replace"); var cardinality = relEntity.Cardinality_Enum ?? CardinalityEnum_Enumeration.ManyToMany; var direction = reverseArg != null && inputs.ContainsKey(reverseArg) ? (((bool?)inputs[reverseArg] ?? false) ? Direction.Reverse : Direction.Forward) : Direction.Forward; var replaceExisting = (replaceArg != null && inputs.ContainsKey(replaceArg) && ((bool?)inputs[replaceArg] ?? false)) || cardinality == CardinalityEnum_Enumeration.OneToOne || (direction == Direction.Forward && cardinality == CardinalityEnum_Enumeration.ManyToOne) || (direction == Direction.Reverse && cardinality == CardinalityEnum_Enumeration.OneToMany); //Log("Updating relationship {0} {1} direction={2} replace={3}", relEntity.Id, relEntity.Name, // direction, // replaceExisting); var oldRelCollection = entityToUpdate.GetRelationships(relEntity, direction); //Log("Before: relationship {0} {1} has {2} related entities", relEntity.Id, relEntity.Name, // relCollection.Count()); var relCollection = new EntityRelationshipCollection <IEntity>(); // We need to create a new collection and set the relationship to it to deal with a bug that occurs when a resource is cloned and then modified with a relationship set to the same value. if (!replaceExisting) { foreach (var e in oldRelCollection) { relCollection.Add(e); } } foreach ( var valueArg in activityAs.InputArguments.Where(p => p.Name.StartsWith(baseName + "_value_"))) { var value = inputs.ContainsKey(valueArg) ? inputs[valueArg] : null; IEnumerable <IEntity> entityRefs; if (value is IEntity) { entityRefs = new List <IEntity> { (IEntity)value }; } else { entityRefs = (IEnumerable <IEntity>)value; } if (entityRefs != null) { foreach (var entity in entityRefs) { if (entity != null) { var relatedEntity = entity.As <Resource>(); if (relatedEntity != null) { //Log(">> adding to relationship {0} {1}, related {2} {3}", relEntity.Id, // relEntity.Name, // relatedEntity.Id, relatedEntity.Name); relCollection.Add(relatedEntity); } } } } } entityToUpdate.SetRelationships(relEntity, relCollection, direction); //Log("After: relationship {0} {1} has {2} related entities", relEntity.Id, relEntity.Name, // relCollection.Count()); } } } }
public void CloneWithOneToOneRelationship() { var x = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss"); #region Arrange var colour = new Definition(); colour.Name = "Colour_" + x; colour.Save(); var objectA = new Definition(); objectA.Name = "ObjectA_" + x; objectA.Save(); var objectB = new Definition(); objectB.Name = "ObjectB_" + x; objectB.Inherits.Add(objectA.As <EntityType>()); objectB.Save(); var relationship = new Relationship(); relationship.Name = "Object To Colour " + x; relationship.FromType = objectA.As <EntityType>(); relationship.ToType = colour.As <EntityType>(); relationship.Cardinality_Enum = CardinalityEnum_Enumeration.OneToOne; relationship.CloneAction_Enum = CloneActionEnum_Enumeration.CloneEntities; relationship.ReverseCloneAction_Enum = CloneActionEnum_Enumeration.CloneEntities; relationship.Save(); var red = Entity.Create(colour.Id); red.Save(); red.SetField(new EntityRef("core", "name"), "Red." + red.Id); red.Save(); var blue = Entity.Create(colour.Id); blue.Save(); blue.SetField(new EntityRef("core", "name"), "Blue." + blue.Id); blue.Save(); var green = Entity.Create(colour.Id); green.Save(); green.SetField(new EntityRef("core", "name"), "Green." + green.Id); green.Save(); var colours = new EntityRelationshipCollection <IEntity>(); colours.Add(blue); var instanceA = Entity.Create(objectA.Id); instanceA.Save(); instanceA.SetField(new EntityRef("core", "name"), "A." + instanceA.Id); instanceA.SetRelationships(relationship, colours); instanceA.Save(); // Workflow Setup var cloneActivity = new CloneActivity(); cloneActivity.Save(); var nextActivity = (CloneImplementation)cloneActivity.As <WfActivity>().CreateWindowsActivity(); var inputs = new Dictionary <string, object> { { "Record", instanceA }, { "Object", objectB } // core:newDefinitionCloneArgument }; ToDelete.Add(cloneActivity.Id); ToDelete.Add(instanceA.Id); ToDelete.Add(red.Id); ToDelete.Add(blue.Id); ToDelete.Add(green.Id); ToDelete.Add(relationship.Id); ToDelete.Add(objectB.Id); ToDelete.Add(objectA.Id); ToDelete.Add(colour.Id); #endregion var result = RunActivity(nextActivity, inputs); var clone = ((IEntity)result["Record"]); var original = Entity.Get(instanceA.Id); var originalColour = Entity.Get(blue.Id); clone.Id.Should().NotBe(original.Id); ToDelete.Add(clone.Id); clone.GetField(new EntityRef("core", "name")).Should().Be("A." + instanceA.Id); var related = clone.GetRelationships(relationship); related.Should().NotBeNull().And.NotBeEmpty(); related.Count.Should().Be(1); var cloneColour = related.First(); cloneColour.Id.Should().NotBe(originalColour.Id); ToDelete.Add(cloneColour.Id); cloneColour.GetField(new EntityRef("core", "name")).Should().Be("Blue." + blue.Id); }
public void CloneRefsWithBaseDefinition() { var x = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss"); #region Arrange // Types var userResource = Entity.Get <EntityType>(new EntityRef("core", "userResource")); var myBaseDefinition = new Definition { Name = "clonebasedefinition" + x, Inherits = new EntityCollection <EntityType>(userResource.ToEnumerable()) }; myBaseDefinition.Save(); var myRelatedDefinition = new Definition { Name = "clonerelateddefinition" + x, Inherits = new EntityCollection <EntityType>(userResource.ToEnumerable()) }; myRelatedDefinition.Save(); var myBaseType = Entity.Get <EntityType>(myBaseDefinition); var myRelatedType = Entity.Get <EntityType>(myRelatedDefinition); var myBaseToRelatedRelationship = new Relationship { FromType = myBaseType, ToType = myRelatedType, Name = "clonebaserelationship" + x, Description = "Clone With Base Definition", Cardinality = Entity.Get <CardinalityEnum>(new EntityRef("core", "manyToMany")), CascadeDelete = false, CascadeDeleteTo = false, CloneAction_Enum = CloneActionEnum_Enumeration.CloneReferences, ReverseCloneAction_Enum = CloneActionEnum_Enumeration.CloneReferences }; myBaseToRelatedRelationship.Save(); var myDefinitionA = new Definition { Name = "clonedefinitionA" + x, Inherits = new EntityCollection <EntityType>(myBaseType.ToEnumerable()) }; myDefinitionA.Save(); var myDefinitionB = new Definition { Name = "clonedefinitionB" + x, Inherits = new EntityCollection <EntityType>(myBaseType.ToEnumerable()) }; myDefinitionB.Save(); // Instances var rOne = new Entity(myRelatedDefinition); rOne.SetField(new EntityRef("core", "name"), "Related 1." + x); rOne.Save(); var rTwo = new Entity(myRelatedDefinition); rTwo.SetField(new EntityRef("core", "name"), "Related 2." + x); rTwo.Save(); var rCollection = new EntityRelationshipCollection <IEntity>(); rCollection.Add(rOne); rCollection.Add(rTwo); var cA = new Entity(myDefinitionA); cA.SetField(new EntityRef("core", "name"), "Clone Me A." + x); cA.SetRelationships(myBaseToRelatedRelationship, rCollection); cA.Save(); // Workflow Setup var cloneActivity = new CloneActivity(); cloneActivity.Save(); var nextActivity = (CloneImplementation)cloneActivity.As <WfActivity>().CreateWindowsActivity(); var inputs = new Dictionary <string, object> { { "Record", cA }, { "Object", myDefinitionB } // core:newDefinitionCloneArgument }; ToDelete.Add(cloneActivity.Id); ToDelete.Add(cA.Id); ToDelete.Add(myDefinitionA.Id); ToDelete.Add(myDefinitionB.Id); ToDelete.Add(myRelatedDefinition.Id); ToDelete.Add(myBaseDefinition.Id); #endregion var result = RunActivity(nextActivity, inputs); var clone = ((IEntity)result["Record"]); var original = Entity.Get(cA.Id); clone.Id.Should().NotBe(original.Id); ToDelete.Add(clone.Id); var rid = myBaseToRelatedRelationship.Id; var cloneRels = clone.GetRelationships(rid, Direction.Forward).ToList(); cloneRels.Count.Should().Be(2); foreach (var cloneRel in cloneRels) { var revs = cloneRel.GetRelationships(rid, Direction.Reverse); revs.Select(r => r.Id).Should().Contain(new [] { original.Id, clone.Id }); } var originalRels = original.GetRelationships(rid, Direction.Forward).ToList(); originalRels.Count.Should().Be(2); originalRels.Select(o => o.Id).Should().BeEquivalentTo(cloneRels.Select(c => c.Id)); }