Bug 232626 - [api] JavaStructureBridge.acceptObject() tests using instanceof IJavaElement
Summary: [api] JavaStructureBridge.acceptObject() tests using instanceof IJavaElement
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Mylyn (show other bugs)
Version: dev   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P2 enhancement (vote)
Target Milestone: 3.1   Edit
Assignee: Andrew Eisenberg CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2008-05-16 18:40 EDT by Andrew Eisenberg CLA
Modified: 2009-01-15 16:52 EST (History)
2 users (show)

See Also:


Attachments
mylyn/context/zip (1.29 KB, application/octet-stream)
2008-05-20 11:56 EDT, Mik Kersten CLA
no flags Details
mylyn/context/zip (3.82 KB, application/octet-stream)
2008-05-22 13:43 EDT, Mik Kersten CLA
no flags Details
mylyn/context/zip (9.25 KB, application/octet-stream)
2008-05-22 16:06 EDT, Andrew Eisenberg CLA
no flags Details
AspectJStructureBridge (10.71 KB, application/octet-stream)
2008-05-22 16:07 EDT, Andrew Eisenberg CLA
no flags Details
patch for changing ContextCorePlugin (1.18 KB, patch)
2008-05-22 16:08 EDT, Andrew Eisenberg CLA
no flags Details | Diff
mylyn/context/zip (9.31 KB, application/octet-stream)
2008-05-22 16:08 EDT, Andrew Eisenberg CLA
no flags Details
Patch that adds shadows extension point (9.74 KB, patch)
2008-06-06 14:50 EDT, Andrew Eisenberg CLA
no flags Details | Diff
mylyn/context/zip (15.93 KB, application/octet-stream)
2008-06-06 14:50 EDT, Andrew Eisenberg CLA
no flags Details
patch is reworked to be based off of tag R_3_0_1 (9.79 KB, patch)
2008-08-29 14:34 EDT, Andrew Eisenberg CLA
no flags Details | Diff
mylyn/context/zip (19.19 KB, application/octet-stream)
2008-09-04 22:37 EDT, Mik Kersten CLA
no flags Details
mylyn/context/zip (11.07 KB, application/octet-stream)
2008-09-05 12:22 EDT, Mik Kersten CLA
no flags Details
passing test case for shadowing structure bridges (8.72 KB, patch)
2008-09-05 19:34 EDT, Andrew Eisenberg CLA
steffen.pingel: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Eisenberg CLA 2008-05-16 18:40:59 EDT
Build ID: I20080502-0100

Steps To Reproduce:
I am creating a structure bridge for AspectJ.  When CoreContextPlugin.getStructureBridge() is determining which structure bridge to use for a particular element, the JavaStructureBridge.acceptObject() method is always used instead of my AspectJStructureBridge.

AspectJ elements are modelled as special subclasses of IJavaElement.  JavaStructureBridge.acceptObject() will return true if the object passed in is a IJavaElement, even if it is an aspect, pointcut, advice, etc.

This is a problem because the AspectJStructureBridge can never be used since JavaStructureBridge always steals the object away.

Thanks.

More information:
Comment 1 Mik Kersten CLA 2008-05-19 15:30:19 EDT
Andrew: you may be able to address this using the child bridge mechanism.  The Java bridge is a child of the resource bridge, and it may be possible to make the AspectJ bridge a child of the Java bridge.  If the mechanism is not sufficient, it probably makes sense to extend it to support this scenario.  Give that a shot and let me know how ti goes.
Comment 2 Andrew Eisenberg CLA 2008-05-19 22:18:28 EDT
My initial implementation was to subclass the JavaStructureBridge class to make AspectStructureBridge.  That's when I came up with the problem.

I started playing around a bit and I commented out 2 extension points in the Mylyn's Java plugin: the structure bridge and ui bridge extensions.  Obviously, this is not meant to be a "fix", but I was able to get the AspectJ bridge working.

What I am saying is that I don't think the mechanism that you are suggesting will work (unless I am misunderstanding you), and that I don't think it will be possible to do this without changing JavaStructureBridge/JavaUIBridge.  Also, not much code is required to get AspectJStructureBridge working if the Java bridge is already there.

I'll think about it some more see what I can get to work.
Comment 3 Mik Kersten CLA 2008-05-20 11:56:09 EDT
The challenge is that both the Java and AspectJ structure bridges need to work in together at the same time.  This means that either we need an extension point that will know when to delegate something to the AspectJ structure bridge instead of the Java structure bridge, or that the Java structure bridge will need to know how to test that an element is a subtype of IJavaElement but not an actual Java element.  I suppose that we could do that via a call to IJavaElmenet.exists(), but that might be too expensive.
Comment 4 Mik Kersten CLA 2008-05-20 11:56:17 EDT
Created attachment 101080 [details]
mylyn/context/zip
Comment 5 Andrew Eisenberg CLA 2008-05-21 16:42:31 EDT
(In reply to comment #3)
> I suppose that we could do that via a call to
> IJavaElmenet.exists(), but that might be too expensive.
> 

We would want to use something like IJavaElement.getElementType().  But, now that I investigate it further, it seems that all aspect elements return either METHOD or TYPE.  So, this wouldn't work either...

Another possibility is to check the file extension of the associated resource.  If .java, then use JavaStructureBridge.  If .aj, then use AspectJStructureBridge.

This would probably work, but there are 2 potential problems:
1. I don't know if the call to get the associated resource's file extension is quick or slow.
2. Aspect elements in Java files will not use the correct structure bridge.  This isn't quite as bad as it sounds because there are quite a few other things that will not work aspect entities are in java files.
Comment 6 Andrew Eisenberg CLA 2008-05-21 19:19:59 EDT
(In reply to comment #5)
> This would probably work, but there are 2 potential problems:
> 1. I don't know if the call to get the associated resource's file extension is
> quick or slow.
> 2. Aspect elements in Java files will not use the correct structure bridge. 
> This isn't quite as bad as it sounds because there are quite a few other things
> that will not work aspect entities are in java files.
> 

Actually, this would need to be tested a bit because I don't know what the behavior would be for class files.

Another possibility (which is admittedly kludgy) is to check the package declaration of the IJavaElement to see if it is in the expected package.  The test would be something like:

((IJavaElement) object).getClass().getPackage().getName().startsWith("org.eclipse.jdt.core");

Comment 7 Mik Kersten CLA 2008-05-22 13:43:25 EDT
Andrew: consider exploring this by making the "aspectj" structure bridge shadow the "java" bride.  See attached context for the relevant methods.  Don't bother with extension points yet, it probably makes more sense to just hack it into getStructureBridge() for now.
Comment 8 Mik Kersten CLA 2008-05-22 13:43:29 EDT
Created attachment 101567 [details]
mylyn/context/zip
Comment 9 Andrew Eisenberg CLA 2008-05-22 16:04:59 EDT
I have something that seems to work.  I subclassed JavaStructureBridge and overriode a few methods.  Not much code in it.

I am attaching a patch, a context, and a project that contains the mylyn-aspectj bridge.
Comment 10 Andrew Eisenberg CLA 2008-05-22 16:06:47 EDT
Created attachment 101608 [details]
mylyn/context/zip

This context contains a first attempt at adding an AspectJStructureBridge.

I hacked the ContextCorePlugin.getStructureBridge(Object) method to test for AspectJStructureBridge before the JavaStructureBridge.
Comment 11 Andrew Eisenberg CLA 2008-05-22 16:07:44 EDT
Created attachment 101610 [details]
AspectJStructureBridge

Contains the plugin and code for AspectJStructureBridge
Comment 12 Andrew Eisenberg CLA 2008-05-22 16:08:55 EDT
Created attachment 101612 [details]
patch for changing ContextCorePlugin

This patch changes ContextCorePlugin as specified in the comments section.
Comment 13 Andrew Eisenberg CLA 2008-05-22 16:08:57 EDT
Created attachment 101613 [details]
mylyn/context/zip
Comment 14 Andrew Eisenberg CLA 2008-06-02 18:37:09 EDT
I need the equivalent of this:

	public AbstractContextStructureBridge getStructureBridge(Object object) {
		BridgesExtensionPointReader.initExtensions();
		// ADE---hack here.
		// must check aspectj structure bridge *before* java structure bridge.
		// get aspectj bridge first
		AbstractContextStructureBridge aspectjBridge = bridges.get("aspectj");
		if (aspectjBridge != null) {
			if (aspectjBridge.acceptsObject(object)) {
				return aspectjBridge;
			}
		}
		for (AbstractContextStructureBridge structureBridge : bridges.values()) {
			if (structureBridge.acceptsObject(object)) {
				return structureBridge;
			}
		}

		// use the default if not found
		return (defaultBridge != null && defaultBridge.acceptsObject(object)) ? defaultBridge : DEFAULT_BRIDGE;
	}
Comment 15 Mik Kersten CLA 2008-06-04 14:30:22 EDT
Andrew: could you consider providing a patch for an extension point that achieves this?  I would like to keep the extension point internal for now, since we have to consider the overlap with the parent attribute on the bridge further.  But for now an extension point along the following lines should provide what you want:

<extension point="org.eclipse.mylyn.context.core.internalBridges">
	<shadow
		baseContent="java"
		shadowedByContent="aspectj"/>
</extension>

Then your code above would be updated to take look up the bridge shadowing similar to how bridge parenting is looked up.
Comment 16 Andrew Eisenberg CLA 2008-06-05 16:30:25 EDT
Sure.  Let me see if I understand you correctly...

1) InternalBridges is a new extension point that indicates for internal use only (and in the future it may be made external).

2) The method "public AbstractContextStructureBridge getStructureBridge(Object object)" will check whatever bridge is returned and see if there is a bridge that shadows it.
Comment 17 Andrew Eisenberg CLA 2008-06-05 17:17:33 EDT
What happens if there there are multiple content types that shadow a single content type?

Eg- 

AspectJ shadows Java
ArchJava shadows Java

Which one gets precedence?  We are back to the original problem.

One solution is to keep this as an internal extension point so that mylyn developers have control over the extension point and can prevent this from happening.
Comment 18 Mik Kersten CLA 2008-06-05 17:39:52 EDT
(In reply to comment #16)
> Sure.  Let me see if I understand you correctly...
> 
> 1) InternalBridges is a new extension point that indicates for internal use only
> (and in the future it may be made external).
> 
> 2) The method "public AbstractContextStructureBridge getStructureBridge(Object
> object)" will check whatever bridge is returned and see if there is a bridge
> that shadows it.

Yup and yup.

(In reply to comment #17)
> What happens if there there are multiple content types that shadow a single
> content type?
...
> One solution is to keep this as an internal extension point so that mylyn
> developers have control over the extension point and can prevent this from
> happening.

Exactly.  Don't worry about collisions right now (just override previous values multiple extensions have been read), and when we make the extension point public we can figure that out.

For an example of how to read extension points see the landmarks (bold things) in the attached context.
Comment 19 Andrew Eisenberg CLA 2008-06-06 14:50:20 EDT
Created attachment 104027 [details]
Patch that adds shadows extension point

Attaching a patch that adds the shadows extension point and adds the appropriate behavior to the ContextCorePlugin as discussed above.
Comment 20 Andrew Eisenberg CLA 2008-06-06 14:50:22 EDT
Created attachment 104028 [details]
mylyn/context/zip
Comment 21 Mik Kersten CLA 2008-06-12 12:13:58 EDT
Andrew: great, thanks.  I'll apply this once we get 3.0 out the door.  For now please just continue to work with your local patch.
Comment 22 Andrew Eisenberg CLA 2008-08-21 19:34:32 EDT
Has this patch been commited to Mylyn?
Comment 23 Mik Kersten CLA 2008-08-22 09:00:07 EDT
No, it hasn't yet, it's scheduled for Mylyn 3.0.2 which will be released on September 17th.  Bumping priority.
Comment 24 Andrew Eisenberg CLA 2008-08-22 11:16:01 EDT
Thanks.  It's not a show stopper for releasing AJDT 1.6, but it would be very, very nice.  We can't advertise this feature if it only half works.
Comment 25 Andrew Eisenberg CLA 2008-08-29 13:46:53 EDT
Mik,

Wanted to make sure that this will be making it in to Mylyn 3.0.2.  We are holding off on our release of AJDT 1.6 final until we have the mylyn structure bridge.  Thanks.
Comment 26 Andrew Eisenberg CLA 2008-08-29 14:34:15 EDT
Created attachment 111321 [details]
patch is reworked to be based off of tag R_3_0_1

Same patch, but reworked to mesh with R_3_0_1.  This can be applied directly to the code base and will work with the AspectJ Structure bridge.

As discussed before, I am using the extension point internalBridge.  When this patch is applied and verified, the internalBridge extension point should be merged into the bridge extension point.
Comment 27 Mik Kersten CLA 2008-09-04 22:37:54 EDT
Good stuff Andrew.  I have tentatively applied it and incorporated some naming changes of the internals which you should look over.  Before resolving this we need a test that exercises the shadowing of the two getStructureBridge(..) methods.
Comment 28 Mik Kersten CLA 2008-09-04 22:37:57 EDT
Created attachment 111753 [details]
mylyn/context/zip
Comment 29 Andrew Eisenberg CLA 2008-09-04 22:45:12 EDT
Thanks for applying the patch.  I'll send you the test soon.  Probably tomorrow.
Comment 30 Mik Kersten CLA 2008-09-05 12:22:27 EDT
Andrew: For an example of a test see the ContextExternalizerTest in the attached context.  But your test should be simpler, since it only needs to exercise ContextCorePlugin.
Comment 31 Mik Kersten CLA 2008-09-05 12:22:32 EDT
Created attachment 111837 [details]
mylyn/context/zip
Comment 32 Andrew Eisenberg CLA 2008-09-05 18:55:32 EDT
Noticed this comment in ContextCorePlugin:

	/**
	 * Recommended bridge registration is via extension point, but bridges can also be added at runtime. Note that only
	 * one bridge per content type is supported. Overriding content types is not supported.
	 */

This is no longer strictly true with Shadowing going on.  Should probably change this comment.
Comment 33 Andrew Eisenberg CLA 2008-09-05 19:34:02 EDT
Created attachment 111889 [details]
passing test case for shadowing structure bridges

Thanks for the pointer.  I have created my own passing test case.
Comment 34 Andrew Eisenberg CLA 2008-10-02 12:12:24 EDT
Has this patch been committed?
Comment 35 Steffen Pingel CLA 2008-10-02 13:46:15 EDT
The patch with the test case is still pending. I have put an item on next week's conference call to go through the outstanding patches.
Comment 36 Steffen Pingel CLA 2009-01-15 16:44:07 EST
I have applied the last patch. Thanks Andrew!