Reformat of parse package

This commit is contained in:
Jeroen Ketelaar
2014-02-14 03:41:41 +01:00
parent b97c022784
commit a5b1977731
6 changed files with 742 additions and 760 deletions
@@ -1,488 +1,480 @@
package org.parabot.core.parsers; package org.parabot.core.parsers;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.parabot.core.asm.adapters.AddInterfaceAdapter; import org.parabot.core.asm.adapters.AddInterfaceAdapter;
import org.parabot.core.asm.interfaces.Injectable; import org.parabot.core.asm.interfaces.Injectable;
import org.parabot.core.asm.wrappers.Callback; import org.parabot.core.asm.wrappers.*;
import org.parabot.core.asm.wrappers.Getter;
import org.parabot.core.asm.wrappers.Interface;
import org.parabot.core.asm.wrappers.Invoker;
import org.parabot.core.asm.wrappers.Setter;
import org.parabot.core.asm.wrappers.Super;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
/** /**
*
* Parses an XML files which injects the hooks and other bytecode manipulation * Parses an XML files which injects the hooks and other bytecode manipulation
* methods * methods
* *
* @author Everel * @author Everel
*
*/ */
public class HookParser { public class HookParser {
private Document doc = null; private Document doc = null;
private boolean parsedInterfaces = false; private boolean parsedInterfaces = false;
private HashMap<String, String> interfaceMap = new HashMap<String, String>(); private HashMap<String, String> interfaceMap = new HashMap<String, String>();
private HashMap<String, String> constants = new HashMap<String, String>(); private HashMap<String, String> constants = new HashMap<String, String>();
public HookParser(URL url) { public HookParser(URL url) {
try { try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance(); .newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(WebUtil.getInputStream(url)); doc = dBuilder.parse(WebUtil.getInputStream(url));
doc.getDocumentElement().normalize(); doc.getDocumentElement().normalize();
if (!doc.getDocumentElement().getNodeName().equals("injector")) { if (!doc.getDocumentElement().getNodeName().equals("injector")) {
throw new RuntimeException("Incorrect hook file."); throw new RuntimeException("Incorrect hook file.");
} }
} catch (Throwable t) { } catch (Throwable t) {
throw new RuntimeException("Unable to parse hooks " + t); throw new RuntimeException("Unable to parse hooks " + t);
} }
} }
public final Interface[] getInterfaces() { public final Interface[] getInterfaces() {
parsedInterfaces = true; parsedInterfaces = true;
final NodeList interfaceRootList = doc final NodeList interfaceRootList = doc
.getElementsByTagName("interfaces"); .getElementsByTagName("interfaces");
switch (interfaceRootList.getLength()) { switch (interfaceRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <interfaces> tags "); "Hook file may not contains multiple <interfaces> tags ");
} }
final Node node = interfaceRootList.item(0); final Node node = interfaceRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element interfaceRoot = (Element) node; final Element interfaceRoot = (Element) node;
final NodeList interfaces = interfaceRoot.getElementsByTagName("add"); final NodeList interfaces = interfaceRoot.getElementsByTagName("add");
if (interfaces.getLength() == 0) { if (interfaces.getLength() == 0) {
return null; return null;
} }
final ArrayList<Interface> interfaceList = new ArrayList<Interface>(); final ArrayList<Interface> interfaceList = new ArrayList<Interface>();
for (int x = 0; x < interfaces.getLength(); x++) { for (int x = 0; x < interfaces.getLength(); x++) {
final Node n = interfaces.item(x); final Node n = interfaces.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addInterface = (Element) n; final Element addInterface = (Element) n;
final String className = getValue("classname", addInterface); final String className = getValue("classname", addInterface);
final String interfaceClass = getValue("interface", addInterface); final String interfaceClass = getValue("interface", addInterface);
interfaceMap.put(interfaceClass, className); interfaceMap.put(interfaceClass, className);
final Interface inf = new Interface(className, interfaceClass); final Interface inf = new Interface(className, interfaceClass);
interfaceList.add(inf); interfaceList.add(inf);
} }
return interfaceList.toArray(new Interface[interfaceList.size()]); return interfaceList.toArray(new Interface[interfaceList.size()]);
} }
public final Super[] getSupers() { public final Super[] getSupers() {
final NodeList interfaceRootList = doc.getElementsByTagName("supers"); final NodeList interfaceRootList = doc.getElementsByTagName("supers");
switch (interfaceRootList.getLength()) { switch (interfaceRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <supers> tags "); "Hook file may not contains multiple <supers> tags ");
} }
final Node node = interfaceRootList.item(0); final Node node = interfaceRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element superRoot = (Element) node; final Element superRoot = (Element) node;
final NodeList supers = superRoot.getElementsByTagName("add"); final NodeList supers = superRoot.getElementsByTagName("add");
if (supers.getLength() == 0) { if (supers.getLength() == 0) {
return null; return null;
} }
final ArrayList<Super> superList = new ArrayList<Super>(); final ArrayList<Super> superList = new ArrayList<Super>();
for (int x = 0; x < supers.getLength(); x++) { for (int x = 0; x < supers.getLength(); x++) {
final Node n = supers.item(x); final Node n = supers.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addSuper = (Element) n; final Element addSuper = (Element) n;
final String className = getValue("classname", addSuper); final String className = getValue("classname", addSuper);
final String superClass = getValue("super", addSuper); final String superClass = getValue("super", addSuper);
final Super sup = new Super(className, superClass); final Super sup = new Super(className, superClass);
superList.add(sup); superList.add(sup);
} }
return superList.toArray(new Super[superList.size()]); return superList.toArray(new Super[superList.size()]);
} }
public final Getter[] getGetters() { public final Getter[] getGetters() {
final NodeList getterRootList = doc.getElementsByTagName("getters"); final NodeList getterRootList = doc.getElementsByTagName("getters");
switch (getterRootList.getLength()) { switch (getterRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <getters> tags "); "Hook file may not contains multiple <getters> tags ");
} }
final Node node = getterRootList.item(0); final Node node = getterRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element getterRoot = (Element) node; final Element getterRoot = (Element) node;
final NodeList getters = getterRoot.getElementsByTagName("add"); final NodeList getters = getterRoot.getElementsByTagName("add");
if (getters.getLength() == 0) { if (getters.getLength() == 0) {
return null; return null;
} }
final ArrayList<Getter> getterList = new ArrayList<Getter>(); final ArrayList<Getter> getterList = new ArrayList<Getter>();
for (int x = 0; x < getters.getLength(); x++) { for (int x = 0; x < getters.getLength(); x++) {
final Node n = getters.item(x); final Node n = getters.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addGetter = (Element) n; final Element addGetter = (Element) n;
if (isSet("classname", addGetter) && isSet("accessor", addGetter)) { if (isSet("classname", addGetter) && isSet("accessor", addGetter)) {
throw new RuntimeException( throw new RuntimeException(
"Can't set classname and accessor tag together."); "Can't set classname and accessor tag together.");
} }
if (isSet("accessor", addGetter) && !parsedInterfaces) { if (isSet("accessor", addGetter) && !parsedInterfaces) {
throw new RuntimeException( throw new RuntimeException(
"You'll need to parse interfaces first."); "You'll need to parse interfaces first.");
} }
final String className = isSet("classname", addGetter) ? getValue( final String className = isSet("classname", addGetter) ? getValue(
"classname", addGetter) : interfaceMap.get(getValue( "classname", addGetter) : interfaceMap.get(getValue(
"accessor", addGetter)); "accessor", addGetter));
final String into = isSet("into", addGetter) ? getValue("into", final String into = isSet("into", addGetter) ? getValue("into",
addGetter) : className; addGetter) : className;
final String fieldName = getValue("field", addGetter); final String fieldName = getValue("field", addGetter);
final String methodName = getValue("methodname", addGetter); final String methodName = getValue("methodname", addGetter);
boolean staticMethod = isSet("methstatic", addGetter) ? (getValue( boolean staticMethod = isSet("methstatic", addGetter) ? (getValue(
"methstatic", addGetter).equals("true")) : false; "methstatic", addGetter).equals("true")) : false;
String returnDesc = isSet("desc", addGetter) ? getValue("desc", String returnDesc = isSet("desc", addGetter) ? getValue("desc",
addGetter) : null; addGetter) : null;
String array = ""; String array = "";
if (returnDesc != null && returnDesc.contains("%s")) { if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) { if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) { for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') { if (returnDesc.charAt(i) == '[') {
array += '['; array += '[';
} }
} }
returnDesc = returnDesc.replaceAll("\\[", ""); returnDesc = returnDesc.replaceAll("\\[", "");
} }
str.append(array) str.append(array)
.append('L') .append('L')
.append(String.format(returnDesc, .append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage())) AddInterfaceAdapter.getAccessorPackage()))
.append(";"); .append(";");
returnDesc = str.toString(); returnDesc = str.toString();
} }
final Getter get = new Getter(into, className, fieldName, final Getter get = new Getter(into, className, fieldName,
methodName, returnDesc, staticMethod); methodName, returnDesc, staticMethod);
getterList.add(get); getterList.add(get);
} }
return getterList.toArray(new Getter[getterList.size()]); return getterList.toArray(new Getter[getterList.size()]);
} }
public Injectable[] getInjectables() { public Injectable[] getInjectables() {
ArrayList<Injectable> injectables = new ArrayList<Injectable>(); ArrayList<Injectable> injectables = new ArrayList<Injectable>();
Interface[] interfaces = getInterfaces(); Interface[] interfaces = getInterfaces();
if (interfaces != null) { if (interfaces != null) {
for (Interface inf : interfaces) { for (Interface inf : interfaces) {
injectables.add(inf); injectables.add(inf);
} }
} }
Getter[] getters = getGetters(); Getter[] getters = getGetters();
if (getters != null) { if (getters != null) {
for (Getter get : getters) { for (Getter get : getters) {
injectables.add(get); injectables.add(get);
} }
} }
Setter[] setters = getSetters(); Setter[] setters = getSetters();
if (setters != null) { if (setters != null) {
for (Setter set : setters) { for (Setter set : setters) {
injectables.add(set); injectables.add(set);
} }
} }
Super[] supers = getSupers(); Super[] supers = getSupers();
if (supers != null) { if (supers != null) {
for (Super sup : supers) { for (Super sup : supers) {
injectables.add(sup); injectables.add(sup);
} }
} }
Invoker[] invokers = getInvokers(); Invoker[] invokers = getInvokers();
if (invokers != null) { if (invokers != null) {
for (Invoker vok : invokers) { for (Invoker vok : invokers) {
injectables.add(vok); injectables.add(vok);
} }
} }
Callback[] callbacks = getCallbacks(); Callback[] callbacks = getCallbacks();
if (callbacks != null) { if (callbacks != null) {
for (Callback callback : callbacks) { for (Callback callback : callbacks) {
injectables.add(callback); injectables.add(callback);
} }
} }
return injectables.toArray(new Injectable[injectables.size()]); return injectables.toArray(new Injectable[injectables.size()]);
} }
public final Setter[] getSetters() { public final Setter[] getSetters() {
final NodeList setterRootList = doc.getElementsByTagName("setters"); final NodeList setterRootList = doc.getElementsByTagName("setters");
switch (setterRootList.getLength()) { switch (setterRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <setters> tags "); "Hook file may not contains multiple <setters> tags ");
} }
final Node node = setterRootList.item(0); final Node node = setterRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element setterRoot = (Element) node; final Element setterRoot = (Element) node;
final NodeList setters = setterRoot.getElementsByTagName("add"); final NodeList setters = setterRoot.getElementsByTagName("add");
if (setters.getLength() == 0) { if (setters.getLength() == 0) {
return null; return null;
} }
final ArrayList<Setter> setterList = new ArrayList<Setter>(); final ArrayList<Setter> setterList = new ArrayList<Setter>();
for (int x = 0; x < setters.getLength(); x++) { for (int x = 0; x < setters.getLength(); x++) {
final Node n = setters.item(x); final Node n = setters.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addSetter = (Element) n; final Element addSetter = (Element) n;
if (isSet("classname", addSetter) && isSet("accessor", addSetter)) { if (isSet("classname", addSetter) && isSet("accessor", addSetter)) {
throw new RuntimeException( throw new RuntimeException(
"Can't set classname and accessor tag together."); "Can't set classname and accessor tag together.");
} }
if (isSet("accessor", addSetter) && !parsedInterfaces) { if (isSet("accessor", addSetter) && !parsedInterfaces) {
throw new RuntimeException( throw new RuntimeException(
"You'll need to parse interfaces first."); "You'll need to parse interfaces first.");
} }
final String className = isSet("classname", addSetter) ? getValue( final String className = isSet("classname", addSetter) ? getValue(
"classname", addSetter) : interfaceMap.get(getValue( "classname", addSetter) : interfaceMap.get(getValue(
"accessor", addSetter)); "accessor", addSetter));
final String into = isSet("into", addSetter) ? getValue("into", final String into = isSet("into", addSetter) ? getValue("into",
addSetter) : className; addSetter) : className;
final String fieldName = getValue("field", addSetter); final String fieldName = getValue("field", addSetter);
final String methodName = getValue("methodname", addSetter); final String methodName = getValue("methodname", addSetter);
boolean staticMethod = isSet("methstatic", addSetter) ? (getValue( boolean staticMethod = isSet("methstatic", addSetter) ? (getValue(
"methstatic", addSetter).equals("true")) : false; "methstatic", addSetter).equals("true")) : false;
String returnDesc = isSet("desc", addSetter) ? getValue("desc", String returnDesc = isSet("desc", addSetter) ? getValue("desc",
addSetter) : null; addSetter) : null;
String array = ""; String array = "";
if (returnDesc != null && returnDesc.contains("%s")) { if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) { if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) { for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') { if (returnDesc.charAt(i) == '[') {
array += '['; array += '[';
} }
} }
returnDesc = returnDesc.replaceAll("\\[", ""); returnDesc = returnDesc.replaceAll("\\[", "");
} }
str.append(array) str.append(array)
.append('L') .append('L')
.append(String.format(returnDesc, .append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage())) AddInterfaceAdapter.getAccessorPackage()))
.append(";"); .append(";");
returnDesc = str.toString(); returnDesc = str.toString();
} }
final Setter get = new Setter(className, into, fieldName, final Setter get = new Setter(className, into, fieldName,
methodName, returnDesc, staticMethod); methodName, returnDesc, staticMethod);
setterList.add(get); setterList.add(get);
} }
return setterList.toArray(new Setter[setterList.size()]); return setterList.toArray(new Setter[setterList.size()]);
} }
public final Invoker[] getInvokers() { public final Invoker[] getInvokers() {
final NodeList invokerRootList = doc.getElementsByTagName("invokers"); final NodeList invokerRootList = doc.getElementsByTagName("invokers");
switch (invokerRootList.getLength()) { switch (invokerRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <invokers> tags "); "Hook file may not contains multiple <invokers> tags ");
} }
final Node node = invokerRootList.item(0); final Node node = invokerRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element invokerRoot = (Element) node; final Element invokerRoot = (Element) node;
final NodeList invokers = invokerRoot.getElementsByTagName("add"); final NodeList invokers = invokerRoot.getElementsByTagName("add");
if (invokers.getLength() == 0) { if (invokers.getLength() == 0) {
return null; return null;
} }
final ArrayList<Invoker> invokerList = new ArrayList<Invoker>(); final ArrayList<Invoker> invokerList = new ArrayList<Invoker>();
for (int x = 0; x < invokers.getLength(); x++) { for (int x = 0; x < invokers.getLength(); x++) {
final Node n = invokers.item(x); final Node n = invokers.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addInvoker = (Element) n; final Element addInvoker = (Element) n;
if (isSet("classname", addInvoker) && isSet("accessor", addInvoker)) { if (isSet("classname", addInvoker) && isSet("accessor", addInvoker)) {
throw new RuntimeException( throw new RuntimeException(
"Can't set classname and accessor tag together."); "Can't set classname and accessor tag together.");
} }
if (isSet("accessor", addInvoker) && !parsedInterfaces) { if (isSet("accessor", addInvoker) && !parsedInterfaces) {
throw new RuntimeException( throw new RuntimeException(
"You'll need to parse interfaces first."); "You'll need to parse interfaces first.");
} }
final String className = isSet("classname", addInvoker) ? getValue( final String className = isSet("classname", addInvoker) ? getValue(
"classname", addInvoker) : interfaceMap.get(getValue( "classname", addInvoker) : interfaceMap.get(getValue(
"accessor", addInvoker)); "accessor", addInvoker));
final String into = isSet("into", addInvoker) ? getValue("into", final String into = isSet("into", addInvoker) ? getValue("into",
addInvoker) : className; addInvoker) : className;
final String methodName = getValue("methodname", addInvoker); final String methodName = getValue("methodname", addInvoker);
final String invMethodName = getValue("invokemethod", addInvoker); final String invMethodName = getValue("invokemethod", addInvoker);
final String argsDesc = getValue("argsdesc", addInvoker); final String argsDesc = getValue("argsdesc", addInvoker);
String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue( String returnDesc = isSet("desc", addInvoker) ? resolveDesc(getValue(
"desc", addInvoker)) : null; "desc", addInvoker)) : null;
final Invoker invoker = new Invoker(into, className, invMethodName, final Invoker invoker = new Invoker(into, className, invMethodName,
argsDesc, returnDesc, methodName); argsDesc, returnDesc, methodName);
invokerList.add(invoker); invokerList.add(invoker);
} }
return invokerList.toArray(new Invoker[invokerList.size()]); return invokerList.toArray(new Invoker[invokerList.size()]);
} }
public final Callback[] getCallbacks() { public final Callback[] getCallbacks() {
final NodeList callbackRootList = doc.getElementsByTagName("callbacks"); final NodeList callbackRootList = doc.getElementsByTagName("callbacks");
switch (callbackRootList.getLength()) { switch (callbackRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <callbacks> tags "); "Hook file may not contains multiple <callbacks> tags ");
} }
final Node node = callbackRootList.item(0); final Node node = callbackRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element callbackRoot = (Element) node; final Element callbackRoot = (Element) node;
final NodeList callbacks = callbackRoot.getElementsByTagName("add"); final NodeList callbacks = callbackRoot.getElementsByTagName("add");
if (callbacks.getLength() == 0) { if (callbacks.getLength() == 0) {
return null; return null;
} }
final ArrayList<Callback> callbackList = new ArrayList<Callback>(); final ArrayList<Callback> callbackList = new ArrayList<Callback>();
for (int x = 0; x < callbacks.getLength(); x++) { for (int x = 0; x < callbacks.getLength(); x++) {
final Node n = callbacks.item(x); final Node n = callbacks.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addCallback = (Element) n; final Element addCallback = (Element) n;
if (isSet("classname", addCallback) if (isSet("classname", addCallback)
&& isSet("accessor", addCallback)) { && isSet("accessor", addCallback)) {
throw new RuntimeException( throw new RuntimeException(
"Can't set classname and accessor tag together."); "Can't set classname and accessor tag together.");
} }
if (isSet("accessor", addCallback) && !parsedInterfaces) { if (isSet("accessor", addCallback) && !parsedInterfaces) {
throw new RuntimeException( throw new RuntimeException(
"You'll need to parse interfaces first."); "You'll need to parse interfaces first.");
} }
final String className = isSet("classname", addCallback) ? getValue( final String className = isSet("classname", addCallback) ? getValue(
"classname", addCallback) : interfaceMap.get(getValue( "classname", addCallback) : interfaceMap.get(getValue(
"accessor", addCallback)); "accessor", addCallback));
final String methodName = getValue("methodname", addCallback); final String methodName = getValue("methodname", addCallback);
final String callClass = getValue("callclass", addCallback); final String callClass = getValue("callclass", addCallback);
final String callMethod = getValue("callmethod", addCallback); final String callMethod = getValue("callmethod", addCallback);
final String callDesc = getValue("calldesc", addCallback); final String callDesc = getValue("calldesc", addCallback);
final String callArgs = getValue("callargs", addCallback); final String callArgs = getValue("callargs", addCallback);
final String desc = getValue("desc", addCallback); final String desc = getValue("desc", addCallback);
final Callback callback = new Callback(className, methodName, desc, final Callback callback = new Callback(className, methodName, desc,
callClass, callMethod, callDesc, callArgs); callClass, callMethod, callDesc, callArgs);
callbackList.add(callback); callbackList.add(callback);
} }
return callbackList.toArray(new Callback[callbackList.size()]); return callbackList.toArray(new Callback[callbackList.size()]);
} }
private static String resolveDesc(String returnDesc) { private static String resolveDesc(String returnDesc) {
String array = ""; String array = "";
if (returnDesc != null && returnDesc.contains("%s")) { if (returnDesc != null && returnDesc.contains("%s")) {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
if (returnDesc.startsWith("[")) { if (returnDesc.startsWith("[")) {
for (int i = 0; i < returnDesc.length(); i++) { for (int i = 0; i < returnDesc.length(); i++) {
if (returnDesc.charAt(i) == '[') { if (returnDesc.charAt(i) == '[') {
array += '['; array += '[';
} }
} }
returnDesc = returnDesc.replaceAll("\\[", ""); returnDesc = returnDesc.replaceAll("\\[", "");
} }
str.append(array) str.append(array)
.append('L') .append('L')
.append(String.format(returnDesc, .append(String.format(returnDesc,
AddInterfaceAdapter.getAccessorPackage())) AddInterfaceAdapter.getAccessorPackage()))
.append(";"); .append(";");
returnDesc = str.toString(); returnDesc = str.toString();
} }
return returnDesc; return returnDesc;
} }
private static final boolean isSet(String tag, Element element) { private static final boolean isSet(String tag, Element element) {
return element.getElementsByTagName(tag).getLength() > 0; return element.getElementsByTagName(tag).getLength() > 0;
} }
private static final String getValue(String tag, Element element) { private static final String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0) NodeList nodes = element.getElementsByTagName(tag).item(0)
.getChildNodes(); .getChildNodes();
Node node = (Node) nodes.item(0); Node node = (Node) nodes.item(0);
return node.getNodeValue(); return node.getNodeValue();
} }
public final HashMap<String, String> getConstants() { public final HashMap<String, String> getConstants() {
if (!constants.isEmpty()) { if (!constants.isEmpty()) {
return constants; return constants;
} }
final NodeList constantsRootList = doc final NodeList constantsRootList = doc
.getElementsByTagName("constants"); .getElementsByTagName("constants");
switch (constantsRootList.getLength()) { switch (constantsRootList.getLength()) {
case 0: case 0:
return null; return null;
case 1: case 1:
break; break;
default: default:
throw new RuntimeException( throw new RuntimeException(
"Hook file may not contains multiple <constants> tags "); "Hook file may not contains multiple <constants> tags ");
} }
final Node node = constantsRootList.item(0); final Node node = constantsRootList.item(0);
if (node.getNodeType() != Node.ELEMENT_NODE) { if (node.getNodeType() != Node.ELEMENT_NODE) {
return null; return null;
} }
final Element constantRoot = (Element) node; final Element constantRoot = (Element) node;
final NodeList constantsList = constantRoot.getElementsByTagName("add"); final NodeList constantsList = constantRoot.getElementsByTagName("add");
if (constantsList.getLength() == 0) { if (constantsList.getLength() == 0) {
// return empty hashmap // return empty hashmap
return constants; return constants;
} }
for (int x = 0; x < constantsList.getLength(); x++) { for (int x = 0; x < constantsList.getLength(); x++) {
final Node n = constantsList.item(x); final Node n = constantsList.item(x);
if (n.getNodeType() != Node.ELEMENT_NODE) { if (n.getNodeType() != Node.ELEMENT_NODE) {
continue; continue;
} }
final Element addConstant = (Element) n; final Element addConstant = (Element) n;
final String key = getValue("key", addConstant); final String key = getValue("key", addConstant);
final String value = getValue("value", addConstant); final String value = getValue("value", addConstant);
constants.put(key, value); constants.put(key, value);
} }
return constants; return constants;
} }
} }
@@ -1,9 +1,5 @@
package org.parabot.core.parsers.scripts; package org.parabot.core.parsers.scripts;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.classpath.ClassPath; import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ScriptDescription; import org.parabot.core.desc.ScriptDescription;
@@ -12,69 +8,71 @@ import org.parabot.environment.scripts.Script;
import org.parabot.environment.scripts.ScriptManifest; import org.parabot.environment.scripts.ScriptManifest;
import org.parabot.environment.scripts.loader.JavaScriptLoader; import org.parabot.environment.scripts.loader.JavaScriptLoader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
/** /**
*
* Parses locally stored java scripts * Parses locally stored java scripts
*
* @author Everel
* *
* @author Everel
*/ */
public class LocalJavaScripts extends ScriptParser { public class LocalJavaScripts extends ScriptParser {
@Override @Override
public void execute() { public void execute() {
// parse classes in server directories // parse classes in server directories
final ClassPath path = new ClassPath(); final ClassPath path = new ClassPath();
path.addClasses(Directories.getScriptCompiledPath()); path.addClasses(Directories.getScriptCompiledPath());
// init the script loader // init the script loader
final JavaScriptLoader loader = new JavaScriptLoader(path); final JavaScriptLoader loader = new JavaScriptLoader(path);
// list of scripts // list of scripts
final List<Script> scripts = new ArrayList<Script>(); final List<Script> scripts = new ArrayList<Script>();
// list of descriptions // list of descriptions
final List<ScriptDescription> descs = new ArrayList<ScriptDescription>(); final List<ScriptDescription> descs = new ArrayList<ScriptDescription>();
// loop through all classes which extends the 'Script' class // loop through all classes which extends the 'Script' class
for (final String className : loader.getScriptClassNames()) { for (final String className : loader.getScriptClassNames()) {
try { try {
// get class // get class
final Class<?> scriptClass; final Class<?> scriptClass;
try { try {
scriptClass = loader.loadClass(className); scriptClass = loader.loadClass(className);
} catch (NoClassDefFoundError ignored) { } catch (NoClassDefFoundError ignored) {
// script for an other server provider // script for an other server provider
continue; continue;
} }
// get annotation // get annotation
final Object annotation = scriptClass final Object annotation = scriptClass
.getAnnotation(ScriptManifest.class); .getAnnotation(ScriptManifest.class);
if (annotation == null) { if (annotation == null) {
throw new RuntimeException("Missing manifest at " throw new RuntimeException("Missing manifest at "
+ className); + className);
} }
// cast object annotation to script manifest annotation // cast object annotation to script manifest annotation
final ScriptManifest manifest = (ScriptManifest) annotation; final ScriptManifest manifest = (ScriptManifest) annotation;
// get constructor // get constructor
final Constructor<?> con = scriptClass.getConstructor(); final Constructor<?> con = scriptClass.getConstructor();
final Script script = (Script) con.newInstance(); final Script script = (Script) con.newInstance();
scripts.add(script); scripts.add(script);
final ScriptDescription desc = new ScriptDescription( final ScriptDescription desc = new ScriptDescription(
manifest.name(), manifest.author(), manifest.category() manifest.name(), manifest.author(), manifest.category()
.toString(), manifest.version(), .toString(), manifest.version(),
manifest.description(), manifest.servers(), manifest.description(), manifest.servers(),
manifest.vip() ? "yes" : "no", manifest.vip() ? "yes" : "no",
manifest.premium() ? "yes" : "no"); manifest.premium() ? "yes" : "no");
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script)); SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script));
descs.add(desc); descs.add(desc);
} catch (ClassNotFoundException ignored) { } catch (ClassNotFoundException ignored) {
} catch (NoClassDefFoundError ignored) { } catch (NoClassDefFoundError ignored) {
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} }
} }
} }
@@ -1,9 +1,5 @@
package org.parabot.core.parsers.scripts; package org.parabot.core.parsers.scripts;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.desc.ScriptDescription; import org.parabot.core.desc.ScriptDescription;
import org.parabot.environment.scripts.Category; import org.parabot.environment.scripts.Category;
@@ -12,91 +8,91 @@ import org.parabot.environment.scripts.framework.PythonScript;
import org.python.core.PyObject; import org.python.core.PyObject;
import org.python.util.PythonInterpreter; import org.python.util.PythonInterpreter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
/** /**
*
* Parses python scripts * Parses python scripts
*
* @author Everel
* *
* @author Everel
*/ */
public class LocalPythonScripts extends ScriptParser { public class LocalPythonScripts extends ScriptParser {
private PythonInterpreter interpreter = new PythonInterpreter(); private PythonInterpreter interpreter = new PythonInterpreter();
private static final FilenameFilter PYTHON_SCRIPT_FILTER = new FilenameFilter() { private static final FilenameFilter PYTHON_SCRIPT_FILTER = new FilenameFilter() {
@Override @Override
public boolean accept(File dir, String name) { public boolean accept(File dir, String name) {
return name.endsWith(".py"); return name.endsWith(".py");
} }
}; };
/** /**
* * @param name - local var name
* @param name * @return script instance
* - local var name */
* @return script instance public PythonScript getScript(String name) {
*/ PyObject clazz = interpreter.get(name);
public PythonScript getScript(String name) { if (clazz.toString().startsWith("<class '__main__.")) {
PyObject clazz = interpreter.get(name); final PyObject instanceClass = clazz.__call__();
if (clazz.toString().startsWith("<class '__main__.")) { final Object javaInstance = instanceClass
final PyObject instanceClass = clazz.__call__(); .__tojava__(PythonScript.class);
final Object javaInstance = instanceClass if (javaInstance instanceof PythonScript) {
.__tojava__(PythonScript.class); return (PythonScript) javaInstance;
if (javaInstance instanceof PythonScript) { }
return (PythonScript) javaInstance; }
} return null;
} }
return null;
}
@Override @Override
public void execute() { public void execute() {
for (final File scriptFile : Directories.getScriptSourcesPath() for (final File scriptFile : Directories.getScriptSourcesPath()
.listFiles(PYTHON_SCRIPT_FILTER)) { .listFiles(PYTHON_SCRIPT_FILTER)) {
try { try {
interpreter.execfile(new FileInputStream(scriptFile)); interpreter.execfile(new FileInputStream(scriptFile));
final String name = interpreter.get("__scriptname__") final String name = interpreter.get("__scriptname__")
.asString(); .asString();
final String author = interpreter.get("__author__").asString(); final String author = interpreter.get("__author__").asString();
final Category cat = (Category) interpreter.get("__category__") final Category cat = (Category) interpreter.get("__category__")
.__tojava__(Category.class); .__tojava__(Category.class);
final double version = interpreter.get("__version__") final double version = interpreter.get("__version__")
.asDouble(); .asDouble();
final String description = interpreter.get("__description__") final String description = interpreter.get("__description__")
.asString(); .asString();
final String[] servers = (String[]) interpreter.get( final String[] servers = (String[]) interpreter.get(
"__servers__").__tojava__(String[].class); "__servers__").__tojava__(String[].class);
Object ob;
String vip = "no";
if( (ob = interpreter.get("__vip__")) != null) {
final String isVip = ob.toString();
vip = isVip.equals("True") ? "yes" : "no";
}
String prem = "no";
if( (ob = interpreter.get("__premium__")) != null) {
final String isPrem = ob.toString();
prem = isPrem.equals("True") ? "yes" : "no";
}
final ScriptDescription desc = new ScriptDescription(name,
author, cat.toString(), version, description, servers, vip, prem);
for (final PyObject o : interpreter.getLocals().asIterable()) {
PythonScript script = getScript(o.asString());
if (script != null) {
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script));
break;
}
}
interpreter.cleanup();
} catch (Throwable t) {
t.printStackTrace();
}
}
} Object ob;
String vip = "no";
if ((ob = interpreter.get("__vip__")) != null) {
final String isVip = ob.toString();
vip = isVip.equals("True") ? "yes" : "no";
}
String prem = "no";
if ((ob = interpreter.get("__premium__")) != null) {
final String isPrem = ob.toString();
prem = isPrem.equals("True") ? "yes" : "no";
}
final ScriptDescription desc = new ScriptDescription(name,
author, cat.toString(), version, description, servers, vip, prem);
for (final PyObject o : interpreter.getLocals().asIterable()) {
PythonScript script = getScript(o.asString());
if (script != null) {
SCRIPT_CACHE.put(desc, new LocalScriptExecuter(script));
break;
}
}
interpreter.cleanup();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
} }
@@ -1,7 +1,5 @@
package org.parabot.core.parsers.scripts; package org.parabot.core.parsers.scripts;
import java.io.BufferedReader;
import java.net.URL;
import org.parabot.core.Configuration; import org.parabot.core.Configuration;
import org.parabot.core.desc.ScriptDescription; import org.parabot.core.desc.ScriptDescription;
import org.parabot.core.forum.AccountManager; import org.parabot.core.forum.AccountManager;
@@ -9,90 +7,91 @@ import org.parabot.core.forum.AccountManagerAccess;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.scripts.SDNScriptExecuter; import org.parabot.environment.scripts.SDNScriptExecuter;
import java.io.BufferedReader;
import java.net.URL;
/** /**
* * Parses scripts stored at parabots sdn
* Parses scripts stored at parabot´s sdn
*
* @author Everel
* *
* @author Everel
*/ */
public class SDNScripts extends ScriptParser { public class SDNScripts extends ScriptParser {
private static AccountManager manager = null; private static AccountManager manager = null;
public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() { public static final AccountManagerAccess MANAGER_FETCHER = new AccountManagerAccess() {
@Override @Override
public final void setManager(AccountManager manager) { public final void setManager(AccountManager manager) {
SDNScripts.manager = manager; SDNScripts.manager = manager;
} }
}; };
@Override @Override
public void execute() { public void execute() {
if (!manager.isLoggedIn()) { if (!manager.isLoggedIn()) {
System.err.println("Not logged in..."); System.err.println("Not logged in...");
return; return;
} }
try { try {
BufferedReader br = WebUtil.getReader(new URL(String.format(Configuration.SDN_SCRIPTS, manager.getAccount() BufferedReader br = WebUtil.getReader(new URL(String.format(Configuration.SDN_SCRIPTS, manager.getAccount()
.getUsername()))); .getUsername())));
int count = 0; int count = 0;
String line; String line;
String jarName = null; String jarName = null;
int sdnId = -1; int sdnId = -1;
String scriptName = null; String scriptName = null;
String author = null; String author = null;
double version = 0D; double version = 0D;
String category = null; String category = null;
String description = null; String description = null;
String[] servers = null; String[] servers = null;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
count++; count++;
switch (count % 8) { switch (count % 8) {
case 1: case 1:
// jarname // jarname
jarName = line; jarName = line;
break; break;
case 2: case 2:
// sdn id // sdn id
sdnId = Integer.parseInt(line); sdnId = Integer.parseInt(line);
break; break;
case 3: case 3:
scriptName = line; scriptName = line;
break; break;
case 4: case 4:
author = line; author = line;
break; break;
case 5: case 5:
version = Double.parseDouble(line); version = Double.parseDouble(line);
break; break;
case 6: case 6:
category = line; category = line;
break; break;
case 7: case 7:
description = line; description = line;
break; break;
case 0: case 0:
if (line.contains(", ")) { if (line.contains(", ")) {
servers = line.split(", "); servers = line.split(", ");
} else { } else {
servers = new String[] { line }; servers = new String[]{line};
} }
final ScriptDescription desc = new ScriptDescription(jarName, scriptName, final ScriptDescription desc = new ScriptDescription(jarName, scriptName,
author, category, version, description, author, category, version, description,
servers, sdnId); servers, sdnId);
SCRIPT_CACHE.put(desc, new SDNScriptExecuter(sdnId)); SCRIPT_CACHE.put(desc, new SDNScriptExecuter(sdnId));
} }
} }
br.close();
} catch (Throwable t) { br.close();
t.printStackTrace();
} } catch (Throwable t) {
} t.printStackTrace();
}
}
} }
@@ -1,7 +1,5 @@
package org.parabot.core.parsers.servers; package org.parabot.core.parsers.servers;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import org.parabot.core.Directories; import org.parabot.core.Directories;
import org.parabot.core.classpath.ClassPath; import org.parabot.core.classpath.ClassPath;
import org.parabot.core.desc.ServerDescription; import org.parabot.core.desc.ServerDescription;
@@ -10,64 +8,65 @@ import org.parabot.environment.servers.ServerManifest;
import org.parabot.environment.servers.ServerProvider; import org.parabot.environment.servers.ServerProvider;
import org.parabot.environment.servers.loader.ServerLoader; import org.parabot.environment.servers.loader.ServerLoader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
/** /**
*
* Parses local server providers located in the servers directory * Parses local server providers located in the servers directory
* *
* @author Everel * @author Everel
*
*/ */
public class LocalServers extends ServerParser { public class LocalServers extends ServerParser {
@Override @Override
public void execute() { public void execute() {
// parse classes in server directories // parse classes in server directories
final ClassPath basePath = new ClassPath(); final ClassPath basePath = new ClassPath();
basePath.parseJarFiles(false); basePath.parseJarFiles(false);
basePath.addClasses(Directories.getServerPath()); basePath.addClasses(Directories.getServerPath());
final ArrayList<ClassPath> classPaths = new ArrayList<ClassPath>(); final ArrayList<ClassPath> classPaths = new ArrayList<ClassPath>();
classPaths.add(basePath); classPaths.add(basePath);
for (final ClassPath classPath : basePath.getJarFiles()) { for (final ClassPath classPath : basePath.getJarFiles()) {
classPaths.add(classPath); classPaths.add(classPath);
} }
for (final ClassPath path : classPaths) { for (final ClassPath path : classPaths) {
// init the server loader // init the server loader
final ServerLoader loader = new ServerLoader(path); final ServerLoader loader = new ServerLoader(path);
// loop through all classes which extends the 'ServerProvider' class // loop through all classes which extends the 'ServerProvider' class
for (final String className : loader.getServerClassNames()) { for (final String className : loader.getServerClassNames()) {
try { try {
// get class // get class
final Class<?> serverProviderClass = loader final Class<?> serverProviderClass = loader
.loadClass(className); .loadClass(className);
// get annotation // get annotation
final Object annotation = serverProviderClass final Object annotation = serverProviderClass
.getAnnotation(ServerManifest.class); .getAnnotation(ServerManifest.class);
if (annotation == null) { if (annotation == null) {
throw new RuntimeException("Missing manifest at " throw new RuntimeException("Missing manifest at "
+ className); + className);
} }
// cast object annotation to server manifest annotation // cast object annotation to server manifest annotation
final ServerManifest manifest = (ServerManifest) annotation; final ServerManifest manifest = (ServerManifest) annotation;
// get constructor // get constructor
final Constructor<?> con = serverProviderClass final Constructor<?> con = serverProviderClass
.getConstructor(); .getConstructor();
final ServerProvider serverProvider = (ServerProvider) con final ServerProvider serverProvider = (ServerProvider) con
.newInstance(); .newInstance();
SERVER_CACHE.put( SERVER_CACHE.put(
new ServerDescription(manifest.name(), manifest new ServerDescription(manifest.name(), manifest
.author(), manifest.version()), .author(), manifest.version()),
new LocalServerExecuter(serverProvider, path, new LocalServerExecuter(serverProvider, path,
manifest.name())); manifest.name()));
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
} }
} }
} }
} }
} }
@@ -1,62 +1,60 @@
package org.parabot.core.parsers.servers; package org.parabot.core.parsers.servers;
import java.io.BufferedReader;
import java.net.URL;
import org.parabot.core.Configuration; import org.parabot.core.Configuration;
import org.parabot.core.desc.ServerDescription; import org.parabot.core.desc.ServerDescription;
import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.api.utils.WebUtil;
import org.parabot.environment.servers.PublicServerExecuter; import org.parabot.environment.servers.PublicServerExecuter;
import java.io.BufferedReader;
import java.net.URL;
/** /**
*
* Parses servers hosted on parabot * Parses servers hosted on parabot
* *
* @author Everel * @author Everel
*
*/ */
public class PublicServers extends ServerParser { public class PublicServers extends ServerParser {
@Override @Override
public void execute() { public void execute() {
try { try {
BufferedReader br = WebUtil.getReader(new URL( BufferedReader br = WebUtil.getReader(new URL(
Configuration.GET_SERVER_PROVIDERS)); Configuration.GET_SERVER_PROVIDERS));
int count = 0; int count = 0;
String line; String line;
String name = null; String name = null;
String author = null; String author = null;
double version = 0D; double version = 0D;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
count++; count++;
switch (count % 4) { switch (count % 4) {
case 1: case 1:
// server name // server name
name = line; name = line;
break; break;
case 2: case 2:
// author // author
author = line; author = line;
break; break;
case 3: case 3:
// version // version
version = Double.parseDouble(line); version = Double.parseDouble(line);
break; break;
case 0: case 0:
// jarName // jarName
ServerDescription desc = new ServerDescription(name, ServerDescription desc = new ServerDescription(name,
author, version); author, version);
SERVER_CACHE.put(desc, new PublicServerExecuter(name, line)); SERVER_CACHE.put(desc, new PublicServerExecuter(name, line));
} }
} }
br.close();
} catch (Exception e) { br.close();
e.printStackTrace();
} } catch (Exception e) {
} e.printStackTrace();
}
}
} }