This commit is contained in:
Jack Kanarish
2018-05-02 15:38:00 -04:00
9 changed files with 275 additions and 6 deletions

View File

@@ -3,3 +3,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [3.0.0] - 2018-04-23
### Added
- Adding extension method for getting Informational Version from an Assembly
- Adding WeakKeyDictionary for caching
- Reflection util methods
### Changed
- JSON serialization/deserialization features moved into base converter
- Removed suffix from assembly name

View File

@@ -84,6 +84,14 @@ namespace ICD.Common.Utils
{
foreach (Exception inner in e.LoaderExceptions)
{
if (inner is System.IO.FileNotFoundException)
{
Logger.AddEntry(eSeverity.Error,
"{0} failed to cache assembly {1} - Could not find one or more dependencies by path",
typeof(AttributeUtils).Name, assembly.GetName().Name);
continue;
}
Logger.AddEntry(eSeverity.Error, inner, "{0} failed to cache assembly {1}", typeof(AttributeUtils).Name,
assembly.GetName().Name);
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using ICD.Common.Properties;
using ICD.Common.Utils.IO;
#if SIMPLSHARP
@@ -12,7 +13,7 @@ namespace ICD.Common.Utils.Extensions
public static class AssemblyExtensions
{
/// <summary>
/// Gets the path for the given assembly. Returns null if the assembly can not be found on disk.
/// Gets the path for the assembly. Returns null if the assembly can not be found on disk.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
@@ -45,10 +46,11 @@ namespace ICD.Common.Utils.Extensions
}
/// <summary>
/// Gets the creation date of the given assembly.
/// Gets the creation date of the assembly.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
[PublicAPI]
public static DateTime GetCreationTime(this Assembly extends)
{
if (extends == null)
@@ -57,5 +59,40 @@ namespace ICD.Common.Utils.Extensions
string path = extends.GetPath();
return path == null ? DateTime.MinValue : IcdFile.GetCreationTime(path);
}
/// <summary>
/// Gets the informational version for the assembly.
/// </summary>
/// <param name="extends"></param>
/// <returns></returns>
[PublicAPI]
public static string GetInformationalVersion(this Assembly extends)
{
if (extends == null)
throw new ArgumentNullException("extends");
string version;
if (extends.TryGetInformationalVersion(out version))
return version;
throw new InvalidOperationException("Assembly has no informational version attribute.");
}
/// <summary>
/// Tries to get the informational version for the assembly.
/// </summary>
/// <param name="extends"></param>
/// <param name="version"></param>
/// <returns></returns>
[PublicAPI]
public static bool TryGetInformationalVersion(this Assembly extends, out string version)
{
if (extends == null)
throw new ArgumentNullException("extends");
return extends.GetCustomAttributes<AssemblyInformationalVersionAttribute>()
.Select(a => a.InformationalVersion)
.TryFirst(out version);
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using ICD.Common.Properties;
using ICD.Common.Utils.Comparers;
namespace ICD.Common.Utils.Extensions
{
@@ -29,7 +30,7 @@ namespace ICD.Common.Utils.Extensions
}
/// <summary>
/// Adds the item into a sorted list.
/// Adds the items into a sorted list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="extends"></param>
@@ -50,6 +51,30 @@ namespace ICD.Common.Utils.Extensions
items.ForEach(i => extends.AddSorted(i, comparer));
}
/// <summary>
/// Adds the items into a sorted list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp"></typeparam>
/// <param name="extends"></param>
/// <param name="items"></param>
/// <param name="predicate"></param>
[PublicAPI]
public static void AddSorted<T, TProp>(this List<T> extends, IEnumerable<T> items, Func<T, TProp> predicate)
{
if (extends == null)
throw new ArgumentNullException("extends");
if (items == null)
throw new ArgumentNullException("items");
if (predicate == null)
throw new ArgumentNullException("predicate");
PredicateComparer<T, TProp> comparer = new PredicateComparer<T, TProp>(predicate);
extends.AddSorted(items, comparer);
}
/// <summary>
/// Adds the item into a sorted list.
/// </summary>
@@ -106,6 +131,27 @@ namespace ICD.Common.Utils.Extensions
extends.Insert(index, item);
}
/// <summary>
/// Adds the item into a sorted list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TProp"></typeparam>
/// <param name="extends"></param>
/// <param name="item"></param>
/// <param name="predicate"></param>
[PublicAPI]
public static void AddSorted<T, TProp>(this List<T> extends, T item, Func<T, TProp> predicate)
{
if (extends == null)
throw new ArgumentNullException("extends");
if (predicate == null)
throw new ArgumentNullException("predicate");
PredicateComparer<T, TProp> comparer = new PredicateComparer<T, TProp>(predicate);
extends.AddSorted(item, comparer);
}
/// <summary>
/// Pads the list to the given total length.
/// </summary>

View File

@@ -10,6 +10,10 @@ namespace ICD.Common.Utils.IO
{
public static class IcdPath
{
public static char DirectorySeparatorChar { get { return Path.DirectorySeparatorChar; } }
public static char AltDirectorySeparatorChar { get { return Path.AltDirectorySeparatorChar; } }
public static string GetFileName(string path)
{
if (path == null)

View File

@@ -6,6 +6,15 @@ namespace ICD.Common.Utils.Json
{
public abstract class AbstractGenericJsonConverter<T> : JsonConverter
{
/// <summary>
/// Creates a new instance of T.
/// </summary>
/// <returns></returns>
protected virtual T Instantiate()
{
return ReflectionUtils.CreateInstance<T>();
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
@@ -36,7 +45,24 @@ namespace ICD.Common.Utils.Json
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
[PublicAPI]
public abstract void WriteJson(JsonWriter writer, T value, JsonSerializer serializer);
public virtual void WriteJson(JsonWriter writer, T value, JsonSerializer serializer)
{
writer.WriteStartObject();
{
WriteProperties(writer, value, serializer);
}
writer.WriteEndObject();
}
/// <summary>
/// Override to write properties to the writer.
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="serializer"></param>
protected virtual void WriteProperties(JsonWriter writer, T value, JsonSerializer serializer)
{
}
/// <summary>
/// Reads the JSON representation of the object.
@@ -70,7 +96,52 @@ namespace ICD.Common.Utils.Json
/// The object value.
/// </returns>
[PublicAPI]
public abstract T ReadJson(JsonReader reader, T existingValue, JsonSerializer serializer);
public virtual T ReadJson(JsonReader reader, T existingValue, JsonSerializer serializer)
{
T output = default(T);
bool instantiated = false;
while (reader.Read())
{
if (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.EndObject)
break;
if (!instantiated)
{
instantiated = true;
output = Instantiate();
}
// Get the property
if (reader.TokenType != JsonToken.PropertyName)
continue;
string property = (string)reader.Value;
// Read into the value
reader.Read();
switch (property)
{
default:
ReadProperty(property, reader, output, serializer);
break;
}
}
return output;
}
/// <summary>
/// Override to handle the current property value with the given name.
/// </summary>
/// <param name="property"></param>
/// <param name="reader"></param>
/// <param name="instance"></param>
/// <param name="serializer"></param>
protected virtual void ReadProperty(string property, JsonReader reader, T instance, JsonSerializer serializer)
{
reader.Skip();
}
/// <summary>
/// Determines whether this instance can convert the specified object type.

View File

@@ -185,6 +185,24 @@ namespace ICD.Common.Utils
return IcdFile.Exists(path) || IcdDirectory.Exists(path);
}
/// <summary>
/// Returns the path if the given path is already a directory or has a trailing slash.
/// Otherwise returns the parent directory name.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
[PublicAPI]
public static string GetDirectoryNameFromPath(string path)
{
if (IcdDirectory.Exists(path))
return path;
if (path.EndsWith(IcdPath.DirectorySeparatorChar) || path.EndsWith(IcdPath.AltDirectorySeparatorChar))
return path;
return IcdPath.GetDirectoryName(path);
}
#endregion
}
}

View File

@@ -4,4 +4,4 @@ using System.Reflection;
[assembly: AssemblyCompany("ICD Systems")]
[assembly: AssemblyProduct("ICD.Common.Utils")]
[assembly: AssemblyCopyright("Copyright © ICD Systems 2018")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyVersion("3.0.0.0")]

View File

@@ -610,5 +610,77 @@ namespace ICD.Common.Utils
{
return value == null ? null : value.ToUpper();
}
/// <summary>
/// Compares the given chars for equality.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="ignoreCase"></param>
/// <returns></returns>
[PublicAPI]
public static bool Compare(char a, char b, bool ignoreCase)
{
if (ignoreCase)
{
a = char.ToUpper(a, CultureInfo.InvariantCulture);
b = char.ToUpper(b, CultureInfo.InvariantCulture);
}
return a == b;
}
/// <summary>
/// Find the longest common string between the matches.
/// E.g.
///
/// C:\\Workspace
/// C:\\Workshop
///
/// Results in
///
/// C:\\Work
/// </summary>
/// <param name="items"></param>
/// <param name="ignoreCase"></param>
/// <returns></returns>
[PublicAPI]
public static string GetLongestCommonIntersectionFromStart(IEnumerable<string> items, bool ignoreCase)
{
if (items == null)
throw new ArgumentNullException("items");
string output = null;
foreach (string item in items)
{
// If there is a null in the sequence that's the best match we can make
if (string.IsNullOrEmpty(item))
return null;
// Seed our first item
if (output == null)
{
output = item;
continue;
}
// Find the common substring
for (int index = 0; index < output.Length; index++)
{
if (index >= item.Length || !Compare(output[index], item[index], ignoreCase))
{
output = output.Substring(0, index);
break;
}
}
// Abandon the search if there is no common substring
if (string.IsNullOrEmpty(output))
break;
}
return output;
}
}
}