/**
*
*/
package jframe.core.plugin.service;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jframe.core.plugin.Plugin;
import jframe.core.plugin.annotation.Start;
import jframe.core.plugin.loader.PluginClassLoader;
/**
* <p>
* Support annotations:
* <li>InjectPlugin</li>
* <li>Start</li>
* <li>Stop</li>
* </p>
*
* @author dzh
* @date Sep 16, 2014 6:39:45 AM
* @since 1.1
*/
public class Service {
static final Logger LOG = LoggerFactory.getLogger(Service.class);
String id;
/**
* service's interface class
*/
String name;
/**
* service's implement class
*/
String clazz;
/**
* service's singleton instance
*/
Object single;
/**
*
*/
PluginClassLoader classLoader;
public PluginClassLoader getClassLoader() {
return classLoader;
}
public Service setClassLoader(PluginClassLoader classLoader) {
this.classLoader = classLoader;
return this;
}
public String getId() {
return id;
}
public Service setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Service setName(String name) {
this.name = name;
return this;
}
public String getClazz() {
return clazz;
}
public Service setClazz(String clazz) {
this.clazz = clazz;
return this;
}
public Plugin getPlugin() {
return classLoader.getPlugin();
}
/**
*
* @return
* @throws ServiceException
*/
public synchronized Object getSingle() throws ServiceException {
if (single == null) {
single = createSingle();
}
return single;
}
private synchronized Object createSingle() throws ServiceException {
Object single = null;
try {
Class<?> clazz = getClassLoader().loadClass(getClazz());
Constructor<?> c = clazz.getDeclaredConstructor();
c.setAccessible(true);
single = c.newInstance();
// start
invokeServiceMethod(single, Start.class);
} catch (Exception e) {
throw new ServiceException(e.getCause());
}
return single;
}
/**
* Invoke service start/stop
*
* TODO optimize method searching
*
* @param svc
* @throws Exception
*/
public static void invokeServiceMethod(Object single, Class<? extends Annotation> anno) throws Exception {
Class<?> clazz = single.getClass();
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(anno)) {
m.setAccessible(true);
m.invoke(single);
break;
}
}
}
public static Service newInstance(jframe.core.plugin.annotation.Service anno) throws ServiceException {
if (anno == null) {
throw new ServiceException("Service Annotation is null");
}
Service svc = new Service();
svc.setId(anno.id());
svc.setClazz(anno.clazz());
return svc;
}
@Override
public String toString() {
return "{ id -> " + id + ", name -> " + name + "}";
}
}