1 /******************************************************************************* 2 * Copyright (c) 2003, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Patrik Suzzi <psuzzi@gmail.com> - Bug 501590 14 *******************************************************************************/ 15 package org.eclipse.ui.navigator; 16 17 import java.util.Set; 18 19 import org.eclipse.jface.viewers.IContentProvider; 20 import org.eclipse.jface.viewers.ILabelProvider; 21 import org.eclipse.jface.viewers.IStructuredContentProvider; 22 import org.eclipse.jface.viewers.ITreeContentProvider; 23 import org.eclipse.jface.viewers.ViewerSorter; 24 import org.eclipse.ui.IMemento; 25 import org.eclipse.ui.ISaveablesSource; 26 27 /** 28 * 29 * Manages content extensions for extensible viewers and provides reusable 30 * services for filters, sorting, the activation of content extensions, and DND. 31 * The service can locate the appropriate providers (for contents or labels) for 32 * an element and provide a ready-to-go {@link ITreeContentProvider} and 33 * {@link ILabelProvider} for viewers that wish to take advantage of the 34 * <b>org.eclipse.ui.navigator.navigatorContent</b> extensions defined for a 35 * particular <i>viewerId</i>. 36 * 37 * <p> 38 * Clients can get the instance of this associated with the 39 * {@link CommonNavigator} using 40 * {@link CommonNavigator#getNavigatorContentService()}. 41 * </p> 42 * 43 * <p> 44 * Clients may contribute logical extensions using 45 * <b>org.eclipse.ui.navigator.navigatorContent</b>. Each extension has three 46 * states which determine whether the extension is used by the content service: 47 * </p> 48 * <ul> 49 * <li><i>visible</i>: If a content extension id matches a 50 * <b>viewerContentBinding</b> for the <i>viewerId</i> of this content service, 51 * then the extension is <i>visible</i>. Visible extensions may only be 52 * configured through <b>viewerContentBinding</b>s.</li> 53 * 54 * <li><i>active</i>: The active state may be set to a default using the 55 * <i>activeByDefault</i> attribute of <b>navigatorContent</b>. Users may toggle 56 * the <i>active</i> state through the "Filters and Customization" dialog. 57 * Clients may also configure the active extensions using 58 * {@link INavigatorActivationService#activateExtensions(String[], boolean)} or 59 * {@link INavigatorActivationService#deactivateExtensions(String[], boolean)} 60 * from the {@link #getActivationService() Activation Service}</li> 61 * 62 * <li><i>enabled</i>: An extension is <i>enabled</i> for an element if the 63 * extension contributed that element or if the element is described in the 64 * <i>triggerPoints</i> element of the <b>navigatorContent</b> extension. The 65 * findXXX() methods search for <i>enabled</i> extensions.</li> 66 * </ul> 67 * <p> 68 * A new instance of the content service should be created for each viewer. 69 * Clients should use {@link #createCommonContentProvider()} and 70 * {@link #createCommonLabelProvider()} for the viewer. Each content service 71 * tracks the viewer it is attached to. Clients may create the content service 72 * with a viewer using 73 * ({@link NavigatorContentServiceFactory#createContentService(String)}). 74 * Alternatively, when the content provider is created and set on a viewer, 75 * {@link IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, Object, Object)} 76 * will be called and the content provider will update the viewer used by its 77 * backing content service. Therefore, only each content service has exactly one 78 * content provider and one label provider. 79 * </p> 80 * <p> 81 * Extensions may also coordinate their behavior through a 82 * {@link IExtensionStateModel state model}. The state model holds properties 83 * and supports property change listeners. Actions can toggle the setting of 84 * properties and the corresponding content/label providers will respond to 85 * property change event. Each <b>navigatorContent</b> extension has its own 86 * contained state model keyed off of the content extension id. 87 * </p> 88 * <p> 89 * Clients may respond when content extensions are loaded by attaching a 90 * {@link INavigatorContentServiceListener} to the content service. 91 * </p> 92 * <p> 93 * Some extensions may provide content or label providers which implement 94 * {@link IMemento}. Clients must call {@link #restoreState(IMemento)} and 95 * {@link #saveState(IMemento)} at the appropriate times for these extensions to 96 * prepare themselves with the memento. 97 * </p> 98 * 99 * @since 3.2 100 * @noimplement This interface is not intended to be implemented by clients. 101 * @noextend This interface is not intended to be extended by clients. 102 * 103 */ 104 public interface INavigatorContentService { 105 106 /** 107 * Create a Content Provider which will use an enhanced delegation model to 108 * locate extension content providers using this content service for each 109 * element in the tree. 110 * 111 * <p> 112 * The content provider returned will populate the root of the viewer in one 113 * of two ways. 114 * <p> 115 * In the first approach, the content provider will seek out content 116 * extensions which are bound using a <b>viewerContentBinding</b>. If any 117 * of the found <b>viewerContentBindings</b> declare the <i>isRoot</i> 118 * attribute on as true, then that set of extensions will be consulted for 119 * the root elements of the tree. The input of the viewer will be supplied 120 * to each of their {@link IStructuredContentProvider#getElements(Object)} 121 * methods and aggregate the results for the root of the viewer. 122 * </p> 123 * <p> 124 * In the second approach, if no <b>viewerContentBindings</b> declare 125 * <i>isRoot</i> as true, then all matching extensions are consulted based 126 * on their <b>triggerPoints</b> expression in the <b>navigatorContent</b> 127 * extension. Any matching extensions are then consulted via their 128 * {@link IStructuredContentProvider#getElements(Object)} methods and the 129 * results are aggregated into the root. 130 * </p> 131 * <p> 132 * After the root is populated, the children of each root element are 133 * determined by consulting the source extension and all extension which 134 * describe the element in their <b>triggerPoints</b> expression. 135 * </p> 136 * <p> 137 * If clients wish to use a viewer other than the CommonViewer, then they 138 * are responsible for creating the content provider, and setting it on 139 * their viewer. 140 * </p> 141 * 142 * @return An enhanced content provider that will use this content service 143 * to drive the viewer. 144 */ createCommonContentProvider()145 ITreeContentProvider createCommonContentProvider(); 146 147 /** 148 * Create a Label Provider which will use an enhanced delegation model to 149 * locate extension label providers using this content service for each 150 * element in the tree. 151 * 152 * <p> 153 * The label of each element is determined by consulting the source of the 154 * element. If the source chooses to return null, then other extensions 155 * which declare the element in their <b>triggerPoints</b> extension are 156 * consulted. The first non-null value is used (including the empty label). 157 * </p> 158 * 159 * <p> 160 * If clients wish to use a viewer other than the CommonViewer, then they 161 * are responsible for creating the label provider, and setting it on their 162 * viewer. 163 * </p> 164 * 165 * @return An enhanced label provider that will use this content service to 166 * drive labels in the viewer. 167 */ createCommonLabelProvider()168 ILabelProvider createCommonLabelProvider(); 169 170 /** 171 * 172 * @return The description provider for this content service. 173 */ createCommonDescriptionProvider()174 IDescriptionProvider createCommonDescriptionProvider(); 175 176 /** 177 * The state model stores properties associated with the extension. Each 178 * content extension has its own contained state model. Components of the 179 * extension (content provider, label provider, action providers, etc) may 180 * attach themselves as listeners to the model ({@link IExtensionStateModel#addPropertyChangeListener(org.eclipse.jface.util.IPropertyChangeListener)}) 181 * and respond to changes to the values of the properties. 182 * 183 * @param anExtensionId 184 * The extension id defined by a <b>navigatorContent</b> 185 * extension. 186 * @return The state model for the given extension id. 187 */ findStateModel(String anExtensionId)188 IExtensionStateModel findStateModel(String anExtensionId); 189 190 /** 191 * The viewer id is used to locate matching <b>viewerContentBindings</b>. 192 * In general, this would be the id of the view defined by a 193 * <b>org.eclipse.ui.views</b> extension. However, there is no formal 194 * requirement that this is the case. 195 * 196 * @return The viewerId used to create this content service. 197 */ getViewerId()198 String getViewerId(); 199 200 /** 201 * The viewer descriptor provides some basic information about the abstract 202 * viewer that uses this content service. 203 * 204 * @return The viewer descriptor for this content service. 205 * @see INavigatorViewerDescriptor 206 */ getViewerDescriptor()207 INavigatorViewerDescriptor getViewerDescriptor(); 208 209 /** 210 * See <a href="INavigatorContentService.html#active">above</a> for the 211 * definition of <i>active</i>. 212 * 213 * @param anExtensionId 214 * The unqiue identifier from a content extension. 215 * @return True if and only if the given extension id is <i>active</i> for 216 * this content service. 217 * @see INavigatorContentService For more information on what <i>active</i> 218 * means. 219 * 220 */ isActive(String anExtensionId)221 boolean isActive(String anExtensionId); 222 223 /** 224 * See <a href="INavigatorContentService.html#visible">above</a> for the 225 * definition of <i>visible</i>. 226 * 227 * @param anExtensionId 228 * The unqiue identifier from a content extension. 229 * @return True if and only if the given extension id is <i>visible</i> to 230 * this content service. 231 * @see INavigatorContentService For more information on what <i>visible</i> 232 * means. 233 */ isVisible(String anExtensionId)234 boolean isVisible(String anExtensionId); 235 236 /** 237 * Return the set of <i>visible</i> extension ids for this content service, 238 * which includes those that are bound through <b>viewerContentBinding</b>s 239 * and those that are bound through 240 * {@link #bindExtensions(String[], boolean)}. 241 * 242 * @return The set of <i>visible</i> extension ids for this content service 243 */ getVisibleExtensionIds()244 String[] getVisibleExtensionIds(); 245 246 /** 247 * Return the set of <i>visible</i> content descriptors for this content 248 * service, which includes those that are bound through 249 * <b>viewerContentBinding</b>s and those that are bound through 250 * {@link #bindExtensions(String[], boolean)}. 251 * 252 * @return The set of <i>visible</i> content descriptors for this content 253 * service 254 */ getVisibleExtensions()255 INavigatorContentDescriptor[] getVisibleExtensions(); 256 257 /** 258 * Bind the set of given extensions to this content service. Programmatic 259 * bindings allow clients to make extensions <i>visible</i> to an instance 260 * of the content service by appending to the bindings declared through 261 * <b>org.eclipse.ui.navigator.viewer</b>. Programmatic bindings are not 262 * persisted and are not remembered or propagated to other instances of the 263 * INavigatorContentService in the same session. Programmatic bindings 264 * cannot be undone for a given instance of the INavigatorContentService and 265 * do not override declarative bindings. 266 * <p> 267 * Once a content extension has been bound to the INavigatorContentService, 268 * clients may use 269 * {@link INavigatorActivationService#activateExtensions(String[], boolean) } 270 * or 271 * {@link INavigatorActivationService#deactivateExtensions(String[], boolean) } 272 * to control the <i>activation</i> state of the extension. See 273 * {@link INavigatorContentService} for more information on the difference 274 * between <i>visible</i> and <i>active</i>. 275 * </p> 276 * 277 * @param extensionIds 278 * The list of extensions to make visible. 279 * @param isRoot 280 * whether the context provider should be a root content provider 281 * @return A list of all INavigatorContentDescriptors that correspond to the 282 * given extensionIds. 283 */ bindExtensions(String[] extensionIds, boolean isRoot)284 INavigatorContentDescriptor[] bindExtensions(String[] extensionIds, 285 boolean isRoot); 286 287 /** 288 * Restore the state associated with the memento. 289 * 290 * @param aMemento 291 * The memento for extensions to use when restoring previous 292 * settings. 293 */ restoreState(IMemento aMemento)294 void restoreState(IMemento aMemento); 295 296 /** 297 * Persist any session-to-session state with the memento. 298 * 299 * @param aMemento 300 * The memento for extensions to use when persisting previous 301 * settings. 302 */ saveState(IMemento aMemento)303 void saveState(IMemento aMemento); 304 305 /** 306 * Add a listener to be notified whenever an extension is loaded. 307 * 308 * @param aListener 309 * A listener to be attached. 310 */ addListener(INavigatorContentServiceListener aListener)311 void addListener(INavigatorContentServiceListener aListener); 312 313 /** 314 * Remove a listener (by identity) from the set of listeners. 315 * 316 * @param aListener 317 * A listener to be detached. 318 */ removeListener(INavigatorContentServiceListener aListener)319 void removeListener(INavigatorContentServiceListener aListener); 320 321 /** 322 * The root content providers are recalculated by this method. The attached 323 * viewer is also refreshed as a result of this method. 324 * 325 */ update()326 void update(); 327 328 /** 329 * Release any acquired resources and instantiated content extensions. 330 * 331 */ dispose()332 void dispose(); 333 334 /** 335 * Search for extensions that declare the given element in their 336 * <b>triggerPoints</b> expression or that indicate they should be bound as 337 * a root extension. 338 * 339 * @param anElement 340 * The element to use in the query 341 * @return The set of {@link INavigatorContentExtension}s that are 342 * <i>visible</i> and <i>active</i> for this content service and 343 * either declared through a 344 * <b>org.eclipse.ui.navigator.viewer/viewerContentBinding</b> to 345 * be a root element or have a <b>triggerPoints</b> expression that 346 * is <i>enabled</i> for the given element. 347 */ findRootContentExtensions(Object anElement)348 Set findRootContentExtensions(Object anElement); 349 350 /** 351 * Search for extensions that declare the given element in their 352 * <b>triggerPoints</b> expression. 353 * 354 * @param anElement 355 * The element to use in the query 356 * @return The set of {@link INavigatorContentExtension}s that are 357 * <i>visible</i> and <i>active</i> for this content service and 358 * have a <b>triggerPoints</b> expression that is <i>enabled</i> 359 * for the given element. 360 */ findContentExtensionsByTriggerPoint(Object anElement)361 Set findContentExtensionsByTriggerPoint(Object anElement); 362 363 /** 364 * Search for extensions that declare the given element in their 365 * <b>possibleChildren</b> expression. 366 * 367 * @param anElement 368 * The element to use in the query 369 * @return The set of {@link INavigatorContentExtension}s that are 370 * <i>visible</i> and <i>active</i> for this content service and 371 * have a <b>possibleChildren</b> expression that is <i>enabled</i> 372 * for the given element. 373 */ findContentExtensionsWithPossibleChild(Object anElement)374 Set findContentExtensionsWithPossibleChild(Object anElement); 375 376 /** 377 * The filter service can provide the available filters for the viewer, and 378 * manage which filters are <i>active</i>. 379 * 380 * @return An {@link INavigatorFilterService} that can provide information 381 * to a viewer about what filters are <i>visible</i> and <i>active</i>. 382 */ getFilterService()383 INavigatorFilterService getFilterService(); 384 385 /** 386 * The sorter service provides the appropriate sorter based on the current 387 * items being sorted. By default, the CommonViewer uses 388 * {@link CommonViewerSorter} which delegates to this service. Clients do 389 * not need to provide their own {@link ViewerSorter} unless they wish to 390 * override this functionality. 391 * 392 * @return An {@link INavigatorSorterService} that can provide 393 * {@link ViewerSorter} based on the context of the parent. 394 */ getSorterService()395 INavigatorSorterService getSorterService(); 396 397 /** 398 * The pipeline service calculates the appropriate viewer modification or 399 * refresh that should be applied for viewers that wish to take advantage of 400 * the model pipelining that some extensions use to massage or reshape 401 * contents in the viewer. Clients that use the {@link CommonViewer} do not 402 * need to be concerned with this service as the refreshes are automatically 403 * computed using this service. 404 * 405 * 406 * @return The {@link INavigatorPipelineService} which can determine the 407 * correct updates to apply to a viewer. 408 */ getPipelineService()409 INavigatorPipelineService getPipelineService(); 410 411 /** 412 * The DND Service provides instances of {@link CommonDragAdapterAssistant} 413 * and {@link CommonDropAdapterAssistant} for this content service. 414 * 415 * @return The {@link INavigatorDnDService} which can add additional 416 * TransferTypes for the DragAdapter and setup the data correctly 417 * for those extended Transfer Types. 418 */ getDnDService()419 INavigatorDnDService getDnDService(); 420 421 /** 422 * The activation service is used to toggle whether certain extensions have 423 * the opportunity to contribute content and/or actions. 424 * 425 * @return The {@link INavigatorActivationService} for this content service. 426 */ getActivationService()427 INavigatorActivationService getActivationService(); 428 429 /** 430 * The saveable service helps implementing {@link ISaveablesSource}. 431 * 432 * @return the {@link INavigatorSaveablesService} for this content service. 433 */ getSaveablesService()434 INavigatorSaveablesService getSaveablesService(); 435 436 /** 437 * Return the content extension for the given id. 438 * 439 * @param anExtensionId The id used to define the <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent</b> extension. 440 * @return An instance of the content extension for the given extension id. May return <b>null</b> if the id is invalid. 441 */ getContentExtensionById(String anExtensionId)442 public INavigatorContentExtension getContentExtensionById(String anExtensionId); 443 444 /** 445 * Return the content extension for the given id. 446 * 447 * @param anExtensionId The id used to define the <b>org.eclipse.ui.navigator.navigatorContent/navigatorContent</b> extension. 448 * @return An instance of the content extension for the given extension id. May return <b>null</b> if the id is invalid. 449 * @since 3.3 450 */ getContentDescriptorById(String anExtensionId)451 public INavigatorContentDescriptor getContentDescriptorById(String anExtensionId); 452 453 454 455 } 456