Merge branch 'dev/AR-4_delinter_fixes' into dev/AR-1_serialization
This commit is contained in:
@@ -1,20 +1,12 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Archetype.PropertyEditors;
|
||||
using Archetype.Serialization;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Editors;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Archetype.Tests.Serialization.Base
|
||||
@@ -93,59 +85,11 @@ namespace Archetype.Tests.Serialization.Base
|
||||
AssertAreEqual(model, resultfromArchetypeJson);
|
||||
}
|
||||
|
||||
protected void CompoundModel_WithEscapedJson_Regression_Battery<T>(T model)
|
||||
{
|
||||
var propGuid = new Guid();
|
||||
var dtd = new DataTypeDefinition(-1, String.Empty) {Id = 0};
|
||||
|
||||
var dataTypeService = new Mock<IDataTypeService>();
|
||||
dataTypeService.Setup(dts => dts.GetDataTypeDefinitionById(Guid.Parse(propGuid.ToString()))).Returns(dtd);
|
||||
dataTypeService.Setup(dts => dts.GetPreValuesCollectionByDataTypeId(dtd.Id)).Returns(new PreValueCollection(new Dictionary<string, PreValue>()));
|
||||
|
||||
var propValueEditor = new Mock<ArchetypePropertyEditor.ArchetypePropertyValueEditor>(new PropertyValueEditor());
|
||||
propValueEditor.Setup(pe => pe.GetPropertyEditor(dtd)).Returns(new ArchetypePropertyEditor());
|
||||
|
||||
var archetype = ConvertModelToArchetype(model);
|
||||
|
||||
foreach (var prop in archetype.Fieldsets.SelectMany(fs => fs.Properties))
|
||||
{
|
||||
prop.DataTypeGuid = propGuid.ToString();
|
||||
if (prop.Value.ToString().Contains("fieldsets"))
|
||||
prop.PropertyEditorAlias = Constants.PropertyEditorAlias;
|
||||
}
|
||||
|
||||
var archetypeJson = JsonConvert.SerializeObject(archetype);
|
||||
Assert.IsNotNullOrEmpty(archetypeJson);
|
||||
|
||||
EnsureUmbracoContext(dataTypeService);
|
||||
|
||||
var propEditor = new ArchetypePropertyEditor.ArchetypePropertyValueEditor(new PropertyValueEditor());
|
||||
var convertedJson = propEditor.ConvertEditorToDb(new ContentPropertyData(JObject.FromObject(archetype),
|
||||
new PreValueCollection(new Dictionary<string, PreValue>()), new Dictionary<string, object>()),
|
||||
archetypeJson);
|
||||
|
||||
Assert.IsNotNull(convertedJson);
|
||||
|
||||
var resultfromArchetypeJson = ConvertArchetypeJsonToModel<T>(archetypeJson);
|
||||
var resultfromConvertedJson = ConvertArchetypeJsonToModel<T>(convertedJson.ToString().DelintArchetypeJson());
|
||||
|
||||
Assert.IsInstanceOf<T>(resultfromArchetypeJson);
|
||||
AssertAreEqual(model, resultfromArchetypeJson);
|
||||
|
||||
Assert.IsInstanceOf<T>(resultfromConvertedJson);
|
||||
AssertAreEqual(model, resultfromConvertedJson);
|
||||
}
|
||||
|
||||
protected void NestedModel_Regression_Battery<T>(T model)
|
||||
{
|
||||
CompoundModel_Regression_Battery(model);
|
||||
}
|
||||
|
||||
protected void NestedModel_WithEscapedJson_Regression_Battery<T>(T model)
|
||||
{
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(model);
|
||||
}
|
||||
|
||||
protected void ComplexModel_Regression_Battery<T>(T model)
|
||||
{
|
||||
CompoundModel_Regression_Battery(model);
|
||||
|
||||
@@ -49,7 +49,46 @@ namespace Archetype.Tests.Serialization.Delinter
|
||||
_nestedClass.Nested.SlideShow = _referenceModel;
|
||||
_nestedClass.Nested.Nested = GetNestedClass();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Delinter_RemoveNewLine_ByPasses_Values()
|
||||
{
|
||||
const string _JSON_WITH_RESERVED_CHARS = @"{
|
||||
""alias"": ""captions"",
|
||||
""value"": ""{ \""fieldsets\"": [
|
||||
{
|
||||
\""properties\"":
|
||||
[
|
||||
{ \""alias\"": \""textstring\"" , \""value\"":\""test1 \r\n test1\r\n\""}], \""alias\"":\""textstringArray\"" },{\""properties\"": [ { \""alias\"":\""textstring\"",\""value\"":\""test2\r\ntest2\""}],\""alias\"":\""textstringArray\""},{\""properties\"":[{\""alias\"":\""textstring\"",\""value\"":\""test3b \""quote\"" \\r\\r\\rtest3\""}],\""alias\"":\""textstringArray\"" } ] }""
|
||||
}";
|
||||
|
||||
var referenceModel = new Captions()
|
||||
{
|
||||
new TextString() {Text = @"test1
|
||||
test1
|
||||
"},
|
||||
new TextString() {Text = @"test2
|
||||
test2"},
|
||||
new TextString() {Text = @"test3b ""quote"" \r\r\rtest3"}
|
||||
};
|
||||
|
||||
var delintedJson = _JSON_WITH_RESERVED_CHARS.DelintArchetypeJson();
|
||||
var actualModel = ConvertArchetypeJsonToModel<Captions>(delintedJson);
|
||||
|
||||
var t = JToken.Parse(delintedJson).ToString(Formatting.None);
|
||||
|
||||
Assert.IsInstanceOf<Captions>(actualModel);
|
||||
Assert.IsNotNull(actualModel);
|
||||
|
||||
Assert.AreEqual(3, actualModel.Count);
|
||||
|
||||
foreach (var refItem in referenceModel)
|
||||
{
|
||||
var index = referenceModel.IndexOf(refItem);
|
||||
AssertAreEqual(refItem, actualModel.ElementAt(index));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReferenceJsonAndModel_Equal_ExpectedJsonAndModel()
|
||||
|
||||
@@ -67,13 +67,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModel_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModel>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetVariant1_Regression_Battery()
|
||||
{
|
||||
@@ -81,13 +74,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetVariant1_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithMixedFieldsetVariant1>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetVariant2_Regression_Battery()
|
||||
{
|
||||
@@ -95,13 +81,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetVariant2_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithMixedFieldsetVariant2>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithFieldset_Regression_Battery()
|
||||
{
|
||||
@@ -109,13 +88,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithFieldset_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithFieldset>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithList_Regression_Battery()
|
||||
{
|
||||
@@ -123,13 +95,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModelWithList);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithList_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithList>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetWithList_Regression_Battery()
|
||||
{
|
||||
@@ -137,13 +102,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModelWithList);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithMixedFieldsetWithList_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithMixedFieldsetWithList>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithFieldsetWithList_Regression_Battery()
|
||||
{
|
||||
@@ -151,13 +109,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
CompoundModel_Regression_Battery(compoundModelWithList);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CompoundModelWithFieldsetWithList_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var compoundModel = _testHelper.GetModel<CompoundModelWithFieldsetWithList>();
|
||||
CompoundModel_WithEscapedJson_Regression_Battery(compoundModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModel_Regression_Battery()
|
||||
{
|
||||
@@ -165,13 +116,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
NestedModel_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModel_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var nestedModel = _testHelper.GetModel<NestedModel>();
|
||||
NestedModel_WithEscapedJson_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModelWithMixedFieldset_Regression_Battery()
|
||||
{
|
||||
@@ -179,13 +123,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
NestedModel_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModelWithMixedFieldset_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var nestedModel = _testHelper.GetModel<NestedModelWithMixedFieldset>();
|
||||
NestedModel_WithEscapedJson_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModelWithFieldset_Regression_Battery()
|
||||
{
|
||||
@@ -193,13 +130,6 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
NestedModel_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedModelWithFieldset_WithEscapedJson_Regression_Battery()
|
||||
{
|
||||
var nestedModel = _testHelper.GetModel<NestedModelWithFieldset>();
|
||||
NestedModel_WithEscapedJson_Regression_Battery(nestedModel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComplexModel_Regression_Battery()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
""properties"": [
|
||||
{
|
||||
""alias"": ""text"",
|
||||
""value"": ""Test Text""
|
||||
""value"": ""Test \r\nText \""quote\"" \r\n""
|
||||
},
|
||||
{
|
||||
""alias"": ""integer"",
|
||||
|
||||
@@ -27,7 +27,9 @@ namespace Archetype.Tests.Serialization.Regression
|
||||
DateTwo = null,
|
||||
Id = 123,
|
||||
NullableId = null,
|
||||
Text = "Test Text"
|
||||
Text = @"Test
|
||||
Text ""quote""
|
||||
"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -126,8 +126,8 @@ namespace Archetype.PropertyEditors
|
||||
{
|
||||
var dtd = ApplicationContext.Current.Services.DataTypeService.GetDataTypeDefinitionById(Guid.Parse(propDef.DataTypeGuid));
|
||||
var preValues = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id);
|
||||
var propData = new ContentPropertyData(propDef.Value, preValues, new Dictionary<string, object>());
|
||||
var propEditor = GetPropertyEditor(dtd);
|
||||
var propData = new ContentPropertyData(propDef.Value, preValues, new Dictionary<string, object>());
|
||||
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
|
||||
propDef.Value = propEditor.ValueEditor.ConvertEditorToDb(propData, propDef.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -38,22 +38,9 @@ namespace Archetype.Serialization
|
||||
var jToken = JToken.ReadFrom(reader);
|
||||
|
||||
if (jToken == null)
|
||||
return null;
|
||||
|
||||
var obj = Activator.CreateInstance(objectType);
|
||||
return null;
|
||||
|
||||
if (null != obj as IEnumerable<object>)
|
||||
{
|
||||
JToken enumerableToken;
|
||||
|
||||
if (TryParseJTokenAsEnumerable(jToken, out enumerableToken)
|
||||
|| TryParseJTokenAsEnumerable(jToken["value"], out enumerableToken))
|
||||
return DeserializeEnumerableObject(obj, enumerableToken);
|
||||
}
|
||||
|
||||
return null == jToken as JArray
|
||||
? DeserializeObject(obj, jToken)
|
||||
: PopulateProperties(obj, jToken);
|
||||
return DeserializeJson(objectType, GetDelintedJToken(jToken));
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
@@ -63,17 +50,48 @@ namespace Archetype.Serialization
|
||||
|
||||
#endregion
|
||||
|
||||
#region private methods - deserialization
|
||||
#region private methods - deserialization
|
||||
|
||||
private JToken GetDelintedJToken(JToken jToken)
|
||||
{
|
||||
return JToken.Parse(jToken.ToString(Formatting.None).DelintArchetypeJson());
|
||||
}
|
||||
|
||||
private object DeserializeJson(Type objectType, JToken jToken)
|
||||
{
|
||||
|
||||
var obj = Activator.CreateInstance(objectType);
|
||||
|
||||
if (null != obj as IEnumerable<object>)
|
||||
{
|
||||
JToken enumerableToken;
|
||||
|
||||
if (TryParseJTokenAsEnumerable(jToken, out enumerableToken)
|
||||
|| (jToken.SelectToken("value") != null && TryParseJTokenAsEnumerable(jToken["value"], out enumerableToken)))
|
||||
return DeserializeEnumerableObject(obj, enumerableToken);
|
||||
}
|
||||
|
||||
return null == jToken as JArray
|
||||
? DeserializeObject(obj, jToken)
|
||||
: PopulateProperties(obj, jToken);
|
||||
}
|
||||
|
||||
private object DeserializeEnumerableObject(object obj, JToken jToken)
|
||||
{
|
||||
var model = obj as IEnumerable<object>;
|
||||
|
||||
var itemType = model.GetType().BaseType.GetGenericArguments().First();
|
||||
foreach (var fs in jToken["fieldsets"].Where(fs => fs["alias"].ToString().Equals(GetFieldsetName(itemType))))
|
||||
{
|
||||
var item = JsonConvert.DeserializeObject(
|
||||
fs["properties"].ToString().DelintArchetypeJson(), itemType, this);
|
||||
var model = obj as IEnumerable<object>;
|
||||
var fsToken = jToken;
|
||||
|
||||
var itemType = model.GetType().GetGenericArguments().FirstOrDefault();
|
||||
|
||||
if (itemType == null)
|
||||
{
|
||||
itemType = model.GetType().BaseType.GetGenericArguments().First();
|
||||
fsToken = fsToken["fieldsets"];
|
||||
}
|
||||
|
||||
foreach (var fs in fsToken.Where(fs => fs["alias"].ToString().Equals(GetFieldsetName(itemType))))
|
||||
{
|
||||
var item = DeserializeJson(itemType, fs["properties"]);
|
||||
|
||||
obj.GetType().GetMethod("Add").Invoke(obj, new[] { item });
|
||||
}
|
||||
@@ -208,15 +226,12 @@ namespace Archetype.Serialization
|
||||
private object GetPropertyValue(PropertyInfo propertyInfo, JToken propJToken)
|
||||
{
|
||||
return IsTypeArchetypeDatatype(propertyInfo.PropertyType)
|
||||
? JsonConvert.DeserializeObject(propJToken.ToString().DelintArchetypeJson(), propertyInfo.PropertyType,
|
||||
this)
|
||||
? DeserializeJson(propertyInfo.PropertyType, propJToken)
|
||||
: IsTypeIEnumerableArchetypeDatatype(propertyInfo.PropertyType)
|
||||
? JsonConvert.DeserializeObject(propJToken["value"].SelectToken("fieldsets").ToString(), propertyInfo.PropertyType,
|
||||
this)
|
||||
? DeserializeJson(propertyInfo.PropertyType, propJToken["value"].SelectToken("fieldsets"))
|
||||
: GetDeserializedPropertyValue(propJToken, propertyInfo.PropertyType);
|
||||
}
|
||||
|
||||
|
||||
private JToken ParseJTokenFromItem(JToken jToken, string itemAlias)
|
||||
{
|
||||
return (jToken.SelectToken("alias") != null && jToken["alias"].ToString().Equals(itemAlias))
|
||||
@@ -266,8 +281,14 @@ namespace Archetype.Serialization
|
||||
resultToken = null;
|
||||
|
||||
//To Do: Strange newtonsoft behaviour
|
||||
var fsToken = jToken.Parent == null ? jToken["fieldsets"] : jToken.Parent.Children().First();
|
||||
var jTokenEnumerable = jToken != null && fsToken != null && fsToken.Any();
|
||||
var fsToken = jToken.Parent != null
|
||||
? jToken.Parent.Children().First() is JArray
|
||||
? jToken.Parent.Children().First()
|
||||
: jToken.Parent.Children().First()["fieldsets"]
|
||||
: jToken.SelectToken("fieldsets");
|
||||
|
||||
var jTokenEnumerable = jToken != null
|
||||
&& fsToken != null && fsToken is JArray;
|
||||
|
||||
if (jTokenEnumerable)
|
||||
resultToken = jToken;
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Archetype.Serialization
|
||||
{
|
||||
public enum DelinterStep
|
||||
{
|
||||
{
|
||||
RemoveNewLine = 0,
|
||||
LabelFieldsets,
|
||||
LabelProperties,
|
||||
LabelAlias,
|
||||
LabelValue,
|
||||
RemoveWhiteSpace,
|
||||
UnescapeLabels,
|
||||
UnescapeAlias,
|
||||
UnescapeValues,
|
||||
FixNestedFieldsets,
|
||||
RemoveWhiteSpace
|
||||
FixNestedFieldsets
|
||||
}
|
||||
|
||||
public enum DelinterAction
|
||||
{
|
||||
Remove = 0,
|
||||
RemoveWhiteSpace,
|
||||
UnescapeLabels,
|
||||
UnescapeValues,
|
||||
FixNestedFieldsets
|
||||
@@ -26,9 +26,9 @@ namespace Archetype.Serialization
|
||||
|
||||
public class ArchetypeJsonDelinter
|
||||
{
|
||||
public IDictionary<DelinterStep, DelinterAction> Pipeline { get; set; }
|
||||
public IDictionary<DelinterStep, Regex> Tokens { get; set; }
|
||||
public IDictionary<DelinterAction, Func<Match,string>> Actions { get; set; }
|
||||
public IDictionary<DelinterStep, DelinterAction> Pipeline { get; private set; }
|
||||
public IDictionary<DelinterStep, Regex> Tokens { get; private set; }
|
||||
public IDictionary<DelinterAction, Func<string, Regex, string>> Actions { get; private set; }
|
||||
|
||||
public ArchetypeJsonDelinter()
|
||||
{
|
||||
@@ -42,11 +42,7 @@ namespace Archetype.Serialization
|
||||
foreach (var step in Pipeline.Keys)
|
||||
{
|
||||
var action = Pipeline[step];
|
||||
while (Tokens[step].IsMatch(buffer))
|
||||
{
|
||||
buffer = Tokens[step]
|
||||
.Replace(buffer, match => Actions[action](match));
|
||||
}
|
||||
buffer = Actions[action](buffer, Tokens[step]);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -56,35 +52,54 @@ namespace Archetype.Serialization
|
||||
{
|
||||
Tokens = new Dictionary<DelinterStep, Regex>
|
||||
{
|
||||
{DelinterStep.RemoveNewLine, new Regex(@"\\r|\\n|[\r\n]", RegexOptions.Multiline)},
|
||||
{DelinterStep.LabelFieldsets, new Regex(@"\s*\\+""(fieldsets)\\+"":\s*")},
|
||||
{DelinterStep.LabelProperties, new Regex(@"\s*\\+""(properties)\\+"":\s*")},
|
||||
{DelinterStep.LabelAlias, new Regex(@"\s*\\+""(alias)\\+"":\s*")},
|
||||
{DelinterStep.LabelValue, new Regex(@"\s*\\+""(value)\\+"":\s*")},
|
||||
{DelinterStep.UnescapeValues, new Regex(@"""(alias|value)"":\\+""(.*?)\\+""")},
|
||||
{DelinterStep.FixNestedFieldsets, new Regex(@"""(value)"":\s*?""({""fieldsets"".+?})""")},
|
||||
{DelinterStep.RemoveWhiteSpace, new Regex(@"\s+(?=([^""]*""[^""]*"")*[^""]*$)")}
|
||||
{DelinterStep.RemoveNewLine, new Regex(@"(?<=\,){0,1}(\\+r\\+n)(?=\\*?""(alias|value|properties|fieldsets)\\*?"":\{*?(\\*|""|\[))|(\r|\n)+|(\\+r\\+n)(?=\s*?(\{|\}|\]))|(\\+r\\n+)(?=\s+\\*?""(alias|value|properties|fieldsets))")},
|
||||
{DelinterStep.RemoveWhiteSpace, new Regex(@"(""\S+?"":)(\s+?)("")|([\{\[\}\],]|(?<!\\)"")(\s+)([\{\[\}\],]|(?<!\\)"")")},
|
||||
{DelinterStep.UnescapeLabels, new Regex(@"\\+""(fieldsets|properties|alias|value)\\+"":(\s*)")},
|
||||
{DelinterStep.UnescapeAlias, new Regex(@"""(alias)"":\\+""(.*?)\\+""")},
|
||||
{DelinterStep.UnescapeValues, new Regex(@"""(value)"":\\+""(.*?)\\+""(?=\s*?\})")},
|
||||
{DelinterStep.FixNestedFieldsets, new Regex(@"""(value)"":\s*?""\{\s*?(""fieldsets""[\S\s]+?)}""")}
|
||||
};
|
||||
|
||||
Actions = new Dictionary<DelinterAction, Func<Match, string>>
|
||||
|
||||
Actions = new Dictionary<DelinterAction, Func<string, Regex, string>>
|
||||
{
|
||||
{DelinterAction.Remove, match => String.Empty},
|
||||
{DelinterAction.UnescapeLabels, match => String.Format(@"""{0}"":", match.Groups[1])},
|
||||
{DelinterAction.UnescapeValues, match => String.Format(@"""{0}"":""{1}""", match.Groups[1], match.Groups[2])},
|
||||
{DelinterAction.FixNestedFieldsets, match => String.Format(@"""{0}"":{1}", match.Groups[1], match.Groups[2])}
|
||||
{DelinterAction.Remove, (input, pattern) =>
|
||||
RecursiveReplace(input, pattern, match => String.Empty)
|
||||
},
|
||||
{DelinterAction.RemoveWhiteSpace, (input, pattern) =>
|
||||
RecursiveReplace(input.Trim(), pattern, match =>
|
||||
String.Format("{0}{1}{2}{3}", match.Groups[1].Value,
|
||||
match.Groups[3].Value, match.Groups[4].Value, match.Groups[6].Value))
|
||||
},
|
||||
{DelinterAction.UnescapeLabels, (input, pattern) =>
|
||||
RecursiveReplace(input, pattern, match => String.Format(@"""{0}"":", match.Groups[1].Value))
|
||||
},
|
||||
{DelinterAction.UnescapeValues, (input, pattern) =>
|
||||
RecursiveReplace(input, pattern, match => String.Format(@"""{0}"":""{1}""", match.Groups[1].Value, match.Groups[2].Value))
|
||||
},
|
||||
{DelinterAction.FixNestedFieldsets, (input, pattern) =>
|
||||
RecursiveReplace(input, pattern, match => String.Format(@"""{0}"":{{{1}}}", match.Groups[1].Value, match.Groups[2].Value))
|
||||
}
|
||||
};
|
||||
|
||||
Pipeline = new Dictionary<DelinterStep, DelinterAction>
|
||||
{
|
||||
{DelinterStep.RemoveNewLine, DelinterAction.Remove},
|
||||
{DelinterStep.LabelFieldsets, DelinterAction.UnescapeLabels},
|
||||
{DelinterStep.LabelProperties, DelinterAction.UnescapeLabels},
|
||||
{DelinterStep.LabelAlias, DelinterAction.UnescapeLabels},
|
||||
{DelinterStep.LabelValue, DelinterAction.UnescapeLabels},
|
||||
{DelinterStep.RemoveNewLine, DelinterAction.Remove},
|
||||
{DelinterStep.UnescapeLabels, DelinterAction.UnescapeLabels},
|
||||
{DelinterStep.UnescapeAlias, DelinterAction.UnescapeValues},
|
||||
{DelinterStep.UnescapeValues, DelinterAction.UnescapeValues},
|
||||
{DelinterStep.FixNestedFieldsets, DelinterAction.FixNestedFieldsets},
|
||||
{DelinterStep.RemoveWhiteSpace, DelinterAction.Remove}
|
||||
{DelinterStep.RemoveWhiteSpace, DelinterAction.RemoveWhiteSpace},
|
||||
};
|
||||
}
|
||||
|
||||
private string RecursiveReplace(string input, Regex pattern, Func<Match, string> matchFunc)
|
||||
{
|
||||
var buffer = input;
|
||||
while (pattern.IsMatch(buffer))
|
||||
{
|
||||
buffer = pattern.Replace(buffer, match => matchFunc(match));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user