-
-
Notifications
You must be signed in to change notification settings - Fork 196
/
uncaught_exception.ump
155 lines (153 loc) · 6.15 KB
/
uncaught_exception.ump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class UmpleToJava {
uncaught_exception <<!<</*uncaught_exception*/>><<#
java.util.regex.Pattern lineNumberPattern = java.util.regex.Pattern.compile("// line ([0|1|2|3|4|5|6|7|8|9]*) \"(.*)\"");
private void addUncaughtExceptionVariables(int javaline, String code, String methodname)
{
String[] lines = code.split("\\n");
java.util.regex.Matcher matcher = lineNumberPattern.matcher(lines[0]);
if(matcher.matches())
{
if(!uncaughtExceptions.containsKey(methodname))
{
uncaughtExceptions.put(methodname,new UncaughtException(globalUmpleClass.getName(), methodname));
}
int fileIndex = matcher.group(2).lastIndexOf('/') + 1;
uncaughtExceptions.get(methodname).addUncaughtFileName(matcher.group(2).substring(fileIndex));
uncaughtExceptions.get(methodname).addUncaughtUmpleLine(Integer.parseInt(matcher.group(1)));
uncaughtExceptions.get(methodname).addUncaughtJavaLine(javaline+1);
// Subtract two to compensate for the comments at the top and bottom of each inject statement
uncaughtExceptions.get(methodname).addUncaughtLength(lines.length-2);
}
}
private void addUncaughtExceptionVariables(String methodname, String filename, int umpleline, int javaline, int length)
{
if(!uncaughtExceptions.containsKey(methodname))
{
uncaughtExceptions.put(methodname,new UncaughtException(globalUmpleClass.getName(), methodname));
}
uncaughtExceptions.get(methodname).addUncaughtFileName(filename);
uncaughtExceptions.get(methodname).addUncaughtUmpleLine(umpleline-1);
uncaughtExceptions.get(methodname).addUncaughtJavaLine(javaline+1);
uncaughtExceptions.get(methodname).addUncaughtLength(length);
}
public String getExceptionHandler(String exceptions) {
StringBuilder realSb = new StringBuilder();#>>
public static class UmpleExceptionHandler implements Thread.UncaughtExceptionHandler
{
public void uncaughtException(Thread t, Throwable e)
{
translate(e);
if(e.getCause()!=null)
{
translate(e.getCause());
}
e.printStackTrace();
}
public void translate(Throwable e)
{
java.util.List<StackTraceElement> result = new java.util.ArrayList<StackTraceElement>();
StackTraceElement[] elements = e.getStackTrace();
try
{
for(StackTraceElement element:elements)
{
String className = element.getClassName();
String methodName = element.getMethodName();
boolean methodFound = false;
int index = className.lastIndexOf('.')+1;
try {
java.lang.reflect.Method query = this.getClass().getMethod(className.substring(index)+"_"+methodName,new Class[]{});
UmpleSourceData sourceInformation = (UmpleSourceData)query.invoke(this,new Object[]{});
for(int i=0;i<sourceInformation.size();++i)
{
// To compensate for any offsets caused by injected code we need to loop through the other references to this function
// and adjust the start / length of the function.
int functionStart = sourceInformation.getJavaLine(i) + (("main".equals(methodName))?3:1);
int functionEnd = functionStart + sourceInformation.getLength(i);
int afterInjectionLines = 0;
// We can leverage the fact that all inject statements are added to the uncaught exception list
// before the functions that they are within
for (int j = 0; j < i; j++) {
if (sourceInformation.getJavaLine(j) - 1 >= functionStart &&
sourceInformation.getJavaLine(j) - 1 <= functionEnd &&
sourceInformation.getJavaLine(j) - 1 <= element.getLineNumber()) {
// A before injection, +2 for the comments surrounding the injected code
if (sourceInformation.getJavaLine(j) - 1 == functionStart) {
functionStart += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
} else {
// An after injection
afterInjectionLines += sourceInformation.getLength(j) + 2;
functionEnd += sourceInformation.getLength(j) + 2;
}
}
}
int distanceFromStart = element.getLineNumber() - functionStart - afterInjectionLines;
if(distanceFromStart>=0&&distanceFromStart<=sourceInformation.getLength(i))
{
result.add(new StackTraceElement(element.getClassName(),element.getMethodName(),sourceInformation.getFileName(i),sourceInformation.getUmpleLine(i)+distanceFromStart));
methodFound = true;
break;
}
}
}
catch (Exception e2){}
if(!methodFound)
{
result.add(element);
}
}
}
catch (Exception e1)
{
e1.printStackTrace();
}
e.setStackTrace(result.toArray(new StackTraceElement[0]));
}
//The following methods Map Java lines back to their original Umple file / line
<<=exceptions>>
}
public static class UmpleSourceData
{
String[] umpleFileNames;
Integer[] umpleLines;
Integer[] umpleJavaLines;
Integer[] umpleLengths;
public UmpleSourceData(){
}
public String getFileName(int i){
return umpleFileNames[i];
}
public Integer getUmpleLine(int i){
return umpleLines[i];
}
public Integer getJavaLine(int i){
return umpleJavaLines[i];
}
public Integer getLength(int i){
return umpleLengths[i];
}
public UmpleSourceData setFileNames(String... filenames){
umpleFileNames = filenames;
return this;
}
public UmpleSourceData setUmpleLines(Integer... umplelines){
umpleLines = umplelines;
return this;
}
public UmpleSourceData setJavaLines(Integer... javalines){
umpleJavaLines = javalines;
return this;
}
public UmpleSourceData setLengths(Integer... lengths){
umpleLengths = lengths;
return this;
}
public int size(){
return umpleFileNames.length;
}
}
}<<#
return realSb.toString();
}#>>!>>
}