/// <summary> /// Populate this <see cref="WspPostOperation"/> with the correct setup for the OCDT protocol /// </summary> /// <param name="operation"> /// The operation. /// </param> public override void ConstructFromOperation(Operation operation) { if (operation.ModifiedThing == null) { throw new ArgumentNullException("operation"); } if (operation.OperationKind == OperationKind.Update && operation.OriginalThing == null) { throw new ArgumentException( "When OperationKind is an Update the OriginalThing of the operation may not be null"); } switch (operation.OperationKind) { case OperationKind.Create: this.Create.Add(operation.ModifiedThing); break; case OperationKind.Delete: this.Delete.Add(ClasslessDtoFactory.FromThing(this.metaDataProvider, operation.ModifiedThing)); break; case OperationKind.Update: this.ResolveUpdate(operation); break; case OperationKind.Copy: throw new NotSupportedException("The WSP Post operations do not support a Copy"); case OperationKind.Move: throw new NotSupportedException("The WSP Post operations do not support a Move"); } }
/// <summary> /// Populate the current <see cref="PostOperation"/> with the content based on the /// provided <see cref="Operation"/> /// </summary> /// <param name="operation"> /// The <see cref="Operation"/> that contains all the <see cref="Thing"/>s that need to be /// updated to the data-source /// </param> public override void ConstructFromOperation(Operation operation) { if (operation.ModifiedThing == null) { throw new ArgumentNullException("operation", "The operation may not be null"); } switch (operation.OperationKind) { case OperationKind.Create: this.Create.Add(operation.ModifiedThing); break; case OperationKind.Delete: this.Delete.Add(ClasslessDtoFactory.FromThing(this.metaDataProvider, operation.ModifiedThing)); break; case OperationKind.Update: this.ResolveUpdate(operation); break; case OperationKind.Move: throw new NotImplementedException(); break; default: this.ResolveCopy(operation); break; } }
public void TestFromThing() { var siteDir = new SiteDirectory(Guid.NewGuid(), 2); siteDir.DefaultPersonRole = Guid.NewGuid(); var properties = new List <string> { "DefaultPersonRole", "Iid" }; var returned = ClasslessDtoFactory.FromThing(this.metaDataProvider, siteDir, properties); Assert.AreEqual(3, returned.Count); object guid; Assert.IsTrue(returned.TryGetValue("DefaultPersonRole", out guid)); Assert.AreEqual(siteDir.DefaultPersonRole, (guid as Guid?).Value); }
public void TestNullThing() { Thing thing = null; Assert.Throws <ArgumentNullException>(() => ClasslessDtoFactory.FromThing(this.metaDataProvider, thing)); }
/// <summary> /// Resolves the Update container of the <see cref="Operation"/> /// </summary> /// <param name="operation"> /// The operation. /// </param> private void ResolveUpdate(Operation operation) { var original = ClasslessDtoFactory.FullFromThing(this.metaDataProvider, operation.OriginalThing); var modifiedFull = ClasslessDtoFactory.FullFromThing(this.metaDataProvider, operation.ModifiedThing); var modified = ClasslessDtoFactory.FullFromThing(this.metaDataProvider, operation.ModifiedThing); var listsToDelete = new Dictionary <string, IEnumerable <object> >(); var listsToAdd = new Dictionary <string, IEnumerable <object> >(); foreach (var key in original.Keys) { var originalIenumerable = original[key] as IEnumerable; if (originalIenumerable != null && originalIenumerable.GetType().IsGenericType) { var modifiedIenumerable = (IEnumerable)modifiedFull[key]; // value array case if (originalIenumerable is ValueArray <string> ) { var originalValue = (ValueArray <string>)originalIenumerable; var modifiedValue = (ValueArray <string>)modifiedIenumerable; if (originalValue.ToString() == modifiedValue.ToString()) { modified.Remove(key); } } else { var possibleAdditions = new List <object>(); List <object> originalProperty; List <object> modifiedProperty; var genericTypeArgument = original[key].GetType().GenericTypeArguments[0]; if (genericTypeArgument == typeof(Guid) || genericTypeArgument == typeof(ClassKind) || genericTypeArgument == typeof(VcardTelephoneNumberKind)) { originalProperty = originalIenumerable.Cast <object>().ToList(); modifiedProperty = modifiedIenumerable.Cast <object>().ToList(); } else if (genericTypeArgument == typeof(OrderedItem)) { originalProperty = originalIenumerable.Cast <object>().ToList(); modifiedProperty = modifiedIenumerable.Cast <object>().ToList(); var originalPropertyOrdered = ((List <OrderedItem>)original[key]).ToList(); var modifiedPropertyOrdered = ((List <OrderedItem>)modifiedFull[key]).ToList(); // move property using intersection var sameItems = originalPropertyOrdered.Intersect(modifiedPropertyOrdered); foreach (var sameItem in sameItems) { var orItem = originalPropertyOrdered.Find(o => o.V.Equals(sameItem.V)); var modItem = modifiedPropertyOrdered.Find(m => m.V.Equals(sameItem.V)); if (orItem.K != modItem.K) { modItem.MoveItem(orItem.K, modItem.K); possibleAdditions.Add(modItem); } } } else { // either way remove key in case the generic type is not one of the expected ones modified.Remove(key); continue; } possibleAdditions.AddRange(modifiedProperty.Except(originalProperty).ToList()); if (possibleAdditions.Count > 0) { // this part will be added to the update listsToAdd.Add(key, possibleAdditions); } var possibleDeletions = originalProperty.Except(modifiedProperty).ToList(); if (possibleDeletions.Count > 0) { // this part will be added to the delete listsToDelete.Add(key, possibleDeletions); } // either way remove key modified.Remove(key); } } else { // whatever outputs here has to be an update // remove the properties that have not changed if (key.Equals("Iid") || key.Equals("ClassKind")) { continue; } if (original[key] == null) { if (original[key] == modifiedFull[key]) { modified.Remove(key); } } else { if (original[key].Equals(modifiedFull[key])) { modified.Remove(key); } } } } if (listsToDelete.Count > 0) { var deleteDto = ClasslessDtoFactory.FromThing(this.metaDataProvider, operation.ModifiedThing); foreach (var kvp in listsToDelete) { deleteDto.Add(kvp.Key, kvp.Value); } // add a delete container // Add to the list of deleted thing, WSP will compute what references were removed for the current Thing // example: a category was removed from an ElementDefinition => add a operation in the Delete Operation with the removed category this.Delete.Add(deleteDto); } if (listsToAdd.Count > 0) { var updateDto = modified; foreach (var kvp in listsToAdd) { updateDto.Add(kvp.Key, kvp.Value); } } // if more than just Iid and Classkind have changed then add it to update if (modified.Count > 2) { this.Update.Add(modified); } }