001: /*****************************************************************************************
002: * Copyright (c) 2004 Andrei Loskutov. All rights reserved. This program and the
003: * accompanying materials are made available under the terms of the BSD License which
004: * accompanies this distribution, and is available at
005: * http://www.opensource.org/licenses/bsd-license.php Contributor: Andrei Loskutov -
006: * initial API and implementation
007: ****************************************************************************************/package de.loskutov.bco.compare;
008:
009: import java.io.ByteArrayInputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.util.BitSet;
013:
014: import org.eclipse.compare.BufferedContent;
015: import org.eclipse.compare.CompareUI;
016: import org.eclipse.compare.ITypedElement;
017: import org.eclipse.compare.structuremergeviewer.IStructureComparator;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IStatus;
020: import org.eclipse.core.runtime.Status;
021: import org.eclipse.jdt.core.IJavaElement;
022: import org.eclipse.swt.graphics.Image;
023: import org.eclipse.swt.widgets.Display;
024:
025: import de.loskutov.bco.BytecodeOutlinePlugin;
026: import de.loskutov.bco.asm.DecompiledClass;
027: import de.loskutov.bco.asm.DecompilerClassVisitor;
028: import de.loskutov.bco.ui.JdtUtils;
029:
030: /**
031: * @author Andrei
032: */
033: public class TypedElement extends BufferedContent implements
034: ITypedElement, IStructureComparator {
035:
036: private final String name;
037:
038: private String type;
039:
040: private final String methodName;
041:
042: private final IJavaElement element;
043:
044: /** used by Eclipse to recognize appropriated viewer */
045: public static final String TYPE_BYTECODE = "bytecode";
046:
047: /** used by Eclipse to recognize appropriated viewer */
048: public static final String TYPE_ASM_IFIER = "java";
049:
050: private final BitSet modes;
051:
052: /**
053: * Constructor for TypedElement.
054: * @param name
055: * @param type
056: * @param element
057: * @param modes
058: */
059: public TypedElement(String name, String methodName, String type,
060: IJavaElement element, BitSet modes) {
061: super ();
062: this .name = name;
063: this .methodName = methodName;
064: this .type = type;
065: this .element = element;
066: this .modes = modes;
067: }
068:
069: /**
070: * @see org.eclipse.compare.ITypedElement#getName()
071: */
072: public String getName() {
073: return name;
074: }
075:
076: /**
077: * @see org.eclipse.compare.ITypedElement#getType()
078: */
079: public String getType() {
080: return type;
081: }
082:
083: /**
084: * @param type The type to set.
085: */
086: protected void setType(String type) {
087: this .type = type;
088: }
089:
090: /**
091: * @return name
092: */
093: public String getElementName() {
094: return JdtUtils.getElementName(element);
095: }
096:
097: public Image getImage() {
098: // default image for .class files
099: return CompareUI.getImage("class");
100: }
101:
102: public Object[] getChildren() {
103: return new TypedElement[0];
104: }
105:
106: protected InputStream createStream() throws CoreException {
107: InputStream stream = JdtUtils.createInputStream(element);
108: if (stream == null) {
109: throw new CoreException(new Status(IStatus.ERROR,
110: "de.loskutov.bco", -1,
111: "cannot get bytecode from class file", null));
112: }
113: DecompiledClass decompiledClass = null;
114: try {
115: decompiledClass = DecompilerClassVisitor
116: .getDecompiledClass(stream, null, methodName,
117: modes, null);
118: } catch (IOException e) {
119: throw new CoreException(new Status(IStatus.ERROR,
120: "de.loskutov.bco", -1, "cannot get bytecode dump",
121: e));
122: } catch (UnsupportedClassVersionError e) {
123: throw new CoreException(new Status(IStatus.ERROR,
124: "de.loskutov.bco", -1,
125: "Error caused by attempt to load class compiled with Java version which"
126: + " is not supported by current JVM", e));
127: } finally {
128: try {
129: stream.close();
130: } catch (IOException e) {
131: BytecodeOutlinePlugin.log(e, IStatus.WARNING);
132: }
133: }
134: final byte[] bytes = decompiledClass.getText().getBytes();
135: // use internal buffering to prevent multiple calls to this method
136: Display.getDefault().syncExec(new Runnable() {
137: public void run() {
138: setContent(bytes);
139: }
140: });
141:
142: return new ByteArrayInputStream(bytes);
143: }
144:
145: /**
146: *
147: * @param mode one of BCOConstants.F_* modes
148: * @param value
149: */
150: public void setMode(int mode, boolean value) {
151: modes.set(mode, value);
152: // force create new stream
153: discardBuffer();
154: }
155: }
|