001: package org.drools.eclipse.debug;
002:
003: import org.drools.eclipse.DroolsEclipsePlugin;
004: import org.eclipse.core.resources.IResource;
005: import org.eclipse.core.runtime.CoreException;
006: import org.eclipse.core.runtime.IAdaptable;
007: import org.eclipse.core.runtime.IStatus;
008: import org.eclipse.core.runtime.Status;
009: import org.eclipse.debug.core.DebugEvent;
010: import org.eclipse.debug.core.DebugException;
011: import org.eclipse.debug.core.DebugPlugin;
012: import org.eclipse.debug.core.IStatusHandler;
013: import org.eclipse.debug.core.model.IDebugTarget;
014: import org.eclipse.debug.core.model.ISourceLocator;
015: import org.eclipse.debug.core.model.IThread;
016: import org.eclipse.debug.core.model.IValue;
017: import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
018: import org.eclipse.jdt.core.IJavaElement;
019: import org.eclipse.jdt.core.IJavaProject;
020: import org.eclipse.jdt.core.JavaCore;
021: import org.eclipse.jdt.debug.core.IJavaClassType;
022: import org.eclipse.jdt.debug.core.IJavaDebugTarget;
023: import org.eclipse.jdt.debug.core.IJavaObject;
024: import org.eclipse.jdt.debug.core.IJavaReferenceType;
025: import org.eclipse.jdt.debug.core.IJavaStackFrame;
026: import org.eclipse.jdt.debug.core.IJavaThread;
027: import org.eclipse.jdt.debug.core.IJavaType;
028: import org.eclipse.jdt.debug.core.IJavaValue;
029: import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
030: import org.eclipse.jdt.debug.eval.ICompiledExpression;
031: import org.eclipse.jdt.debug.eval.IEvaluationListener;
032: import org.eclipse.jdt.debug.eval.IEvaluationResult;
033: import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
034:
035: public class DebugUtil {
036:
037: public static final int INFO_EVALUATION_STACK_FRAME = 111;
038: private static IStatus fgNeedStackFrame = new Status(IStatus.INFO,
039: DroolsEclipsePlugin.getUniqueIdentifier(),
040: INFO_EVALUATION_STACK_FRAME,
041: "Provides thread context for an evaluation", null);
042: private static IStatusHandler fgStackFrameProvider;
043:
044: public static IValue getValueByExpression(String expression,
045: IValue value) {
046: if (!(value instanceof IJavaObject)) {
047: return null;
048: }
049: IJavaObject javaValue = (IJavaObject) value;
050: try {
051: IJavaType type = javaValue.getJavaType();
052: if (!(type instanceof IJavaClassType)) {
053: return null;
054: }
055: IJavaStackFrame stackFrame = getStackFrame(javaValue);
056: if (stackFrame == null) {
057: return null;
058: }
059:
060: // find the project the snippets will be compiled in.
061: ISourceLocator locator = javaValue.getLaunch()
062: .getSourceLocator();
063: Object sourceElement = null;
064: if (locator instanceof ISourceLookupDirector) {
065: String[] sourcePaths = ((IJavaClassType) type)
066: .getSourcePaths(null);
067: if (sourcePaths != null && sourcePaths.length > 0) {
068: sourceElement = ((ISourceLookupDirector) locator)
069: .getSourceElement(sourcePaths[0]);
070: }
071: if (!(sourceElement instanceof IJavaElement)
072: && sourceElement instanceof IAdaptable) {
073: sourceElement = ((IAdaptable) sourceElement)
074: .getAdapter(IJavaElement.class);
075: }
076: }
077: if (sourceElement == null) {
078: sourceElement = locator.getSourceElement(stackFrame);
079: if (!(sourceElement instanceof IJavaElement)
080: && sourceElement instanceof IAdaptable) {
081: Object newSourceElement = ((IAdaptable) sourceElement)
082: .getAdapter(IJavaElement.class);
083: // if the source is a drl during the execution of the rule
084: if (newSourceElement != null) {
085: sourceElement = newSourceElement;
086: }
087: }
088: }
089: IJavaProject project = null;
090: if (sourceElement instanceof IJavaElement) {
091: project = ((IJavaElement) sourceElement)
092: .getJavaProject();
093: } else if (sourceElement instanceof IResource) {
094: IJavaProject resourceProject = JavaCore
095: .create(((IResource) sourceElement)
096: .getProject());
097: if (resourceProject.exists()) {
098: project = resourceProject;
099: }
100: }
101: if (project == null) {
102: return null;
103: }
104:
105: IAstEvaluationEngine evaluationEngine = JDIDebugPlugin
106: .getDefault().getEvaluationEngine(
107: project,
108: (IJavaDebugTarget) stackFrame
109: .getDebugTarget());
110:
111: EvaluationBlock evaluationBlock = new EvaluationBlock(
112: javaValue, (IJavaReferenceType) type,
113: (IJavaThread) stackFrame.getThread(),
114: evaluationEngine);
115: return evaluationBlock.evaluate(expression);
116:
117: } catch (CoreException e) {
118: DroolsEclipsePlugin.log(e);
119: }
120: return null;
121: }
122:
123: /**
124: * Return the current stack frame context, or a valid stack frame for the
125: * given value.
126: */
127: private static IJavaStackFrame getStackFrame(IValue value)
128: throws CoreException {
129: IStatusHandler handler = getStackFrameProvider();
130: if (handler != null) {
131: IJavaStackFrame stackFrame = (IJavaStackFrame) handler
132: .handleStatus(fgNeedStackFrame, value);
133: if (stackFrame != null) {
134: return stackFrame;
135: }
136: }
137: IDebugTarget target = value.getDebugTarget();
138: IJavaDebugTarget javaTarget = (IJavaDebugTarget) target
139: .getAdapter(IJavaDebugTarget.class);
140: if (javaTarget != null) {
141: IThread[] threads = javaTarget.getThreads();
142: for (int i = 0; i < threads.length; i++) {
143: IThread thread = threads[i];
144: if (thread.isSuspended()) {
145: return (IJavaStackFrame) thread.getTopStackFrame();
146: }
147: }
148: }
149: return null;
150: }
151:
152: private static IStatusHandler getStackFrameProvider() {
153: if (fgStackFrameProvider == null) {
154: fgStackFrameProvider = DebugPlugin.getDefault()
155: .getStatusHandler(fgNeedStackFrame);
156: }
157: return fgStackFrameProvider;
158: }
159:
160: private static class EvaluationBlock implements IEvaluationListener {
161:
162: private IJavaObject fEvaluationValue;
163: private IJavaReferenceType fEvaluationType;
164: private IJavaThread fThread;
165: private IAstEvaluationEngine fEvaluationEngine;
166: private IEvaluationResult fResult;
167:
168: public EvaluationBlock(IJavaObject value,
169: IJavaReferenceType type, IJavaThread thread,
170: IAstEvaluationEngine evaluationEngine) {
171: fEvaluationValue = value;
172: fEvaluationType = type;
173: fThread = thread;
174: fEvaluationEngine = evaluationEngine;
175: }
176:
177: public void evaluationComplete(IEvaluationResult result) {
178: synchronized (this ) {
179: fResult = result;
180: this .notify();
181: }
182: }
183:
184: public IJavaValue evaluate(String snippet)
185: throws DebugException {
186: ICompiledExpression compiledExpression = fEvaluationEngine
187: .getCompiledExpression(snippet, fEvaluationType);
188: if (compiledExpression.hasErrors()) {
189: String[] errorMessages = compiledExpression
190: .getErrorMessages();
191: String message = "";
192:
193: for (int i = 0; i < errorMessages.length; i++) {
194: message += errorMessages[i] + "\n";
195: }
196: throw new DebugException(new Status(IStatus.ERROR,
197: DroolsEclipsePlugin.PLUGIN_ID,
198: DroolsEclipsePlugin.INTERNAL_ERROR,
199: "Error when compiling snippet " + snippet
200: + ": " + message, null));
201: }
202: fResult = null;
203: fEvaluationEngine.evaluateExpression(compiledExpression,
204: fEvaluationValue, fThread, this ,
205: DebugEvent.EVALUATION_IMPLICIT, false);
206: synchronized (this ) {
207: if (fResult == null) {
208: try {
209: this .wait();
210: } catch (InterruptedException e) {
211: }
212: }
213: }
214: if (fResult == null) {
215: return null;
216: }
217: if (fResult.hasErrors()) {
218: return null;
219: }
220: return fResult.getValue();
221: }
222: }
223:
224: }
|