113 lines
3.7 KiB
C#
113 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using appsrv.server;
|
|
using System.Reflection;
|
|
using appsrv.exceptions;
|
|
using appsrv.attributes;
|
|
using System.Runtime.Remoting.Metadata.W3cXsd2001;
|
|
namespace appsrv.resources.reflection
|
|
{
|
|
public class ReflectiveResourceCrawler
|
|
{
|
|
/* Instance Members */
|
|
public ReflectiveResource Resource { get; }
|
|
public Type NativeType { get; }
|
|
|
|
public ReflectiveResourceCrawler(ReflectiveResource resource,Type type)
|
|
{
|
|
Resource = resource;
|
|
NativeType = type;
|
|
}
|
|
|
|
public object Crawl(object instance,Request request,Stack<String> pathStack)
|
|
{
|
|
if (pathStack.Count == 0)
|
|
return instance;
|
|
|
|
String next = pathStack.Pop();
|
|
|
|
foreach (FieldInfo fieldInfo in NativeType.GetFields())
|
|
{
|
|
if (fieldInfo.GetCustomAttribute<PublishedMemberAttribute>()!=null)
|
|
{
|
|
if (fieldInfo.Name.Equals(next))
|
|
{
|
|
return FixupIntermediate(fieldInfo.GetValue(instance), request, pathStack);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (PropertyInfo propertyInfo in NativeType.GetProperties())
|
|
{
|
|
if (propertyInfo.GetCustomAttribute<PublishedMemberAttribute>() != null)
|
|
{
|
|
if (propertyInfo.Name.Equals(next))
|
|
{
|
|
return FixupIntermediate(propertyInfo.GetValue(instance), request, pathStack);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (MethodInfo methodInfo in NativeType.GetMethods())
|
|
{
|
|
if (methodInfo.GetCustomAttribute<PublishedMemberAttribute>() != null)
|
|
{
|
|
if (methodInfo.Name.Equals(next))
|
|
{
|
|
object[] parameters = PopParameters(methodInfo,pathStack,request);
|
|
object i = methodInfo.IsStatic ? null : instance;
|
|
return FixupIntermediate( methodInfo.Invoke(i,parameters), request, pathStack);
|
|
}
|
|
}
|
|
}
|
|
|
|
throw new KeyNotFoundException(next);
|
|
}
|
|
|
|
private object[] PopParameters(MethodInfo methodInfo,Stack<String> pathStack,Request request)
|
|
{
|
|
ParameterInfo[] parameterInfos = methodInfo.GetParameters();
|
|
object[] p = new object[parameterInfos.Length];
|
|
|
|
for (int n = 0; n < parameterInfos.Length;n++)
|
|
{
|
|
string nextparm = null;
|
|
|
|
if (request.HasParameter(parameterInfos[n].Name))
|
|
{
|
|
nextparm = request.GetParameterValue(parameterInfos[n].Name);
|
|
} else
|
|
{
|
|
if (pathStack.Count > 0)
|
|
{
|
|
nextparm = pathStack.Pop();
|
|
}
|
|
}
|
|
|
|
p[n] = Convert.ChangeType(nextparm, parameterInfos[n].ParameterType);
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
private object FixupIntermediate(object intermediate,Request request, Stack<String> pathStack)
|
|
{
|
|
if (intermediate.GetType().IsArray)
|
|
return FixupIntermediateArray((Array)intermediate, request, pathStack);
|
|
|
|
return intermediate;
|
|
}
|
|
|
|
private object FixupIntermediateArray(Array intermediate, Request request, Stack<String> pathStack)
|
|
{
|
|
if (pathStack.Count == 0)
|
|
return intermediate;
|
|
|
|
int index = int.Parse(pathStack.Pop());
|
|
return intermediate.GetValue(index);
|
|
}
|
|
|
|
|
|
}
|
|
}
|