|
Lines 10-20
Link Here
|
| 10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
| 11 |
package org.eclipse.e4.internal.core.services.osgi; |
11 |
package org.eclipse.e4.internal.core.services.osgi; |
| 12 |
|
12 |
|
| 13 |
import java.util.*; |
13 |
import java.util.Collections; |
|
|
14 |
import java.util.HashMap; |
| 15 |
import java.util.Iterator; |
| 16 |
import java.util.Map; |
| 17 |
import java.util.WeakHashMap; |
| 14 |
import org.eclipse.e4.core.services.IDisposable; |
18 |
import org.eclipse.e4.core.services.IDisposable; |
|
|
19 |
import org.eclipse.e4.core.services.context.IContextFunction; |
| 15 |
import org.eclipse.e4.core.services.context.IEclipseContext; |
20 |
import org.eclipse.e4.core.services.context.IEclipseContext; |
| 16 |
import org.eclipse.e4.core.services.context.spi.ILookupStrategy; |
21 |
import org.eclipse.e4.core.services.context.spi.ILookupStrategy; |
| 17 |
import org.osgi.framework.*; |
22 |
import org.osgi.framework.BundleContext; |
|
|
23 |
import org.osgi.framework.Constants; |
| 24 |
import org.osgi.framework.InvalidSyntaxException; |
| 25 |
import org.osgi.framework.ServiceReference; |
| 18 |
import org.osgi.util.tracker.ServiceTracker; |
26 |
import org.osgi.util.tracker.ServiceTracker; |
| 19 |
import org.osgi.util.tracker.ServiceTrackerCustomizer; |
27 |
import org.osgi.util.tracker.ServiceTrackerCustomizer; |
| 20 |
|
28 |
|
|
Lines 25-35
Link Here
|
| 25 |
*/ |
33 |
*/ |
| 26 |
public class OSGiContextStrategy implements ILookupStrategy, IDisposable, ServiceTrackerCustomizer { |
34 |
public class OSGiContextStrategy implements ILookupStrategy, IDisposable, ServiceTrackerCustomizer { |
| 27 |
class ServiceData { |
35 |
class ServiceData { |
| 28 |
//the service name |
36 |
// the service name |
| 29 |
String name; |
37 |
String name; |
| 30 |
|
38 |
|
| 31 |
ServiceTracker tracker; |
39 |
ServiceTracker tracker; |
| 32 |
//the contexts using this service (IEclipseContext -> null) |
40 |
// the contexts using this service (IEclipseContext -> null) |
| 33 |
final Map users = new WeakHashMap(); |
41 |
final Map users = new WeakHashMap(); |
| 34 |
|
42 |
|
| 35 |
ServiceData(String name) { |
43 |
ServiceData(String name) { |
|
Lines 57-63
Link Here
|
| 57 |
Object newValue = bundleContext.getService(reference); |
65 |
Object newValue = bundleContext.getService(reference); |
| 58 |
if (newValue == null) |
66 |
if (newValue == null) |
| 59 |
return null; |
67 |
return null; |
| 60 |
//for performance we store the concrete service object with each context that requested it |
68 |
// for performance we store the concrete service object with each |
|
|
69 |
// context that requested it |
| 61 |
ServiceData data = (ServiceData) services.get(name); |
70 |
ServiceData data = (ServiceData) services.get(name); |
| 62 |
for (Iterator it = data.users.keySet().iterator(); it.hasNext();) |
71 |
for (Iterator it = data.users.keySet().iterator(); it.hasNext();) |
| 63 |
((IEclipseContext) it.next()).set(name, newValue); |
72 |
((IEclipseContext) it.next()).set(name, newValue); |
|
Lines 65-78
Link Here
|
| 65 |
} |
74 |
} |
| 66 |
|
75 |
|
| 67 |
/** |
76 |
/** |
| 68 |
* Discards any services that are no longer used by any strongly |
77 |
* Discards any services that are no longer used by any strongly reachable |
| 69 |
* reachable contexts. |
78 |
* contexts. |
| 70 |
*/ |
79 |
*/ |
| 71 |
private void cleanReferences() { |
80 |
private void cleanReferences() { |
| 72 |
synchronized (services) { |
81 |
synchronized (services) { |
| 73 |
for (Iterator it = services.values().iterator(); it.hasNext();) { |
82 |
for (Iterator it = services.values().iterator(); it.hasNext();) { |
| 74 |
ServiceData data = (ServiceData) it.next(); |
83 |
ServiceData data = (ServiceData) it.next(); |
| 75 |
//if there are no more references, discard the service |
84 |
// if there are no more references, discard the service |
| 76 |
if (data.users.isEmpty()) { |
85 |
if (data.users.isEmpty()) { |
| 77 |
data.tracker.close(); |
86 |
data.tracker.close(); |
| 78 |
it.remove(); |
87 |
it.remove(); |
|
Lines 98-107
Link Here
|
| 98 |
cleanReferences(); |
107 |
cleanReferences(); |
| 99 |
ServiceData data = (ServiceData) services.get(name); |
108 |
ServiceData data = (ServiceData) services.get(name); |
| 100 |
if (data == null) { |
109 |
if (data == null) { |
|
|
110 |
// see if there is an IContextFunction registered for this name |
| 111 |
try { |
| 112 |
ServiceReference[] refs = bundleContext.getServiceReferences( |
| 113 |
IContextFunction.SERVICE_NAME, "(" //$NON-NLS-1$ |
| 114 |
+ IContextFunction.SERVICE_CONTEXT_KEY + '=' + name + ')'); |
| 115 |
if (refs != null && refs.length > 0) |
| 116 |
return bundleContext.getService(refs[0]); |
| 117 |
} catch (InvalidSyntaxException e) { |
| 118 |
// the name is not a valid service name, so just carry on |
| 119 |
} |
| 120 |
|
| 121 |
// create a tracker to retrieve the service with the given name |
| 101 |
data = new ServiceData(name); |
122 |
data = new ServiceData(name); |
| 102 |
data.tracker = new ServiceTracker(bundleContext, name, this); |
123 |
data.tracker = new ServiceTracker(bundleContext, name, this); |
| 103 |
services.put(name, data); |
124 |
services.put(name, data); |
| 104 |
//just opening a tracker will cause values to be set by the tracker callback methods |
125 |
// just opening a tracker will cause values to be set by the tracker |
|
|
126 |
// callback methods |
| 105 |
data.tracker.open(); |
127 |
data.tracker.open(); |
| 106 |
} |
128 |
} |
| 107 |
data.addContext(originatingContext); |
129 |
data.addContext(originatingContext); |
|
Lines 117-123
Link Here
|
| 117 |
|
139 |
|
| 118 |
public void removedService(ServiceReference reference, Object service) { |
140 |
public void removedService(ServiceReference reference, Object service) { |
| 119 |
String name = serviceName(reference); |
141 |
String name = serviceName(reference); |
| 120 |
//must set to null rather than removing so injection continues to work |
142 |
// must set to null rather than removing so injection continues to work |
| 121 |
ServiceData data = (ServiceData) services.get(name); |
143 |
ServiceData data = (ServiceData) services.get(name); |
| 122 |
for (Iterator it = data.users.keySet().iterator(); it.hasNext();) |
144 |
for (Iterator it = data.users.keySet().iterator(); it.hasNext();) |
| 123 |
((IEclipseContext) it.next()).set(name, null); |
145 |
((IEclipseContext) it.next()).set(name, null); |