Skip to content

Commit

Permalink
Add explicit id serializer for compatibility purposes
Browse files Browse the repository at this point in the history
  • Loading branch information
georghinkel committed Feb 22, 2021
1 parent 86d3cad commit c1f29bf
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 34 deletions.
53 changes: 53 additions & 0 deletions Models/Models.Tests/ExplicitIdTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NMF.Models.Repository;
using NMF.Models.Repository.Serialization;
using NMF.Models.Tests.Railway;
using NMF.Serialization;

namespace NMF.Models.Tests
{
[TestClass]
public class ExplicitIDTests
{
private ModelRepository repository;
private Model railwayModel;
private RailwayContainer railway;

private static readonly string BaseUri = "http://github.com/NMFCode/NMF/Models/Models.Test/railway.railway";

[TestInitialize]
public void LoadRailwayModel()
{
Model.PromoteSingleRootElement = true;
repository = new ModelRepository();
railwayModel = repository.Resolve(new Uri(BaseUri), "railway.railway").Model;
Assert.IsNotNull(railwayModel);
railway = railwayModel.RootElements.Single() as RailwayContainer;
Assert.IsNotNull(railway);
}

[TestMethod]
public void ExplicitIdsRenderedCorrectly()
{
var serializer = new ExplicitIdSerializer();
using (var ms = new MemoryStream())
{
serializer.Serialize(railwayModel, ms);
ms.Position = 0;
using (var reader = new StreamReader(ms))
{
var result = reader.ReadToEnd();
var idPattern = new Regex("xmi:id", RegexOptions.Compiled);
var counts = idPattern.Matches(result).Count;
Assert.AreEqual(railwayModel.Descendants().Count(), counts);
}
}
}
}
}
8 changes: 4 additions & 4 deletions Models/Models/Repository/MetaRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ namespace NMF.Models.Repository
{
public sealed class MetaRepository : IModelRepository
{
private static MetaRepository instance = new MetaRepository();
private ModelCollection entries;
private ModelSerializer serializer = new ModelSerializer();
private HashSet<Assembly> traversedAssemblies = new HashSet<Assembly>();
private static readonly MetaRepository instance = new MetaRepository();
private readonly ModelCollection entries;
private readonly ModelSerializer serializer = new ModelSerializer();
private readonly HashSet<Assembly> traversedAssemblies = new HashSet<Assembly>();

event EventHandler<BubbledChangeEventArgs> IModelRepository.BubbledChange
{
Expand Down
16 changes: 12 additions & 4 deletions Models/Models/Repository/ModelRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,21 @@ public class ModelRepository : IModelRepository
/// </summary>
/// <param name="parent">The parent repository</param>
/// <remarks>If no parent repository is provided, the meta repository is used as parent repository</remarks>
public ModelRepository(IModelRepository parent)
public ModelRepository(IModelRepository parent) : this(parent, null, FileLocator.Instance) { }

/// <summary>
/// Creates a new model repository with a given parent
/// </summary>
/// <param name="parent">The parent repository</param>
/// <param name="serializer">A serializer object or null to use the default</param>
/// <param name="locators">A set of model locators</param>
/// <remarks>If no parent repository is provided, the meta repository is used as parent repository</remarks>
public ModelRepository(IModelRepository parent, IModelSerializer serializer, params IModelLocator[] locators)
{
models = new ModelRepositoryModelCollection(this);
Locators = new List<IModelLocator>();
Locators.Add(FileLocator.Instance);
Locators = new List<IModelLocator>(locators);
Parent = parent ?? MetaRepository.Instance;
Serializer = MetaRepository.Instance.Serializer;
Serializer = serializer ?? MetaRepository.Instance.Serializer;
Parent.BubbledChange += Parent_BubbledChange;
}

Expand Down
51 changes: 51 additions & 0 deletions Models/Models/Repository/Serialization/ExplicitIdSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using NMF.Serialization;
using NMF.Serialization.Xmi;

namespace NMF.Models.Repository.Serialization
{
/// <summary>
/// Denotes a serializer that is able to read and understand all model URIs but serializes using XMI IDs
/// </summary>
public class ExplicitIdSerializer : ModelSerializer
{
public ExplicitIdSerializer()
{
}

public ExplicitIdSerializer(XmlSerializationSettings settings) : base(settings)
{
}

public ExplicitIdSerializer(XmlSerializer parent) : base(parent)
{
}

public ExplicitIdSerializer(XmlSerializationSettings settings, IEnumerable<Type> knownTypes) : base(settings, knownTypes)
{
}

/// <inheritdoc />
protected override string GetAttributeValue(object value, ITypeSerializationInfo info, bool isCollection, XmlSerializationContext context)
{
if (value is IModelElement modelElement && modelElement.Model == context.Root)
{
return info.IdentifierProperty.GetValue(value, context).ToString();
}
return base.GetAttributeValue(value, info, isCollection, context);
}

/// <inheritdoc />
protected override bool WriteIdentifiedObject(XmlWriter writer, object obj, XmlIdentificationMode identificationMode, ITypeSerializationInfo info, XmlSerializationContext context)
{
return false;
}

/// <inheritdoc />
protected override IPropertySerializationInfo IdAttribute => XmiArtificialIdAttribute.Instance;
}
}
45 changes: 21 additions & 24 deletions Models/Models/Repository/Serialization/ModelSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,20 @@

namespace NMF.Models.Repository.Serialization
{
/// <summary>
/// Denotes the standard model serializer
/// </summary>
public class ModelSerializer : XmiSerializer, IModelSerializer
{
/// <summary>
/// Creates a new model serializer
/// </summary>
public ModelSerializer() : this(XmlSerializationSettings.Default) { }

/// <summary>
/// Creates a new model serializer
/// </summary>
/// <param name="settings">The serialization settings</param>
public ModelSerializer(XmlSerializationSettings settings) : this(settings, null) { }

/// <summary>
Expand All @@ -26,13 +36,11 @@ public class ModelSerializer : XmiSerializer, IModelSerializer
public ModelSerializer(XmlSerializationSettings settings, IEnumerable<Type> knownTypes)
: base(settings, knownTypes)
{

}

protected override void InitializeElementProperties(XmlReader reader, ref object obj, ITypeSerializationInfo info, XmlSerializationContext context)
{
var model = obj as Model;
if (model == null)
if (!(obj is Model model))
{
base.InitializeElementProperties(reader, ref obj, info, context);
}
Expand Down Expand Up @@ -64,8 +72,7 @@ protected override void InitializeElementProperties(XmlReader reader, ref object

protected override void WriteElementProperties(XmlWriter writer, object obj, ITypeSerializationInfo info, XmlSerializationContext context)
{
var model = obj as Model;
if (model == null)
if (!(obj is Model model))
{
base.WriteElementProperties(writer, obj, info, context);
}
Expand Down Expand Up @@ -94,18 +101,13 @@ protected override bool WriteIdentifiedObject(XmlWriter writer, object obj, XmlI
{
if (identificationMode == XmlIdentificationMode.Identifier)
{
var model = context.Root as Model;
if (model != null)
if (context.Root is Model model && obj is IModelElement modelElement)
{
var modelElement = obj as IModelElement;
if (modelElement != null)
var uri = model.CreateUriForElement(modelElement);
if (uri != null)
{
Uri uri = model.CreateUriForElement(modelElement);
if (uri != null)
{
writer.WriteString(uri.ConvertToString());
return true;
}
writer.WriteString(uri.ConvertToString());
return true;
}
}
}
Expand All @@ -114,12 +116,10 @@ protected override bool WriteIdentifiedObject(XmlWriter writer, object obj, XmlI

public override void Serialize(object obj, XmlWriter writer, IPropertySerializationInfo property, bool writeInstance, XmlIdentificationMode identificationMode, XmlSerializationContext context)
{
var modelElement = obj as IModelElement;
var useBaseSerialization = true;
if (modelElement != null)
if (obj is IModelElement modelElement)
{
var modelSerializationContext = context as ModelSerializationContext;
if (modelSerializationContext != null && modelSerializationContext.Model != null)
if (context is ModelSerializationContext modelSerializationContext && modelSerializationContext.Model != null)
{
useBaseSerialization = !modelSerializationContext.Model.SerializeAsReference(modelElement);
}
Expand All @@ -138,9 +138,7 @@ public override void Serialize(object obj, XmlWriter writer, IPropertySerializat

protected override string GetAttributeValue(object value, ITypeSerializationInfo info, bool isCollection, XmlSerializationContext context)
{
var model = context.Root as Model;
var modelElement = value as ModelElement;
if (modelElement != null && model != null)
if (value is ModelElement modelElement && context.Root is Model model)
{
Uri uri = model.CreateUriForElement(modelElement);
if (uri != null)
Expand Down Expand Up @@ -235,8 +233,7 @@ public Model Deserialize(Stream source, Uri modelUri, IModelRepository repositor
protected override object SelectRoot(object graph, bool fragment)
{
if (fragment) return graph;
var modelElement = graph as IModelElement;
if (modelElement != null)
if (graph is IModelElement modelElement)
{
var model = modelElement.Model;
if (model == null) return graph;
Expand Down
3 changes: 1 addition & 2 deletions Models/Serialization/XMI/XmiSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,8 @@ protected override void InitializeTypeSerializationInfo(Type type, ITypeSerializ

if (!serializationInfo.IsIdentified && !serializationInfo.IsCollection && serializationInfo is XmlTypeSerializationInfo)
{
XmlTypeSerializationInfo info = serializationInfo as XmlTypeSerializationInfo;
var id = IdAttribute;
if (id != null && info != null)
if (id != null && serializationInfo is XmlTypeSerializationInfo info)
{
if (!info.AttributeProperties.Contains(id))
{
Expand Down

0 comments on commit c1f29bf

Please sign in to comment.