package org.hive.container.lib;
import org.hive.container.lib.JarReader;
import org.hive.container.lib.LoggerFactory;
import org.hive.container.manifest.HiveMethod;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xeustechnologies.jcl.JarClassLoader;
import org.xeustechnologies.jcl.JclObjectFactory;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Application {
public static final int APPLICATION_INTERFACE_XML = 0;
public static final int APPLICATION_INTERFACE_HTML = 1;
private JarClassLoader jcl;
private String name;
private ArrayList<HiveMethod> applicationMethods;
private Object instance;
private String jarLocation;
public Application(String jarLocation) {
this.jarLocation = jarLocation;
jcl = new JarClassLoader();
jcl.add(jarLocation);
Document manifest = null;
try {
manifest = new JarReader().readXML(jarLocation, "manifest.xml");
} catch (ParserConfigurationException e) {
LoggerFactory.getLogger().fatal("Failed to initialize parser!", e);
} catch (SAXException e) {
LoggerFactory.getLogger().fatal("Failed to parse application manifest!", e);
}
Element hiveRoot = (Element) manifest.getElementsByTagName("hive").item(0);
Element application = (Element) hiveRoot.getElementsByTagName("application").item(0);
name = application.getAttribute("name");
String className = application.getAttribute("classname");
// TODO: return main interface when page for application wasn't specified
String mainInterfaceFile = application.getAttribute("interface");
NodeList methods = application.getElementsByTagName("method");
applicationMethods = new ArrayList<HiveMethod>();
for (int i = 0; i < methods.getLength(); i++) {
applicationMethods.add(HiveMethod.createMethod((Element) methods.item(i)));
}
// Extracting class from the JAR
JclObjectFactory factory = JclObjectFactory.getInstance();
// This is application object
instance = factory.create(jcl, className);
}
public String getName() {
return name;
}
public String getInterface(String page, int type) {
String suffix = null;
switch (type) {
case APPLICATION_INTERFACE_XML: suffix = ".xml"; break;
case APPLICATION_INTERFACE_HTML: suffix = ".html"; break;
}
return new JarReader().readFile(jarLocation, "interface/" + page + suffix);
}
private HiveMethod getApplicationMethod(String name) {
HiveMethod hiveMethod = null;
for (HiveMethod applicationMethod : applicationMethods) {
if (applicationMethod.getName().equals(name)) {
hiveMethod = applicationMethod;
break;
}
}
return hiveMethod;
}
/**
* Invocation of the method from the application
* @param name The name of the method
* @param args An arguments of the method
* @return Response of the invoked method
*/
public Object invokeMethod(String name, Object ... args) {
HiveMethod hiveMethod = getApplicationMethod(name);
if (hiveMethod == null) {
LoggerFactory.getLogger().error("Can't find requested method!");
return null;
}
Method method;
try {
method = hiveMethod.getReflectionMethod(jcl, instance);
} catch (Exception e) {
LoggerFactory.getLogger().error("Can't reflect method!", e);
return null;
}
try {
return method.invoke(instance, args);
} catch (Exception e) {
LoggerFactory.getLogger().error("Can't invoke method!", e);
return null;
}
}
public Object getInstance() {
return instance;
}
public String getTypes() {
return new JarReader().readFile(jarLocation, "types.xsd");
}
}