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

Bug 348710

Summary: AnnotationProcessing for "on navigation node events" adds listeners multiple times
Product: [RT] Riena Reporter: Stefan Liebig <Stefan.Liebig>
Component: navigationAssignee: Stefan Liebig <Stefan.Liebig>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P2 CC: christian.campo
Version: 3.0.0   
Target Milestone: 3.0.0   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Stefan Liebig CLA 2011-06-08 08:00:25 EDT
The annotation processing for "on navigation node events" occurs in the afterBind() method of the NavigationNodeController. However for the same instance this method can be called more than once and so multiple listeners will be added and so notifications can also occur more than once.

Possible solutions:
1. the NavigationNodeController remembers (boolean flag) whether it already has done the annotation processing or
2. the NavigationNodeControllerAnnotationProcessor does this by remembering the processed NavigationNodeControllers (WeakHashMap)

Solution 1 is very simple.
Solution 2 is more general (can provide a patch).


Besides this problem exists another: the created listeners will never get removed.
Comment 1 Christian Campo CLA 2011-06-08 08:02:51 EDT
+1 for solution 1 (Sounds easier with less risk)
Comment 2 Stefan Liebig CLA 2011-06-08 08:47:00 EDT
yes, 1. is simpler but 2. is more general since it protects itself instead of relying on someone else to do that.
And, I think this:

+	private final Map<INavigationNodeController, ?> alreadyProcessed = new WeakHashMap<INavigationNodeController, Object>();

	private NavigationNodeControllerAnnotationProcessor() {
		// singleton
	}

	/**
	 * Process the {@link OnNavigationNodeEvent} annotations for the given
	 * {@link INavigationNodeController}.
	 * 
	 * @param navigationNodeController
	 *            the {@link INavigationNodeController} to process
	 */
	public void processAnnotations(final INavigationNodeController navigationNodeController) {
+		synchronized (alreadyProcessed) {
+			if (alreadyProcessed.containsKey(navigationNodeController)) {
+				return;
+			}
+			alreadyProcessed.put(navigationNodeController, null);
+		}
		processAnnotations(navigationNodeController, navigationNodeController.getClass());
	}

is also quite simple. New code lines marked with +
Comment 3 Stefan Liebig CLA 2011-06-14 07:34:05 EDT
Fixed with solution 2.