mirror of https://github.com/Squidex/squidex.git
109 changed files with 1649 additions and 755 deletions
@ -0,0 +1,23 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace Squidex.Infrastructure.Json |
|||
{ |
|||
public interface IJsonSerializer |
|||
{ |
|||
string Serialize<T>(T value); |
|||
|
|||
void Serialize<T>(T value, Stream stream); |
|||
|
|||
T Deserialize<T>(string value, Type actualType = null); |
|||
|
|||
T Deserialize<T>(Stream stream, Type actualType = null); |
|||
} |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using Newtonsoft.Json.Linq; |
|||
|
|||
namespace Squidex.Infrastructure.Json |
|||
{ |
|||
public static class JsonExtension |
|||
{ |
|||
public static bool IsNull(this JToken token) |
|||
{ |
|||
if (token == null) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (token.Type == JTokenType.Null) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
if (token is JValue value) |
|||
{ |
|||
return value.Value == null; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,161 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using Newtonsoft.Json; |
|||
using Squidex.Infrastructure.Json.Objects; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Newtonsoft |
|||
{ |
|||
public sealed class JsonValueConverter : JsonConverter |
|||
{ |
|||
public override bool CanConvert(Type objectType) |
|||
{ |
|||
return typeof(IJsonValue).IsAssignableFrom(objectType); |
|||
} |
|||
|
|||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
|||
{ |
|||
return ReadJson(reader); |
|||
} |
|||
|
|||
private IJsonValue ReadJson(JsonReader reader) |
|||
{ |
|||
switch (reader.TokenType) |
|||
{ |
|||
case JsonToken.Comment: |
|||
reader.Read(); |
|||
break; |
|||
case JsonToken.StartObject: |
|||
{ |
|||
var result = JsonValue.Object(); |
|||
|
|||
while (reader.Read()) |
|||
{ |
|||
switch (reader.TokenType) |
|||
{ |
|||
case JsonToken.PropertyName: |
|||
var propertyName = reader.Value.ToString(); |
|||
|
|||
if (!reader.Read()) |
|||
{ |
|||
throw new JsonSerializationException("Unexpected end when reading Object."); |
|||
} |
|||
|
|||
var value = ReadJson(reader); |
|||
|
|||
result[propertyName] = value; |
|||
break; |
|||
case JsonToken.EndObject: |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
throw new JsonSerializationException("Unexpected end when reading Object."); |
|||
} |
|||
|
|||
case JsonToken.StartArray: |
|||
{ |
|||
var result = JsonValue.Array(); |
|||
|
|||
while (reader.Read()) |
|||
{ |
|||
switch (reader.TokenType) |
|||
{ |
|||
case JsonToken.Comment: |
|||
break; |
|||
default: |
|||
var value = ReadJson(reader); |
|||
|
|||
result.Add(value); |
|||
break; |
|||
case JsonToken.EndArray: |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
throw new JsonSerializationException("Unexpected end when reading Object."); |
|||
} |
|||
|
|||
case JsonToken.Integer: |
|||
return JsonValue.Create((long)reader.Value); |
|||
case JsonToken.Float: |
|||
return JsonValue.Create((double)reader.Value); |
|||
case JsonToken.Boolean: |
|||
return JsonValue.Create((bool)reader.Value); |
|||
case JsonToken.Date: |
|||
return JsonValue.Create(((DateTime)reader.Value).ToString("yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture)); |
|||
case JsonToken.String: |
|||
return JsonValue.Create(reader.Value.ToString()); |
|||
case JsonToken.Null: |
|||
case JsonToken.Undefined: |
|||
return JsonValue.Null; |
|||
} |
|||
|
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
writer.WriteNull(); |
|||
return; |
|||
} |
|||
|
|||
WriteJson(writer, (IJsonValue)value); |
|||
} |
|||
|
|||
private void WriteJson(JsonWriter writer, IJsonValue value) |
|||
{ |
|||
switch (value) |
|||
{ |
|||
case JsonNull n: |
|||
writer.WriteNull(); |
|||
break; |
|||
case JsonScalar<bool> s: |
|||
writer.WriteValue(s.Value); |
|||
break; |
|||
case JsonScalar<string> s: |
|||
writer.WriteValue(s.Value); |
|||
break; |
|||
case JsonScalar<double> s: |
|||
writer.WriteValue(s.Value); |
|||
break; |
|||
case JsonArray array: |
|||
{ |
|||
writer.WriteStartArray(); |
|||
|
|||
foreach (var item in array) |
|||
{ |
|||
WriteJson(writer, item); |
|||
} |
|||
|
|||
writer.WriteEndArray(); |
|||
break; |
|||
} |
|||
|
|||
case JsonObject obj: |
|||
{ |
|||
writer.WriteStartObject(); |
|||
|
|||
foreach (var kvp in obj) |
|||
{ |
|||
writer.WritePropertyName(kvp.Key); |
|||
|
|||
WriteJson(writer, kvp.Value); |
|||
} |
|||
|
|||
writer.WriteEndObject(); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using Newtonsoft.Json; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Newtonsoft |
|||
{ |
|||
public sealed class NewtonsoftJsonSerializer : IJsonSerializer |
|||
{ |
|||
private readonly JsonSerializerSettings settings; |
|||
private readonly JsonSerializer serializer; |
|||
|
|||
public NewtonsoftJsonSerializer(JsonSerializerSettings settings) |
|||
{ |
|||
Guard.NotNull(settings, nameof(settings)); |
|||
|
|||
this.settings = settings; |
|||
|
|||
serializer = JsonSerializer.Create(settings); |
|||
} |
|||
|
|||
public T Deserialize<T>(string value, Type actualType = null) |
|||
{ |
|||
actualType = actualType ?? typeof(T); |
|||
|
|||
return (T)JsonConvert.DeserializeObject(value, actualType, settings); |
|||
} |
|||
|
|||
public T Deserialize<T>(Stream stream, Type actualType = null) |
|||
{ |
|||
using (var streamReader = new StreamReader(stream)) |
|||
{ |
|||
actualType = actualType ?? typeof(T); |
|||
|
|||
return (T)serializer.Deserialize(streamReader, actualType); |
|||
} |
|||
} |
|||
|
|||
public string Serialize<T>(T value) |
|||
{ |
|||
return JsonConvert.SerializeObject(value, settings); |
|||
} |
|||
|
|||
public void Serialize<T>(T value, Stream stream) |
|||
{ |
|||
using (var writer = new StreamWriter(stream)) |
|||
{ |
|||
serializer.Serialize(writer, value); |
|||
|
|||
writer.Flush(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public interface IJsonValue : IEquatable<IJsonValue> |
|||
{ |
|||
JsonValueType Type { get; } |
|||
|
|||
string ToJsonString(); |
|||
} |
|||
} |
|||
@ -0,0 +1,100 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public sealed class JsonArray : Collection<IJsonValue>, IJsonValue, IEquatable<JsonArray> |
|||
{ |
|||
public JsonValueType Type |
|||
{ |
|||
get { return JsonValueType.Array; } |
|||
} |
|||
|
|||
public JsonArray() |
|||
{ |
|||
} |
|||
|
|||
public JsonArray(IList<IJsonValue> values) |
|||
: base(values) |
|||
{ |
|||
} |
|||
|
|||
public JsonArray(params object[] values) |
|||
: base(values?.Select(JsonValue.Create).ToList()) |
|||
{ |
|||
} |
|||
|
|||
protected override void InsertItem(int index, IJsonValue item) |
|||
{ |
|||
Guard.NotNull(item, nameof(item)); |
|||
|
|||
base.InsertItem(index, item); |
|||
} |
|||
|
|||
protected override void SetItem(int index, IJsonValue item) |
|||
{ |
|||
Guard.NotNull(item, nameof(item)); |
|||
|
|||
base.SetItem(index, item); |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return Equals(obj as JsonArray); |
|||
} |
|||
|
|||
public bool Equals(IJsonValue other) |
|||
{ |
|||
return Equals(other as JsonArray); |
|||
} |
|||
|
|||
public bool Equals(JsonArray array) |
|||
{ |
|||
if (array == null || array.Count != Count) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
for (var i = 0; i < Count; i++) |
|||
{ |
|||
if (!this[i].Equals(array[i])) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
var hashCode = 0; |
|||
|
|||
for (var i = 0; i < Count; i++) |
|||
{ |
|||
hashCode = (hashCode * 23) + this[i].GetHashCode(); |
|||
} |
|||
|
|||
return hashCode; |
|||
} |
|||
|
|||
public string ToJsonString() |
|||
{ |
|||
return ToString(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"[{string.Join(", ", this)}]"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public sealed class JsonNull : IJsonValue, IEquatable<JsonNull> |
|||
{ |
|||
public static readonly JsonNull Null = new JsonNull(); |
|||
|
|||
public JsonValueType Type |
|||
{ |
|||
get { return JsonValueType.Null; } |
|||
} |
|||
|
|||
private JsonNull() |
|||
{ |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return Equals(obj as JsonNull); |
|||
} |
|||
|
|||
public bool Equals(IJsonValue other) |
|||
{ |
|||
return Equals(other as JsonNull); |
|||
} |
|||
|
|||
public bool Equals(JsonNull other) |
|||
{ |
|||
return other != null; |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
public string ToJsonString() |
|||
{ |
|||
return ToString(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return "null"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,129 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public sealed class JsonObject : IReadOnlyDictionary<string, IJsonValue>, IJsonValue, IEquatable<JsonObject> |
|||
{ |
|||
private readonly Dictionary<string, IJsonValue> inner = new Dictionary<string, IJsonValue>(); |
|||
|
|||
public IJsonValue this[string key] |
|||
{ |
|||
get |
|||
{ |
|||
return inner[key]; |
|||
} |
|||
set |
|||
{ |
|||
Guard.NotNullOrEmpty(key, nameof(key)); |
|||
Guard.NotNull(value, nameof(value)); |
|||
|
|||
inner[key] = value; |
|||
} |
|||
} |
|||
|
|||
public IEnumerable<string> Keys |
|||
{ |
|||
get { return inner.Keys; } |
|||
} |
|||
|
|||
public IEnumerable<IJsonValue> Values |
|||
{ |
|||
get { return inner.Values; } |
|||
} |
|||
|
|||
public int Count |
|||
{ |
|||
get { return inner.Count; } |
|||
} |
|||
|
|||
public JsonValueType Type |
|||
{ |
|||
get { return JsonValueType.Array; } |
|||
} |
|||
|
|||
public JsonObject Add(string key, object value) |
|||
{ |
|||
return Add(key, JsonValue.Create(value)); |
|||
} |
|||
|
|||
public JsonObject Add(string key, IJsonValue value) |
|||
{ |
|||
Guard.NotNullOrEmpty(key, nameof(key)); |
|||
Guard.NotNull(value, nameof(value)); |
|||
|
|||
inner.Add(key, value); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
public void Clear() |
|||
{ |
|||
inner.Clear(); |
|||
} |
|||
|
|||
public bool Remove(string key) |
|||
{ |
|||
return inner.Remove(key); |
|||
} |
|||
|
|||
public bool ContainsKey(string key) |
|||
{ |
|||
return inner.ContainsKey(key); |
|||
} |
|||
|
|||
public bool TryGetValue(string key, out IJsonValue value) |
|||
{ |
|||
return inner.TryGetValue(key, out value); |
|||
} |
|||
|
|||
public IEnumerator<KeyValuePair<string, IJsonValue>> GetEnumerator() |
|||
{ |
|||
return inner.GetEnumerator(); |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return inner.GetEnumerator(); |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return Equals(obj as JsonObject); |
|||
} |
|||
|
|||
public bool Equals(IJsonValue other) |
|||
{ |
|||
return Equals(other as JsonObject); |
|||
} |
|||
|
|||
public bool Equals(JsonObject other) |
|||
{ |
|||
return other != null && inner.EqualsDictionary(other.inner); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
return inner.DictionaryHashCode(); |
|||
} |
|||
|
|||
public string ToJsonString() |
|||
{ |
|||
return ToString(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"{{{string.Join(", ", this.Select(x => $"\"{x.Key}\"={x.Value}\""))}}}";
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public sealed class JsonScalar<T> : IJsonValue, IEquatable<JsonScalar<T>> |
|||
{ |
|||
private readonly T value; |
|||
|
|||
public JsonValueType Type { get; } |
|||
|
|||
public T Value |
|||
{ |
|||
get { return value; } |
|||
} |
|||
|
|||
internal JsonScalar(JsonValueType type, T value) |
|||
{ |
|||
Type = type; |
|||
|
|||
this.value = value; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return Equals(obj as JsonScalar<T>); |
|||
} |
|||
|
|||
public bool Equals(IJsonValue other) |
|||
{ |
|||
return Equals(other as JsonScalar<T>); |
|||
} |
|||
|
|||
public bool Equals(JsonScalar<T> other) |
|||
{ |
|||
return other != null && other.Type == Type && Equals(other.value, value); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
return value.GetHashCode(); |
|||
} |
|||
|
|||
public string ToJsonString() |
|||
{ |
|||
return Type == JsonValueType.String ? $"\"{value}\"" : ToString(); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return value.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public static class JsonValue |
|||
{ |
|||
public static readonly JsonScalar<string> Empty = new JsonScalar<string>(JsonValueType.String, string.Empty); |
|||
|
|||
public static readonly JsonScalar<bool> True = new JsonScalar<bool>(JsonValueType.Boolean, true); |
|||
public static readonly JsonScalar<bool> False = new JsonScalar<bool>(JsonValueType.Boolean, false); |
|||
|
|||
public static readonly JsonNull Null = JsonNull.Null; |
|||
|
|||
public static JsonArray Array() |
|||
{ |
|||
return new JsonArray(); |
|||
} |
|||
|
|||
public static JsonArray Array(params object[] values) |
|||
{ |
|||
return new JsonArray(values); |
|||
} |
|||
|
|||
public static JsonObject Object() |
|||
{ |
|||
return new JsonObject(); |
|||
} |
|||
|
|||
public static IJsonValue Create(object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return Null; |
|||
} |
|||
|
|||
if (value is IJsonValue v) |
|||
{ |
|||
return v; |
|||
} |
|||
|
|||
switch (value) |
|||
{ |
|||
case string s: |
|||
return Create(s); |
|||
case bool b: |
|||
return Create(b); |
|||
case float f: |
|||
return Create(f); |
|||
case double d: |
|||
return Create(d); |
|||
case int i: |
|||
return Create(i); |
|||
case long l: |
|||
return Create(l); |
|||
} |
|||
|
|||
throw new ArgumentException("Invalid json type"); |
|||
} |
|||
|
|||
public static IJsonValue Create(bool value) |
|||
{ |
|||
return value ? True : False; |
|||
} |
|||
|
|||
public static IJsonValue Create(double value) |
|||
{ |
|||
Guard.ValidNumber(value, nameof(value)); |
|||
|
|||
return new JsonScalar<double>(JsonValueType.Number, value); |
|||
} |
|||
|
|||
public static IJsonValue Create(double? value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return Null; |
|||
} |
|||
|
|||
return Create(value.Value); |
|||
} |
|||
|
|||
public static IJsonValue Create(bool? value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return Null; |
|||
} |
|||
|
|||
return Create(value.Value); |
|||
} |
|||
|
|||
public static IJsonValue Create(string value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return Null; |
|||
} |
|||
|
|||
if (value.Length == 0) |
|||
{ |
|||
return Empty; |
|||
} |
|||
|
|||
return new JsonScalar<string>(JsonValueType.String, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
namespace Squidex.Infrastructure.Json.Objects |
|||
{ |
|||
public enum JsonValueType |
|||
{ |
|||
Array, |
|||
Boolean, |
|||
Null, |
|||
Number, |
|||
Object, |
|||
String |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue