View | Details | Raw Unified | Return to bug 341660 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/cdt/dsf/service/AbstractDsfService.java (-57 / +108 lines)
Lines 10-23 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.cdt.dsf.service;
11
package org.eclipse.cdt.dsf.service;
12
12
13
import java.util.Arrays;
14
import java.util.Dictionary;
13
import java.util.Dictionary;
15
import java.util.Enumeration;
14
import java.util.Enumeration;
16
import java.util.HashSet;
15
import java.util.Hashtable;
17
import java.util.Set;
16
import java.util.List;
18
17
19
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
18
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
20
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
19
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
20
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
21
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
21
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
22
import org.osgi.framework.BundleContext;
22
import org.osgi.framework.BundleContext;
23
import org.osgi.framework.Constants;
23
import org.osgi.framework.Constants;
Lines 65-71 Link Here
65
    public DsfExecutor getExecutor() { return fSession.getExecutor(); }
65
    public DsfExecutor getExecutor() { return fSession.getExecutor(); }
66
66
67
	/**
67
	/**
68
	 * The the returned collection is a superset of the properties specified in
68
	 * The returned collection is a superset of the properties specified in
69
	 * {@link #register(String[], Dictionary)}. That method can add additional
69
	 * {@link #register(String[], Dictionary)}. That method can add additional
70
	 * (implicit) properties. For one, it tacks on the
70
	 * (implicit) properties. For one, it tacks on the
71
	 * {@link Constants#OBJECTCLASS} property associated with the service after
71
	 * {@link Constants#OBJECTCLASS} property associated with the service after
Lines 81-98 Link Here
81
    
81
    
82
    public int getStartupNumber() { return fStartupNumber; }
82
    public int getStartupNumber() { return fStartupNumber; }
83
    
83
    
84
    public void initialize(RequestMonitor rm) {
84
    /** 
85
     * @return The class names under which the service can be located. For
86
	 *         convenience, [classes] need not contain {@link IDsfService},
87
	 *         it is automatically added if not present. The complete list 
88
	 *         of classes the service ends up being registered in OSGi with
89
	 *         is recorded and made available via
90
	 *         <code>getProperties().get(Constants.OBJECTCLASS)</code>
91
     */
92
    abstract protected List<String> getClassNamesToRegister();
93
94
    /**
95
     * Sub-classes can override this method to specify properties to use for
96
     * the registration of the service, or to obtain directly the final
97
     * list of properties that was used to register the service.
98
     * 
99
     * @return The properties for this service. The keys in the properties
100
	 *         object must all be <code>String</code> objects. See
101
	 *         {@link Constants} for a list of standard service property
102
	 *         keys. To update the service's properties after initialization
103
	 *         the {@link ServiceRegistration#setProperties} method must be
104
	 *         called. Caller should, at a minimum, pass an empty
105
	 *         dictionary--never null. We add a property to the collection
106
	 *         (we modify the list returned by this method), to record the id of
107
	 *         the dsf session associated with the service as well as all the names
108
	 *         of the classes the service ends up being registered in OSGi with.
109
	 */
110
    @SuppressWarnings("rawtypes")
111
    protected Dictionary getPropertiesToRegister() {
112
    	return new Hashtable<String, String>();
113
    }
114
115
    final public void initialize(final RequestMonitor rm) {
85
        fTracker = new DsfServicesTracker(getBundleContext(), fSession.getId());
116
        fTracker = new DsfServicesTracker(getBundleContext(), fSession.getId());
86
        fStartupNumber = fSession.getAndIncrementServiceStartupCounter();
117
        fStartupNumber = fSession.getAndIncrementServiceStartupCounter();
118
        performInitialization(
119
                new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
120
                    @Override
121
                    protected void handleSuccess() {
122
                    	if (getClassNamesToRegister() != null) {
123
                    		// Once all the initialization has been performed, we need to register
124
                    		// the service to make it available to be used.
125
                    		register(getClassNamesToRegister(), getPropertiesToRegister());
126
                    	}
127
                        rm.done();
128
                    }});
129
    }
130
    
131
    /** @since 2.2 */
132
    protected void performInitialization(RequestMonitor rm) {
87
        rm.done();
133
        rm.done();
88
    }
134
    }
89
        
135
        
90
    public void shutdown(RequestMonitor rm) {
136
    final public void shutdown(RequestMonitor rm) {
91
        fTracker.dispose();
137
    	unregister();
92
        fTracker = null;
138
    	performShutdown(rm);
139
    }
140
141
    /** @since 2.2 */
142
    protected void performShutdown(RequestMonitor rm) {
143
    	fTracker.dispose();
144
    	fTracker = null;
93
        rm.done();
145
        rm.done();
94
    }
146
    }
95
    
147
96
    /**
148
    /**
97
	 * @since 2.0
149
	 * @since 2.0
98
	 */
150
	 */
Lines 117-126 Link Here
117
	 * 
169
	 * 
118
	 * @param classes
170
	 * @param classes
119
	 *            The class names under which the service can be located. For
171
	 *            The class names under which the service can be located. For
120
	 *            convenience, [classes] need not contain {@link IDsfService} or
172
	 *            convenience, [classes] need not contain {@link IDsfService} 
121
	 *            the runtime class of this object; they are automatically added
173
	 *            TODO or the runtime class of this object; they are automatically added
122
	 *            if not present. The complete list of classes the service ends
174
	 *            if not present (we modify the caller's object). 
123
	 *            up being registered in OSGi with is recorded and made
175
	 *            The complete list of classes the service ends
176
	 *            up being registered in OSGi with is recorded and also made
124
	 *            available via
177
	 *            available via
125
	 *            <code>getProperties().get(Constants.OBJECTCLASS)</code>
178
	 *            <code>getProperties().get(Constants.OBJECTCLASS)</code>
126
	 * @param properties
179
	 * @param properties
Lines 136-187 Link Here
136
	 *            session associated with the service.
189
	 *            session associated with the service.
137
	 */
190
	 */
138
    @SuppressWarnings({ "rawtypes", "unchecked" })
191
    @SuppressWarnings({ "rawtypes", "unchecked" })
139
    protected void register(String[] classes, Dictionary properties) {
192
    private void register(List<String> classes, Dictionary properties) {
193
    	assert fRegistration == null;
140
    	
194
    	
141
    	/*
142
    	 * If this service has already been registered, make sure we
143
    	 * keep the names it has been registered with.  However, we
144
    	 * must trigger a new registration or else OSGI will keep the two
145
    	 * registration separate. 
146
    	 */
147
    	if (fRegistration != null) {
148
    		String[] previousClasses = (String[])fRegistration.getReference().getProperty(Constants.OBJECTCLASS);
149
    		
150
            // Use a HashSet to avoid duplicates
151
        	Set<String> newClasses = new HashSet<String>();
152
        	newClasses.addAll(Arrays.asList(previousClasses));
153
        	newClasses.addAll(Arrays.asList(classes));
154
        	classes = newClasses.toArray(new String[0]);
155
156
        	/*
157
        	 * Also keep all previous properties.
158
        	 */
159
            if (fProperties != null) {
160
            	for (Enumeration e = fProperties.keys() ; e.hasMoreElements();) {
161
            		Object key = e.nextElement();
162
            		Object value = fProperties.get(key);
163
            		properties.put(key, value);
164
            	}
165
            }
166
            
167
        	// Now, cancel the previous registration
168
    		unregister();
169
    	}
170
        /*
195
        /*
171
         * Ensure that the list of classes contains the base DSF service 
196
         * Ensure that the list of classes contains the base DSF service interface.
172
         * interface, as well as the actual class type of this object.
173
         */
197
         */
174
        if (!Arrays.asList(classes).contains(IDsfService.class.getName())) {
198
        if (!classes.contains(IDsfService.class.getName())) {
175
            String[] newClasses = new String[classes.length + 1];
199
            classes.add(0, IDsfService.class.getName());
176
            System.arraycopy(classes, 0, newClasses, 1, classes.length);
177
            newClasses[0] = IDsfService.class.getName();
178
            classes = newClasses;
179
        }
200
        }
180
        if (!Arrays.asList(classes).contains(getClass().getName())) {
201
181
            String[] newClasses = new String[classes.length + 1];
202
        /*
182
            System.arraycopy(classes, 0, newClasses, 1, classes.length);
203
          TODO
183
            newClasses[0] = getClass().getName();
204
          I think we should remove this, although it may cause problems to existing extenders.
184
            classes = newClasses;
205
         
206
         The reason is that with the new getClassNamesToRegiter() method, I can see someone doing
207
         something like this
208
        
209
         BaseClass {
210
           protected List<String> getClassNamesToRegiter() {
211
              return new ArrayList<String>();
212
              // Here the designer did not explicitly add
213
              // BaseClass.class.getName() to the list of names to register
214
              // because he relied on AbstractDsfService.register() to add
215
              // it automatically.
216
           }
217
         };
218
        
219
         DerivedClass extends baseClass {
220
           protected List<String> getClassNamesToRegiter() {
221
              List<String> classes = super.getClassNamesToRegiter();
222
              
223
              // PROBLEM, classes does not contain BaseClass.class.getName()
224
              // and AbstractDsfService.register() won't add it!
225
              
226
              classes.add(DerivedClass.class.getName());
227
              return classes;
228
           }
229
         };
230
         */
231
        /*
232
         * Ensure that the list of classes contains the actual class type of this object.
233
         */        
234
        if (!classes.contains(getClass().getName())) {
235
        	classes.add(0, getClass().getName());
185
        }
236
        }
186
        /*
237
        /*
187
         * Make sure that the session ID is set in the service properties.
238
         * Make sure that the session ID is set in the service properties.
Lines 190-196 Link Here
190
         */
241
         */
191
        properties.put(PROP_SESSION_ID, getSession().getId());
242
        properties.put(PROP_SESSION_ID, getSession().getId());
192
        fProperties = properties;
243
        fProperties = properties;
193
        fRegistration = getBundleContext().registerService(classes, this, properties);
244
        fRegistration = getBundleContext().registerService(classes.toArray(new String[classes.size()]), this, properties);
194
        
245
        
195
        /*
246
        /*
196
         * Retrieve the OBJECTCLASS property directly from the service 
247
         * Retrieve the OBJECTCLASS property directly from the service 
Lines 248-254 Link Here
248
     * De-registers this service.
299
     * De-registers this service.
249
     *
300
     *
250
     */
301
     */
251
    protected void unregister() {
302
    private void unregister() {
252
    	if (fRegistration != null) {
303
    	if (fRegistration != null) {
253
    		fRegistration.unregister();
304
    		fRegistration.unregister();
254
    	}
305
    	}
(-)src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java (-16 / +14 lines)
Lines 12-18 Link Here
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.HashMap;
14
import java.util.HashMap;
15
import java.util.Hashtable;
15
import java.util.List;
16
import java.util.Map;
16
import java.util.Map;
17
17
18
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
18
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
Lines 22-29 Link Here
22
import org.eclipse.cdt.dsf.concurrent.Sequence.Step;
22
import org.eclipse.cdt.dsf.concurrent.Sequence.Step;
23
import org.eclipse.cdt.dsf.datamodel.DMContexts;
23
import org.eclipse.cdt.dsf.datamodel.DMContexts;
24
import org.eclipse.cdt.dsf.datamodel.IDMContext;
24
import org.eclipse.cdt.dsf.datamodel.IDMContext;
25
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
26
import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension;
27
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
25
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
28
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
26
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
29
import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
27
import org.eclipse.cdt.dsf.gdb.internal.tracepointactions.ITracepointAction;
Lines 59-69 Link Here
59
	}
57
	}
60
58
61
	/* (non-Javadoc)
59
	/* (non-Javadoc)
62
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
60
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#performInitialization
61
	 * (org.eclipse.cdt.dsf.concurrent.RequestMonitor)
63
	 */
62
	 */
64
	@Override
63
	@Override
65
	public void initialize(final RequestMonitor rm) {
64
	protected void performInitialization(final RequestMonitor rm) {
66
		super.initialize(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
65
		super.performInitialization(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {			
67
			@Override
66
			@Override
68
			protected void handleSuccess() {
67
			protected void handleSuccess() {
69
				doInitialize(rm);
68
				doInitialize(rm);
Lines 77-96 Link Here
77
		fRunControl = getServicesTracker().getService(IMIRunControl.class);
76
		fRunControl = getServicesTracker().getService(IMIRunControl.class);
78
        fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
77
        fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
79
78
80
		// Register this service
81
		register(new String[] { IBreakpoints.class.getName(),
82
		                        IBreakpointsExtension.class.getName(),
83
								MIBreakpoints.class.getName(),
84
				 				GDBBreakpoints_7_0.class.getName() },
85
				new Hashtable<String, String>());
86
87
		rm.done();
79
		rm.done();
88
	}
80
	}
81
	
82
	@Override
83
	protected List<String> getClassNamesToRegister() {
84
		List<String> classes = super.getClassNamesToRegister();
85
		classes.add(GDBBreakpoints_7_0.class.getName());
86
		return classes;
87
	}
89
88
90
	@Override
89
	@Override
91
	public void shutdown(RequestMonitor requestMonitor) {
90
	public void performShutdown(RequestMonitor requestMonitor) {
92
        unregister();
91
		super.performShutdown(requestMonitor);
93
		super.shutdown(requestMonitor);
94
	}
92
	}
95
93
96
	/**
94
	/**
(-)src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java (-12 / +16 lines)
Lines 13-19 Link Here
13
13
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.HashMap;
15
import java.util.HashMap;
16
import java.util.Hashtable;
17
import java.util.Iterator;
16
import java.util.Iterator;
18
import java.util.List;
17
import java.util.List;
19
import java.util.Map;
18
import java.util.Map;
Lines 289-299 Link Here
289
	}
288
	}
290
289
291
	/* (non-Javadoc)
290
	/* (non-Javadoc)
292
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
291
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#performInitialization(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
293
	 */
292
	 */
294
	@Override
293
	@Override
295
	public void initialize(final RequestMonitor rm) {
294
	protected void performInitialization(final RequestMonitor rm) {
296
		super.initialize(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
295
		super.performInitialization(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {			
297
			@Override
296
			@Override
298
			protected void handleSuccess() {
297
			protected void handleSuccess() {
299
				doInitialize(rm);
298
				doInitialize(rm);
Lines 315-335 Link Here
315
        // Register for the useful events
314
        // Register for the useful events
316
		getSession().addServiceEventListener(this, null);
315
		getSession().addServiceEventListener(this, null);
317
316
318
		// Register this service
319
		register(new String[] { IBreakpoints.class.getName(), IBreakpointsExtension.class.getName(), MIBreakpoints.class.getName() },
320
				new Hashtable<String, String>());
321
322
		rm.done();
317
		rm.done();
323
	}
318
	}
324
319
320
	@Override
321
	protected List<String> getClassNamesToRegister() {
322
		List<String> names = new ArrayList<String>();
323
		names.add(IBreakpoints.class.getName());
324
		names.add(IBreakpointsExtension.class.getName());
325
		names.add(MIBreakpoints.class.getName());
326
327
		return names;
328
	}
329
	
325
	/* (non-Javadoc)
330
	/* (non-Javadoc)
326
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
331
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#performShutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
327
	 */
332
	 */
328
	@Override
333
	@Override
329
	public void shutdown(final RequestMonitor rm) {
334
	protected void performShutdown(final RequestMonitor rm) {
330
		unregister();
331
		getSession().removeServiceEventListener(this);
335
		getSession().removeServiceEventListener(this);
332
		super.shutdown(rm);
336
		super.performShutdown(rm);
333
	}
337
	}
334
338
335
	/* (non-Javadoc)
339
	/* (non-Javadoc)

Return to bug 341660