Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 145480

Summary: [Actions] OperationHistoryActionHandler#getAdapter() return instance if match with interface
Product: [Eclipse Project] Platform Reporter: Dennis Nguyen <dennis.nguyen.06>
Component: UIAssignee: Paul Webster <pwebster>
Status: RESOLVED INVALID QA Contact:
Severity: normal    
Priority: P5 CC: bokowski
Version: 3.2Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Dennis Nguyen CLA 2006-06-06 03:45:54 EDT
Package org.eclipse.ui.operations
class OperationHistoryActionHandler#getAdapter(Class adapter) is an implementation of org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class). 

It is my expectation that the above method returns an instance of the adapter class passing in as argument. However, the implementation actually compares the adapter class with interface IUndoContext, IProgressMonitor, IWorkbenchWindow and IWorkbenchPart. In my specific case, we passed a subclass of IUndoContext and expected the "undoContext" instance, but received null as our subclass is not equal to IUndoContext.class.

================================================
Example Problem:

>>if (adapter.equals(IUndoContext.class)) {
>>	return undoContext;
>>}
================================================
Could be somethings like:

if ((undoContext != null) && (adapter.equals(undoContext.class))) {
	return undoContext;
}

================================================
Comment 1 Paul Webster CLA 2006-06-06 09:24:36 EDT
The adapters are meant to support adaptation to a well known interface for another object.  In this case, it's IUndoContext.

Examples of the adaptations I was able to find are all adapter.equals(IUndoContext.class) or adapter==IUndoContext.class.  Some implementations of getAdapter(*) go to the workbench adapter factories, which would allow other plugins to register unknown adapters at runtime (like your sublcass).

You will have to adapt to IUndoContext and then check with instanceof and downcast.

BTW: checking for undoContext.class would prevent IUndoContext adaptation and your subclass of IUndoContext, since undoContext.class would equal the implementation class of undoContext, not any interfaces it implements.

Later,
PW
Comment 2 Dennis Nguyen CLA 2006-07-16 20:08:51 EDT
> BTW: checking for undoContext.class would prevent IUndoContext adaptation and
> your subclass of IUndoContext, since undoContext.class would equal the
> implementation class of undoContext, not any interfaces it implements.

The comparing with undoContext.class is actually coded in OperationHistoryActionHandler#getAdapter(Class adapter), and as you commented, it is not working as intended. Would something like: 

"adapter instanceof IUndoContext"

works ?

thank you
Comment 3 Boris Bokowski CLA 2006-09-12 15:09:52 EDT
This one might have been fixed as part of bug 156581.
Comment 4 Boris Bokowski CLA 2007-06-22 09:33:21 EDT
The recommended pattern is to use "instanceof IUndoContext" rather than "adapter.equals(IUndoContext.class)". This is what we do in Util.getAdapter().
Comment 5 Dennis Nguyen CLA 2007-06-24 19:33:01 EDT
Actually, this is not a bug, but for my mistakes. Close as invalid.