Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 308650 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/e4/core/internal/contexts/ContextObjectSupplier.java (-9 / +43 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.e4.core.internal.contexts;
11
package org.eclipse.e4.core.internal.contexts;
12
12
13
import java.lang.reflect.InvocationTargetException;
14
13
import javax.inject.Named;
15
import javax.inject.Named;
14
16
15
import org.eclipse.e4.core.contexts.ContextChangeEvent;
17
import org.eclipse.e4.core.contexts.ContextChangeEvent;
Lines 19-24 Link Here
19
import org.eclipse.e4.core.di.IInjector;
21
import org.eclipse.e4.core.di.IInjector;
20
import org.eclipse.e4.core.di.IObjectDescriptor;
22
import org.eclipse.e4.core.di.IObjectDescriptor;
21
import org.eclipse.e4.core.di.IRequestor;
23
import org.eclipse.e4.core.di.IRequestor;
24
import org.eclipse.e4.core.di.InjectionException;
22
25
23
public class ContextObjectSupplier extends AbstractObjectSupplier {
26
public class ContextObjectSupplier extends AbstractObjectSupplier {
24
27
Lines 36-42 Link Here
36
			this.context = context;
39
			this.context = context;
37
		}
40
		}
38
41
39
		public boolean notify(ContextChangeEvent event) {
42
		public boolean notify(ContextChangeEvent event, final IContextRecorder recorder) {
40
			if (event.getEventType() == ContextChangeEvent.INITIAL) {
43
			if (event.getEventType() == ContextChangeEvent.INITIAL) {
41
				// needs to be done inside runnable to establish dependencies
44
				// needs to be done inside runnable to establish dependencies
42
				for (int i = 0; i < keys.length; i++) {
45
				for (int i = 0; i < keys.length; i++) {
Lines 50-56 Link Here
50
				}
53
				}
51
				return true;
54
				return true;
52
			}
55
			}
53
			
56
54
			IInjector injector = requestor.getInjector();
57
			IInjector injector = requestor.getInjector();
55
			if (event.getEventType() == ContextChangeEvent.DISPOSE) {
58
			if (event.getEventType() == ContextChangeEvent.DISPOSE) {
56
				IEclipseContext originatingContext = event.getContext();
59
				IEclipseContext originatingContext = event.getContext();
Lines 67-76 Link Here
67
					return false;
70
					return false;
68
				}
71
				}
69
			} else {
72
			} else {
70
				injector.update(new IRequestor[] { requestor }, requestor.getPrimarySupplier());
73
				boolean resolved = injector.resolveArguments(requestor, requestor.getPrimarySupplier());
74
				if (resolved) {
75
					if (recorder != null)
76
						recorder.stopAccessRecording();
77
						
78
					try {
79
						requestor.execute();
80
					} catch (InvocationTargetException e) {
81
						logError("Injection failed for the object \""
82
								+ requestor.getRequestingObject().toString() + "\". Unable to execute \""
83
								+ requestor.toString() + "\"");
84
						return false;
85
					} catch (InstantiationException e) {
86
						logError("Injection failed for the object \""
87
								+ requestor.getRequestingObject().toString() + "\". Unable to execute \""
88
								+ requestor.toString() + "\"");
89
						return false;
90
					} finally {
91
						if (recorder != null)
92
							recorder.startAcessRecording();
93
					}
94
				}
71
			}
95
			}
72
			return true;
96
			return true;
73
		}
97
		}
98
		
99
		public boolean notify(ContextChangeEvent event) {
100
			return notify(event, null);
101
		}
74
102
75
		@Override
103
		@Override
76
		public int hashCode() {
104
		public int hashCode() {
Lines 103-117 Link Here
103
			return true;
131
			return true;
104
		}
132
		}
105
133
106
		public Object getObject() {
107
			// XXX remove?
108
			// TODO Auto-generated method stub
109
			return null;
110
		}
111
112
		public boolean batchProcess() {
134
		public boolean batchProcess() {
113
			return requestor.shouldGroupUpdates();
135
			return requestor.shouldGroupUpdates();
114
		}
136
		}
137
115
	}
138
	}
116
139
117
	final static private String ECLIPSE_CONTEXT_NAME = IEclipseContext.class.getName();
140
	final static private String ECLIPSE_CONTEXT_NAME = IEclipseContext.class.getName();
Lines 186-190 Link Here
186
		context.set(key, objectSupplier);
209
		context.set(key, objectSupplier);
187
		return objectSupplier;
210
		return objectSupplier;
188
	}
211
	}
212
	// TBD implement logging
213
	static protected void logError(String msg) {
214
		logError(msg, new InjectionException());
215
	}
216
217
	static protected void logError(String msg, Throwable e) {
218
		if (msg != null)
219
			System.err.println(msg);
220
		if (e != null)
221
			e.printStackTrace();
222
	}
189
223
190
}
224
}
(-)src/org/eclipse/e4/core/internal/contexts/EclipseContext.java (-11 / +19 lines)
Lines 85-91 Link Here
85
		}
85
		}
86
	}
86
	}
87
87
88
	static class TrackableComputationExt extends Computation implements IRunAndTrack {
88
	static class TrackableComputationExt extends Computation implements IRunAndTrack, IContextRecorder {
89
89
90
		private ContextChangeEvent cachedEvent;
90
		private ContextChangeEvent cachedEvent;
91
91
Lines 125-136 Link Here
125
			this.runnable = runnable;
125
			this.runnable = runnable;
126
		}
126
		}
127
127
128
		public Object getObject() {
129
			if (runnable instanceof IRunAndTrackObject)
130
				return ((IRunAndTrackObject) runnable).getObject();
131
			return null;
132
		}
133
134
		final protected void doHandleInvalid(ContextChangeEvent event, List<Scheduled> scheduledList) {
128
		final protected void doHandleInvalid(ContextChangeEvent event, List<Scheduled> scheduledList) {
135
			int eventType = event.getEventType();
129
			int eventType = event.getEventType();
136
			if (eventType == ContextChangeEvent.INITIAL || eventType == ContextChangeEvent.DISPOSE) {
130
			if (eventType == ContextChangeEvent.INITIAL || eventType == ContextChangeEvent.DISPOSE) {
Lines 153-159 Link Here
153
					cachedEvent = event;
147
					cachedEvent = event;
154
					EclipseContext eventsContext = (EclipseContext) event.getContext();
148
					EclipseContext eventsContext = (EclipseContext) event.getContext();
155
					eventsContext.addWaiting(this);
149
					eventsContext.addWaiting(this);
156
					// eventsContext.getRoot().waiting.add(this);
157
					return true;
150
					return true;
158
				}
151
				}
159
			}
152
			}
Lines 162-172 Link Here
162
			boolean result = true;
155
			boolean result = true;
163
			try {
156
			try {
164
				if (cachedEvent != null) {
157
				if (cachedEvent != null) {
165
					result = runnable.notify(cachedEvent);
158
					if (runnable instanceof IRunAndTrackObject)
159
						result = ((IRunAndTrackObject)runnable).notify(event, this);
160
					else
161
						result = runnable.notify(cachedEvent);
166
					cachedEvent = null;
162
					cachedEvent = null;
167
				}
163
				}
168
				if (eventType != ContextChangeEvent.UPDATE)
164
				if (eventType != ContextChangeEvent.UPDATE) {
169
					result = runnable.notify(event);
165
					if (runnable instanceof IRunAndTrackObject)
166
						result = ((IRunAndTrackObject)runnable).notify(event, this);
167
					else
168
						result = runnable.notify(event);
169
				}
170
			} finally {
170
			} finally {
171
				currentComputation.set(oldComputation);
171
				currentComputation.set(oldComputation);
172
			}
172
			}
Lines 181-186 Link Here
181
		public String toString() {
181
		public String toString() {
182
			return "TrackableComputationExt(" + runnable + ')'; //$NON-NLS-1$
182
			return "TrackableComputationExt(" + runnable + ')'; //$NON-NLS-1$
183
		}
183
		}
184
185
		public void startAcessRecording() {
186
			currentComputation.set(this);
187
		}
188
189
		public void stopAccessRecording() {
190
			currentComputation.set(null);
191
		}
184
	}
192
	}
185
193
186
	static class Scheduled {
194
	static class Scheduled {
(-)src/org/eclipse/e4/core/internal/contexts/IContextRecorder.java (+20 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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
12
package org.eclipse.e4.core.internal.contexts;
13
14
15
public interface IContextRecorder {
16
17
	public void startAcessRecording();
18
19
	public void stopAccessRecording();
20
}
(-)src/org/eclipse/e4/core/internal/contexts/IRunAndTrackObject.java (-2 / +3 lines)
Lines 11-22 Link Here
11
11
12
package org.eclipse.e4.core.internal.contexts;
12
package org.eclipse.e4.core.internal.contexts;
13
13
14
import org.eclipse.e4.core.contexts.ContextChangeEvent;
14
import org.eclipse.e4.core.contexts.IRunAndTrack;
15
import org.eclipse.e4.core.contexts.IRunAndTrack;
15
16
16
public interface IRunAndTrackObject extends IRunAndTrack {
17
public interface IRunAndTrackObject extends IRunAndTrack {
17
18
18
	public Object getObject();
19
20
	public boolean batchProcess();
19
	public boolean batchProcess();
20
	
21
	public boolean notify(ContextChangeEvent event, IContextRecorder recorder);
21
22
22
}
23
}
(-)src/org/eclipse/e4/core/di/IInjector.java (-2 / +1 lines)
Lines 42-53 Link Here
42
42
43
	public boolean injectStatic(Class<?> clazz, AbstractObjectSupplier objectSupplier);
43
	public boolean injectStatic(Class<?> clazz, AbstractObjectSupplier objectSupplier);
44
44
45
	public boolean update(IRequestor[] requestors, AbstractObjectSupplier objectSupplier);
46
47
	public boolean disposed(AbstractObjectSupplier objectSupplier);
45
	public boolean disposed(AbstractObjectSupplier objectSupplier);
48
46
49
	public IBinding addBinding(Class<?> clazz);
47
	public IBinding addBinding(Class<?> clazz);
50
48
51
	public IBinding addBinding(IBinding binding);
49
	public IBinding addBinding(IBinding binding);
52
50
51
	public boolean resolveArguments(IRequestor requestor, AbstractObjectSupplier objectSupplier);
53
}
52
}
(-)src/org/eclipse/e4/core/di/IRequestor.java (+3 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.e4.core.di;
11
package org.eclipse.e4.core.di;
12
12
13
import java.lang.reflect.InvocationTargetException;
14
13
// TBD this is really a "feedback" object. 
15
// TBD this is really a "feedback" object. 
14
/**
16
/**
15
 * @noimplement This interface is not intended to be implemented by clients.
17
 * @noimplement This interface is not intended to be implemented by clients.
Lines 31-34 Link Here
31
33
32
	public boolean shouldGroupUpdates();
34
	public boolean shouldGroupUpdates();
33
35
36
	public abstract Object execute() throws InvocationTargetException, InstantiationException;
34
}
37
}
(-)src/org/eclipse/e4/core/internal/di/InjectorImpl.java (-22 / +3 lines)
Lines 347-375 Link Here
347
		return true;
347
		return true;
348
	}
348
	}
349
349
350
	public boolean update(IRequestor[] requestors, AbstractObjectSupplier objectSupplier) {
350
	public boolean resolveArguments(IRequestor requestor, AbstractObjectSupplier objectSupplier) {
351
		ArrayList<Requestor> list = new ArrayList<Requestor>(requestors.length);
351
		ArrayList<Requestor> list = new ArrayList<Requestor>(1);
352
		for (IRequestor requestor : requestors) {
352
		list.add((Requestor)requestor);
353
			list.add((Requestor) requestor);
354
		}
355
		resolveRequestorArgs(list, objectSupplier, true);
353
		resolveRequestorArgs(list, objectSupplier, true);
356
357
		// Call requestors in order
358
		for (IRequestor requestor : requestors) {
359
			try {
360
				((Requestor) requestor).execute();
361
			} catch (InvocationTargetException e) {
362
				logError("Injection failed for the object \""
363
						+ requestor.getRequestingObject().toString() + "\". Unable to execute \""
364
						+ requestor.toString() + "\"");
365
				return false;
366
			} catch (InstantiationException e) {
367
				logError("Injection failed for the object \""
368
						+ requestor.getRequestingObject().toString() + "\". Unable to execute \""
369
						+ requestor.toString() + "\"");
370
				return false;
371
			}
372
		}
373
		return true;
354
		return true;
374
	}
355
	}
375
356
(-)src/org/eclipse/e4/core/internal/di/Requestor.java (-3 lines)
Lines 11-17 Link Here
11
package org.eclipse.e4.core.internal.di;
11
package org.eclipse.e4.core.internal.di;
12
12
13
import java.lang.ref.WeakReference;
13
import java.lang.ref.WeakReference;
14
import java.lang.reflect.InvocationTargetException;
15
14
16
import org.eclipse.e4.core.di.AbstractObjectSupplier;
15
import org.eclipse.e4.core.di.AbstractObjectSupplier;
17
import org.eclipse.e4.core.di.IInjector;
16
import org.eclipse.e4.core.di.IInjector;
Lines 39-46 Link Here
39
38
40
	public abstract IObjectDescriptor[] getDependentObjects();
39
	public abstract IObjectDescriptor[] getDependentObjects();
41
40
42
	public abstract Object execute() throws InvocationTargetException, InstantiationException;
43
44
	public Requestor(IInjector injector, AbstractObjectSupplier primarySupplier, Object requestingObject, boolean track, boolean groupUpdates,
41
	public Requestor(IInjector injector, AbstractObjectSupplier primarySupplier, Object requestingObject, boolean track, boolean groupUpdates,
45
			boolean isOptional) {
42
			boolean isOptional) {
46
		this.injector = injector;
43
		this.injector = injector;
(-)src/org/eclipse/e4/core/di/internal/extensions/PreferencesObjectSupplier.java (-2 / +32 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.e4.core.di.internal.extensions;
11
package org.eclipse.e4.core.di.internal.extensions;
12
12
13
import java.lang.reflect.InvocationTargetException;
13
import java.util.ArrayList;
14
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.HashMap;
15
import java.util.List;
16
import java.util.List;
Lines 23-28 Link Here
23
import org.eclipse.e4.core.di.IInjector;
24
import org.eclipse.e4.core.di.IInjector;
24
import org.eclipse.e4.core.di.IObjectDescriptor;
25
import org.eclipse.e4.core.di.IObjectDescriptor;
25
import org.eclipse.e4.core.di.IRequestor;
26
import org.eclipse.e4.core.di.IRequestor;
27
import org.eclipse.e4.core.di.InjectionException;
26
import org.eclipse.e4.core.di.extensions.Preferences;
28
import org.eclipse.e4.core.di.extensions.Preferences;
27
import org.osgi.framework.FrameworkUtil;
29
import org.osgi.framework.FrameworkUtil;
28
30
Lines 98-106 Link Here
98
		node.addPreferenceChangeListener(new IPreferenceChangeListener() {
100
		node.addPreferenceChangeListener(new IPreferenceChangeListener() {
99
			public void preferenceChange(PreferenceChangeEvent event) {
101
			public void preferenceChange(PreferenceChangeEvent event) {
100
				IInjector requestorInjector = requestor.getInjector();
102
				IInjector requestorInjector = requestor.getInjector();
101
				if (requestorInjector != null)
103
				if (requestorInjector != null) {
102
					requestorInjector.update(new IRequestor[] { requestor }, requestor
104
					boolean resolved = requestorInjector.resolveArguments(requestor, requestor
103
							.getPrimarySupplier());
105
							.getPrimarySupplier());
106
					if (resolved) {
107
						try {
108
							requestor.execute();
109
						} catch (InvocationTargetException e) {
110
							logError("Injection failed for the object \""
111
									+ requestor.getRequestingObject().toString()
112
									+ "\". Unable to execute \"" + requestor.toString() + "\"");
113
							return;
114
						} catch (InstantiationException e) {
115
							logError("Injection failed for the object \""
116
									+ requestor.getRequestingObject().toString()
117
									+ "\". Unable to execute \"" + requestor.toString() + "\"");
118
							return;
119
						}
120
					}
121
				}
104
			}
122
			}
105
		});
123
		});
106
		synchronized (listenerCache) {
124
		synchronized (listenerCache) {
Lines 114-117 Link Here
114
		}
132
		}
115
	}
133
	}
116
134
135
	// TBD implement logging
136
	static protected void logError(String msg) {
137
		logError(msg, new InjectionException());
138
	}
139
140
	static protected void logError(String msg, Throwable e) {
141
		if (msg != null)
142
			System.err.println(msg);
143
		if (e != null)
144
			e.printStackTrace();
145
	}
146
117
}
147
}
(-)src/org/eclipse/e4/core/tests/services/internal/annotations/ExtraDependenciesTest.java (+105 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 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.e4.core.tests.services.internal.annotations;
12
13
import java.lang.reflect.InvocationTargetException;
14
15
import javax.inject.Inject;
16
import javax.inject.Named;
17
18
import junit.framework.TestCase;
19
20
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
21
import org.eclipse.e4.core.contexts.EclipseContextFactory;
22
import org.eclipse.e4.core.contexts.IEclipseContext;
23
import org.eclipse.e4.core.di.IDisposable;
24
import org.eclipse.e4.core.di.annotations.PreDestroy;
25
26
public class ExtraDependenciesTest extends TestCase {
27
28
	static public class TestObject {
29
		
30
		public String string;
31
		public Integer integer;
32
		public String other;
33
		
34
		public boolean disposed = false;
35
		
36
		@Inject
37
		public void injectedMethod(@Named("arg1") String strValue, @Named("arg2") Integer intValue, IEclipseContext context) {
38
			string = strValue;
39
			integer = intValue;
40
			if (context == null) {
41
				other = null;
42
				return;
43
			}
44
			IEclipseContext otherContext = (IEclipseContext) context.get("otherContext");
45
			if (otherContext == null)
46
				other = null;
47
			else
48
				other = (String) otherContext.get("arg3");
49
		}
50
		
51
		@PreDestroy
52
		public void finita() {
53
			disposed = true;
54
		}
55
	}
56
	
57
	public void testExtraDependencies() throws InvocationTargetException, InstantiationException {
58
		IEclipseContext context = EclipseContextFactory.create();
59
		context.set("arg1", "abc");
60
		context.set("arg2", new Integer (123));
61
		
62
		IEclipseContext otherContext = EclipseContextFactory.create();
63
		otherContext.set("arg3", "other");
64
		
65
		context.set("otherContext", otherContext);
66
		
67
		TestObject object = (TestObject) ContextInjectionFactory.make(TestObject.class, context);
68
		
69
		// check that initial values are properly injected
70
		assertEquals("abc", object.string);
71
		assertEquals(new Integer(123), object.integer);
72
		assertEquals("other", object.other);
73
		
74
		// modify argument value to cause update - bug 308650
75
		context.set("arg2", new Integer (789));
76
		
77
		// change the "other" value; should not be propagated
78
		otherContext.set("arg3", "wrong");
79
		assertEquals("other", object.other);
80
		
81
		// dispose the other context; should not cause disposal of the test object
82
		((IDisposable)otherContext).dispose();
83
		assertEquals("other", object.other);
84
		assertFalse(object.disposed);
85
		
86
		// remove "other" context, should not be propagated
87
		context.remove("otherContext");
88
		assertEquals("other", object.other);
89
		
90
		// check that changes in the method arguments are propagated
91
		context.set("arg1", "xyz");
92
		context.set("arg2", new Integer (456));
93
		assertEquals("xyz", object.string);
94
		assertEquals(new Integer(456), object.integer);
95
		assertNull(object.other);
96
		
97
		// check that disposal of the injected context causes disposal of the injected object
98
		((IDisposable)context).dispose();
99
		assertTrue(object.disposed);
100
		assertNull(object.string);
101
		assertNull(object.integer);
102
		assertNull(object.other);
103
	}
104
105
}
(-)src/org/eclipse/e4/core/tests/services/internal/annotations/ServicesTestSuiteAnnotations.java (+1 lines)
Lines 29-33 Link Here
29
		addTestSuite(InjectionOrderTest.class);
29
		addTestSuite(InjectionOrderTest.class);
30
		addTestSuite(GroupedUpdatesTest.class);
30
		addTestSuite(GroupedUpdatesTest.class);
31
		addTestSuite(Bug304585Test.class);
31
		addTestSuite(Bug304585Test.class);
32
		addTestSuite(ExtraDependenciesTest.class);
32
	}
33
	}
33
}
34
}

Return to bug 308650