KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > NavigatorPipelineService


1 /*******************************************************************************
2  * Copyright (c) 2006 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.ui.internal.navigator;
13
14 import java.util.Arrays JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.LinkedHashSet JavaDoc;
17 import java.util.Set JavaDoc;
18
19 import org.eclipse.jface.viewers.TreePath;
20 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
21 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension;
22 import org.eclipse.ui.navigator.INavigatorContentDescriptor;
23 import org.eclipse.ui.navigator.INavigatorPipelineService;
24 import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
25 import org.eclipse.ui.navigator.PipelinedShapeModification;
26 import org.eclipse.ui.navigator.PipelinedViewerUpdate;
27
28 /**
29  * @since 3.2
30  *
31  */

32 public class NavigatorPipelineService implements INavigatorPipelineService {
33
34     private NavigatorContentService contentService;
35
36     /**
37      * Create a pipeline assistnat for the given content service.
38      *
39      * @param aContentService
40      * The content service that will drive this pipeline assistant.
41      */

42     public NavigatorPipelineService(NavigatorContentService aContentService) {
43         contentService = aContentService;
44     }
45
46     /**
47      * Intercept attempts to add elements directly to the viewer.
48      *
49      * <p>
50      * For content extensions that reshape the structure of children in a
51      * viewer, their overridden extensions may sometimes use optimized refreshes
52      * to add elements to the tree. These attempts must be intercepted and
53      * mapped to the correct set of model elements in the overridding extension.
54      * Clients may add, remove, or modify elements in the given set of added
55      * children. Clients should return a set for downstream extensions to
56      * massage further.
57      * </p>
58      * <p>
59      * <b>Clients should not call any of the add, remove, refresh, or update
60      * methods on the viewer from this method or any code invoked by the
61      * implementation of this method.</b>
62      * </p>
63      *
64      * @param anAddModification
65      * The shape modification which contains the current suggested
66      * parent and children. Clients may modify this parameter
67      * directly and return it as the new shape modification.
68      * @return The new shape modification to use. Clients should <b>never</b>
69      * return <b>null</b> from this method.
70      */

71     public PipelinedShapeModification interceptAdd(
72             PipelinedShapeModification anAddModification) {
73         
74         ContributorTrackingSet trackedSet =(ContributorTrackingSet) anAddModification.getChildren();
75         
76         Set JavaDoc contentDescriptors = contentService.findDescriptorsByTriggerPoint(anAddModification.getParent());
77         
78         
79         for (Iterator JavaDoc descriptorsItr = contentDescriptors.iterator(); descriptorsItr.hasNext();) {
80             INavigatorContentDescriptor descriptor = (INavigatorContentDescriptor) descriptorsItr.next();
81             pipelineInterceptAdd(anAddModification, trackedSet, descriptor);
82         }
83
84         // for consistency, we register the contribution from our best known match
85
registerContribution(anAddModification.getParent(), anAddModification.getChildren().toArray());
86         return anAddModification;
87
88     }
89  
90     /**
91      * @param parent The object to which data was contributed
92      * @param contributions Data contributed to the viewer
93      */

94     private void registerContribution(Object JavaDoc parent, Object JavaDoc[] contributions) {
95          
96         // returns an array sorted by priority
97
Set JavaDoc possibleContributors = contentService.findDescriptorsByTriggerPoint(parent);
98         Set JavaDoc possibleMatches = null;
99         for (int i = 0; i < contributions.length; i++) {
100             // returns an array sorted by reverse priority
101
possibleMatches = contentService.findDescriptorsWithPossibleChild(contributions[i]);
102             NavigatorContentDescriptor[] descriptors = (NavigatorContentDescriptor[]) possibleMatches.toArray(new NavigatorContentDescriptor[possibleMatches.size()]);
103             for (int indx = possibleMatches.size()-1; indx > -1; indx--) {
104                                 
105                 // terminates once the highest priority match is found for this child
106
if(possibleContributors.contains(descriptors[indx])) {
107                     contentService.rememberContribution(descriptors[indx], contributions[i]);
108                     break;
109                 }
110                 
111             }
112         }
113     }
114
115     private void pipelineInterceptAdd(PipelinedShapeModification anAddModification, ContributorTrackingSet trackedSet, INavigatorContentDescriptor descriptor) {
116         if(descriptor.hasOverridingExtensions()) {
117             Set JavaDoc overridingDescriptors = descriptor.getOverriddingExtensions();
118             for (Iterator JavaDoc overridingDescriptorsItr = overridingDescriptors.iterator(); overridingDescriptorsItr
119                     .hasNext();) {
120                 INavigatorContentDescriptor overridingDescriptor = (INavigatorContentDescriptor) overridingDescriptorsItr.next();
121                 if(contentService.isVisible(overridingDescriptor.getId()) && contentService.isActive(overridingDescriptor.getId())) {
122                     trackedSet.setContributor((NavigatorContentDescriptor) overridingDescriptor);
123                     NavigatorContentExtension extension = contentService.getExtension(overridingDescriptor);
124                     ((IPipelinedTreeContentProvider) extension.internalGetContentProvider()).interceptAdd(anAddModification);
125                     trackedSet.setContributor(null);
126                     pipelineInterceptAdd(anAddModification, trackedSet, overridingDescriptor);
127                 }
128             }
129         }
130     }
131      
132
133     /**
134      * Intercept attempts to remove elements directly from the viewer.
135      *
136      * <p>
137      * For content extensions that reshape the structure of children in a
138      * viewer, their overridden extensions may sometimes use optimized refreshes
139      * to remove elements to the tree. These attempts must be intercepted and
140      * mapped to the correct set of model elements in the overridding extension.
141      * Clients may add, remove, or modify elements in the given set of removed
142      * children. Clients should return a set for downstream extensions to
143      * massage further.
144      * </p>
145      * <p>
146      * <b>Clients should not call any of the add, remove, refresh, or update
147      * methods on the viewer from this method or any code invoked by the
148      * implementation of this method.</b>
149      * </p>
150      *
151      * @param aRemoveModification
152      * The shape modification which contains the current suggested
153      * parent and children. Clients may modify this parameter
154      * directly and return it as the new shape modification.
155      * @return The new shape modification to use. Clients should <b>never</b>
156      * return <b>null</b> from this method.
157      */

158     public PipelinedShapeModification interceptRemove(
159             PipelinedShapeModification aRemoveModification) {
160         
161         ContributorTrackingSet trackedSet =(ContributorTrackingSet) aRemoveModification.getChildren();
162
163         Set JavaDoc interestedExtensions = new LinkedHashSet JavaDoc();
164         for (Iterator JavaDoc iter = trackedSet.iterator(); iter.hasNext();) {
165             Object JavaDoc element = (Object JavaDoc) iter.next();
166             if(element instanceof TreePath) {
167                 interestedExtensions.addAll(contentService.findOverrideableContentExtensionsForPossibleChild(((TreePath)element).getLastSegment()));
168             } else {
169                 interestedExtensions = contentService.findOverrideableContentExtensionsForPossibleChild(element);
170                 
171             }
172         }
173         for (Iterator JavaDoc overridingExtensionsIter = interestedExtensions.iterator(); overridingExtensionsIter.hasNext();)
174             pipelineInterceptRemove(aRemoveModification, trackedSet, (NavigatorContentExtension) overridingExtensionsIter.next());
175         return aRemoveModification;
176     }
177     
178
179     private void pipelineInterceptRemove(PipelinedShapeModification aRemoveModification, ContributorTrackingSet trackedSet, NavigatorContentExtension overrideableExtension) {
180         
181         
182         try {
183             NavigatorContentExtension overridingExtension = null;
184             Set JavaDoc overridingExtensions = new LinkedHashSet JavaDoc();
185             for (Iterator JavaDoc iter = trackedSet.iterator(); iter.hasNext();) {
186                 Object JavaDoc element = (Object JavaDoc) iter.next();
187                 if(element instanceof TreePath) {
188                     overridingExtensions.addAll(Arrays.asList(overrideableExtension.getOverridingExtensionsForPossibleChild(((TreePath)element).getLastSegment())));
189                 } else {
190                     overridingExtensions.addAll(Arrays.asList(overrideableExtension.getOverridingExtensionsForPossibleChild(element)));
191                 }
192             }
193              
194             for (Iterator JavaDoc extensionsItr = overridingExtensions.iterator(); extensionsItr.hasNext();) {
195                 overridingExtension = (NavigatorContentExtension) extensionsItr.next();
196                 trackedSet.setContributor((NavigatorContentDescriptor) overridingExtension.getDescriptor());
197                 if (overridingExtension.getContentProvider() instanceof IPipelinedTreeContentProvider) {
198                     ((IPipelinedTreeContentProvider) overridingExtension.getContentProvider()).interceptRemove(aRemoveModification);
199                 }
200                 trackedSet.setContributor(null);
201                 if(overridingExtension.getDescriptor().hasOverridingExtensions())
202                     pipelineInterceptRemove(aRemoveModification, trackedSet, overridingExtension);
203                                                 
204             }
205             
206         } catch (Throwable JavaDoc e) {
207             String JavaDoc msg = e.getMessage() != null ? e.getMessage() : e.toString();
208             NavigatorPlugin.logError(0, msg, e);
209         }
210     }
211
212     /**
213      * Intercept calls to viewer <code>refresh()</code> methods.
214      *
215      * <p>
216      * Clients may modify the given update to add or remove the elements to be
217      * refreshed. Clients may return the same instance that was passed in for
218      * the next downstream extension.
219      * </p>
220      *
221      * <p>
222      * <b>Clients should not call any of the add, remove, refresh, or update
223      * methods on the viewer from this method or any code invoked by the
224      * implementation of this method.</b>
225      * </p>
226      *
227      * @param aRefreshSynchronization
228      * The (current) refresh update to execute against the viewer.
229      * @return The (potentially reshaped) refresh to execute against the viewer.
230      */

231     public boolean interceptRefresh(
232             PipelinedViewerUpdate aRefreshSynchronization) {
233  
234         boolean pipelined = false;
235         Object JavaDoc refreshable = null;
236         Set JavaDoc overrideableExtensions = new LinkedHashSet JavaDoc();
237         for (Iterator JavaDoc iter = aRefreshSynchronization.getRefreshTargets().iterator(); iter.hasNext();) {
238             refreshable = iter.next();
239             overrideableExtensions.addAll(contentService.findOverrideableContentExtensionsForPossibleChild(refreshable));
240         }
241         for (Iterator JavaDoc overrideableExtensionItr = overrideableExtensions.iterator(); overrideableExtensionItr.hasNext();) {
242             pipelined |= pipelineInterceptRefresh((NavigatorContentExtension) overrideableExtensionItr.next(), aRefreshSynchronization, refreshable);
243         }
244
245         return pipelined;
246         
247     }
248
249     private boolean pipelineInterceptRefresh(NavigatorContentExtension overrideableExtension,
250             PipelinedViewerUpdate aRefreshSynchronization, Object JavaDoc refreshable) {
251
252         boolean intercepted = false;
253         
254         NavigatorContentExtension[] overridingExtensionsForPossibleChild = overrideableExtension.getOverridingExtensionsForPossibleChild(refreshable);
255         for (int i=0; i<overridingExtensionsForPossibleChild.length; i++) {
256             try {
257                 if (overridingExtensionsForPossibleChild[i].getContentProvider() instanceof IPipelinedTreeContentProvider) {
258
259                     intercepted |= ((IPipelinedTreeContentProvider) overridingExtensionsForPossibleChild[i]
260                             .getContentProvider())
261                             .interceptRefresh(aRefreshSynchronization);
262                     
263                     if (overridingExtensionsForPossibleChild[i].getDescriptor().hasOverridingExtensions())
264                         intercepted |= pipelineInterceptRefresh(overridingExtensionsForPossibleChild[i], aRefreshSynchronization, refreshable);
265                 }
266             } catch (Throwable JavaDoc e) {
267                 String JavaDoc msg = e.getMessage() != null ? e.getMessage() : e.toString();
268                 NavigatorPlugin.logError(0, msg, e);
269             }
270         }
271
272         return intercepted;
273     }
274     
275
276
277     /**
278      * Intercept calls to viewer <code>update()</code> methods.
279      *
280      * <p>
281      * Clients may modify the given update to add or remove the elements to be
282      * updated. Clients may also add or remove properties for the given targets
283      * to optimize the refresh. Clients may return the same instance that was
284      * passed in for the next downstream extension.
285      * </p>
286      *
287      * <p>
288      * <b>Clients should not call any of the add, remove, refresh, or update
289      * methods on the viewer from this method or any code invoked by the
290      * implementation of this method.</b>
291      * </p>
292      *
293      * @param anUpdateSynchronization
294      * The (current) update to execute against the viewer.
295      * @return The (potentially reshaped) update to execute against the viewer.
296      */

297     public boolean interceptUpdate(
298             PipelinedViewerUpdate anUpdateSynchronization) {
299          
300         boolean pipelined = false;
301         Object JavaDoc refreshable = null;
302
303         Set JavaDoc overrideableExtensions = new LinkedHashSet JavaDoc();
304         for (Iterator JavaDoc iter = anUpdateSynchronization.getRefreshTargets().iterator(); iter.hasNext();) {
305             refreshable = iter.next();
306             overrideableExtensions.addAll(contentService.findOverrideableContentExtensionsForPossibleChild(refreshable));
307         }
308         for (Iterator JavaDoc overrideableExtensionItr = overrideableExtensions.iterator(); overrideableExtensionItr.hasNext();) {
309             pipelined |= pipelineInterceptUpdate((NavigatorContentExtension) overrideableExtensionItr.next(), anUpdateSynchronization, refreshable);
310         }
311
312         return pipelined;
313         
314     }
315
316     private boolean pipelineInterceptUpdate(NavigatorContentExtension overrideableExtension,
317                     PipelinedViewerUpdate anUpdateSynchronization, Object JavaDoc refreshable) {
318
319         boolean intercepted = false;
320         NavigatorContentExtension[] overridingExtensionsForPossibleChild = overrideableExtension.getOverridingExtensionsForPossibleChild(refreshable);
321         for (int i=0; i<overridingExtensionsForPossibleChild.length; i++) {
322             try {
323                 if (overridingExtensionsForPossibleChild[i].getContentProvider() instanceof IPipelinedTreeContentProvider) {
324
325                     intercepted |= ((IPipelinedTreeContentProvider) overridingExtensionsForPossibleChild[i]
326                             .getContentProvider())
327                             .interceptUpdate(anUpdateSynchronization);
328                     
329                     if (overridingExtensionsForPossibleChild[i].getDescriptor().hasOverridingExtensions())
330                         intercepted |= pipelineInterceptUpdate(overridingExtensionsForPossibleChild[i], anUpdateSynchronization, refreshable);
331                 }
332             } catch (Throwable JavaDoc e) {
333                 String JavaDoc msg = e.getMessage() != null ? e.getMessage() : e.toString();
334                 NavigatorPlugin.logError(0, msg, e);
335             }
336         }
337
338         return intercepted;
339     }
340
341 }
342
Popular Tags