/*
* Behaviour.java Copyright (c) 2006,07 Swaroop Belur
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package net.sf.jdec.reflection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.sf.jdec.blocks.IFBlock;
import net.sf.jdec.core.DecompilerHelper;
import net.sf.jdec.core.GeneratedIfTracker;
import net.sf.jdec.core.GlobalVariableStore;
import net.sf.jdec.core.LocalVariableStructure;
import net.sf.jdec.core.OperandStack;
import net.sf.jdec.core.ShortcutAnalyser;
import net.sf.jdec.core.GeneratedIfTracker.IfStore;
import net.sf.jdec.util.Util;
/**
* This Is a Class to indicate any code processing an Object of this type that
* it is handling an object of a Class representing the behaviour of the Class.
* According the Java terminology behaviour represents a method of a class <p/>
* <p/> <p/> <br>
* <br>
* Example representation: Any Method or constructor<br>
* Example Usage: In Disassembling Code Section
*/
public abstract class Behaviour {
private StringBuffer codeAsBuffer = new StringBuffer();
protected JavaClass classRef;
private Set methodIfs = new HashSet();
protected Map datatypesForParams=new HashMap();
private ArrayList variablesatfront = new ArrayList();
private java.lang.String vmInstructions = "";
private java.lang.String codeStatements = "";
private OperandStack opStack = new OperandStack();
private boolean hasBeenDissassembled = false;
private Behaviour parentBehaviour = null;
private LocalVariableStructure methodLocalVariables = null;
public abstract java.lang.String getBehaviourName();
public abstract void setShortCutAnalyser(ShortcutAnalyser sa);
public abstract ShortcutAnalyser getShortCutAnalyser();
private Map labels = new HashMap();
public abstract byte[] getCode();
/**
* Called From Disassembled Section of the project
*
* @param code
* represents the actual blocks for this method interpreted from
* the bytes of the code for this behaviour
*/
public void setVMInstructions(java.lang.String code) {
vmInstructions = code;
}
public java.lang.String getVMInstructions() {
return vmInstructions;
}
public java.lang.String getUserFriendlyMethodAccessors() {
return null;
}
public java.lang.String getReturnType() {
return null;
}
public java.lang.String getUserFriendlyMethodParams() {
return null;
}
public abstract int getNumberofparamters();
public abstract java.lang.String getStringifiedParameters();
public abstract String[] getMethodParams();
public OperandStack getOpStack() {
return opStack;
}
public void setOpStack(OperandStack opStack) {
this.opStack = opStack;
}
public boolean isHasBeenDissassembled() {
return hasBeenDissassembled;
}
public void setHasBeenDissassembled(boolean hasBeenDissassembled) {
this.hasBeenDissassembled = hasBeenDissassembled;
}
public Behaviour getParentBehaviour() {
return parentBehaviour;
}
public void setParentBehaviour(Behaviour parentBehaviour) {
this.parentBehaviour = parentBehaviour;
}
public java.lang.String getCodeStatements() {
return codeStatements;
}
public void setVariablesAtFront(ArrayList list) {
variablesatfront = list;
}
private void setCodeStatements(java.lang.String codeAsString) {
this.codeStatements = codeAsString;
this.codeStatements = removeDummyLabels();
this.codeStatements = removeLeftOverMarkers0();
this.codeStatements = removeLeftOverMarkers1();
// this.codeStatements=correctAnyInvalidSuperPosition(this.codeStatements);
this.codeStatements = removeExtraSpaces0(this.codeStatements);
this.codeStatements = removeExtraSpaces1(this.codeStatements);
this.codeStatements = removeExtraJdecLabels(this.codeStatements); // Hack
this.codeStatements = this.codeStatements.replaceAll("this\\$",
"This\\$");
// this.codeStatements=removeOrphanJDECLabels(this.codeStatements);
// TODO: Need to write better code for stripping extra spaces in code
this.codeStatements = this.codeStatements.replaceAll("\\) ", "\\)");
this.codeStatements = this.codeStatements.replaceAll("\\) ", "\\)");
this.codeStatements = this.codeStatements.replaceAll("\\) ", "\\)");
this.codeStatements = addVariablesAtFront(this.codeStatements);
//this.codeStatements = this.codeStatements.replaceAll("\r\n\r\n", "\r\n");
replaceDoWhileMarkersWithIfs();
//this.codeStatements=Util.formatDecompiledStatement(this.codeStatements);
}
private void replaceDoWhileMarkersWithIfs(){
if(GlobalVariableStore.getDowhileloopmarkers().size() > 0){
int size = GlobalVariableStore.getDowhileloopmarkers().size();
String ls="//INSERT IFCODE FOR DOWHILE HERE";
String ifs ="<IF_AT_LOOP_END_BEGIN_";
String ife ="<IF_AT_LOOP_END_END_";
for(int i=0;i< size;i++){
int temp = ((Integer)GlobalVariableStore.getDowhileloopmarkers().get(i))
.intValue();
ls=ls+temp;
ifs=ifs+temp+"_>";
ife=ife+temp+"_>";
int lindex =codeStatements.indexOf(ls);
if( lindex != -1){
int start = codeStatements.indexOf(ifs,lindex+1);
if(start != -1){
int end = codeStatements.indexOf(ife,start+1);
if(end != -1){
int tempStart = start;
start = start+ifs.length();
String reqdif = codeStatements.substring(start,end);
String sub1=codeStatements.substring(0,tempStart);
String sub2=codeStatements.substring(end+ife.length());
codeStatements = sub1+sub2;
codeStatements = codeStatements.replaceFirst(ls, reqdif);
}
}
else{
codeStatements = codeStatements.replaceFirst(ls, "");
}
}
ifs ="<IF_AT_LOOP_END_BEGIN_";
ife ="<IF_AT_LOOP_END_END_";
ls="//INSERT IFCODE FOR DOWHILE HERE";
}
}
}
private void removeInvalidElseBreaksAtIfEnd() {
Iterator iterator = getMethodIfs().iterator();
while (iterator.hasNext()) {
IFBlock ifb = (IFBlock) iterator.next();
if (ifb.isElsebreakinvalid()) {
int start = ifb.getIfStart();
String marker = "<elsebreak" + start + ">";
String endmarker = "</elsebreak" + start + ">";
int markerIndex = codeAsBuffer.indexOf(marker);
if (markerIndex != -1) {
int endmarkerIndex = codeAsBuffer.indexOf(endmarker,
markerIndex + 1);
if (endmarkerIndex != -1) {
endmarkerIndex += endmarker.length();
/*if ((endmarkerIndex + 1) < codeAsBuffer.length()) {
endmarkerIndex = endmarkerIndex + 1;
}*/
if (endmarkerIndex < codeAsBuffer.length()) {
codeAsBuffer.replace(markerIndex, endmarkerIndex,
"");
}
}
}
} else {
int start = ifb.getIfStart();
String marker = "<elsebreak" + start + ">";
int markerIndex = codeAsBuffer.indexOf(marker);
if (markerIndex != -1) {
int endmarkerIndex = markerIndex + marker.length();
//endmarkerIndex = endmarkerIndex + 1;
codeAsBuffer.replace(markerIndex, endmarkerIndex, "");
}
marker = "</elsebreak" + start + ">";
markerIndex = codeAsBuffer.indexOf(marker);
if (markerIndex != -1) {
int endmarkerIndex = markerIndex + marker.length();
//endmarkerIndex = endmarkerIndex + 1;
codeAsBuffer.replace(markerIndex, endmarkerIndex, "");
}
}
}
}
public void filterCode(GeneratedIfTracker generatedIfTracker) {
removeInvalidElseBreaksAtIfEnd();
setCodeStatements(codeAsBuffer.toString());
removeInvalidGeneratedIfs(generatedIfTracker);
}
private void removeInvalidGeneratedIfs(GeneratedIfTracker generatedIfTracker) {
Map ifs = generatedIfTracker.getIfs();
Iterator iterator = ifs.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
IfStore aif = (IfStore) entry.getKey();
if (aif.isInvalid()) {
String name = aif.getName();
String toRemove = name + "=false;";
this.codeStatements = codeStatements.replaceAll(toRemove, "");
toRemove = "boolean " + name + "= true;";
this.codeStatements = codeStatements.replaceAll(toRemove, "");
}
}
}
public LocalVariableStructure getLocalVariables() {
return methodLocalVariables;
}
public void setMethodLocalVariables(
LocalVariableStructure methodLocalVariables) {
this.methodLocalVariables = methodLocalVariables;
}
public abstract java.lang.String[] getMethodAccessors();
public abstract void setExceptionTableList(ArrayList tables);
public abstract ArrayList getExceptionTableList();
public abstract ArrayList getAllTriesForMethod();
public abstract void setAllTriesForMethod(ArrayList alltries);
public abstract void setCreatedTableList(ArrayList list);
public abstract ArrayList getCreatedTableList();
protected ArrayList exceptionTables;
public abstract String[] getExceptionTypes();
public abstract java.lang.String getDeclaringClass();
public abstract ArrayList getAllSwitchBlks();
public abstract void setSynchronizedTableEntries(ArrayList list);
public abstract ArrayList getSynchronizedEntries();
public abstract ArrayList getBehaviourLoops();
public abstract void setBehaviourLoops(ArrayList list);
public abstract ArrayList getInstructionStartPositions();
public Map getLabels() {
return labels;
}
public void setLabels(Map labels) {
this.labels = labels;
}
protected abstract java.lang.String removeDummyLabels();
protected boolean isConstructor = false;
// public abstract boolean isMethodConstructor();
// public abstract void setMethodAsConstructor(boolean c);
private java.lang.String correctAnyInvalidSuperPosition(
java.lang.String codeS) {
java.lang.String temp4 = codeS.trim();
int index = temp4.indexOf("super(");
if (index == 0)
return codeS;
index = codeS.indexOf("super(");
if (index != -1) {
java.lang.String temp = codeS.substring(0, index);
int semi = codeS.indexOf(";", index);
if (semi != -1) {
java.lang.String temp2 = codeS.substring(semi + 1);
java.lang.String temp3 = temp + temp2;
java.lang.String s = codeS.substring(index, semi + 1);
return "\t" + "\t" + "\t" + "\t" + s + "\n" + temp3;
} else
return codeS; // Invalid return actually
} else
return codeS;
}
public java.lang.String getShortDescription() {
java.lang.String desc = "";
desc += "\n[Name ]:" + this.getBehaviourName() + "\n";
desc += "[Parameters ]:" + this.getUserFriendlyMethodParams() + "\n";
desc += "[Accessors ]:" + this.getUserFriendlyMethodAccessors() + "\n";
desc += "[Return TYpe ]:" + this.getReturnType() + "\n";
desc += "[Belonging Class ]:" + this.getDeclaringClass() + "\n";
return desc;
}
public java.lang.String removeLeftOverMarkers0() {
ArrayList codeList = new ArrayList();
java.lang.String temp = getCodeStatements();
// if(getLabels()==null || getLabels().size()==0)return temp;
int i = -1;
int start = 0;
String copy = getCodeStatements();
i = copy.indexOf("#REPLACE_INT_", start);
if (i == -1) {
String sr = copy;
sr = sr.replaceAll("\n\n", "\n");
return sr;
}
while (i != -1) {
int j = i + 13;
int hash = copy.indexOf("#", (i + 1));
java.lang.String num = copy.substring(j, hash);
java.lang.String dummy = copy.substring(i, (hash + 1));
boolean excep = false;
try {
int inum = Integer.parseInt(num);
} catch (NumberFormatException ne) {
excep = true;
}
if (!excep) {
String tempCode = copy.substring(0, i);
copy = copy.substring(i);
copy = copy.replaceFirst(dummy, "");
codeList.add(tempCode);
i = copy.indexOf("#REPLACE_INT_", start);
if (i == -1) {
codeList.add(copy);
}
} else {
String tempCode = copy.substring(0, j);
copy = copy.substring(j);
codeList.add(tempCode);
i = copy.indexOf("#REPLACE_INT_", start);
if (i == -1) {
codeList.add(copy);
}
}
}
StringBuffer buf = new StringBuffer("");
for (int k = 0; k < codeList.size(); k++) {
buf.append(codeList.get(k).toString());
}
temp = buf.toString();
temp = temp.replaceAll("\n\n", "\n");
return temp;
}
public java.lang.String removeLeftOverMarkers1() {
ArrayList codeList = new ArrayList();
java.lang.String temp = getCodeStatements();
// if(getLabels()==null || getLabels().size()==0)return temp;
int i = -1;
int start = 0;
String copy = getCodeStatements();
i = copy.indexOf("#VALUE", start);
if (i == -1) {
String sr = copy;
sr = sr.replaceAll("\n\n", "\n");
return sr;
}
while (i != -1) {
int j = i + 6;
int hash = copy.indexOf("#", (i + 1));
java.lang.String num = copy.substring(j, hash);
java.lang.String dummy = copy.substring(i, (hash + 1));
boolean excep = false;
try {
int inum = Integer.parseInt(num);
} catch (NumberFormatException ne) {
excep = true;
}
if (!excep) {
String tempCode = copy.substring(0, i);
copy = copy.substring(i);
copy = copy.replaceFirst(dummy, "");
codeList.add(tempCode);
i = copy.indexOf("#VALUE", start);
if (i == -1) {
codeList.add(copy);
}
} else {
String tempCode = copy.substring(0, j);
copy = copy.substring(j);
codeList.add(tempCode);
i = copy.indexOf("#VALUE", start);
if (i == -1) {
codeList.add(copy);
}
}
}
StringBuffer buf = new StringBuffer("");
for (int k = 0; k < codeList.size(); k++) {
buf.append(codeList.get(k).toString());
}
temp = buf.toString();
temp = temp.replaceAll("\n\n", "\n");
return temp;
}
public abstract boolean isMethodConstructor();
private java.lang.String removeExtraSpaces0(java.lang.String codes) {
java.lang.String temp = codes;
int j = temp.indexOf("||");
if (j == -1)
return temp;
else {
while (j != -1) {
java.lang.String temp1 = temp.substring(0, j + 2);
int k = j + 2;
if (k < temp.length()) {
char c = temp.charAt(k);
while (c == ' ') {
k++;
if (k >= temp.length())
return codes;// Should Not happen
c = temp.charAt(k);
}
temp1 = temp1 + " ";
java.lang.String temp2 = temp.substring(k);
temp1 = temp1 + temp2;
temp = temp1;
j = temp.indexOf("||", j + 2);
} else {
return codes; // should not happen
}
}
}
// temp=temp.replaceAll(" "," ");
return temp;
}
private java.lang.String removeExtraSpaces1(java.lang.String codes) {
java.lang.String temp = codes;
int j = temp.indexOf("||");
if (j == -1)
return codes;
else {
while (j != -1) {
int next = j + 2;
if (next >= temp.length())
return codes;
char c = temp.charAt(next);
while (c == ' ') {
next++;
if (next >= temp.length())
return codes;
c = temp.charAt(next);
}
if (c == ';') {
do {
next++;
if (next >= temp.length())
return codes;
c = temp.charAt(next);
} while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
}
while (c != ' ') {
if (c == ';') {
do {
next++;
if (next >= temp.length())
return codes;
c = temp.charAt(next);
} while (c == ' ' || c == '\n' || c == '\r'
|| c == '\t');
}
next++;
if (next >= temp.length())
return codes;
c = temp.charAt(next);
}
// next++;
if ((next + 1) >= temp.length())
return codes;
java.lang.String temp1 = temp.substring(0, next);
while (c == ' ') {
next++;
if (next >= temp.length())
return codes;
c = temp.charAt(next);
}
temp1 = temp1 + " ";
temp1 = temp1 + temp.substring(next);
temp = temp1;
j = temp.indexOf("||", j + 2);
}
}
return temp;
}
private java.lang.String removeOrphanJDECLabels(java.lang.String codes) {
java.lang.String temp = codes;
int fromwhere = temp.indexOf("jdecLABEL");
if (fromwhere == -1)
return codes;
boolean processed = false;
do {
int index = fromwhere;
int colon = temp.indexOf(":", index);
int start = index + 9;
java.lang.String lbl = "jdecLABEL" + temp.substring(start, colon);
int nextIndex = temp.indexOf(lbl, index + 1);
if (nextIndex == -1) {
temp = temp.replaceAll(lbl + ":", "");
processed = true;
}
} while ((fromwhere = temp.indexOf("jdecLABEL", fromwhere + 9)) != -1);
return (processed == true) ? temp : codes;
}
public abstract void createExceptionTableInStringifiedForm();
public abstract String getShortExceptionTableDetails();
public abstract String getDetailedExceptionTableDetails();
public abstract String getSynchTableDetails();
private ArrayList varatfrontTemp = new ArrayList();
private java.lang.String removeExtraJdecLabels(java.lang.String input) {
java.lang.String output = input;
if (output.indexOf("jdecLABEL") == -1)
return output;
int i = output.indexOf("jdecLABEL");
while (i != -1) {
int colon = output.indexOf(":", i);
if (colon != -1) {
java.lang.String lbl = output.substring(i, colon);
try {
String number = output.substring(i + 9, colon);
int num = Integer.parseInt(number);
int j = output.indexOf(lbl, colon + 1);
if (j == -1) {
output = output.replaceFirst(lbl + ":", "");
}
i = output.indexOf("jdecLABEL", colon);
} catch (NumberFormatException ne) {
i = output.indexOf("jdecLABEL", colon);
}
} else {
i = output.indexOf("jdecLABEL", i + 8);
}
}
return output;
}
// Bug Here
private String addVariablesAtFront(String code) {
if (variablesatfront == null || variablesatfront.size() == 0)
return code;
String front = "";
for (int z = 0; z < variablesatfront.size(); z++) {
DecompilerHelper.VariableAtFront v = (DecompilerHelper.VariableAtFront) variablesatfront
.get(z);
String temp = v.getType() + " " + v.getName() + "= "
+ v.getInitial() + ";\n";
temp = Util.formatFieldsOrMethodHeader(temp, "field");
varatfrontTemp.add(" " + temp);
}
varatfrontTemp = removeDuplicates(varatfrontTemp);
for (int k = 0; k < varatfrontTemp.size(); k++) {
String t = (String) varatfrontTemp.get(k);
front += t;
if (!t.endsWith("\n")) {
front += "\n";
}
}
boolean added = false;
if (this instanceof ConstructorMember) {
int m = code.indexOf("super(");
if (m == -1) {
m = code.indexOf("this(");
}
if (m != -1) {
int semi = code.indexOf(";", m);
if (semi != -1) {
String t1 = code.substring(0, semi + 1);
String t2 = code.substring(semi + 1);
code = t1 + "\n" + front + t2;
added = true;
}
}
}
if (added == false)
code = front + code;
return code;
}
public static ArrayList removeDuplicates(ArrayList input) {
ArrayList updatedList = new ArrayList();
if (input != null && input.size() > 0) {
String[] fullList = (java.lang.String[]) input
.toArray(new java.lang.String[] {});
java.util.Arrays.sort(fullList);
updatedList.add(fullList[0]);
for (int s = 1; s < fullList.length; s++) {
if (s < fullList.length) {
String currentItem = fullList[s];
// currentItem=currentItem.trim();
int prev = s - 1;
String temp = "";
if (prev >= 0 && prev < fullList.length) {
temp = fullList[prev];
// /temp=temp.trim();
if (temp.equals(currentItem) == false) {
// if(currentItem.indexOf("[")==-1) ??
updatedList.add(currentItem);
}
}
}
}
}
return updatedList;
}
public JavaClass getClassRef() {
return classRef;
}
public abstract void setClassRef(JavaClass classRef);
public Map getDatatypesForParams() {
return datatypesForParams;
}
public abstract void setDatatypesForParams(Map datatypesForParams);
public Set getMethodIfs() {
return methodIfs;
}
public String appendToBuffer(String string) {
//if(string.indexOf("}") != -1)string=string+ExecutionState.getCurrentInstructionPosition();
codeAsBuffer.append(string);
return null;
}
public void replaceBuffer(String string) {
codeAsBuffer = new StringBuffer(string);
}
public void replaceBuffer(StringBuffer stringbuffer) {
codeAsBuffer = stringbuffer;
}
public StringBuffer getCodeAsBuffer() {
return codeAsBuffer;
}
}
|