Skip to content

Commit

Permalink
Impliment ISyncOptionsSerializer interface and base class stuff. #136
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Jump committed Jul 13, 2020
1 parent 9c63a25 commit a347b00
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 22 deletions.
50 changes: 44 additions & 6 deletions uSync8.BackOffice/SyncHandlers/SyncHandlerRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading.Tasks;
using System.Xml.Linq;

using Examine;

using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
Expand Down Expand Up @@ -406,7 +408,7 @@ public virtual SyncAttempt<TObject> Import(string filePath, HandlerSettings conf
var node = XElement.Load(stream);
if (ShouldImport(node, config))
{
var attempt = serializer.Deserialize(node, flags);
var attempt = DeserializeItem(node, new SyncSerializerOptions(flags, config.Settings));
return attempt;
}
else
Expand Down Expand Up @@ -449,7 +451,7 @@ virtual public SyncAttempt<TObject> ImportSecondPass(string file, TObject item,
using (var stream = syncFileService.OpenRead(file))
{
var node = XElement.Load(stream);
var attempt = serializer.DeserializeSecondPass(item, node, flags);
var attempt = DeserializeItemSecondPass(item, node, new SyncSerializerOptions(flags, config.Settings));
stream.Dispose();
return attempt;
}
Expand Down Expand Up @@ -519,7 +521,7 @@ virtual public IEnumerable<uSyncAction> Export(TObject item, string folder, Hand

var filename = GetPath(folder, item, config.GuidNames, config.UseFlatStructure);

var attempt = serializer.Serialize(item);
var attempt = SerializeItem(item, new SyncSerializerOptions(config.Settings));
if (attempt.Success)
{
if (ShouldExport(attempt.Item, config))
Expand Down Expand Up @@ -726,7 +728,7 @@ protected virtual IEnumerable<uSyncAction> ReportElement(XElement node, string f
{
var actions = new List<uSyncAction>();

var change = serializer.IsCurrent(node);
var change = IsItemCurrent(node, new SyncSerializerOptions(config.Settings));
var action = uSyncActionHelper<TObject>
.ReportAction(change, node.GetAlias(), !string.IsNullOrWhiteSpace(filename) ? filename : node.GetAlias(), node.GetKey(), this.Alias);

Expand Down Expand Up @@ -1015,7 +1017,7 @@ virtual public IEnumerable<uSyncAction> ImportElement(XElement node, bool force)
var flags = SerializerFlags.OnePass;
if (force) flags |= SerializerFlags.Force;

var attempt = serializer.Deserialize(node, flags);
var attempt = DeserializeItem(node, new SyncSerializerOptions(flags));
return uSyncActionHelper<TObject>.SetAction(attempt, node.GetAlias(), this.Alias, IsTwoPass)
.AsEnumerableOfOne();
}
Expand Down Expand Up @@ -1044,7 +1046,7 @@ public SyncAttempt<XElement> GetElement(Udi udi)
{
var element = FindByUdi(udi);
if (element != null)
return this.serializer.Serialize(element);
return SerializeItem(element, new SyncSerializerOptions());

return SyncAttempt<XElement>.Fail(udi.ToString(), ChangeType.Fail, "Item not found");
}
Expand Down Expand Up @@ -1120,5 +1122,41 @@ private IEnumerable<uSyncDependency> GetContainerDependencies(TContainer parent,

#endregion


#region Serializer Calls

private SyncAttempt<XElement> SerializeItem(TObject item, SyncSerializerOptions options)
{
if (serializer is ISyncOptionsSerializer<TObject> optionSerializer)
return optionSerializer.Serialize(item, options);

return serializer.Serialize(item);
}

private SyncAttempt<TObject> DeserializeItem(XElement node, SyncSerializerOptions options)
{
if (serializer is ISyncOptionsSerializer<TObject> optionSerializer)
return optionSerializer.Deserialize(node, options);

return serializer.Deserialize(node, options.Flags);
}

private SyncAttempt<TObject> DeserializeItemSecondPass(TObject item, XElement node, SyncSerializerOptions options)
{
if (serializer is ISyncOptionsSerializer<TObject> optionSerializer)
return optionSerializer.DeserializeSecondPass(item, node, options);

return serializer.DeserializeSecondPass(item, node, options.Flags);
}

private ChangeType IsItemCurrent(XElement node, SyncSerializerOptions options)
{
if (serializer is ISyncOptionsSerializer<TObject> optionSerializer)
return optionSerializer.IsCurrent(node, options);

return serializer.IsCurrent(node);
}
#endregion

}
}
6 changes: 6 additions & 0 deletions uSync8.Core/Extensions/XElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public static Guid GetKey(this XElement node)
public static string GetAlias(this XElement node)
=> node.Attribute("Alias").ValueOrDefault(string.Empty);

public static string GetCultures(this XElement node)
=> node.Attribute(uSyncConstants.CultureKey).ValueOrDefault(string.Empty);

public static string GetSegments(this XElement node)
=> node.Attribute(uSyncConstants.SegmentKey).ValueOrDefault(string.Empty);

/// <summary>
/// Get the key of any parent value that is in the file.
/// </summary>
Expand Down
37 changes: 37 additions & 0 deletions uSync8.Core/Serialization/ISyncOptionsSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

using uSync8.Core.Models;

namespace uSync8.Core.Serialization
{
/// <summary>
/// Serializer that can take options to the main methods.
/// </summary>
public interface ISyncOptionsSerializer<TObject> : ISyncSerializer<TObject>
{
/// <summary>
/// Serialize and Item into uSync XML format (with options)
/// </summary>
SyncAttempt<XElement> Serialize(TObject item, SyncSerializerOptions options);

/// <summary>
/// Deserialize an item from XML into Umbraco (with options)
/// </summary>
SyncAttempt<TObject> Deserialize(XElement node, SyncSerializerOptions options);

/// <summary>
/// Run the second pass of a deserialization (with options)
/// </summary>
SyncAttempt<TObject> DeserializeSecondPass(TObject item, XElement node, SyncSerializerOptions options);

/// <summary>
/// Is the XML in sync with what is inside Umbraco? (with options)
/// </summary>
ChangeType IsCurrent(XElement node, SyncSerializerOptions options);
}
}
117 changes: 117 additions & 0 deletions uSync8.Core/Serialization/SyncSerializerOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System.Collections.Generic;
using System.Configuration;
using System.Xml.Linq;

using NPoco.Expressions;
using Superpower.Model;
using Umbraco.Core;

using uSync8.Core.Extensions;

namespace uSync8.Core.Serialization
{
/// <summary>
/// options class that can be passed to a serialize/deserialize method.
/// </summary>
public class SyncSerializerOptions
{
public SyncSerializerOptions() { }

public SyncSerializerOptions(SerializerFlags flags)
{
this.Flags = flags;
}

public SyncSerializerOptions(Dictionary<string, string> settings)
{
this.Settings = settings ?? new Dictionary<string, string>();

}

public SyncSerializerOptions(SerializerFlags flags, Dictionary<string, string> settings)
: this(settings)
{
this.Flags = flags;
}

/// <summary>
/// Only create item if it doesn't already exist.
/// </summary>
public bool CreateOnly { get; set; }

/// <summary>
/// Serializer flags, turn things like DontSave, FailWhenParent is missing on
/// </summary>
/// <remarks>
/// this is now private - we might phase it out for the options instead.
/// </remarks>
public SerializerFlags Flags { get; internal set; }

/// <summary>
/// Parameterized options, custom for each handler
/// </summary>
public Dictionary<string, string> Settings { get; internal set; }

/// <summary>
/// flag properties, we can move this away from flags if we want to.
/// </summary>
public bool Force => Flags.HasFlag(SerializerFlags.Force);

// public bool DoNotSave => Flags.HasFlag(SerializerFlags.DoNotSave);

public bool FailOnMissingParent => Flags.HasFlag(SerializerFlags.FailMissingParent);

public bool OnePass => Flags.HasFlag(SerializerFlags.OnePass);


public TResult GetSetting<TResult>(string key, TResult defaultValue)
{
if (this.Settings != null && this.Settings.ContainsKey(key))
{
var attempt = this.Settings[key].TryConvertTo<TResult>();
if (attempt.Success)
return attempt.Result;
}

return defaultValue;
}

/// <summary>
/// Get the cultures defined in the settings.
/// </summary>
/// <returns></returns>
public IList<string> GetCultures() => GetSetting(uSyncConstants.CultureKey, string.Empty).ToDelimitedList();

/// <summary>
/// Gets the cultures that can be de-serialized from this node.
/// </summary>
/// <remarks>
/// If a node has 'Cultures' set on the top node, then its only a partial sync
/// so we need to treat all the functions like this is set on the handler..
/// </remarks>
public IList<string> GetDeserializedCultures(XElement node)
{
var nodeCultures = node.GetCultures();
if (!string.IsNullOrEmpty(nodeCultures)) return nodeCultures.ToDelimitedList();
return GetCultures();
}

public IList<string> GetSegments()
=> GetSetting(uSyncConstants.SegmentKey, string.Empty).ToDelimitedList();

public string SwapValue(string key, string newValue)
{
string oldValue = null;

if (!this.Settings.ContainsKey(key))
oldValue = this.Settings[key];

if (newValue == null)
this.Settings.Remove(key);
else
this.Settings[key] = newValue;

return oldValue;
}
}
}
Loading

0 comments on commit a347b00

Please sign in to comment.