Project

General

Profile

Download (11.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2003, 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.ui.internal.navigator.extensions;
12

    
13
import java.util.Iterator;
14
import java.util.LinkedHashSet;
15
import java.util.Set;
16

    
17
import org.eclipse.core.runtime.Assert;
18
import org.eclipse.core.runtime.SafeRunner;
19

    
20
import org.eclipse.jface.viewers.ILabelProvider;
21
import org.eclipse.jface.viewers.ILabelProviderListener;
22
import org.eclipse.jface.viewers.ITreeContentProvider;
23

    
24
import org.eclipse.ui.IMemento;
25
import org.eclipse.ui.internal.navigator.NavigatorContentService;
26
import org.eclipse.ui.internal.navigator.NavigatorSafeRunnable;
27
import org.eclipse.ui.internal.navigator.Policy;
28
import org.eclipse.ui.navigator.ICommonLabelProvider;
29
import org.eclipse.ui.navigator.IExtensionStateModel;
30
import org.eclipse.ui.navigator.IMementoAware;
31
import org.eclipse.ui.navigator.INavigatorContentDescriptor;
32
import org.eclipse.ui.navigator.INavigatorContentExtension;
33

    
34
/**
35
 * 
36
 * @since 3.2
37
 */
38
public class NavigatorContentExtension implements IMementoAware,
39
		INavigatorContentExtension {
40

    
41
	private static final NavigatorContentExtension[] NO_EXTENSIONS = new NavigatorContentExtension[0];
42

    
43
	private NavigatorContentService contentService;
44

    
45
	private NavigatorContentDescriptor descriptor;
46

    
47
	private SafeDelegateTreeContentProvider contentProvider;
48

    
49
	private ICommonLabelProvider labelProvider;
50

    
51
	private boolean labelProviderInitializationFailed = false;
52

    
53
	private boolean contentProviderInitializationFailed = false;
54

    
55
	private boolean isDisposed = false;
56

    
57
	private IMemento appliedMemento;
58

    
59
	private StructuredViewerManager viewerManager;
60

    
61
	/**
62
	 * Create an object to manage the instantiated elements from the extension.
63
	 * 
64
	 * @param aDescriptor
65
	 *            The descriptor that knows how to create elements and knows the
66
	 *            id of the extension
67
	 * @param aContentService
68
	 *            The content service that will manage this extension
69
	 * @param aViewerManager
70
	 *            The viewer manager that knows how to initialize the content
71
	 *            provider created by this extension.
72
	 */
73
	public NavigatorContentExtension(NavigatorContentDescriptor aDescriptor,
74
			NavigatorContentService aContentService,
75
			StructuredViewerManager aViewerManager) {
76
		super();
77
		Assert.isNotNull(aDescriptor);
78

    
79
		descriptor = aDescriptor;
80
		contentService = aContentService;
81
		viewerManager = aViewerManager;
82
	}
83

    
84
	/*
85
	 * (non-Javadoc)
86
	 * 
87
	 * @see
88
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
89
	 * #getId()
90
	 */
91
	public String getId() {
92
		return descriptor.getId();
93
	}
94

    
95
	/*
96
	 * (non-Javadoc)
97
	 * 
98
	 * @see
99
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
100
	 * #getDescriptor()
101
	 */
102
	public INavigatorContentDescriptor getDescriptor() {
103
		return descriptor;
104
	}
105

    
106
	/*
107
	 * (non-Javadoc)
108
	 * 
109
	 * @see
110
	 * org.eclipse.ui.navigator.INavigatorContentExtension#getContentProvider()
111
	 */
112
	public ITreeContentProvider getContentProvider() {
113
		return internalGetContentProvider().getDelegateContentProvider();
114
	}
115

    
116
	/**
117
	 * 
118
	 * @return The internal content provider that is wrapped by this extension.
119
	 */
120
	public SafeDelegateTreeContentProvider internalGetContentProvider() {
121
		if (contentProvider != null || contentProviderInitializationFailed) {
122
			return contentProvider;
123
		}
124
		synchronized (this) {
125
			SafeRunner.run(new NavigatorSafeRunnable() {
126
				public void run() throws Exception {
127
					if (contentProvider == null) {
128
						ITreeContentProvider treeContentProvider = descriptor
129
								.createContentProvider();
130
						if (treeContentProvider != null) {
131
							contentProvider = new SafeDelegateTreeContentProvider(
132
									treeContentProvider);
133
							contentProvider.init(new CommonContentExtensionSite(getId(),
134
									contentService, appliedMemento));
135
							viewerManager.initialize(contentProvider);
136
						} else {
137
							contentProvider = new SafeDelegateTreeContentProvider(
138
									SkeletonTreeContentProvider.INSTANCE);
139
						}
140
					}
141
				}
142

    
143
				public void handleException(Throwable e) {
144
					super.handleException(e);
145
					contentProviderInitializationFailed = true;
146
				}
147
			});
148

    
149
			if (contentProviderInitializationFailed) {
150
				contentProvider = new SafeDelegateTreeContentProvider(
151
						SkeletonTreeContentProvider.INSTANCE);
152
			}
153
		}
154
		return contentProvider;
155
	}
156

    
157
	/*
158
	 * (non-Javadoc)
159
	 * 
160
	 * @see
161
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
162
	 * #getLabelProvider()
163
	 */
164
	public ICommonLabelProvider getLabelProvider() {
165
		if (labelProvider != null || labelProviderInitializationFailed) {
166
			return labelProvider;
167
		}
168
		synchronized (this) {
169
			SafeRunner.run(new NavigatorSafeRunnable() {
170
				public void run() throws Exception {
171
					if (labelProvider == null) {
172
						ILabelProvider tempLabelProvider = descriptor.createLabelProvider();
173

    
174
						if (tempLabelProvider instanceof ICommonLabelProvider) {
175
							labelProvider = (ICommonLabelProvider) tempLabelProvider;
176
							labelProvider.init(new CommonContentExtensionSite(getId(),
177
									contentService, appliedMemento));
178
						} else {
179
							labelProvider = new SafeDelegateCommonLabelProvider(tempLabelProvider);
180
						}
181

    
182
						labelProvider.addListener((ILabelProviderListener) contentService
183
								.createCommonLabelProvider());
184
					}
185
				}
186

    
187
				public void handleException(Throwable e) {
188
					super.handleException(e);
189
					labelProviderInitializationFailed = true;
190
				}
191
			});
192
			if (labelProviderInitializationFailed) {
193
				labelProvider = SkeletonLabelProvider.INSTANCE;
194
			}
195
		}
196
		return labelProvider;
197
	}
198

    
199
	/**
200
	 * Dispose of any resources acquired during the lifecycle of the extension.
201
	 * 
202
	 */
203
	public void dispose() {
204
		try {
205
			synchronized (this) {
206

    
207
				SafeRunner.run(new NavigatorSafeRunnable() {
208
					public void run() throws Exception {
209
						if (contentProvider != null) {
210
							contentProvider.dispose();
211
						}
212

    
213
					}
214
				});
215

    
216
				SafeRunner.run(new NavigatorSafeRunnable() {
217
					public void run() throws Exception {
218
						if (labelProvider != null) {
219
							labelProvider
220
									.removeListener((ILabelProviderListener) contentService
221
											.createCommonLabelProvider());
222
							labelProvider.dispose();
223
						}
224
					}
225
				});
226

    
227
			}
228
		} finally {
229
			isDisposed = true;
230
		}
231
	}
232

    
233
	/*
234
	 * (non-Javadoc)
235
	 * 
236
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
237
	 */
238
	/*
239
	 * (non-Javadoc)
240
	 * 
241
	 * @see
242
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
243
	 * #getAdapter(java.lang.Class)
244
	 */
245
	public Object getAdapter(Class adapter) {
246
		return null;
247
	}
248

    
249
	/**
250
	 * @return Returns the contentProviderInitializationFailed.
251
	 */
252
	public boolean hasContentProviderInitializationFailed() {
253
		return contentProviderInitializationFailed;
254
	}
255

    
256
	/**
257
	 * @return Returns the labelProviderInitializationFailed.
258
	 */
259
	public boolean hasLabelProviderInitializationFailed() {
260
		return labelProviderInitializationFailed;
261
	}
262

    
263
	/**
264
	 * 
265
	 * @return True if the loading of the content provider has failed.
266
	 */
267
	public boolean hasLoadingFailed() {
268
		return contentProviderInitializationFailed;
269
	}
270

    
271
	/*
272
	 * (non-Javadoc)
273
	 * 
274
	 * @see
275
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
276
	 * #isLoaded()
277
	 */
278
	public boolean isLoaded() {
279
		return contentProvider != null;
280
	}
281

    
282
	public void restoreState(IMemento aMemento) {
283
		synchronized (this) {
284
			appliedMemento = aMemento;
285
			applyMemento(contentProvider);
286
			applyMemento(labelProvider);
287

    
288
		}
289
	}
290

    
291
	public void saveState(IMemento aMemento) {
292
		synchronized (this) {
293
			if (contentProvider != null
294
					&& contentProvider instanceof IMementoAware)
295
				((IMementoAware) contentProvider).saveState(aMemento);
296
			if (labelProvider != null && labelProvider instanceof IMementoAware)
297
				((IMementoAware) labelProvider).saveState(aMemento);
298

    
299
		}
300
	}
301

    
302
	private void applyMemento(IMementoAware target) {
303
		if (target != null) {
304
			target.restoreState(appliedMemento);
305
		}
306

    
307
	}
308

    
309
	protected final void complainDisposedIfNecessary() {
310
		if (isDisposed) {
311
			throw new IllegalStateException("INavigatorContentExtension " //$NON-NLS-1$
312
					+ descriptor.getId() + " is disposed!"); //$NON-NLS-1$
313
		}
314
	}
315

    
316
	/*
317
	 * (non-Javadoc)
318
	 * 
319
	 * @see
320
	 * org.eclipse.ui.internal.navigator.extensions.INavigatorContentExtension
321
	 * #getStateModel()
322
	 */
323
	public IExtensionStateModel getStateModel() {
324
		return contentService.getExtensionStateService()
325
				.getExtensionStateModel(getDescriptor());
326
	}
327

    
328
	/**
329
	 * @param anElement
330
	 *            The element for the query.
331
	 * @return Returns the overridingExtensions.
332
	 */
333
	public NavigatorContentExtension[] getOverridingExtensionsForTriggerPoint(
334
			Object anElement) {
335
		return getOverridingExtensions(anElement, TRIGGER_POINT);
336
	}
337

    
338
	/**
339
	 * 
340
	 * @param anElement
341
	 *            The element for the query.
342
	 * @return Returns the overridingExtensions.
343
	 */
344
	public NavigatorContentExtension[] getOverridingExtensionsForPossibleChild(
345
			Object anElement) {
346
		return getOverridingExtensions(anElement, !TRIGGER_POINT);
347
	}
348

    
349
	/**
350
	 * 
351
	 * @return Returns the overridingExtensions.
352
	 */
353
	public NavigatorContentExtension[] getOverridingExtensions() {
354
		return getOverridingExtensions(null, !TRIGGER_POINT);
355
	}
356

    
357
	private static final boolean TRIGGER_POINT = true;
358
	
359
	/**
360
	 * @param anElement
361
	 *            The element for the query.
362
	 * @return Returns the overridingExtensions.
363
	 */
364
	private NavigatorContentExtension[] getOverridingExtensions(Object anElement,
365
			boolean triggerPoint) {
366
		if (!descriptor.hasOverridingExtensions()) {
367
			return NO_EXTENSIONS;
368
		}
369

    
370
		NavigatorContentDescriptor overridingDescriptor;
371
		Set overridingExtensions = new LinkedHashSet();
372
		for (Iterator contentDescriptorsItr = descriptor.getOverriddingExtensions().iterator(); contentDescriptorsItr
373
				.hasNext();) {
374
			overridingDescriptor = (NavigatorContentDescriptor) contentDescriptorsItr.next();
375

    
376
			if (contentService.isActive(overridingDescriptor.getId())
377
					&& contentService.isVisible(overridingDescriptor.getId())
378
					&& (anElement == null || (triggerPoint ? overridingDescriptor
379
							.isTriggerPoint(anElement) : overridingDescriptor
380
							.isPossibleChild(anElement)))) {
381
				overridingExtensions.add(contentService.getExtension(overridingDescriptor));
382
			}
383
		}
384
		if (overridingExtensions.size() == 0) {
385
			return NO_EXTENSIONS;
386
		}
387
		if (Policy.DEBUG_EXTENSION_SETUP) {
388
			System.out
389
					.println(this
390
							+ " overriding: " + //$NON-NLS-1$
391
							(triggerPoint ? "(trigger pt: " : "(poss child: ") + anElement + "): " + overridingExtensions); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
392
		}
393
		return (NavigatorContentExtension[]) overridingExtensions
394
				.toArray(new NavigatorContentExtension[overridingExtensions.size()]);
395
	}
396

    
397
	/*
398
	 * (non-Javadoc)
399
	 * 
400
	 * @see java.lang.Object#toString()
401
	 */
402
	public String toString() {
403
		return descriptor.toString() + " Instance"; //$NON-NLS-1$
404
	}
405
}
(17-17/29)