You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Globalization;
|
||||
|
||||
//using System.Workflow.Activities;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
using Hosting = System.Workflow.Runtime.Hosting;
|
||||
|
||||
namespace System.Workflow.Runtime.Tracking
|
||||
{
|
||||
|
||||
internal sealed class PropertyHelper
|
||||
{
|
||||
private PropertyHelper() { }
|
||||
|
||||
#region Internal Static Methods
|
||||
|
||||
internal static void GetProperty(string name, Activity activity, TrackingAnnotationCollection annotations, out TrackingDataItem item)
|
||||
{
|
||||
item = null;
|
||||
object tmp = PropertyHelper.GetProperty(name, activity);
|
||||
|
||||
item = new TrackingDataItem();
|
||||
item.FieldName = name;
|
||||
item.Data = tmp;
|
||||
foreach (string s in annotations)
|
||||
item.Annotations.Add(s);
|
||||
}
|
||||
|
||||
internal static object GetProperty(string name, object obj)
|
||||
{
|
||||
if (null == name)
|
||||
throw new ArgumentNullException("name");
|
||||
|
||||
if (null == obj)
|
||||
throw new ArgumentNullException("obj");
|
||||
//
|
||||
// Split the names
|
||||
string[] names = name.Split(new char[] { '.' });
|
||||
|
||||
object currObj = obj;
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if ((null == names[i]) || (0 == names[i].Length))
|
||||
throw new InvalidOperationException(ExecutionStringManager.TrackingProfileInvalidMember);
|
||||
|
||||
object tmp = null;
|
||||
PropertyHelper.GetPropertyOrField(names[i], currObj, out tmp);
|
||||
//
|
||||
// Attempt to resolve runtime values (ParameterBinding, ParameterDeclaration and Bind)
|
||||
if (currObj is Activity)
|
||||
currObj = GetRuntimeValue(tmp, (Activity)currObj);
|
||||
else
|
||||
currObj = tmp;
|
||||
}
|
||||
|
||||
return currObj;
|
||||
}
|
||||
|
||||
internal static void GetPropertyOrField(string name, object o, out object obj)
|
||||
{
|
||||
obj = null;
|
||||
|
||||
if (null == name)
|
||||
throw new ArgumentNullException("name");
|
||||
|
||||
if (null == o)
|
||||
throw new ArgumentNullException("o");
|
||||
|
||||
Type t = o.GetType();
|
||||
|
||||
string tmp = null, realName = null;
|
||||
bool isCollection = false;
|
||||
int index = -1;
|
||||
|
||||
if (TryParseIndex(name, out tmp, out index))
|
||||
isCollection = true;
|
||||
else
|
||||
tmp = name;
|
||||
|
||||
object val = null;
|
||||
if ((null != tmp) && (tmp.Length > 0))
|
||||
{
|
||||
if (!NameIsDefined(tmp, o, out realName))
|
||||
throw new MissingMemberException(o.GetType().Name, tmp);
|
||||
//
|
||||
// Attempt to match default, no parameter (if overloaded)
|
||||
// Indexer accesses will fail - we do not handle indexers
|
||||
// Do case sensitive here because we have the real name of the matching member
|
||||
val = t.InvokeMember(realName,
|
||||
BindingFlags.Public |
|
||||
BindingFlags.NonPublic |
|
||||
BindingFlags.GetProperty |
|
||||
BindingFlags.GetField |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static,
|
||||
null,
|
||||
o,
|
||||
null,
|
||||
System.Globalization.CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
val = o; // root object is a collection - all that is passed for name is "[1]"
|
||||
|
||||
if (isCollection)
|
||||
{
|
||||
IEnumerable collection = val as IEnumerable;
|
||||
if (null != collection)
|
||||
GetEnumerationMember(collection, index, out obj);
|
||||
}
|
||||
else
|
||||
obj = val;
|
||||
}
|
||||
|
||||
internal static void GetEnumerationMember(IEnumerable collection, int index, out object obj)
|
||||
{
|
||||
obj = null;
|
||||
|
||||
if (null == collection)
|
||||
throw new ArgumentNullException("collection");
|
||||
|
||||
IEnumerator e = collection.GetEnumerator();
|
||||
int i = 0;
|
||||
while (e.MoveNext())
|
||||
{
|
||||
if (i++ == index)
|
||||
{
|
||||
obj = e.Current;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
internal static object GetRuntimeValue(object o, Activity activity)
|
||||
{
|
||||
if (null == o)
|
||||
return o;
|
||||
|
||||
object tmp = o;
|
||||
if (o is ActivityBind)
|
||||
{
|
||||
if (null == activity)
|
||||
throw new ArgumentNullException("activity");
|
||||
|
||||
tmp = ((ActivityBind)o).GetRuntimeValue(activity);
|
||||
}
|
||||
else if (o is WorkflowParameterBinding)
|
||||
{
|
||||
tmp = ((WorkflowParameterBinding)o).Value;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
internal static void GetAllMembers(Activity activity, IList<TrackingDataItem> items, TrackingAnnotationCollection annotations)
|
||||
{
|
||||
Type t = activity.GetType();
|
||||
//
|
||||
// Get all fields
|
||||
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
|
||||
BindingFlags.NonPublic |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static |
|
||||
BindingFlags.GetField);
|
||||
|
||||
foreach (FieldInfo f in fields)
|
||||
{
|
||||
if (!PropertyHelper.IsInternalVariable(f.Name))
|
||||
{
|
||||
TrackingDataItem data = new TrackingDataItem();
|
||||
data.FieldName = f.Name;
|
||||
data.Data = GetRuntimeValue(f.GetValue(activity), activity);
|
||||
foreach (string s in annotations)
|
||||
data.Annotations.Add(s);
|
||||
items.Add(data);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Get all properties (except indexers)
|
||||
PropertyInfo[] properties = t.GetProperties(BindingFlags.Public |
|
||||
BindingFlags.NonPublic |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static |
|
||||
BindingFlags.GetProperty);
|
||||
|
||||
foreach (PropertyInfo p in properties)
|
||||
{
|
||||
if (!IsInternalVariable(p.Name))
|
||||
{
|
||||
//
|
||||
// Skip indexers, since private data members
|
||||
// are exposed the data is still available.
|
||||
if (p.GetIndexParameters().Length > 0)
|
||||
continue;
|
||||
|
||||
TrackingDataItem data = new TrackingDataItem();
|
||||
data.FieldName = p.Name;
|
||||
data.Data = GetRuntimeValue(p.GetValue(activity, null), activity);
|
||||
foreach (string s in annotations)
|
||||
data.Annotations.Add(s);
|
||||
items.Add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private static bool IsInternalVariable(string name)
|
||||
{
|
||||
string[] vars = { "__winoe_ActivityLocks_", "__winoe_StaticActivityLocks_", "__winoe_MethodLocks_" };
|
||||
|
||||
foreach (string s in vars)
|
||||
{
|
||||
if (0 == string.Compare(s, name, StringComparison.Ordinal))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool NameIsDefined(string name, object o, out string realName)
|
||||
{
|
||||
realName = null;
|
||||
Type t = o.GetType();
|
||||
//
|
||||
// Get the member with the requested name
|
||||
// Do case specific first
|
||||
MemberInfo[] members = t.GetMember(name,
|
||||
BindingFlags.Public |
|
||||
BindingFlags.NonPublic |
|
||||
BindingFlags.GetProperty |
|
||||
BindingFlags.GetField |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static);
|
||||
|
||||
//
|
||||
// Not found
|
||||
if ((null == members) || (0 == members.Length))
|
||||
{
|
||||
//
|
||||
// Do case insensitive
|
||||
members = t.GetMember(name,
|
||||
BindingFlags.Public |
|
||||
BindingFlags.NonPublic |
|
||||
BindingFlags.GetProperty |
|
||||
BindingFlags.GetField |
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Static |
|
||||
BindingFlags.IgnoreCase);
|
||||
//
|
||||
// Not found
|
||||
if ((null == members) || (0 == members.Length))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((null == members) || (0 == members.Length) || (null == members[0].Name) || (0 == members[0].Name.Length))
|
||||
return false;
|
||||
|
||||
realName = members[0].Name;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryParseIndex(string fullName, out string name, out int index)
|
||||
{
|
||||
name = null;
|
||||
index = -1;
|
||||
|
||||
int endPos = -1, startPos = -1;
|
||||
for (int i = fullName.Length - 1; i > 0; i--)
|
||||
{
|
||||
if ((']' == fullName[i]) && (-1 == endPos))
|
||||
{
|
||||
endPos = i;
|
||||
}
|
||||
else if (('[' == fullName[i]) && (-1 == startPos))
|
||||
{
|
||||
startPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((-1 == endPos) || (-1 == startPos))
|
||||
return false;
|
||||
|
||||
string idx = fullName.Substring(startPos + 1, endPos - 1 - startPos);
|
||||
name = fullName.Substring(0, startPos);
|
||||
|
||||
return int.TryParse(idx, out index);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user