17 using System.Collections.Generic;
24 namespace Deveel.Data.Routines {
27 : this(type, null, argTypes) {
31 : this(type,
String.Empty) {
35 : this(type, methodName, Type.EmptyTypes) {
39 : this(type.FullName, methodName, ToTypeNames(argTypes)) {
43 : this(typeString, methodName, new string[0]) {
47 this.TypeName = typeString;
48 this.MethodName = methodName;
49 this.Arguments = argNames;
52 public string TypeName {
get;
private set; }
54 public string MethodName {
get;
private set; }
56 public bool HasMethodName {
57 get {
return !
String.IsNullOrEmpty(MethodName); }
60 public string[] Arguments {
get;
private set; }
63 if (argTypes == null || argTypes.Length == 0)
66 var argNames =
new string[argTypes.Length];
67 for (var i = 0; i < argTypes.Length; i++) {
68 argNames[i] = argTypes[i].FullName;
81 typeString = typeString.Trim();
85 int lastIndex = typeString.Length;
86 while (lastIndex > 0) {
88 lastIndex = typeString.LastIndexOf(
"[]", lastIndex, StringComparison.InvariantCulture) - 1;
92 int arrayEnd = typeString.Length - (dimensions * 2);
93 String typePart = typeString.Substring(0, arrayEnd);
95 if (typePart.IndexOf(
"[]", StringComparison.InvariantCulture) != -1)
96 throw new Exception(
"Type specification incorrectly formatted: " + typeString);
102 if (typePart.IndexOf(
'.') != -1) {
105 cl = Type.GetType(typePart);
106 }
catch (TypeLoadException) {
107 throw new Exception(
"Type not found: " + typePart);
112 else if (typePart.Equals(
"boolean") ||
113 typePart.Equals(
"bool")) {
115 }
else if (typePart.Equals(
"byte")) {
117 }
else if (typePart.Equals(
"short")) {
119 }
else if (typePart.Equals(
"char")) {
121 }
else if (typePart.Equals(
"int")) {
123 }
else if (typePart.Equals(
"long")) {
125 }
else if (typePart.Equals(
"float")) {
127 }
else if (typePart.Equals(
"double")) {
132 if (typePart.Equals(
"IProcedureConnection")) {
133 cl = typeof(IProcedureConnection);
136 cl = Type.GetType(
"System." + typePart);
137 }
catch (TypeLoadException) {
139 throw new Exception(
"Type not found: " + typePart);
145 if (dimensions > 0) {
148 cl =
Array.CreateInstance(cl,
new int[dimensions]).GetType();
163 bool firstProcedureConnectionIgnore;
165 if (!HasMethodName) {
169 methodName =
"Invoke";
171 argTypes =
new Type[paramTypes.Length];
173 firstProcedureConnectionIgnore =
true;
178 methodName = MethodName;
179 argTypes =
new Type[Arguments.Length];
181 for (
int i = 0; i < Arguments.Length; ++i) {
182 String typeSpec = Arguments[i];
183 argTypes[i] = ResolveToType(typeSpec);
186 firstProcedureConnectionIgnore =
false;
189 Type routineType = Type.GetType(typeName,
false,
true);
190 if (routineType == null)
191 throw new Exception(
"Procedure class not found: " + typeName);
194 MethodInfo[] methods = routineType.GetMethods(BindingFlags.Public | BindingFlags.Static);
195 MethodInfo invokeMethod = null;
197 foreach (MethodInfo method
in methods) {
198 if (method.Name.Equals(methodName)) {
202 ParameterInfo[] methodArgs = method.GetParameters();
206 if (methodArgs.Length == 0 && argTypes.Length == 0) {
211 if (firstProcedureConnectionIgnore &&
212 typeof(IProcedureConnection).IsAssignableFrom(methodArgs[0].ParameterType)) {
217 if (argTypes.Length == methodArgs.Length - searchStart) {
219 bool matchSpec =
true;
220 for (
int n = 0; n < argTypes.Length && matchSpec; ++n) {
221 Type argType = argTypes[n];
222 if (argType != null &&
223 argType != methodArgs[n + searchStart].ParameterType) {
227 paramsMatch = matchSpec;
234 if (invokeMethod != null)
235 throw new Exception(
"Ambiguous public static " + methodName +
" methods in stored procedure class '" + typeName +
"'");
237 invokeMethod = method;
248 int parentheseDelim = s.IndexOf(
"(", StringComparison.InvariantCulture);
250 if (parentheseDelim != -1) {
252 string typeMethod = s.Substring(0, parentheseDelim);
254 int methodDelim = typeMethod.LastIndexOf(
".", StringComparison.InvariantCulture);
255 if (methodDelim == -1)
256 throw new FormatException(
"Incorrectly formatted method string: " + s);
258 string typeString = typeMethod.Substring(0, methodDelim);
259 string methodString = typeMethod.Substring(methodDelim + 1);
262 int endParentheseDelim = s.LastIndexOf(
")", StringComparison.InvariantCulture);
263 if (endParentheseDelim == -1)
264 throw new FormatException(
"Incorrectly formatted method string: " + s);
266 string argListStr = s.Substring(parentheseDelim + 1, endParentheseDelim - (parentheseDelim + 1));
269 string[] args = argListStr.Split(
new[]{
','}, StringSplitOptions.RemoveEmptyEntries);
279 return FormatString(type, Type.EmptyTypes);
283 return FormatString(type, null, argTypes);
287 return FormatString(type, methodName, Type.EmptyTypes);
290 public static string FormatString(Type type,
string methodName, Type[] argTypes) {
292 return routineInfo.ToString();
296 var sb =
new StringBuilder(TypeName);
299 sb.Append(MethodName);
303 if (Arguments != null && Arguments.Length > 0) {
304 for (
int i = 0; i < Arguments.Length; i++) {
305 sb.Append(Arguments[i]);
307 if (i < Arguments.Length - 1)
313 return sb.ToString();
ExternalRoutineInfo(Type type, Type[] argTypes)
static string FormatString(Type type, Type[] argTypes)
A long string in the system.
ExternalRoutineInfo(Type type, string methodName)
static string FormatString(Type type, string methodName)
MethodInfo ResolveMethod(TType[] paramTypes)
static ExternalRoutineInfo Parse(string s)
static string FormatString(Type type)
override string ToString()
ExternalRoutineInfo(Type type)
static string FormatString(Type type, string methodName, Type[] argTypes)
ExternalRoutineInfo(string typeString, string methodName, string[] argNames)
ExternalRoutineInfo(Type type, string methodName, Type[] argTypes)
static Type ResolveToType(string typeString)
Resolves a type specification string to a Type.
static string[] ToTypeNames(Type[] argTypes)
ExternalRoutineInfo(string typeString, string methodName)