/*
This file is part of leafdigital leafChat.
leafChat is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
leafChat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with leafChat. If not, see <http://www.gnu.org/licenses/>.
Copyright 2011 Samuel Marshall.
*/
package com.leafdigital.ui;
import java.lang.reflect.*;
import java.util.*;
import com.leafdigital.ui.api.CallbackHandler;
import leafchat.core.api.*;
/** Implements UI callbacks */
public class CallbackHandlerImp implements CallbackHandler
{
/** Object that callbacks will happen on (null if none) */
private Object owner;
/** Map of String -> Method */
private Map<String, Method> mChecked = new HashMap<String, Method>();
Object getCallbackObject()
{
return owner;
}
/**
* @param owner Object that callbacks will happen on (null if none)
*/
public CallbackHandlerImp(Object owner)
{
this.owner=owner;
}
@Override
public synchronized void check(String method)
{
check(method, new Class<?>[0]);
}
@Override
public synchronized void check(String method, Class<?>... params)
{
if(method==null) return;
String prefix="Checking callback "+method+"(";
if(params!=null && params.length>0)
{
for(int i=0;i<params.length;i++)
{
if(i>0) prefix+=",";
prefix+=params[i].getName();
}
}
prefix+=") in "+owner+": ";
if(owner==null)
throw new BugException(prefix+"no callback object specified");
try
{
Method m=owner.getClass().getMethod(method,params);
if(!Modifier.isPublic(m.getModifiers()))
throw new BugException(prefix+"method must be public");
if(Modifier.isAbstract(m.getModifiers()))
throw new BugException(prefix+"method must not be abstract");
if(m.getReturnType()!=void.class)
throw new BugException(prefix+"method must return void");
mChecked.put(method,m);
}
catch(NoSuchMethodException e)
{
throw new BugException(prefix+"method not found ");
}
}
@Override
public synchronized void call(String method, Object... params)
{
Method m=mChecked.get(method);
String prefix="Calling "+method+" in "+owner+": ";
if(m==null) throw new BugException(prefix+"method not checked");
try
{
m.invoke(owner, params);
}
catch(IllegalArgumentException e)
{
throw new BugException(prefix+"Unexpected error",e);
}
catch(IllegalAccessException e)
{
throw new BugException(prefix+"Unexpected error",e);
}
catch(InvocationTargetException e)
{
throw new BugException(prefix+" Method caused exception",e.getCause());
}
}
@Override
public void call(String method)
{
call(method, new Object[0]);
}
@Override
public boolean callHandleErrors(String method)
{
try
{
call(method);
return true;
}
catch(BugException be)
{
ErrorMsg.report(be.getMessage(),be.getCause());
return false;
}
}
@Override
public boolean callHandleErrors(String method, Object... params)
{
try
{
call(method,params);
return true;
}
catch(BugException be)
{
ErrorMsg.report(be.getMessage(),be.getCause());
return false;
}
}
}