//----------------------------------- Injectable.java
package com.zetabot.updater.objects;
import org.jdom.Document;
/**
* User: Johan
* Date: 2010-feb-09
* Time: 18:15:33
*/
public interface Injectable {
public void inject();
}
//----------------------------------- InterfaceInjector.java
package com.zetabot.updater.objects;
import com.zetabot.updater.Updater;
import org.apache.bcel.generic.ClassGen;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
/**
* User: Johan
* Date: 2010-feb-09
* Time: 18:15:21
*/
public class InterfaceInjector implements Injectable {
private static final Logger log = Logger.getLogger(InterfaceInjector.class);
private static final String PACKAGE_NAME
= "com.zetabot.hooks.";
private ClassGen cg;
public InterfaceInjector
(ClassGen cg,
String name
) {
this.cg = cg;
this.name = name;
}
public ClassGen getClazz() {
return cg;
}
public void inject() {
cg.addInterface(name);
log.info("Interface " + PACKAGE_NAME + name + " -> " + cg.getClassName());
Updater.interfaceCount++;
}
iface.setAttribute("name", name);
iface.setAttribute("class", cg.getClassName());
doc.getRootElement().addContent(iface);
}
}
//----------------------------------- MemberInjector.java
package com.zetabot.updater.objects;
import com.zetabot.updater.Updater;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.generic.*;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import java.util.List;
/**
* User: Johan
* Date: 2010-feb-09
* Time: 18:15:14
*/
public class MemberInjector implements Injectable {
private static final Logger log = Logger.getLogger(MemberInjector.class);
private ClassGen target;
private Type returnType;
public MemberInjector
(String name, ClassGen target,
Field field, Type returnType
) {
this.name = name;
this.target = target;
this.field = field;
this.returnType = returnType;
}
public ClassGen getTarget() {
return target;
}
public void inject() {
if(field == null || target == null) {
log.info("Broken: " + name + "()");
return;
}
InstructionFactory ifactory = new InstructionFactory(target.getConstantPool());
InstructionList il = new InstructionList();
MethodGen methodGen
= new MethodGen
(Constants.
ACC_PUBLIC, returnType, Type.
NO_ARGS,
new String[]{}, name, target.
getClassName(), il, target.
getConstantPool());
il.append(new ALOAD(0));
il.append(ifactory.createFieldAccess(target.getClassName(), field.getName(), field.getType(), Constants.GETFIELD));
il.append(InstructionFactory.createReturn(field.getType()));
methodGen.setMaxLocals();
methodGen.setMaxStack();
target.addMethod(methodGen.getMethod());
log.info("Field " + name + "() -> " + field.getType() + " " + target.getClassName() + "." + field.getName());
Updater.fieldCount++;
}
if(field == null || target == null) {
return;
}
List list
= doc.
getRootElement().
getChildren("Class");
int elementIndex = 0;
for(int i = 0; i < elements.length; i++) {
if(elements[i].getAttribute("class").getValue().equals(target.getClassName())) {
elementIndex = i;
}
}
if(name.contains("get")) {
fixedId = name.split("get")[1];
String firstChar
= fixedId.
substring(0, 1
);
String fixedChar
= firstChar.
toLowerCase();
fixedId = fixedId.replaceFirst(firstChar, fixedChar);
}
val.setAttribute("id", fixedId);
val.setAttribute("name", field.getName());
val.setAttribute("type", field.getType().toString());
((Element)doc.
getRootElement().
getChildren().
get(elementIndex
)).
addContent(val
);
}
}
//----------------------------------- StaticMemberInjector.java
package com.zetabot.updater.objects;
import com.zetabot.updater.Updater;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.generic.*;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
/**
* User: Johan
* Date: 2010-feb-09
* Time: 18:13:13
*/
public class StaticMemberInjector implements Injectable {
private static final Logger log = Logger.getLogger(StaticMemberInjector.class);
private ClassGen clazz;
private Type returnType;
public StaticMemberInjector
(String name, ClassGen clazz,
Field field, Type returnType
) {
this.name = name;
this.clazz = clazz;
this.field = field;
this.returnType = returnType;
}
public void inject() {
if(field == null || clazz == null) {
log.info("Broken: " + name + "()");
return;
}
ClassGen client = Updater.getClassByName("client");
InstructionFactory ifactory = new InstructionFactory(client, client.getConstantPool());
InstructionList il = new InstructionList();
MethodGen methodGen
= new MethodGen
(Constants.
ACC_PUBLIC, returnType, Type.
NO_ARGS,
new String[]{}, name, client.
getClassName(), il, client.
getConstantPool());
il.append(ifactory.createFieldAccess(clazz.getClassName(), field.getName(), field.getType(), Constants.GETSTATIC));
il.append(InstructionFactory.createReturn(field.getType()));
methodGen.setMaxLocals();
methodGen.setMaxStack();
client.addMethod(methodGen.getMethod());
log.info("Static Field " + name + "() -> " + field.getType() + " " + clazz.getClassName() + "." + field.getName());
Updater.staticCount++;
}
if(name.contains("get")) {
fixedId = name.split("get")[1];
String firstChar
= fixedId.
substring(0, 1
);
String fixedChar
= firstChar.
toLowerCase();
fixedId = fixedId.replaceFirst(firstChar, fixedChar);
}
data.setAttribute("id", fixedId);
data.setAttribute("name", field.getName());
data.setAttribute("class", clazz.getClassName());
data.setAttribute("type", field.getType().toString());
doc.getRootElement().getChild("Static").addContent(data);
}
}