Source Code Cross Referenced for NavigatorContentServiceContentProvider.java in  » IDE-Eclipse » ui » org » eclipse » ui » internal » navigator » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui » org.eclipse.ui.internal.navigator 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2003, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.ui.internal.navigator;
011:
012:        import java.util.ArrayList;
013:        import java.util.Collections;
014:        import java.util.Iterator;
015:        import java.util.LinkedHashSet;
016:        import java.util.LinkedList;
017:        import java.util.List;
018:        import java.util.Set;
019:
020:        import org.eclipse.jface.viewers.ITreeContentProvider;
021:        import org.eclipse.jface.viewers.ITreePathContentProvider;
022:        import org.eclipse.jface.viewers.TreePath;
023:        import org.eclipse.jface.viewers.Viewer;
024:        import org.eclipse.osgi.util.NLS;
025:        import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor;
026:        import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension;
027:        import org.eclipse.ui.internal.navigator.extensions.NavigatorViewerDescriptor;
028:        import org.eclipse.ui.internal.navigator.extensions.OverridePolicy;
029:        import org.eclipse.ui.navigator.CommonViewer;
030:        import org.eclipse.ui.navigator.INavigatorContentDescriptor;
031:        import org.eclipse.ui.navigator.INavigatorViewerDescriptor;
032:        import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
033:
034:        /**
035:         * <p>
036:         * Provides relevant content based on the associated
037:         * {@link org.eclipse.ui.internal.navigator.NavigatorContentService}&nbsp; for
038:         * a TreeViewer .
039:         * </p>
040:         * <p>
041:         * Except for the dependency on
042:         * {@link org.eclipse.ui.internal.navigator.NavigatorContentService}, this
043:         * class has no dependencies on the rest of the Common Navigator framework. Tree
044:         * viewers that would like to use the extensions defined by the Common
045:         * Navigator, without using the actual view part or other pieces of
046:         * functionality (filters, sorting, etc) may choose to use this class, in effect
047:         * using an extensible, aggregating, delegate content provider.
048:         * </p>
049:         * 
050:         * @see org.eclipse.ui.internal.navigator.NavigatorContentService
051:         * @see org.eclipse.ui.internal.navigator.NavigatorContentServiceLabelProvider
052:         * 
053:         * <p>
054:         * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
055:         * part of a work in progress. There is a guarantee neither that this API will
056:         * work nor that it will remain the same. Please do not use this API without
057:         * consulting with the Platform/UI team.
058:         * </p>
059:         * 
060:         * @since 3.2
061:         * 
062:         */
063:        public class NavigatorContentServiceContentProvider implements 
064:                ITreeContentProvider, ITreePathContentProvider {
065:
066:            private static final Object[] NO_CHILDREN = new Object[0];
067:
068:            private final NavigatorContentService contentService;
069:
070:            private final boolean isContentServiceSelfManaged;
071:
072:            private final boolean enforceHasChildren;
073:
074:            private Viewer viewer;
075:
076:            /**
077:             * <p>
078:             * Creates a cached {@link NavigatorContentService}&nbsp;from the given
079:             * viewer Id.
080:             * </p>
081:             * 
082:             * @param aViewerId
083:             *            The associated viewer id that this
084:             *            NavigatorContentServiceContentProvider will provide content
085:             *            for
086:             */
087:            public NavigatorContentServiceContentProvider(String aViewerId) {
088:                super ();
089:                contentService = new NavigatorContentService(aViewerId);
090:                INavigatorViewerDescriptor vDesc = contentService
091:                        .getViewerDescriptor();
092:                enforceHasChildren = vDesc
093:                        .getBooleanConfigProperty(NavigatorViewerDescriptor.PROP_ENFORCE_HAS_CHILDREN);
094:                isContentServiceSelfManaged = true;
095:            }
096:
097:            /**
098:             * <p>
099:             * Uses the supplied content service to acquire the available extensions.
100:             * </p>
101:             * 
102:             * @param aContentService
103:             *            The associated NavigatorContentService that should be used to
104:             *            acquire information.
105:             */
106:            public NavigatorContentServiceContentProvider(
107:                    NavigatorContentService aContentService) {
108:                super ();
109:                contentService = aContentService;
110:                isContentServiceSelfManaged = false;
111:                INavigatorViewerDescriptor vDesc = contentService
112:                        .getViewerDescriptor();
113:                enforceHasChildren = vDesc
114:                        .getBooleanConfigProperty(NavigatorViewerDescriptor.PROP_ENFORCE_HAS_CHILDREN);
115:            }
116:
117:            /**
118:             * 
119:             * <p>
120:             * Return the root objects for the supplied anInputElement. anInputElement
121:             * is the root thing that the viewer visualizes.
122:             * </p>
123:             * <p>
124:             * This method will call out to its {@link NavigatorContentService}&nbsp;for
125:             * extensions that are enabled on the supplied anInputElement or enabled on
126:             * the viewerId supplied when the {@link NavigatorContentService}&nbsp; was
127:             * created (either by this class or its client). The extensions will then be
128:             * queried for relevant content. The children returned from each extension
129:             * will be aggregated and returned as is -- there is no additional sorting
130:             * or filtering at this level.
131:             * </p>
132:             * <p>
133:             * The results of this method will be displayed in the root of the
134:             * TreeViewer.
135:             * </p>
136:             * {@inheritDoc}
137:             * 
138:             * @param anInputElement
139:             *            The relevant element that a client would like children for -
140:             *            the input element of the TreeViewer
141:             * @return A non-null array of objects that are logical children of
142:             *         anInputElement
143:             * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
144:             */
145:            public synchronized Object[] getElements(Object anInputElement) {
146:                Set rootContentExtensions = contentService
147:                        .findRootContentExtensions(anInputElement);
148:                if (rootContentExtensions.size() == 0) {
149:                    return NO_CHILDREN;
150:                }
151:                ContributorTrackingSet finalElementsSet = new ContributorTrackingSet(
152:                        contentService);
153:                ContributorTrackingSet localSet = new ContributorTrackingSet(
154:                        contentService);
155:
156:                Object[] contributedChildren = null;
157:                NavigatorContentExtension foundExtension;
158:                NavigatorContentExtension[] overridingExtensions;
159:                for (Iterator itr = rootContentExtensions.iterator(); itr
160:                        .hasNext();) {
161:                    foundExtension = (NavigatorContentExtension) itr.next();
162:                    try {
163:
164:                        if (!isOverridingExtensionInSet(foundExtension
165:                                .getDescriptor(), rootContentExtensions)) {
166:
167:                            contributedChildren = foundExtension
168:                                    .internalGetContentProvider().getElements(
169:                                            anInputElement);
170:
171:                            localSet.setContents(contributedChildren);
172:
173:                            overridingExtensions = foundExtension
174:                                    .getOverridingExtensionsForTriggerPoint(anInputElement);
175:
176:                            if (overridingExtensions.length > 0) {
177:                                localSet = pipelineElements(anInputElement,
178:                                        overridingExtensions, localSet);
179:                            }
180:                            finalElementsSet.addAll(localSet);
181:                        }
182:                    } catch (RuntimeException re) {
183:                        NavigatorPlugin
184:                                .logError(
185:                                        0,
186:                                        NLS
187:                                                .bind(
188:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
189:                                                        new Object[] { foundExtension
190:                                                                .getDescriptor()
191:                                                                .getId() }), re);
192:                    } catch (Error e) {
193:                        NavigatorPlugin
194:                                .logError(
195:                                        0,
196:                                        NLS
197:                                                .bind(
198:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
199:                                                        new Object[] { foundExtension
200:                                                                .getDescriptor()
201:                                                                .getId() }), e);
202:
203:                    }
204:                }
205:                return finalElementsSet.toArray();
206:            }
207:
208:            /**
209:             * <p>
210:             * Return the children of the supplied aParentElement
211:             * </p>
212:             * 
213:             * <p>
214:             * This method will call out to its {@link NavigatorContentService}&nbsp;for
215:             * extensions that are enabled on the supplied aParentElement. The
216:             * extensions will then be queried for children for aParentElement. The
217:             * children returned from each extension will be aggregated and returned as
218:             * is -- there is no additional sorting or filtering at this level.
219:             * </p>
220:             * <p>
221:             * The results of this method will be displayed as children of the supplied
222:             * element in the TreeViewer.
223:             * </p>
224:             * {@inheritDoc}
225:             * 
226:             * @param aParentElement
227:             *            An element that requires children content in the viewer (e.g.
228:             *            an end-user expanded a node)
229:             * @return A non-null array of objects that are logical children of
230:             *         aParentElement
231:             * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
232:             */
233:            public synchronized Object[] getChildren(Object aParentElement) {
234:                return internalGetChildren(aParentElement);
235:            }
236:
237:            private Object[] internalGetChildren(Object aParentElementOrPath) {
238:                Object aParentElement = internalAsElement(aParentElementOrPath);
239:                Set enabledExtensions = contentService
240:                        .findContentExtensionsByTriggerPoint(aParentElement);
241:                if (enabledExtensions.size() == 0) {
242:                    return NO_CHILDREN;
243:                }
244:                ContributorTrackingSet finalChildrenSet = new ContributorTrackingSet(
245:                        contentService);
246:                ContributorTrackingSet localSet = new ContributorTrackingSet(
247:                        contentService);
248:
249:                Object[] contributedChildren = null;
250:                NavigatorContentExtension foundExtension;
251:                NavigatorContentExtension[] overridingExtensions;
252:                for (Iterator itr = enabledExtensions.iterator(); itr.hasNext();) {
253:                    foundExtension = (NavigatorContentExtension) itr.next();
254:                    try {
255:
256:                        if (!isOverridingExtensionInSet(foundExtension
257:                                .getDescriptor(), enabledExtensions)) {
258:
259:                            contributedChildren = foundExtension
260:                                    .internalGetContentProvider().getChildren(
261:                                            aParentElementOrPath);
262:
263:                            overridingExtensions = foundExtension
264:                                    .getOverridingExtensionsForTriggerPoint(aParentElement);
265:
266:                            localSet.setContents(contributedChildren);
267:
268:                            if (overridingExtensions.length > 0) {
269:                                // TODO: could pass tree path through pipeline						
270:                                localSet = pipelineChildren(aParentElement,
271:                                        overridingExtensions, localSet);
272:                            }
273:                            finalChildrenSet.addAll(localSet);
274:                        }
275:                    } catch (RuntimeException re) {
276:                        NavigatorPlugin
277:                                .logError(
278:                                        0,
279:                                        NLS
280:                                                .bind(
281:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
282:                                                        new Object[] { foundExtension
283:                                                                .getDescriptor()
284:                                                                .getId() }), re);
285:                    } catch (Error e) {
286:                        NavigatorPlugin
287:                                .logError(
288:                                        0,
289:                                        NLS
290:                                                .bind(
291:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
292:                                                        new Object[] { foundExtension
293:                                                                .getDescriptor()
294:                                                                .getId() }), e);
295:
296:                    }
297:                }
298:                return finalChildrenSet.toArray();
299:            }
300:
301:            /**
302:             * Query each of <code>theOverridingExtensions</code> for children, and
303:             * then pipe them through the Pipeline content provider.
304:             * 
305:             * @param aParentOrPath
306:             *            The parent element in the tree
307:             * @param theOverridingExtensions
308:             *            The set of overriding extensions that should participate in
309:             *            the pipeline chain
310:             * @param theCurrentChildren
311:             *            The current children to return to the viewer (should be
312:             *            modifiable)
313:             * @return The set of children to return to the viewer
314:             */
315:            private ContributorTrackingSet pipelineChildren(
316:                    Object aParentOrPath,
317:                    NavigatorContentExtension[] theOverridingExtensions,
318:                    ContributorTrackingSet theCurrentChildren) {
319:                IPipelinedTreeContentProvider pipelinedContentProvider;
320:                NavigatorContentExtension[] overridingExtensions;
321:                ContributorTrackingSet pipelinedChildren = theCurrentChildren;
322:                for (int i = 0; i < theOverridingExtensions.length; i++) {
323:
324:                    if (theOverridingExtensions[i].getContentProvider() instanceof  IPipelinedTreeContentProvider) {
325:                        pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i]
326:                                .getContentProvider();
327:
328:                        pipelinedChildren
329:                                .setContributor((NavigatorContentDescriptor) theOverridingExtensions[i]
330:                                        .getDescriptor());
331:                        pipelinedContentProvider.getPipelinedChildren(
332:                                aParentOrPath, pipelinedChildren);
333:
334:                        pipelinedChildren.setContributor(null);
335:
336:                        overridingExtensions = theOverridingExtensions[i]
337:                                .getOverridingExtensionsForTriggerPoint(aParentOrPath);
338:                        if (overridingExtensions.length > 0) {
339:                            pipelinedChildren = pipelineChildren(aParentOrPath,
340:                                    overridingExtensions, pipelinedChildren);
341:                        }
342:                    }
343:                }
344:
345:                return pipelinedChildren;
346:
347:            }
348:
349:            /**
350:             * Query each of <code>theOverridingExtensions</code> for elements, and
351:             * then pipe them through the Pipeline content provider.
352:             * 
353:             * @param anInputElement
354:             *            The input element in the tree
355:             * @param theOverridingExtensions
356:             *            The set of overriding extensions that should participate in
357:             *            the pipeline chain
358:             * @param theCurrentElements
359:             *            The current elements to return to the viewer (should be
360:             *            modifiable)
361:             * @return The set of elements to return to the viewer
362:             */
363:            private ContributorTrackingSet pipelineElements(
364:                    Object anInputElement,
365:                    NavigatorContentExtension[] theOverridingExtensions,
366:                    ContributorTrackingSet theCurrentElements) {
367:                IPipelinedTreeContentProvider pipelinedContentProvider;
368:                NavigatorContentExtension[] overridingExtensions;
369:                ContributorTrackingSet pipelinedElements = theCurrentElements;
370:                for (int i = 0; i < theOverridingExtensions.length; i++) {
371:
372:                    if (theOverridingExtensions[i].getContentProvider() instanceof  IPipelinedTreeContentProvider) {
373:                        pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i]
374:                                .getContentProvider();
375:
376:                        pipelinedElements
377:                                .setContributor((NavigatorContentDescriptor) theOverridingExtensions[i]
378:                                        .getDescriptor());
379:                        pipelinedContentProvider.getPipelinedElements(
380:                                anInputElement, pipelinedElements);
381:                        pipelinedElements.setContributor(null);
382:
383:                        overridingExtensions = theOverridingExtensions[i]
384:                                .getOverridingExtensionsForTriggerPoint(anInputElement);
385:                        if (overridingExtensions.length > 0) {
386:                            pipelinedElements = pipelineElements(
387:                                    anInputElement, overridingExtensions,
388:                                    pipelinedElements);
389:                        }
390:                    }
391:                }
392:                return pipelinedElements;
393:            }
394:
395:            /**
396:             * Currently this method only checks one level deep. If the suppressed
397:             * extension of the given descriptor is contained lower in the tree, then
398:             * the extension could still be invoked twice.
399:             * 
400:             * @param aDescriptor
401:             *            The descriptor which may be overriding other extensions.
402:             * @param theEnabledExtensions
403:             *            The other available extensions.
404:             * @return True if the results should be pipelined through the downstream
405:             *         extensions.
406:             */
407:            private boolean isOverridingExtensionInSet(
408:                    INavigatorContentDescriptor aDescriptor,
409:                    Set theEnabledExtensions) {
410:
411:                if (aDescriptor.getSuppressedExtensionId() != null /*
412:                 * The descriptor is
413:                 * an override
414:                 * descriptor
415:                 */
416:                        && aDescriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) {
417:                    /*
418:                     * if the policy is set as such, it can lead to this extension being
419:                     * invoked twice; once as a first class extension, and once an
420:                     * overriding extension.
421:                     */
422:                    if (theEnabledExtensions
423:                            .contains(contentService.getExtension(aDescriptor
424:                                    .getOverriddenDescriptor()))) {
425:                        return true;
426:                    }
427:                }
428:                return false;
429:            }
430:
431:            /**
432:             * Currently this method only checks one level deep. If the suppressed
433:             * extension of the given descriptor is contained lower in the tree, then
434:             * the extension could still be invoked twice.
435:             * 
436:             * @param aDescriptor
437:             *            The descriptor which may be overriding other extensions.
438:             * @param theEnabledDescriptors
439:             *            The other available descriptors.
440:             * @return True if the results should be pipelined through the downstream
441:             *         extensions.
442:             */
443:            private boolean isOverridingDescriptorInSet(
444:                    INavigatorContentDescriptor aDescriptor,
445:                    Set theEnabledDescriptors) {
446:
447:                if (aDescriptor.getSuppressedExtensionId() != null /*
448:                 * The descriptor is
449:                 * an override
450:                 * descriptor
451:                 */
452:                        && aDescriptor.getOverridePolicy() == OverridePolicy.InvokeAlwaysRegardlessOfSuppressedExt) {
453:                    /*
454:                     * if the policy is set as such, it can lead to this extension being
455:                     * invoked twice; once as a first class extension, and once an
456:                     * overriding extension.
457:                     */
458:                    if (theEnabledDescriptors.contains(aDescriptor
459:                            .getOverriddenDescriptor())) {
460:                        return true;
461:                    }
462:                }
463:                return false;
464:            }
465:
466:            /**
467:             * <p>
468:             * Returns the logical parent of anElement.
469:             * </p>
470:             * <p>
471:             * This method requires that any extension that would like an opportunity to
472:             * supply a parent for anElement expressly indicate that in the action
473:             * expression &lt;enables&gt; statement of the
474:             * <b>org.eclipse.ui.navigator.navigatorContent </b> extension point.
475:             * </p>
476:             * {@inheritDoc}
477:             * 
478:             * @param anElement
479:             *            An element that requires its logical parent - generally as a
480:             *            result of setSelection(expand=true) on the viewer
481:             * @return The logical parent if available or null if the parent cannot be
482:             *         determined
483:             * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
484:             */
485:            public synchronized Object getParent(Object anElement) {
486:                Set extensions = contentService
487:                        .findContentExtensionsWithPossibleChild(anElement);
488:
489:                Object parent;
490:                NavigatorContentExtension foundExtension;
491:                NavigatorContentExtension[] overridingExtensions;
492:                for (Iterator itr = extensions.iterator(); itr.hasNext();) {
493:                    foundExtension = (NavigatorContentExtension) itr.next();
494:                    try {
495:
496:                        if (!isOverridingExtensionInSet(foundExtension
497:                                .getDescriptor(), extensions)) {
498:
499:                            parent = foundExtension
500:                                    .internalGetContentProvider().getParent(
501:                                            anElement);
502:
503:                            overridingExtensions = foundExtension
504:                                    .getOverridingExtensionsForPossibleChild(anElement);
505:
506:                            if (overridingExtensions.length > 0) {
507:                                parent = pipelineParent(anElement,
508:                                        overridingExtensions, parent);
509:                            }
510:
511:                            if (parent != null) {
512:                                return parent;
513:                            }
514:                        }
515:                    } catch (RuntimeException re) {
516:                        NavigatorPlugin
517:                                .logError(
518:                                        0,
519:                                        NLS
520:                                                .bind(
521:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
522:                                                        new Object[] { foundExtension
523:                                                                .getDescriptor()
524:                                                                .getId() }), re);
525:                    } catch (Error e) {
526:                        NavigatorPlugin
527:                                .logError(
528:                                        0,
529:                                        NLS
530:                                                .bind(
531:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
532:                                                        new Object[] { foundExtension
533:                                                                .getDescriptor()
534:                                                                .getId() }), e);
535:
536:                    }
537:                }
538:
539:                return null;
540:            }
541:
542:            /**
543:             * Query each of <code>theOverridingExtensions</code> for elements, and
544:             * then pipe them through the Pipeline content provider.
545:             * 
546:             * @param anInputElement
547:             *            The input element in the tree
548:             * @param theOverridingExtensions
549:             *            The set of overriding extensions that should participate in
550:             *            the pipeline chain
551:             * @param theCurrentParent
552:             *            The current elements to return to the viewer (should be
553:             *            modifiable)
554:             * @return The set of elements to return to the viewer
555:             */
556:            private Object pipelineParent(Object anInputElement,
557:                    NavigatorContentExtension[] theOverridingExtensions,
558:                    Object theCurrentParent) {
559:                IPipelinedTreeContentProvider pipelinedContentProvider;
560:                NavigatorContentExtension[] overridingExtensions;
561:                Object aSuggestedParent = null;
562:                for (int i = 0; i < theOverridingExtensions.length; i++) {
563:
564:                    if (theOverridingExtensions[i].getContentProvider() instanceof  IPipelinedTreeContentProvider) {
565:                        pipelinedContentProvider = (IPipelinedTreeContentProvider) theOverridingExtensions[i]
566:                                .getContentProvider();
567:
568:                        aSuggestedParent = pipelinedContentProvider
569:                                .getPipelinedParent(anInputElement,
570:                                        aSuggestedParent);
571:
572:                        overridingExtensions = theOverridingExtensions[i]
573:                                .getOverridingExtensionsForTriggerPoint(anInputElement);
574:                        if (overridingExtensions.length > 0) {
575:                            aSuggestedParent = pipelineParent(anInputElement,
576:                                    overridingExtensions, aSuggestedParent);
577:                        }
578:                    }
579:                }
580:                return aSuggestedParent != null ? aSuggestedParent
581:                        : theCurrentParent;
582:            }
583:
584:            /**
585:             * <p>
586:             * Used to determine of anElement should be displayed with a '+' or not.
587:             * </p>
588:             * {@inheritDoc}
589:             * 
590:             * @param anElement
591:             *            The element in question
592:             * @return True if anElement has logical children as returned by this
593:             *         content provider.
594:             * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
595:             */
596:            public synchronized boolean hasChildren(Object anElement) {
597:                Set resultInstances = contentService
598:                        .findContentExtensionsByTriggerPoint(anElement);
599:
600:                NavigatorContentExtension ext;
601:                for (Iterator itr = resultInstances.iterator(); itr.hasNext();) {
602:                    ext = (NavigatorContentExtension) itr.next();
603:                    if (!ext.isLoaded() && !enforceHasChildren) {
604:                        return true;
605:                    } else if (ext.internalGetContentProvider().hasChildren(
606:                            anElement)) {
607:                        return true;
608:                    }
609:                }
610:
611:                return false;
612:            }
613:
614:            /**
615:             * <p>
616:             * Handles any necessary clean up of the {@link NavigatorContentService}
617:             * </p>
618:             * 
619:             * <p>
620:             * <b>If a client uses this class outside of the framework of
621:             * {@link CommonViewer}, the client must ensure that this method is called
622:             * when finished. </b>
623:             * </p>
624:             * 
625:             * @see org.eclipse.jface.viewers.IContentProvider#dispose()
626:             */
627:            public synchronized void dispose() {
628:                if (isContentServiceSelfManaged) {
629:                    contentService.dispose();
630:                }
631:            }
632:
633:            /**
634:             * <p>
635:             * Indicates that the current content provider is now representing a
636:             * different input element. The input element is the root thing that the
637:             * viewer displays.
638:             * </p>
639:             * <p>
640:             * This method should handle any cleanup associated with the old input
641:             * element and any initiailization associated with the new input element.
642:             * </p>
643:             * {@inheritDoc}
644:             * 
645:             * @param aViewer
646:             *            The viewer that the current content provider is associated
647:             *            with
648:             * @param anOldInput
649:             *            The original input element that the viewer was visualizing
650:             * @param aNewInput
651:             *            The new input element that the viewer will visualize.
652:             * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
653:             *      java.lang.Object, java.lang.Object)
654:             * 
655:             */
656:            public synchronized void inputChanged(Viewer aViewer,
657:                    Object anOldInput, Object aNewInput) {
658:                viewer = aViewer;
659:                contentService.updateService(aViewer, anOldInput, aNewInput);
660:            }
661:
662:            /* (non-Javadoc)
663:             * @see org.eclipse.jface.viewers.ITreePathContentProvider#getChildren(org.eclipse.jface.viewers.TreePath)
664:             */
665:            public Object[] getChildren(TreePath parentPath) {
666:                return internalGetChildren(parentPath);
667:            }
668:
669:            /* (non-Javadoc)
670:             * @see org.eclipse.jface.viewers.ITreePathContentProvider#hasChildren(org.eclipse.jface.viewers.TreePath)
671:             */
672:            public boolean hasChildren(TreePath path) {
673:                Object anElement = internalAsElement(path);
674:                Set resultInstances = contentService
675:                        .findContentExtensionsByTriggerPoint(anElement);
676:
677:                NavigatorContentExtension ext;
678:                for (Iterator itr = resultInstances.iterator(); itr.hasNext();) {
679:                    ext = (NavigatorContentExtension) itr.next();
680:                    if (!ext.isLoaded() && !enforceHasChildren)
681:                        return true;
682:                    ITreeContentProvider cp = ext.internalGetContentProvider();
683:                    if (cp instanceof  ITreePathContentProvider) {
684:                        ITreePathContentProvider tpcp = (ITreePathContentProvider) cp;
685:                        if (tpcp.hasChildren(path)) {
686:                            return true;
687:                        }
688:                    } else if (cp.hasChildren(anElement))
689:                        return true;
690:                }
691:
692:                return false;
693:            }
694:
695:            /* (non-Javadoc)
696:             * @see org.eclipse.jface.viewers.ITreePathContentProvider#getParents(java.lang.Object)
697:             */
698:            public TreePath[] getParents(Object anElement) {
699:
700:                List paths = new ArrayList();
701:                TreePathCompiler compiler = new TreePathCompiler(anElement);
702:                Set compilers = findPaths(compiler);
703:                for (Iterator iter = compilers.iterator(); iter.hasNext();) {
704:                    TreePathCompiler c = (TreePathCompiler) iter.next();
705:                    paths.add(c.createParentPath());
706:
707:                }
708:                return (TreePath[]) paths.toArray(new TreePath[paths.size()]);
709:
710:            }
711:
712:            /**
713:             * Get the element from an element or tree path argument.
714:             * @param parentElementOrPath the element or tree path
715:             * @return the element
716:             */
717:            private Object internalAsElement(Object parentElementOrPath) {
718:                if (parentElementOrPath instanceof  TreePath) {
719:                    TreePath tp = (TreePath) parentElementOrPath;
720:                    if (tp.getSegmentCount() > 0) {
721:                        return tp.getLastSegment();
722:                    }
723:                    // If the path is empty, the parent element is the root
724:                    return viewer.getInput();
725:                }
726:                return parentElementOrPath;
727:            }
728:
729:            class CyclicPathException extends Exception {
730:
731:                private static final long serialVersionUID = 2111962579612444989L;
732:
733:                protected CyclicPathException(TreePathCompiler compiler,
734:                        Object invalidSegment, boolean asChild) {
735:                    super ("Cannot add " + invalidSegment + //$NON-NLS-1$ 
736:                            " to the list of segments in " + compiler + //$NON-NLS-1$ 
737:                            (asChild ? " as a child." : " as a parent.")); //$NON-NLS-1$ //$NON-NLS-2$
738:                }
739:            }
740:
741:            class TreePathCompiler {
742:
743:                private final LinkedList segments = new LinkedList();
744:
745:                protected TreePathCompiler(Object segment) {
746:                    segments.add(segment);
747:                }
748:
749:                protected TreePathCompiler(TreePathCompiler aCompiler) {
750:                    segments.addAll(aCompiler.segments);
751:                }
752:
753:                protected TreePathCompiler(TreePath aPath) {
754:                    for (int i = 0; i < aPath.getSegmentCount(); i++) {
755:                        segments.addLast(aPath.getSegment(i));
756:                    }
757:                }
758:
759:                protected void addParent(Object segment)
760:                        throws CyclicPathException {
761:                    if (segments.contains(segment)) {
762:                        throw new CyclicPathException(this , segment, false);
763:                    }
764:                    segments.addFirst(segment);
765:                }
766:
767:                protected void addChild(Object segment)
768:                        throws CyclicPathException {
769:                    if (segments.contains(segment)) {
770:                        throw new CyclicPathException(this , segment, false);
771:                    }
772:                    segments.addLast(segment);
773:                }
774:
775:                /**
776:                 * Create the full tree path.
777:                 * 
778:                 * @return A TreePath with all segments from the compiler.
779:                 */
780:                public TreePath createPath() {
781:                    return new TreePath(segments.toArray());
782:                }
783:
784:                /**
785:                 * Create parent tree path.
786:                 * 
787:                 * @return A TreePath with all segments but the last from the compiler
788:                 */
789:                public TreePath createParentPath() {
790:                    LinkedList parentSegments = new LinkedList(segments);
791:                    parentSegments.removeLast();
792:                    return new TreePath(parentSegments.toArray());
793:                }
794:
795:                public Object getLastSegment() {
796:                    return segments.getLast();
797:                }
798:
799:                public Object getFirstSegment() {
800:                    return segments.getFirst();
801:                }
802:
803:                /* (non-Javadoc)
804:                 * @see java.lang.Object#toString()
805:                 */
806:                public String toString() {
807:
808:                    StringBuffer buffer = new StringBuffer();
809:                    for (Iterator iter = segments.iterator(); iter.hasNext();) {
810:                        Object segment = iter.next();
811:                        buffer.append(segment).append("::"); //$NON-NLS-1$  
812:                    }
813:                    return buffer.toString();
814:                }
815:
816:            }
817:
818:            private Set findPaths(TreePathCompiler aPathCompiler) {
819:
820:                Set/* <Object> */parents = findParents(aPathCompiler
821:                        .getFirstSegment());
822:                Set/* <TreePathCompiler> */parentPaths = new LinkedHashSet();
823:                Set/* <TreePathCompiler> */foundPaths = Collections.EMPTY_SET;
824:                if (parents.size() > 0) {
825:                    for (Iterator parentIter = parents.iterator(); parentIter
826:                            .hasNext();) {
827:                        Object parent = (Object) parentIter.next();
828:                        TreePathCompiler c = new TreePathCompiler(aPathCompiler);
829:                        try {
830:                            c.addParent(parent);
831:                            foundPaths = findPaths(c);
832:                        } catch (CyclicPathException cpe) {
833:                            String msg = cpe.getMessage() != null ? cpe
834:                                    .getMessage() : cpe.toString();
835:                            NavigatorPlugin.logError(0, msg, cpe);
836:                        }
837:                        if (foundPaths.isEmpty())
838:                            parentPaths.add(c);
839:                        else
840:                            parentPaths.addAll(foundPaths);
841:                    }
842:                }
843:                return parentPaths;
844:
845:            }
846:
847:            private Set findParents(Object anElement) {
848:
849:                Set descriptors = contentService
850:                        .findDescriptorsWithPossibleChild(anElement, false);
851:                Set parents = new LinkedHashSet();
852:                NavigatorContentDescriptor foundDescriptor;
853:                NavigatorContentExtension foundExtension;
854:                Object parent = null;
855:                for (Iterator itr = descriptors.iterator(); itr.hasNext();) {
856:                    foundDescriptor = (NavigatorContentDescriptor) itr.next();
857:                    foundExtension = contentService
858:                            .getExtension(foundDescriptor);
859:                    try {
860:
861:                        if (!isOverridingDescriptorInSet(foundExtension
862:                                .getDescriptor(), descriptors)) {
863:
864:                            /* internalGetContentProvider returns the real delegate */
865:                            if (foundExtension.getContentProvider() instanceof  ITreePathContentProvider) {
866:                                /*
867:                                 * but we use the safe version to automatically handle
868:                                 * errors
869:                                 */
870:                                TreePath[] parentTreePaths = ((ITreePathContentProvider) foundExtension
871:                                        .internalGetContentProvider())
872:                                        .getParents(anElement);
873:
874:                                for (int i = 0; i < parentTreePaths.length; i++) {
875:
876:                                    parent = parentTreePaths[i]
877:                                            .getLastSegment();
878:                                    if ((parent = findParent(foundExtension,
879:                                            anElement, parent)) != null)
880:                                        parents.add(parent);
881:                                }
882:
883:                            } else {
884:
885:                                parent = foundExtension
886:                                        .internalGetContentProvider()
887:                                        .getParent(anElement);
888:                                if ((parent = findParent(foundExtension,
889:                                        anElement, parent)) != null)
890:                                    parents.add(parent);
891:                            }
892:                        }
893:
894:                    } catch (RuntimeException re) {
895:                        NavigatorPlugin
896:                                .logError(
897:                                        0,
898:                                        NLS
899:                                                .bind(
900:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
901:                                                        new Object[] { foundExtension
902:                                                                .getDescriptor()
903:                                                                .getId() }), re);
904:                    } catch (Error e) {
905:                        NavigatorPlugin
906:                                .logError(
907:                                        0,
908:                                        NLS
909:                                                .bind(
910:                                                        CommonNavigatorMessages.Could_not_provide_children_for_element,
911:                                                        new Object[] { foundExtension
912:                                                                .getDescriptor()
913:                                                                .getId() }), e);
914:
915:                    }
916:                }
917:
918:                return parents;
919:
920:            }
921:
922:            private Object findParent(NavigatorContentExtension anExtension,
923:                    Object anElement, Object aSuggestedParent) {
924:
925:                /* the last valid (non-null) parent for the anElement */
926:                Object lastValidParent = aSuggestedParent;
927:                /* used to keep track of new suggestions */
928:                Object suggestedOverriddenParent = null;
929:                IPipelinedTreeContentProvider piplineContentProvider;
930:                NavigatorContentExtension[] overridingExtensions = anExtension
931:                        .getOverridingExtensionsForPossibleChild(anElement);
932:                for (int i = 0; i < overridingExtensions.length; i++) {
933:                    if (overridingExtensions[i].getContentProvider() instanceof  IPipelinedTreeContentProvider) {
934:                        piplineContentProvider = (IPipelinedTreeContentProvider) overridingExtensions[i]
935:                                .getContentProvider();
936:                        suggestedOverriddenParent = piplineContentProvider
937:                                .getPipelinedParent(anElement, lastValidParent);
938:
939:                        if (suggestedOverriddenParent != null)
940:                            lastValidParent = suggestedOverriddenParent;
941:
942:                        // should never return null 
943:                        lastValidParent = findParent(overridingExtensions[i],
944:                                anElement, lastValidParent);
945:                    }
946:
947:                }
948:                return lastValidParent;
949:            }
950:
951:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.