Skip to content

Commit

Permalink
added interception registration
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianaisemberg committed Oct 27, 2011
1 parent 0ac51ee commit 740d38b
Showing 1 changed file with 87 additions and 32 deletions.
119 changes: 87 additions & 32 deletions CLAP/Parser.cs
Expand Up @@ -29,6 +29,8 @@ public sealed class Parser<T>
private Dictionary<string, Action<string>> m_registeredHelpHandlers;
private Action m_registeredEmptyHandler;
private Action<Exception> m_registeredErrorHandler;
private Action<PreVerbExecutionContext> m_registeredPreVerbExecutionInterceptor;
private Action<PostVerbExecutionContext> m_registeredPostVerbExecutionInterceptor;
private bool m_registeredErrorHandlerRethrow;

#endregion Fields
Expand Down Expand Up @@ -241,6 +243,27 @@ public void RegisterErrorHandler(Action<Exception> handler, bool rethrow)
m_registeredErrorHandlerRethrow = rethrow;
}


public void RegisterPreVerbExecutionInterceptor(Action<PreVerbExecutionContext> interceptor)
{
if (m_registeredPreVerbExecutionInterceptor != null)
{
throw new MoreThanOnePreVerbInterceptorException();
}

m_registeredPreVerbExecutionInterceptor = interceptor;
}

public void RegisterPostVerbExecutionInterceptor(Action<PostVerbExecutionContext> interceptor)
{
if (m_registeredPostVerbExecutionInterceptor != null)
{
throw new MoreThanOnePostVerbInterceptorException();
}

m_registeredPostVerbExecutionInterceptor = interceptor;
}

#endregion Public Methods

#region Private Methods
Expand Down Expand Up @@ -352,18 +375,7 @@ private void RunInternal(string[] args, object obj)
{
// pre-interception
//
var preVerbExecutionContext = new PreVerbExecutionContext(method, target, parameters);

var preInterceptionMethods = typeof(T).GetMethodsWith<PreVerbExecutionAttribute>();

if (preInterceptionMethods.Any())
{
Debug.Assert(preInterceptionMethods.Count() == 1);

var preInterceptionMethod = preInterceptionMethods.First();

preInterceptionMethod.Invoke(target, new[] { preVerbExecutionContext });
}
var preVerbExecutionContext = PreInterception(target, method, parameters);

Exception verbException = null;

Expand All @@ -390,26 +402,7 @@ private void RunInternal(string[] args, object obj)
{
try
{
// post-interception
//
var postInterceptionMethods = typeof(T).GetMethodsWith<PostVerbExecutionAttribute>();

if (postInterceptionMethods.Any())
{
Debug.Assert(postInterceptionMethods.Count() == 1);

var postInterceptionMethod = postInterceptionMethods.First();

var postVerbExecutionContext = new PostVerbExecutionContext(
method,
target,
parameters,
preVerbExecutionContext.Cancel,
verbException,
preVerbExecutionContext.UserContext);

postInterceptionMethod.Invoke(target, new[] { postVerbExecutionContext });
}
PostInterception(target, method, parameters, preVerbExecutionContext, verbException);
}
finally
{
Expand All @@ -426,6 +419,68 @@ private void RunInternal(string[] args, object obj)
}
}

private void PostInterception(
object target,
Method method,
ParameterAndValue[] parameters,
PreVerbExecutionContext preVerbExecutionContext,
Exception verbException)
{
var postVerbExecutionContext = new PostVerbExecutionContext(
method,
target,
parameters,
preVerbExecutionContext.Cancel,
verbException,
preVerbExecutionContext.UserContext);

if (m_registeredPostVerbExecutionInterceptor != null)
{
m_registeredPostVerbExecutionInterceptor(postVerbExecutionContext);
}
else
{
var postInterceptionMethods = typeof(T).GetMethodsWith<PostVerbExecutionAttribute>();

if (postInterceptionMethods.Any())
{
Debug.Assert(postInterceptionMethods.Count() == 1);

var postInterceptionMethod = postInterceptionMethods.First();

postInterceptionMethod.Invoke(target, new[] { postVerbExecutionContext });
}
}
}

private PreVerbExecutionContext PreInterception(
object target,
Method method,
ParameterAndValue[] parameters)
{
var preVerbExecutionContext = new PreVerbExecutionContext(method, target, parameters);

if (m_registeredPreVerbExecutionInterceptor != null)
{
m_registeredPreVerbExecutionInterceptor(preVerbExecutionContext);
}
else
{
var preInterceptionMethods = typeof(T).GetMethodsWith<PreVerbExecutionAttribute>();

if (preInterceptionMethods.Any())
{
Debug.Assert(preInterceptionMethods.Count() == 1);

var preInterceptionMethod = preInterceptionMethods.First();

preInterceptionMethod.Invoke(target, new[] { preVerbExecutionContext });
}
}

return preVerbExecutionContext;
}

private static void ValidateVerbInput(Method method, List<object> parameterValues)
{
var methodParameters = method.MethodInfo.GetParameters();
Expand Down

0 comments on commit 740d38b

Please sign in to comment.