Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/Microsoft.OpenApi/Any/CloneHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.Reflection;

namespace Microsoft.OpenApi.Any
{
/// <summary>
/// Contains logic for cloning objects through copy constructors.
/// </summary>
public class CloneHelper
{
/// <summary>
/// Clones an instance of <see cref="IOpenApiAny"/> object from the copy constructor
/// </summary>
/// <param name="obj">The object instance.</param>
/// <returns>A clone copy or the object itself.</returns>
public static IOpenApiAny CloneFromCopyConstructor(IOpenApiAny obj)
{
if (obj != null)
{
var t = obj.GetType();
foreach (ConstructorInfo ci in t.GetConstructors())
{
ParameterInfo[] pi = ci.GetParameters();
if (pi.Length == 1 && pi[0].ParameterType == t)
{
return (IOpenApiAny)ci.Invoke(new object[] { obj });
}
}
}

return obj;
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Any/IOpenApiAny.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.OpenApi.Any
/// <summary>
/// Base interface for all the types that represent Open API Any.
/// </summary>
public interface IOpenApiAny : IOpenApiElement, IOpenApiExtension, ICloneable
public interface IOpenApiAny : IOpenApiElement, IOpenApiExtension
{
/// <summary>
/// Type of an <see cref="IOpenApiAny"/>.
Expand Down
11 changes: 1 addition & 10 deletions src/Microsoft.OpenApi/Any/OpenApiArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,13 @@ namespace Microsoft.OpenApi.Any
/// <summary>
/// Open API array.
/// </summary>
public class OpenApiArray : List<IOpenApiAny>, IOpenApiAny, ICloneable
public class OpenApiArray : List<IOpenApiAny>, IOpenApiAny
{
/// <summary>
/// The type of <see cref="IOpenApiAny"/>
/// </summary>
public AnyType AnyType { get; } = AnyType.Array;

/// <summary>
/// Implement ICloneable interface to allow for deep copying
/// </summary>
/// <returns>A new copy of <see cref="OpenApiArray"/></returns>
public object Clone()
{
return new OpenApiArray();
}

/// <summary>
/// Write out contents of OpenApiArray to passed writer
/// </summary>
Expand Down
10 changes: 0 additions & 10 deletions src/Microsoft.OpenApi/Any/OpenApiNull.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ public class OpenApiNull : IOpenApiAny
/// </summary>
public AnyType AnyType { get; } = AnyType.Null;


/// <summary>
/// Implement ICloneable interface to allow for deep copying
/// </summary>
/// <returns>A new copy of <see cref="OpenApiNull"/></returns>
public object Clone()
{
return new OpenApiNull();
}

/// <summary>
/// Write out null representation
/// </summary>
Expand Down
9 changes: 0 additions & 9 deletions src/Microsoft.OpenApi/Any/OpenApiObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ public class OpenApiObject : Dictionary<string, IOpenApiAny>, IOpenApiAny
/// </summary>
public AnyType AnyType { get; } = AnyType.Object;

/// <summary>
/// Implement ICloneable interface to allow for deep copying
/// </summary>
/// <returns>A new copy of <see cref="OpenApiObject"/></returns>
public object Clone()
{
return new OpenApiObject();
}

/// <summary>
/// Serialize OpenApiObject to writer
/// </summary>
Expand Down
35 changes: 0 additions & 35 deletions src/Microsoft.OpenApi/Any/OpenApiPrimitive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public OpenApiPrimitive(OpenApiPrimitive<T> openApiPrimitive)
/// </summary>
public AnyType AnyType { get; } = AnyType.Primitive;


/// <summary>
/// The primitive class this object represents.
/// </summary>
Expand All @@ -50,40 +49,6 @@ public OpenApiPrimitive(OpenApiPrimitive<T> openApiPrimitive)
/// </summary>
public T Value { get; }

/// <summary>
/// Implement ICloneable interface to allow for deep copying
/// </summary>
/// <returns>A new copy of <see cref="IOpenApiPrimitive"/></returns>
public object Clone()
{
var clone = CloneFromCopyConstructor(this);
if (clone == null) throw new ApplicationException("There's no copy constructor defined");
return clone;
}

/// <summary>
/// Clones an instance of <see cref="IOpenApiPrimitive"/> object from the copy constructor
/// </summary>
/// <param name="obj">The object instance.</param>
/// <returns>A clone copy.</returns>
public static object CloneFromCopyConstructor(Object obj)
{
if (obj != null)
{
Type t = obj.GetType();
foreach (ConstructorInfo ci in t.GetConstructors())
{
ParameterInfo[] pi = ci.GetParameters();
if (pi.Length == 1 && pi[0].ParameterType == t)
{
return ci.Invoke(new object[] { obj });
}
}
}

return null;
}

/// <summary>
/// Write out content of primitive element
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public OpenApiExample(OpenApiExample example)
{
Summary = example.Summary;
Description = example.Description;
Value = (IOpenApiAny)example.Value.Clone();
Value = CloneHelper.CloneFromCopyConstructor(example.Value);
ExternalValue = example.ExternalValue;
Extensions = new Dictionary<string, IOpenApiExtension>(example.Extensions);
Reference = new(example.Reference);
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public OpenApiHeader(OpenApiHeader header)
Explode = header.Explode;
AllowReserved = header.AllowReserved;
Schema = new(header.Schema);
Example = (IOpenApiAny)header.Example.Clone();
Example = CloneHelper.CloneFromCopyConstructor(header.Example);
Examples = new Dictionary<string, OpenApiExample>(header.Examples);
Content = new Dictionary<string, OpenApiMediaType>(header.Content);
Extensions = new Dictionary<string, IOpenApiExtension>(header.Extensions);
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public OpenApiMediaType() {}
public OpenApiMediaType(OpenApiMediaType mediaType)
{
Schema = new(mediaType.Schema);
Example = (IOpenApiAny)mediaType.Example.Clone();
Example = CloneHelper.CloneFromCopyConstructor(mediaType.Example);
Examples = new Dictionary<string, OpenApiExample>(mediaType.Examples);
Encoding = new Dictionary<string, OpenApiEncoding>(mediaType.Encoding);
Extensions = new Dictionary<string, IOpenApiExtension>(mediaType.Extensions);
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public OpenApiParameter(OpenApiParameter parameter)
AllowReserved = parameter.AllowReserved;
Schema = new(parameter.Schema);
Examples = new Dictionary<string, OpenApiExample>(parameter.Examples);
Example = (IOpenApiAny)parameter.Example.Clone();
Example = CloneHelper.CloneFromCopyConstructor(parameter.Example);
Content = new Dictionary<string, OpenApiMediaType>(parameter.Content);
Extensions = new Dictionary<string, IOpenApiExtension>(parameter.Extensions);
AllowEmptyValue = parameter.AllowEmptyValue;
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public OpenApiSchema(OpenApiSchema schema)
MinLength = schema.MinLength;
Pattern = schema.Pattern;
MultipleOf = schema.MultipleOf;
Default = (IOpenApiAny)schema.Default.Clone();
Default = CloneHelper.CloneFromCopyConstructor(schema.Default);
ReadOnly = schema.ReadOnly;
WriteOnly = schema.WriteOnly;
AllOf = new List<OpenApiSchema>(schema.AllOf);
Expand All @@ -282,7 +282,7 @@ public OpenApiSchema(OpenApiSchema schema)
AdditionalPropertiesAllowed = schema.AdditionalPropertiesAllowed;
AdditionalProperties = new(schema.AdditionalProperties);
Discriminator = new(schema.Discriminator);
Example = (IOpenApiAny)schema.Example.Clone();
Example = CloneHelper.CloneFromCopyConstructor(schema.Example);
Enum = new List<IOpenApiAny>(schema.Enum);
Nullable = schema.Nullable;
ExternalDocs = new(schema.ExternalDocs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public RuntimeExpressionAnyWrapper() {}
/// </summary>
public RuntimeExpressionAnyWrapper(RuntimeExpressionAnyWrapper runtimeExpressionAnyWrapper)
{
Any = (IOpenApiAny)runtimeExpressionAnyWrapper.Any.Clone();
Any = CloneHelper.CloneFromCopyConstructor(runtimeExpressionAnyWrapper.Any);
Expression = runtimeExpressionAnyWrapper.Expression;
}

Expand Down
22 changes: 11 additions & 11 deletions test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,23 @@ namespace Microsoft.OpenApi.Any
Array = 2,
Object = 3,
}
public interface IOpenApiAny : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public class CloneHelper
{
public CloneHelper() { }
public static Microsoft.OpenApi.Any.IOpenApiAny CloneFromCopyConstructor(Microsoft.OpenApi.Any.IOpenApiAny obj) { }
}
public interface IOpenApiAny : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
Microsoft.OpenApi.Any.AnyType AnyType { get; }
}
public interface IOpenApiPrimitive : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public interface IOpenApiPrimitive : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
Microsoft.OpenApi.Any.PrimitiveType PrimitiveType { get; }
}
public class OpenApiArray : System.Collections.Generic.List<Microsoft.OpenApi.Any.IOpenApiAny>, Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public class OpenApiArray : System.Collections.Generic.List<Microsoft.OpenApi.Any.IOpenApiAny>, Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
public OpenApiArray() { }
public Microsoft.OpenApi.Any.AnyType AnyType { get; }
public object Clone() { }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
}
public class OpenApiBinary : Microsoft.OpenApi.Any.OpenApiPrimitive<byte[]>
Expand Down Expand Up @@ -72,35 +76,31 @@ namespace Microsoft.OpenApi.Any
public OpenApiLong(long value) { }
public override Microsoft.OpenApi.Any.PrimitiveType PrimitiveType { get; }
}
public class OpenApiNull : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public class OpenApiNull : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
public OpenApiNull() { }
public Microsoft.OpenApi.Any.AnyType AnyType { get; }
public object Clone() { }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
}
public class OpenApiObject : System.Collections.Generic.Dictionary<string, Microsoft.OpenApi.Any.IOpenApiAny>, Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public class OpenApiObject : System.Collections.Generic.Dictionary<string, Microsoft.OpenApi.Any.IOpenApiAny>, Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
public OpenApiObject() { }
public Microsoft.OpenApi.Any.AnyType AnyType { get; }
public object Clone() { }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
}
public class OpenApiPassword : Microsoft.OpenApi.Any.OpenApiPrimitive<string>
{
public OpenApiPassword(string value) { }
public override Microsoft.OpenApi.Any.PrimitiveType PrimitiveType { get; }
}
public abstract class OpenApiPrimitive<T> : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Any.IOpenApiPrimitive, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension, System.ICloneable
public abstract class OpenApiPrimitive<T> : Microsoft.OpenApi.Any.IOpenApiAny, Microsoft.OpenApi.Any.IOpenApiPrimitive, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtension
{
public OpenApiPrimitive(Microsoft.OpenApi.Any.OpenApiPrimitive<T> openApiPrimitive) { }
public OpenApiPrimitive(T value) { }
public Microsoft.OpenApi.Any.AnyType AnyType { get; }
public abstract Microsoft.OpenApi.Any.PrimitiveType PrimitiveType { get; }
public T Value { get; }
public object Clone() { }
public void Write(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { }
public static object CloneFromCopyConstructor(object obj) { }
}
public class OpenApiString : Microsoft.OpenApi.Any.OpenApiPrimitive<string>
{
Expand Down