package org.playorm.util.api.serviceproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CustomServiceProxy implements InvocationHandler {
private static final Logger log = Logger.getLogger(CustomServiceProxy.class.getName());
protected Object service;
private boolean isInjected;
private boolean hasStartStop;
private static String startMethodName = "start";
private static String stopMethodName = "stop";
public CustomServiceProxy(Object service) {
this.hasStartStop = getClass().equals(CustomServiceProxy.class);
isInjected = false;
this.service = service;
}
public void setService(Object service) {
if (service == null)
throw new IllegalArgumentException(
"use unsetService instead, can't pass in null");
isInjected = true;
this.service = service;
}
// the default service must be passed into us...
public void unsetService(Object service) {
if (service == null)
throw new IllegalArgumentException(
"cannot pass in null, service must"
+ " be the default(not injected svc)");
isInjected = false;
this.service = service;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
if (method.getName().equalsIgnoreCase("setService")) {
this.setService(args[0]);
return null;
} else if (method.getName().equalsIgnoreCase("unsetService")) {
this.unsetService(args[0]);
return null;
}
if (service == null && hasStartStop)
throw new RuntimeException("need set real service first");
if (method.getName().equalsIgnoreCase(startMethodName)
|| method.getName().equalsIgnoreCase(stopMethodName))
{
return callStartOrStop(proxy, method, args);
}
else
return method.invoke(service, args);
} catch (Exception e) {
throw new RuntimeException("error ", e);
}
}
private Object callStartOrStop(Object proxy, Method method, Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if(isInjected)
return null;
//only invoke something if not dependency injected.
//if something was dependency injected, the client
//is responsible for it's lifecycle
if(method.getName().equalsIgnoreCase(startMethodName)) {
if(hasStartStop)
return method.invoke(service, args);
else {
start();
return null;
}
}
//for stops, make sure we protect from exceptions...
try {
if(hasStartStop)
return method.invoke(service, args);
else
stop();
} catch(Throwable e) {
log.log(Level.WARNING, "Exception in stop", e);
return null;
}
return null;
}
public void start() {
}
public void stop() {
}
}