KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > core > logicalstructures > JavaLogicalStructure


1 /*******************************************************************************
2  * Copyright (c) 2004, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.debug.core.logicalstructures;
12
13 import com.ibm.icu.text.MessageFormat;
14
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IAdaptable;
18 import org.eclipse.core.runtime.IConfigurationElement;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.debug.core.DebugEvent;
22 import org.eclipse.debug.core.DebugException;
23 import org.eclipse.debug.core.DebugPlugin;
24 import org.eclipse.debug.core.ILogicalStructureType;
25 import org.eclipse.debug.core.IStatusHandler;
26 import org.eclipse.debug.core.model.IDebugTarget;
27 import org.eclipse.debug.core.model.ISourceLocator;
28 import org.eclipse.debug.core.model.IThread;
29 import org.eclipse.debug.core.model.IValue;
30 import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
31 import org.eclipse.jdt.core.IJavaElement;
32 import org.eclipse.jdt.core.IJavaProject;
33 import org.eclipse.jdt.core.JavaCore;
34 import org.eclipse.jdt.debug.core.IJavaClassType;
35 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
36 import org.eclipse.jdt.debug.core.IJavaInterfaceType;
37 import org.eclipse.jdt.debug.core.IJavaObject;
38 import org.eclipse.jdt.debug.core.IJavaReferenceType;
39 import org.eclipse.jdt.debug.core.IJavaStackFrame;
40 import org.eclipse.jdt.debug.core.IJavaThread;
41 import org.eclipse.jdt.debug.core.IJavaType;
42 import org.eclipse.jdt.debug.core.IJavaValue;
43 import org.eclipse.jdt.debug.core.IJavaVariable;
44 import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
45 import org.eclipse.jdt.debug.eval.ICompiledExpression;
46 import org.eclipse.jdt.debug.eval.IEvaluationListener;
47 import org.eclipse.jdt.debug.eval.IEvaluationResult;
48 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
49
50 public class JavaLogicalStructure implements ILogicalStructureType {
51
52     private static IStatusHandler fgStackFrameProvider;
53
54     /**
55      * Fully qualified type name.
56      */

57     private String JavaDoc fType;
58     /**
59      * Indicate if this java logical structure should be used on object
60      * instance of subtype of the specified type.
61      */

62     private boolean fSubtypes;
63     /**
64      * Code snippet to evaluate to create the logical value.
65      */

66     private String JavaDoc fValue;
67     /**
68      * Description of the logical structure.
69      */

70     private String JavaDoc fDescription;
71     /**
72      * Name and associated code snippet of the variables of the logical value.
73      */

74     private String JavaDoc[][] fVariables;
75     /**
76      * The plugin identifier of the plugin which contributed this logical structure
77      * or <code>null</code> if this structure was defined by the user.
78      */

79     private String JavaDoc fContributingPluginId= null;
80     
81     /**
82      * Performs the evaluations.
83      */

84     private class EvaluationBlock implements IEvaluationListener {
85         
86         private IJavaObject fEvaluationValue;
87         private IJavaReferenceType fEvaluationType;
88         private IJavaThread fThread;
89         private IAstEvaluationEngine fEvaluationEngine;
90         private IEvaluationResult fResult;
91
92         /**
93          * Constructor
94          * @param value
95          * @param type
96          * @param thread
97          * @param evaluationEngine
98          */

99         public EvaluationBlock(IJavaObject value, IJavaReferenceType type, IJavaThread thread, IAstEvaluationEngine evaluationEngine) {
100             fEvaluationValue= value;
101             fEvaluationType= type;
102             fThread= thread;
103             fEvaluationEngine= evaluationEngine;
104         }
105
106         /* (non-Javadoc)
107          * @see org.eclipse.jdt.debug.eval.IEvaluationListener#evaluationComplete(org.eclipse.jdt.debug.eval.IEvaluationResult)
108          */

109         public void evaluationComplete(IEvaluationResult result) {
110             synchronized(this) {
111                 fResult= result;
112                 this.notify();
113             }
114         }
115
116         /**
117          * Evaluates the specified snippet and returns the <code>IJavaValue</code> from the evaluation
118          * @param snippet the snippet to evaluate
119          * @return the <code>IJavaValue</code> from the evaluation
120          * @throws DebugException
121          */

122         public IJavaValue evaluate(String JavaDoc snippet) throws DebugException {
123             ICompiledExpression compiledExpression= fEvaluationEngine.getCompiledExpression(snippet, fEvaluationType);
124             if (compiledExpression.hasErrors()) {
125                 String JavaDoc[] errorMessages = compiledExpression.getErrorMessages();
126                 log(errorMessages);
127                 return new JavaStructureErrorValue(errorMessages, fEvaluationValue);
128             }
129             fResult= null;
130             fEvaluationEngine.evaluateExpression(compiledExpression, fEvaluationValue, fThread, this, DebugEvent.EVALUATION_IMPLICIT, false);
131             synchronized(this) {
132                 if (fResult == null) {
133                     try {
134                         this.wait();
135                     } catch (InterruptedException JavaDoc e) {
136                     }
137                 }
138             }
139             if (fResult == null) {
140                 return new JavaStructureErrorValue(LogicalStructuresMessages.JavaLogicalStructure_1, fEvaluationValue);
141             }
142             if (fResult.hasErrors()) {
143                 DebugException exception = fResult.getException();
144                 String JavaDoc message;
145                 if (exception != null) {
146                     message= MessageFormat.format(LogicalStructuresMessages.JavaLogicalStructure_2, new String JavaDoc[] { exception.getMessage() });
147                 } else {
148                     message= LogicalStructuresMessages.JavaLogicalStructure_3;
149                 }
150                 return new JavaStructureErrorValue(message, fEvaluationValue);
151             }
152             return fResult.getValue();
153         }
154         
155         /**
156          * Logs the given error messages if this logical structure was contributed
157          * via extension.
158          */

159         private void log(String JavaDoc[] messages) {
160             if (isContributed()) {
161                 StringBuffer JavaDoc log= new StringBuffer JavaDoc();
162                 for (int i = 0; i < messages.length; i++) {
163                     log.append(messages[i]).append('\n');
164                 }
165                 JDIDebugPlugin.log(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IStatus.ERROR, log.toString(),null));
166             }
167         }
168     }
169
170     /**
171      * Constructor from parameters.
172      */

173     public JavaLogicalStructure(String JavaDoc type, boolean subtypes, String JavaDoc value, String JavaDoc description, String JavaDoc[][] variables) {
174         fType= type;
175         fSubtypes= subtypes;
176         fValue= value;
177         fDescription= description;
178         fVariables= variables;
179     }
180
181     /**
182      * Constructor from configuration element.
183      */

184     public JavaLogicalStructure(IConfigurationElement configurationElement) throws CoreException {
185         fType= configurationElement.getAttribute("type"); //$NON-NLS-1$
186
if (fType == null) {
187             throw new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.INTERNAL_ERROR, LogicalStructuresMessages.JavaLogicalStructures_0, null));
188         }
189         fSubtypes= Boolean.valueOf(configurationElement.getAttribute("subtypes")).booleanValue(); //$NON-NLS-1$
190
fValue= configurationElement.getAttribute("value"); //$NON-NLS-1$
191
fDescription= configurationElement.getAttribute("description"); //$NON-NLS-1$
192
if (fDescription == null) {
193             throw new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.INTERNAL_ERROR, LogicalStructuresMessages.JavaLogicalStructures_4, null));
194         }
195         IConfigurationElement[] variableElements= configurationElement.getChildren("variable"); //$NON-NLS-1$
196
if (fValue== null && variableElements.length == 0) {
197             throw new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.INTERNAL_ERROR, LogicalStructuresMessages.JavaLogicalStructures_1, null));
198         }
199         fVariables= new String JavaDoc[variableElements.length][2];
200         for (int j= 0; j < fVariables.length; j++) {
201             String JavaDoc variableName= variableElements[j].getAttribute("name"); //$NON-NLS-1$
202
if (variableName == null) {
203                 throw new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.INTERNAL_ERROR, LogicalStructuresMessages.JavaLogicalStructures_2, null));
204             }
205             fVariables[j][0]= variableName;
206             String JavaDoc variableValue= variableElements[j].getAttribute("value"); //$NON-NLS-1$
207
if (variableValue == null) {
208                 throw new CoreException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.INTERNAL_ERROR, LogicalStructuresMessages.JavaLogicalStructures_3, null));
209             }
210             fVariables[j][1]= variableValue;
211         }
212         fContributingPluginId= configurationElement.getContributor().getName();
213     }
214     
215     /**
216      * @see org.eclipse.debug.core.model.ILogicalStructureTypeDelegate#providesLogicalStructure(IValue)
217      */

218     public boolean providesLogicalStructure(IValue value) {
219         if (!(value instanceof IJavaObject)) {
220             return false;
221         }
222         return getType((IJavaObject) value) != null;
223     }
224
225     /**
226      * @see org.eclipse.debug.core.model.ILogicalStructureTypeDelegate#getLogicalStructure(IValue)
227      */

228     public IValue getLogicalStructure(IValue value) {
229         if (!(value instanceof IJavaObject)) {
230             return value;
231         }
232         IJavaObject javaValue= (IJavaObject) value;
233         try {
234             IJavaReferenceType type = getType(javaValue);
235             if (type == null) {
236                 return value;
237             }
238             IJavaStackFrame stackFrame= getStackFrame(javaValue);
239             if (stackFrame == null) {
240                 return value;
241             }
242             
243             // find the project the snippets will be compiled in.
244
ISourceLocator locator= javaValue.getLaunch().getSourceLocator();
245             Object JavaDoc sourceElement= null;
246             if (locator instanceof ISourceLookupDirector) {
247                 String JavaDoc[] sourcePaths= type.getSourcePaths(null);
248                 if (sourcePaths != null && sourcePaths.length > 0) {
249                     sourceElement= ((ISourceLookupDirector) locator).getSourceElement(sourcePaths[0]);
250                 }
251                 if (!(sourceElement instanceof IJavaElement) && sourceElement instanceof IAdaptable) {
252                     sourceElement = ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
253                 }
254             }
255             if (sourceElement == null) {
256                 sourceElement = locator.getSourceElement(stackFrame);
257                 if (!(sourceElement instanceof IJavaElement) && sourceElement instanceof IAdaptable) {
258                     sourceElement = ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
259                 }
260             }
261             IJavaProject project= null;
262             if (sourceElement instanceof IJavaElement) {
263                 project= ((IJavaElement) sourceElement).getJavaProject();
264             } else if (sourceElement instanceof IResource) {
265                 IJavaProject resourceProject = JavaCore.create(((IResource)sourceElement).getProject());
266                 if (resourceProject.exists()) {
267                     project= resourceProject;
268                 }
269             }
270             if (project == null) {
271                 return value;
272             }
273             
274             IAstEvaluationEngine evaluationEngine= JDIDebugPlugin.getDefault().getEvaluationEngine(project, (IJavaDebugTarget)stackFrame.getDebugTarget());
275             
276             EvaluationBlock evaluationBlock= new EvaluationBlock(javaValue, type, (IJavaThread)stackFrame.getThread(), evaluationEngine);
277             if (fValue == null) {
278                 // evaluate each variable
279
IJavaVariable[] variables= new IJavaVariable[fVariables.length];
280                 for (int i= 0; i < fVariables.length; i++) {
281                     variables[i]= new JDIPlaceholderVariable(fVariables[i][0], evaluationBlock.evaluate(fVariables[i][1]));
282                 }
283                 return new LogicalObjectStructureValue(javaValue, variables);
284             }
285             // evaluate the logical value
286
return evaluationBlock.evaluate(fValue);
287
288         } catch (CoreException e) {
289             JDIDebugPlugin.log(e);
290         }
291         return value;
292     }
293     
294     /**
295      * Returns the <code>IJavaReferenceType</code> from the specified <code>IJavaObject</code>
296      * @param value
297      * @return the <code>IJavaReferenceType</code> from the specified <code>IJavaObject</code>
298      */

299     private IJavaReferenceType getType(IJavaObject value) {
300         try {
301             IJavaType type= value.getJavaType();
302             if (!(type instanceof IJavaClassType)) {
303                 return null;
304             }
305             IJavaClassType classType= (IJavaClassType) type;
306             if (classType.getName().equals(fType)) {
307                 // found the type
308
return classType;
309             }
310             if (!fSubtypes) {
311                 // if not checking the subtypes, stop here
312
return null;
313             }
314             IJavaClassType superClass= classType.getSuperclass();
315             while (superClass != null) {
316                 if (superClass.getName().equals(fType)) {
317                     // found the type, it's a super class
318
return superClass;
319                 }
320                 superClass= superClass.getSuperclass();
321             }
322             IJavaInterfaceType[] superInterfaces= classType.getAllInterfaces();
323             for (int i= 0; i < superInterfaces.length; i++) {
324                 if (superInterfaces[i].getName().equals(fType)) {
325                     // found the type, it's a super interface
326
return superInterfaces[i];
327                 }
328             }
329         } catch (DebugException e) {
330             JDIDebugPlugin.log(e);
331             return null;
332         }
333         return null;
334     }
335
336     /**
337      * Return the current stack frame context, or a valid stack frame for the given value.
338      * @param value
339      * @return the current stack frame context, or a valid stack frame for the given value.
340      * @throws CoreException
341      */

342     private IJavaStackFrame getStackFrame(IValue value) throws CoreException {
343         IStatusHandler handler = getStackFrameProvider();
344         if (handler != null) {
345             IJavaStackFrame stackFrame = (IJavaStackFrame)handler.handleStatus(JDIDebugPlugin.STATUS_GET_EVALUATION_FRAME, value);
346             if (stackFrame != null) {
347                 return stackFrame;
348             }
349         }
350         IDebugTarget target = value.getDebugTarget();
351         IJavaDebugTarget javaTarget = (IJavaDebugTarget) target.getAdapter(IJavaDebugTarget.class);
352         if (javaTarget != null) {
353             IThread[] threads = javaTarget.getThreads();
354             for (int i = 0; i < threads.length; i++) {
355                 IThread thread = threads[i];
356                 if (thread.isSuspended()) {
357                     return (IJavaStackFrame)thread.getTopStackFrame();
358                 }
359             }
360         }
361         return null;
362     }
363     
364     /**
365      * Returns the singleton stackframe provider
366      * @return the singleton stackframe provider
367      */

368     private static IStatusHandler getStackFrameProvider() {
369         if (fgStackFrameProvider == null) {
370             fgStackFrameProvider = DebugPlugin.getDefault().getStatusHandler(JDIDebugPlugin.STATUS_GET_EVALUATION_FRAME);
371         }
372         return fgStackFrameProvider;
373     }
374     
375     /**
376      * Returns if this logical structure should be used for subtypes too.
377      * @return if this logical structure should be used for subtypes too.
378      */

379     public boolean isSubtypes() {
380         return fSubtypes;
381     }
382     
383     /**
384      * Sets if this logical structure should be used for subtypes or not.
385      * @param subtypes
386      */

387     public void setSubtypes(boolean subtypes) {
388         fSubtypes = subtypes;
389     }
390     
391     /**
392      * Returns the name of the type this logical structure should be used for.
393      * @return the name of the type this logical structure should be used for.
394      */

395     public String JavaDoc getQualifiedTypeName() {
396         return fType;
397     }
398     /**
399      * Sets the name of the type this logical structure should be used for.
400      * @param type
401      */

402     public void setType(String JavaDoc type) {
403         fType = type;
404     }
405     /**
406      * Returns the code snippet to use to generate the logical structure.
407      * @return the code snippet to use to generate the logical structure.
408      */

409     public String JavaDoc getValue() {
410         return fValue;
411     }
412     /**
413      * Sets the code snippet to use to generate the logical structure.
414      * @param value
415      */

416     public void setValue(String JavaDoc value) {
417         fValue = value;
418     }
419     /**
420      * Returns the variables of this logical structure.
421      * @return the variables of this logical structure.
422      */

423     public String JavaDoc[][] getVariables() {
424         return fVariables;
425     }
426     /**
427      * Sets the variables of this logical structure.
428      * @param variables
429      */

430     public void setVariables(String JavaDoc[][] variables) {
431         fVariables = variables;
432     }
433     /**
434      * Set the description of this logical structure.
435      * @param description
436      */

437     public void setDescription(String JavaDoc description) {
438         fDescription = description;
439     }
440
441     /* (non-Javadoc)
442      * @see org.eclipse.debug.core.model.ILogicalStructureTypeDelegate2#getDescription(org.eclipse.debug.core.model.IValue)
443      */

444     public String JavaDoc getDescription(IValue value) {
445         return getDescription();
446     }
447     
448     /* (non-Javadoc)
449      * @see org.eclipse.debug.core.ILogicalStructureType#getDescription()
450      */

451     public String JavaDoc getDescription() {
452         return fDescription;
453     }
454     
455     /**
456      * Indicates if this logical structure was contributed by a plug-in
457      * or defined by a user.
458      * @return if this logical structure is contributed
459      */

460     public boolean isContributed() {
461         return fContributingPluginId != null;
462     }
463     
464     /**
465      * Returns the plugin identifier of the plugin which contributed this logical
466      * structure or <code>null</code> if this structure was defined by the user.
467      * @return the plugin identifier of the plugin which contributed this
468      * structure or <code>null</code>
469      */

470     public String JavaDoc getContributingPluginId() {
471         return fContributingPluginId;
472     }
473
474     /* (non-Javadoc)
475      * @see org.eclipse.debug.core.ILogicalStructureType#getId()
476      */

477     public String JavaDoc getId() {
478         return JDIDebugPlugin.getUniqueIdentifier() + fType + fDescription;
479     }
480 }
481
Popular Tags