KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > loskutov > bco > editors > BytecodeSourceMapper


1 package de.loskutov.bco.editors;
2
3 import java.io.FileInputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.InputStream JavaDoc;
6 import java.util.BitSet JavaDoc;
7 import java.util.WeakHashMap JavaDoc;
8 import java.util.zip.ZipEntry JavaDoc;
9 import java.util.zip.ZipFile JavaDoc;
10
11 import org.eclipse.core.resources.IFile;
12 import org.eclipse.core.resources.IResource;
13 import org.eclipse.core.runtime.IStatus;
14 import org.eclipse.debug.core.DebugException;
15 import org.eclipse.debug.internal.ui.contexts.DebugContextManager;
16 import org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener;
17 import org.eclipse.jdt.core.IClassFile;
18 import org.eclipse.jdt.core.IJavaElement;
19 import org.eclipse.jdt.core.IMember;
20 import org.eclipse.jdt.core.IPackageFragment;
21 import org.eclipse.jdt.core.IPackageFragmentRoot;
22 import org.eclipse.jdt.core.IType;
23 import org.eclipse.jdt.core.JavaModelException;
24 import org.eclipse.jdt.debug.core.IJavaReferenceType;
25 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
26 import org.eclipse.jdt.internal.core.BinaryType;
27 import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
28 import org.eclipse.jface.viewers.ISelection;
29 import org.eclipse.jface.viewers.IStructuredSelection;
30 import org.eclipse.ui.IWorkbenchPart;
31
32 import de.loskutov.bco.BytecodeOutlinePlugin;
33 import de.loskutov.bco.asm.DecompiledClass;
34 import de.loskutov.bco.asm.DecompilerClassVisitor;
35 import de.loskutov.bco.ui.JdtUtils;
36
37 /**
38  * @author Jochen Klein
39  * @author Andrei
40  */

41 public class BytecodeSourceMapper implements IDebugContextListener {
42
43     /** key is IClassFile, value is DecompiledClass */
44     private WeakHashMap JavaDoc classToDecompiled;
45     private IJavaReferenceType lastTypeInDebugger;
46     private String JavaDoc lastMethodInDebugger;
47
48     public BytecodeSourceMapper() {
49         super();
50         classToDecompiled = new WeakHashMap JavaDoc();
51         DebugContextManager.getDefault().addDebugContextListener(this);
52     }
53
54     public char[] getSource(IClassFile classFile, BitSet JavaDoc decompilerFlags) {
55         IType type;
56         try {
57             type = classFile.getType();
58         } catch (JavaModelException e) {
59             BytecodeOutlinePlugin.log(e, IStatus.ERROR);
60             return null;
61         }
62         if (!type.isBinary()) {
63             return null;
64         }
65         IBinaryType info = null;
66         try {
67             info = (IBinaryType) ((BinaryType) type).getElementInfo();
68         } catch (JavaModelException e) {
69             BytecodeOutlinePlugin.log(e, IStatus.ERROR);
70             return null;
71         }
72         if (info == null) {
73             return null;
74         }
75         return findSource(type, info, classFile, decompilerFlags);
76     }
77
78     public char[] getSource(IFile file, IClassFile cf, BitSet JavaDoc decompilerFlags) {
79         StringBuffer JavaDoc source = new StringBuffer JavaDoc();
80
81         DecompiledClass decompiledClass = decompile(source, file.getLocation()
82             .toOSString(), decompilerFlags);
83
84         classToDecompiled.put(cf, decompiledClass);
85
86         return source.toString().toCharArray();
87     }
88
89     /**
90      *
91      */

92     protected char[] findSource(IType type, IBinaryType info, IClassFile cf,
93         BitSet JavaDoc decompilerFlags) {
94
95         IPackageFragment pkgFrag = type.getPackageFragment();
96         IPackageFragmentRoot root = (IPackageFragmentRoot) pkgFrag.getParent();
97         String JavaDoc pkg = type.getPackageFragment().getElementName().replace(
98             '.', '/');
99
100         String JavaDoc classFile = new String JavaDoc(info.getFileName());
101         int p = classFile.lastIndexOf('/');
102         classFile = classFile.substring(p + 1);
103
104         StringBuffer JavaDoc source = new StringBuffer JavaDoc();
105         String JavaDoc location = null;
106         String JavaDoc className = pkg + "/" + classFile;
107         if (root.isArchive()) {
108             location = getArchivePath(root);
109             DecompiledClass decompiledClass = decompileFromArchive(
110                 source, location, className, decompilerFlags);
111             classToDecompiled.put(cf, decompiledClass);
112         } else {
113             try {
114                 location = root.getUnderlyingResource().getLocation()
115                     .toOSString()
116                     + "/" + className;
117                 DecompiledClass decompiledClass = decompile(
118                     source, location, decompilerFlags);
119                 classToDecompiled.put(cf, decompiledClass);
120             } catch (JavaModelException e) {
121                 BytecodeOutlinePlugin.log(e, IStatus.ERROR);
122             }
123         }
124
125         source.append("\n\n// DECOMPILED FROM: ");
126         source.append(location).append("\n");
127         return source.toString().toCharArray();
128     }
129
130     public int getDecompiledLine(IMember elt, IClassFile cf) {
131         DecompiledClass dc = (DecompiledClass) classToDecompiled.get(cf);
132         if (dc != null) {
133             String JavaDoc signature = JdtUtils.getMethodSignature(elt);
134             if (signature != null) {
135                 return dc.getDecompiledLine(signature);
136             }
137         }
138         return 0;
139     }
140
141     protected DecompiledClass decompile(StringBuffer JavaDoc source, String JavaDoc filePath,
142         BitSet JavaDoc decompilerFlags) {
143         FileInputStream JavaDoc inputStream = null;
144         DecompiledClass dc = null;
145         try {
146             inputStream = new FileInputStream JavaDoc(filePath);
147             dc = decompile(source, inputStream, decompilerFlags);
148         } catch (IOException JavaDoc e) {
149             source.append(e.toString());
150             BytecodeOutlinePlugin.log(e, IStatus.ERROR);
151         } finally {
152             if (inputStream != null) {
153                 try {
154                     inputStream.close();
155                 } catch (IOException JavaDoc e) {
156                     BytecodeOutlinePlugin.log(e, IStatus.ERROR);
157                 }
158             }
159         }
160         return dc;
161     }
162
163     protected DecompiledClass decompileFromArchive(StringBuffer JavaDoc source,
164         String JavaDoc archivePath, String JavaDoc className, BitSet JavaDoc decompilerFlags) {
165         if(archivePath == null){
166             return null;
167         }
168         InputStream JavaDoc inputStream = null;
169         DecompiledClass decompiledClass = null;
170         try {
171             ZipFile JavaDoc zf = new ZipFile JavaDoc(archivePath);
172             ZipEntry JavaDoc ze = zf.getEntry(className);
173             inputStream = zf.getInputStream(ze);
174             decompiledClass = decompile(source, inputStream, decompilerFlags);
175         } catch (IOException JavaDoc e) {
176             source.append(e.toString());
177             BytecodeOutlinePlugin.log(e, IStatus.ERROR);
178         } finally {
179             if (inputStream != null) {
180                 try {
181                     inputStream.close();
182                 } catch (IOException JavaDoc e) {
183                     BytecodeOutlinePlugin.log(e, IStatus.ERROR);
184                 }
185             }
186         }
187         return decompiledClass;
188     }
189
190     private DecompiledClass decompile(StringBuffer JavaDoc source, InputStream JavaDoc is,
191         BitSet JavaDoc decompilerFlags) throws IOException JavaDoc {
192         DecompiledClass decompiledClass = DecompilerClassVisitor
193             .getDecompiledClass(is, null, null, decompilerFlags, null);
194         source.append(decompiledClass.getText());
195         return decompiledClass;
196     }
197
198     private String JavaDoc getArchivePath(IPackageFragmentRoot root) {
199         String JavaDoc archivePath = null;
200         IResource resource;
201
202         try {
203             if ((resource = root.getUnderlyingResource()) != null) {
204                 // jar in workspace
205
archivePath = resource.getLocation().toOSString();
206             } else {
207                 // external jar
208
archivePath = root.getPath().toOSString();
209             }
210         } catch (JavaModelException e) {
211             BytecodeOutlinePlugin.log(e, IStatus.ERROR);
212         }
213         return archivePath;
214     }
215
216     protected IJavaElement findElement(IClassFile cf, int decompiledLine) {
217         DecompiledClass dc = (DecompiledClass) classToDecompiled.get(cf);
218         if (dc != null) {
219             return dc.getJavaElement(decompiledLine, cf);
220         }
221         return cf;
222     }
223
224     public int mapToSource(int decompiledLine, IClassFile cf) {
225         if (cf == null) {
226             return 0;
227         }
228         DecompiledClass dc = (DecompiledClass) classToDecompiled.get(cf);
229         if (dc != null) {
230             return dc.getSourceLine(decompiledLine);
231         }
232         return 0;
233     }
234
235     /**
236      *
237      * @param cf
238      * @return mapped class or null
239      */

240     public DecompiledClass getDecompiledClass(IClassFile cf){
241         if(cf == null){
242             return null;
243         }
244         return (DecompiledClass) classToDecompiled.get(cf);
245     }
246
247     public int mapToDecompiled(int sourceLine, IClassFile cf) {
248         if (cf == null) {
249             return 0;
250         }
251         DecompiledClass dc = (DecompiledClass) classToDecompiled.get(cf);
252         if (dc != null) {
253             return dc.getDecompiledLine(sourceLine);
254         }
255         return 0;
256     }
257
258     public void contextActivated(ISelection selection, IWorkbenchPart part) {
259         if(selection instanceof IStructuredSelection){
260             IStructuredSelection sSelection = (IStructuredSelection) selection;
261             if(sSelection.isEmpty()){
262                 return;
263             }
264             Object JavaDoc element = sSelection.getFirstElement();
265             if(element instanceof JDIStackFrame){
266                 JDIStackFrame frame = (JDIStackFrame) element;
267                 try {
268                     lastTypeInDebugger = frame.getReferenceType();
269                     lastMethodInDebugger = frame.getMethodName() + frame.getSignature();
270                 } catch (DebugException e) {
271                     BytecodeOutlinePlugin.log(e, IStatus.ERROR);
272                 }
273             }
274         }
275     }
276
277     public void contextChanged(ISelection selection, IWorkbenchPart part) {
278         contextActivated(selection, part);
279     }
280
281     public IJavaReferenceType getLastTypeInDebugger() {
282         return lastTypeInDebugger;
283     }
284
285     public int mapDebuggerToDecompiled(IClassFile cf) {
286         if(cf == null || lastMethodInDebugger == null){
287             return -1;
288         }
289         DecompiledClass dc = (DecompiledClass) classToDecompiled.get(cf);
290         if (dc != null) {
291             return dc.getDecompiledLine(lastMethodInDebugger);
292         }
293         return -1;
294     }
295
296 }
297
Popular Tags