/// <summary> /// Get the input argument groups. /// </summary> /// <param name="activityAs"></param> /// <returns></returns> public static IOrderedEnumerable <int> GetInputArgumentGroups(EntityWithArgsAndExits activityAs) { return(activityAs.InputArguments.Select(e => { var nameParts = e.Name.Split('_'); var index = 0; int.TryParse(nameParts[0], out index); return index; }).Distinct().OrderBy(p => p)); }
/// <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()); } } } }