KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > core > sourcelookup > AbstractSourceLookupDirector


1 /*******************************************************************************
2  * Copyright (c) 2004, 2007 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  * QNX Software Systems - Mikhail Khodjaiants - Bug 88232
11  *******************************************************************************/

12 package org.eclipse.debug.core.sourcelookup;
13
14 import com.ibm.icu.text.MessageFormat;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Arrays JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.ISafeRunnable;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.MultiStatus;
26 import org.eclipse.core.runtime.SafeRunner;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.debug.core.DebugPlugin;
29 import org.eclipse.debug.core.ILaunch;
30 import org.eclipse.debug.core.ILaunchConfiguration;
31 import org.eclipse.debug.core.ILaunchConfigurationListener;
32 import org.eclipse.debug.core.ILaunchListener;
33 import org.eclipse.debug.core.ILaunchManager;
34 import org.eclipse.debug.core.IStatusHandler;
35 import org.eclipse.debug.core.model.IStackFrame;
36 import org.eclipse.debug.core.sourcelookup.containers.DefaultSourceContainer;
37 import org.eclipse.debug.internal.core.sourcelookup.SourceLookupMessages;
38 import org.w3c.dom.Document JavaDoc;
39 import org.w3c.dom.Element JavaDoc;
40 import org.w3c.dom.Node JavaDoc;
41 import org.w3c.dom.NodeList JavaDoc;
42
43 /**
44  * Directs source lookup among a collection of source lookup participants,
45  * and a common collection of source containers.
46  * Each source lookup participant is a source locator itself, which allows
47  * more than one source locator to participate in source lookup for a
48  * launch. Each source lookup participant searches for source in the source
49  * containers managed by this director, and each participant is notified
50  * of changes in the source containers (i.e. when the set of source
51  * containers changes).
52  * <p>
53  * When a source director is initialized, it adds it self as a launch listener,
54  * and automatically disposes itself when its associated launch is removed
55  * from the launch manager. If a source director is instantiated by a client
56  * that is not part of a launch, that client is responsible for disposing
57  * the source director.
58  * </p>
59  * <p>
60  * Clients may subclass this class.
61  * </p>
62  * @since 3.0
63  * @see org.eclipse.debug.core.model.ISourceLocator
64  * @see org.eclipse.debug.core.sourcelookup.ISourceContainer
65  * @see org.eclipse.debug.core.sourcelookup.ISourceContainerType
66  * @see org.eclipse.debug.core.sourcelookup.ISourcePathComputer
67  * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant
68  */

69 public abstract class AbstractSourceLookupDirector implements ISourceLookupDirector, ILaunchConfigurationListener, ILaunchListener {
70     
71     // source locator type identifier
72
protected String JavaDoc fId;
73     //ISourceLocatorParticipants that are listening for container changes
74
protected ArrayList JavaDoc fParticipants = new ArrayList JavaDoc();
75     //list of current source containers
76
protected ISourceContainer[] fSourceContainers = null;
77     //the launch config associated with this director
78
protected ILaunchConfiguration fConfig;
79     //whether duplicates should be searched for or not
80
protected boolean fDuplicates = false;
81     // source path computer, or null if default
82
protected ISourcePathComputer fComputer = null;
83     /**
84      * Cache of resolved source elements when duplicates exist.
85      * Keys are the duplicates, values are the source element to use.
86      */

87     protected Map JavaDoc fResolvedElements = null;
88     
89     protected static final IStatus fPromptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null); //$NON-NLS-1$//$NON-NLS-2$
90
protected static final IStatus fResolveDuplicatesStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 205, "", null); //$NON-NLS-1$//$NON-NLS-2$
91

92     // XML nodes & attributes for persistence
93
protected static final String JavaDoc DIRECTOR_ROOT_NODE = "sourceLookupDirector"; //$NON-NLS-1$
94
protected static final String JavaDoc CONTAINERS_NODE = "sourceContainers"; //$NON-NLS-1$
95
protected static final String JavaDoc DUPLICATES_ATTR = "duplicates"; //$NON-NLS-1$
96
protected static final String JavaDoc CONTAINER_NODE = "container"; //$NON-NLS-1$
97
protected static final String JavaDoc CONTAINER_TYPE_ATTR = "typeId"; //$NON-NLS-1$
98
protected static final String JavaDoc CONTAINER_MEMENTO_ATTR = "memento"; //$NON-NLS-1$
99

100     class SourceLookupQuery implements ISafeRunnable {
101         
102         private List JavaDoc fSourceElements = new ArrayList JavaDoc();
103         private Object JavaDoc fElement = null;
104         private Throwable JavaDoc fException = null;
105         
106         SourceLookupQuery(Object JavaDoc element) {
107             fElement = element;
108         }
109
110         /* (non-Javadoc)
111          * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
112          */

113         public void handleException(Throwable JavaDoc exception) {
114             fException = exception;
115         }
116         
117         /**
118          * Returns any exception that occurred during source lookup.
119          *
120          * @return the (any) exception that occured during source lookup
121          */

122         public Throwable JavaDoc getException() {
123             return fException;
124         }
125
126         /* (non-Javadoc)
127          * @see org.eclipse.core.runtime.ISafeRunnable#run()
128          */

129         public void run() throws Exception JavaDoc {
130             MultiStatus multiStatus = null;
131             CoreException single = null;
132             ISourceLookupParticipant[] participants = getParticipants();
133             for(int i=0; i < participants.length; i++) {
134                 Object JavaDoc[] sourceArray;
135                 try {
136                     sourceArray = participants[i].findSourceElements(fElement);
137                     if (sourceArray !=null && sourceArray.length > 0) {
138                         if (isFindDuplicates()) {
139                             for(int j=0; j<sourceArray.length; j++)
140                                 if(!checkDuplicate(sourceArray[j], fSourceElements))
141                                     fSourceElements.add(sourceArray[j]);
142                         } else {
143                             fSourceElements.add(sourceArray[0]);
144                             return;
145                         }
146                     }
147                 } catch (CoreException e) {
148                     if (single == null) {
149                         single = e;
150                     } else if (multiStatus == null) {
151                         multiStatus = new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, new IStatus[]{single.getStatus()}, SourceLookupMessages.AbstractSourceLookupDirector_19, null);
152                         multiStatus.add(e.getStatus());
153                     } else {
154                         multiStatus.add(e.getStatus());
155                     }
156                 }
157             }
158             if (fSourceElements.isEmpty()) {
159                 // set exception if there was one
160
if (multiStatus != null) {
161                     fException = new CoreException(multiStatus);
162                 } else if (single != null) {
163                     fException = single;
164                 }
165             }
166         }
167         
168         public List JavaDoc getSourceElements() {
169             return fSourceElements;
170         }
171
172         public void dispose() {
173             fElement = null;
174             fSourceElements = null;
175             fException = null;
176         }
177         
178     }
179     
180     /**
181      * Constructs source lookup director
182      */

183     public AbstractSourceLookupDirector() {
184     }
185     
186     /**
187      * Sets the type identifier for this source locator's type
188      *
189      * @param id corresponds to source locator type identifier for a
190      * persistable source locator
191      */

192     public void setId(String JavaDoc id) {
193         fId = id;
194     }
195     
196     /* (non-Javadoc)
197      * @see org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2#dispose()
198      */

199     public synchronized void dispose() {
200         ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
201         launchManager.removeLaunchConfigurationListener(this);
202         launchManager.removeLaunchListener(this);
203         Iterator JavaDoc iterator = fParticipants.iterator();
204         while (iterator.hasNext()) {
205             ISourceLookupParticipant participant = (ISourceLookupParticipant) iterator.next();
206             //director may also be a participant
207
if(participant != this)
208                 participant.dispose();
209         }
210         fParticipants.clear();
211         if (fSourceContainers != null) {
212             for (int i = 0; i < fSourceContainers.length; i++) {
213                 fSourceContainers[i].dispose();
214             }
215         }
216         fSourceContainers = null;
217         fResolvedElements = null;
218     }
219     
220     /**
221      * Throws an exception with the given message and underlying exception.
222      *
223      * @param message error message
224      * @param exception underlying exception, or <code>null</code>
225      * @throws CoreException
226      */

227     protected void abort(String JavaDoc message, Throwable JavaDoc exception) throws CoreException {
228         IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, message, exception);
229         throw new CoreException(status);
230     }
231     
232     /**
233      * Constructs source containers from a list of container mementos.
234      *
235      * @param list the list of nodes to be parsed
236      * @exception CoreException if parsing encounters an error
237      * @return a list of source containers
238      */

239     private List JavaDoc parseSourceContainers(NodeList JavaDoc list) throws CoreException {
240         List JavaDoc containers = new ArrayList JavaDoc();
241         for (int i=0; i < list.getLength(); i++) {
242             if(!(list.item(i).getNodeType() == Node.ELEMENT_NODE))
243                 continue;
244             Element JavaDoc element = (Element JavaDoc)list.item(i);
245             String JavaDoc typeId = element.getAttribute(CONTAINER_TYPE_ATTR);
246             if (typeId == null || typeId.equals("")) { //$NON-NLS-1$
247
abort(SourceLookupMessages.AbstractSourceLookupDirector_11, null);
248             }
249             ISourceContainerType type = DebugPlugin.getDefault().getLaunchManager().getSourceContainerType(typeId);
250             if(type == null) {
251                 abort(MessageFormat.format(SourceLookupMessages.AbstractSourceLookupDirector_12, new String JavaDoc[]{typeId}), null);
252             }
253             String JavaDoc memento = element.getAttribute(CONTAINER_MEMENTO_ATTR);
254             if (memento == null || memento.equals("")) { //$NON-NLS-1$
255
abort(SourceLookupMessages.AbstractSourceLookupDirector_13, null);
256             }
257             ISourceContainer container = type.createSourceContainer(memento);
258             containers.add(container);
259         }
260         return containers;
261     }
262     
263     /**
264      * Registers the given source lookup participant. Has no effect if an identical
265      * participant is already registered. Participants receive notification
266      * when the source containers associated with this source director change.
267      *
268      * @param participant the participant to register
269      */

270     private synchronized void addSourceLookupParticipant(ISourceLookupParticipant participant) {
271         if (!fParticipants.contains(participant)) {
272             fParticipants.add(participant);
273             participant.init(this);
274         }
275     }
276     
277     /* (non-Javadoc)
278      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getSourceContainers()
279      */

280     public synchronized ISourceContainer[] getSourceContainers() {
281         if (fSourceContainers == null) {
282             return new ISourceContainer[0];
283         }
284         ISourceContainer[] copy = new ISourceContainer[fSourceContainers.length];
285         System.arraycopy(fSourceContainers, 0, copy, 0, fSourceContainers.length);
286         return copy;
287     }
288     
289     /* (non-Javadoc)
290      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#isFindDuplicates()
291      */

292     public boolean isFindDuplicates() {
293         return fDuplicates;
294     }
295     
296     /* (non-Javadoc)
297      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#setFindDuplicates(boolean)
298      */

299     public void setFindDuplicates(boolean duplicates) {
300         fDuplicates = duplicates;
301     }
302     
303     /**
304      * Removes the given participant from the list of registered participants.
305      * Has no effect if an identical participant is not already registered.
306      *
307      * @param participant the participant to remove
308      */

309     private synchronized void removeSourceLookupParticipant(ISourceLookupParticipant participant) {
310         if (fParticipants.remove(participant)) {
311             participant.dispose();
312         }
313     }
314
315     /* (non-Javadoc)
316      * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration)
317      */

318     public void launchConfigurationAdded(ILaunchConfiguration configuration) {
319         ILaunchConfiguration from = DebugPlugin.getDefault().getLaunchManager().getMovedFrom(configuration);
320         if (from != null && from.equals(getLaunchConfiguration())) {
321             fConfig = configuration;
322         }
323     }
324     
325     /* (non-Javadoc)
326      *
327      * Updates source containers in response to changes in underlying launch
328      * configuration. Only responds to changes in non-working copies.
329      *
330      * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration)
331      */

332     public void launchConfigurationChanged(ILaunchConfiguration configuration) {
333         if (fConfig == null || configuration.isWorkingCopy()) {
334             return;
335         }
336         if(fConfig.equals(configuration)) {
337             try{
338                 String JavaDoc locatorMemento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO,(String JavaDoc)null);
339                 if (locatorMemento == null) {
340                     initializeDefaults(configuration);
341                 } else {
342                     initializeFromMemento(locatorMemento, configuration);
343                 }
344             } catch (CoreException e){
345             }
346         }
347     }
348     
349     
350     /* (non-Javadoc)
351      * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration)
352      */

353     public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
354         if (configuration.equals(getLaunchConfiguration())) {
355             if (DebugPlugin.getDefault().getLaunchManager().getMovedTo(configuration) == null) {
356                 fConfig = null;
357             }
358         }
359     }
360     
361     /* (non-Javadoc)
362      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento()
363      */

364     public synchronized String JavaDoc getMemento() throws CoreException {
365         Document JavaDoc doc = DebugPlugin.newDocument();
366         Element JavaDoc rootNode = doc.createElement(DIRECTOR_ROOT_NODE);
367         doc.appendChild(rootNode);
368                 
369         Element JavaDoc pathNode = doc.createElement(CONTAINERS_NODE);
370         if(fDuplicates) {
371             pathNode.setAttribute(DUPLICATES_ATTR, "true"); //$NON-NLS-1$
372
} else {
373             pathNode.setAttribute(DUPLICATES_ATTR, "false"); //$NON-NLS-1$
374
}
375         rootNode.appendChild(pathNode);
376         if(fSourceContainers !=null){
377             for(int i=0; i<fSourceContainers.length; i++){
378                 Element JavaDoc node = doc.createElement(CONTAINER_NODE);
379                 ISourceContainer container = fSourceContainers[i];
380                 ISourceContainerType type = container.getType();
381                 node.setAttribute(CONTAINER_TYPE_ATTR, type.getId());
382                 node.setAttribute(CONTAINER_MEMENTO_ATTR, type.getMemento(container));
383                 pathNode.appendChild(node);
384             }
385         }
386         return DebugPlugin.serializeDocument(doc);
387     }
388     
389     /* (non-Javadoc)
390      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(java.lang.String)
391      */

392     public void initializeFromMemento(String JavaDoc memento) throws CoreException {
393         doInitializeFromMemento(memento, true);
394     }
395     
396     /**
397      * Initializes this source lookup director from the given memento.
398      * Disposes itself before initialization if specified.
399      *
400      * @param memento source locator memento
401      * @param dispose whether to dispose any current source containers and participants
402      * before initializing
403      * @throws CoreException if an exception occurs during initialization
404      * @since 3.1
405      */

406     protected void doInitializeFromMemento(String JavaDoc memento, boolean dispose) throws CoreException {
407         if (dispose) {
408             dispose();
409         }
410         Element JavaDoc rootElement = DebugPlugin.parseDocument(memento);
411         if (!rootElement.getNodeName().equalsIgnoreCase(DIRECTOR_ROOT_NODE)) {
412             abort(SourceLookupMessages.AbstractSourceLookupDirector_14, null);
413         }
414         NodeList JavaDoc list = rootElement.getChildNodes();
415         int length = list.getLength();
416         for (int i = 0; i < length; ++i) {
417             Node JavaDoc node = list.item(i);
418             short type = node.getNodeType();
419             if (type == Node.ELEMENT_NODE) {
420                 Element JavaDoc entry = (Element JavaDoc) node;
421                 if(entry.getNodeName().equalsIgnoreCase(CONTAINERS_NODE)){
422                     setFindDuplicates("true".equals(entry.getAttribute(DUPLICATES_ATTR))); //$NON-NLS-1$
423
NodeList JavaDoc children = entry.getChildNodes();
424                     List JavaDoc containers = parseSourceContainers(children);
425                     setSourceContainers((ISourceContainer[]) containers.toArray(new ISourceContainer[containers.size()]));
426                 }
427             }
428         }
429         initializeParticipants();
430     }
431     
432     /**
433      * Sets the source containers used by this source lookup
434      * director.
435      *
436      * @param containers source containers to search
437      */

438     public void setSourceContainers(ISourceContainer[] containers) {
439         synchronized (this) {
440             List JavaDoc list = Arrays.asList( containers );
441             ISourceContainer[] old = getSourceContainers();
442             for (int i = 0; i < old.length; i++) {
443                 // skip overlapping containers
444
if (!list.contains(old[i]))
445                     old[i].dispose();
446             }
447             fSourceContainers = containers;
448             for (int i = 0; i < containers.length; i++) {
449                 ISourceContainer container = containers[i];
450                 container.init(this);
451             }
452         }
453         // clear resolved duplicates
454
fResolvedElements = null;
455         // notify participants
456
ISourceLookupParticipant[] participants = getParticipants();
457         for (int i = 0; i < participants.length; i++) {
458             ISourceLookupParticipant participant = participants[i];
459             participant.sourceContainersChanged(this);
460         }
461     }
462     
463     /* (non-Javadoc)
464      * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(org.eclipse.debug.core.model.IStackFrame)
465      * Would be better to accept Object so this can be used for breakpoints and other objects.
466      */

467     public Object JavaDoc getSourceElement(IStackFrame stackFrame) {
468         return getSourceElement((Object JavaDoc)stackFrame);
469     }
470     
471     /**
472      * Performs a source lookup query for the given element
473      * returning the source elements associated with the element.
474      *
475      * @param element stack frame
476      * @return list of associated source elements
477      */

478     protected List JavaDoc doSourceLookup(Object JavaDoc element) {
479         SourceLookupQuery query = new SourceLookupQuery(element);
480         SafeRunner.run(query);
481         List JavaDoc sources = query.getSourceElements();
482         query.dispose();
483         return sources;
484     }
485     
486     /**
487      * Returns the source element to associate with the given element.
488      * This method is called when more than one source element has been found
489      * for an element, and allows the source director to select a single
490      * source element to associate with the element.
491      * <p>
492      * Subclasses should override this method as appropriate. For example,
493      * to prompt the user to choose a source element.
494      * </p>
495      * @param element the debug artifact for which source is being searched for
496      * @param sources the source elements found for the given element
497      * @return a single source element for the given element
498      */

499     public Object JavaDoc resolveSourceElement(Object JavaDoc element, List JavaDoc sources) {
500         // check the duplicates cache first
501
Iterator JavaDoc duplicates = sources.iterator();
502         while (duplicates.hasNext()) {
503             Object JavaDoc dup = duplicates.next();
504             Object JavaDoc resolved = getCachedElement(dup);
505             if (resolved != null) {
506                 return resolved;
507             }
508         }
509         // consult a status handler
510
IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(fPromptStatus);
511         if (prompter != null) {
512             try {
513                 Object JavaDoc result = prompter.handleStatus(fResolveDuplicatesStatus, new Object JavaDoc[]{element, sources});
514                 if (result != null) {
515                     cacheResolvedElement(sources, result);
516                     return result;
517                 }
518             } catch (CoreException e) {
519             }
520         }
521         return sources.get(0);
522     }
523
524     /**
525      * Checks if the object being added to the list of sources is a duplicate of what's already in the list
526      * @param sourceToAdd the new source file to be added
527      * @param sources the list that the source will be compared against
528      * @return true if it is already in the list, false if it is a new object
529      */

530     private boolean checkDuplicate(Object JavaDoc sourceToAdd, List JavaDoc sources){
531         if(sources.size() == 0)
532             return false;
533         Iterator JavaDoc iterator = sources.iterator();
534         while(iterator.hasNext())
535             if(iterator.next().equals(sourceToAdd))
536                 return true;
537         return false;
538     }
539     
540     /* (non-Javadoc)
541      * @see org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2#initializeFromMemento(java.lang.String, org.eclipse.debug.core.ILaunchConfiguration)
542      */

543     public void initializeFromMemento(String JavaDoc memento, ILaunchConfiguration configuration) throws CoreException {
544         dispose();
545         setLaunchConfiguration(configuration);
546         doInitializeFromMemento(memento, false);
547     }
548
549     /* (non-Javadoc)
550      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(org.eclipse.debug.core.ILaunchConfiguration)
551      */

552     public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException {
553         dispose();
554         setLaunchConfiguration(configuration);
555         setSourceContainers(new ISourceContainer[]{new DefaultSourceContainer()});
556         initializeParticipants();
557     }
558     
559     /* (non-Javadoc)
560      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getLaunchConfiguration()
561      */

562     public ILaunchConfiguration getLaunchConfiguration() {
563         return fConfig;
564     }
565     
566     /**
567      * Sets the launch configuration associated with this source lookup
568      * director. If the given configuration is a working copy, this director
569      * will respond to changes the working copy. If the given configuration
570      * is a persisted launch configuration, this director will respond to changes
571      * in the persisted launch configuration.
572      *
573      * @param configuration launch configuration to associate with this
574      * source lookup director, or <code>null</code> if none
575      */

576     protected void setLaunchConfiguration(ILaunchConfiguration configuration) {
577         fConfig = configuration;
578         ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
579         launchManager.addLaunchConfigurationListener(this);
580         launchManager.addLaunchListener(this);
581     }
582     
583     /* (non-Javadoc)
584      * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch)
585      */

586     public void launchAdded(ILaunch launch) {
587     }
588     /* (non-Javadoc)
589      * @see org.eclipse.debug.core.ILaunchListener#launchChanged(org.eclipse.debug.core.ILaunch)
590      */

591     public void launchChanged(ILaunch launch) {
592     }
593     /* (non-Javadoc)
594      * @see org.eclipse.debug.core.ILaunchListener#launchRemoved(org.eclipse.debug.core.ILaunch)
595      */

596     public void launchRemoved(ILaunch launch) {
597         if (this.equals(launch.getSourceLocator())) {
598             dispose();
599         }
600     }
601     /* (non-Javadoc)
602      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getParticipants()
603      */

604     public synchronized ISourceLookupParticipant[] getParticipants() {
605         return (ISourceLookupParticipant[]) fParticipants.toArray(new ISourceLookupParticipant[fParticipants.size()]);
606     }
607     /* (non-Javadoc)
608      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#supportsSourceContainerType(org.eclipse.debug.core.sourcelookup.ISourceContainerType)
609      */

610     public boolean supportsSourceContainerType(ISourceContainerType type) {
611         return true;
612     }
613     
614     /**
615      * Caches the resolved source element to use when one of the following
616      * duplicates is found.
617      *
618      * @param duplicates duplicates source elements
619      * @param sourceElement chosen source element to use in place of the
620      * duplicates
621      */

622     protected void cacheResolvedElement(List JavaDoc duplicates, Object JavaDoc sourceElement) {
623         if (fResolvedElements == null) {
624             fResolvedElements = new HashMap JavaDoc(10);
625         }
626         Iterator JavaDoc iterator = duplicates.iterator();
627         while (iterator.hasNext()) {
628             Object JavaDoc dup = iterator.next();
629             fResolvedElements.put(dup, sourceElement);
630         }
631         
632     }
633     
634     /**
635      * Returns the cached source element to use when the given duplicate
636      * is encountered.
637      *
638      * @param duplicate duplicates source element
639      * @return element to use in the duplicate's place
640      */

641     protected Object JavaDoc getCachedElement(Object JavaDoc duplicate) {
642         if (fResolvedElements != null) {
643             return fResolvedElements.get(duplicate);
644         }
645         return null;
646     }
647     
648     /**
649      * Clears any cached source element associated with the given duplicate
650      * is source element.
651      *
652      * @param duplicate duplicate source element to cache resolved results
653      * for
654      */

655     protected void clearCachedElement(Object JavaDoc duplicate) {
656         if (fResolvedElements != null) {
657             fResolvedElements.remove(duplicate);
658         }
659     }
660     
661     /* (non-Javadoc)
662      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#clearSourceElements(java.lang.Object)
663      */

664     public void clearSourceElements(Object JavaDoc element) {
665         List JavaDoc list = doSourceLookup(element);
666         if (list.size() > 0) {
667             Iterator JavaDoc iterator = list.iterator();
668             while (iterator.hasNext()) {
669                 clearCachedElement(iterator.next());
670             }
671         }
672     }
673     /* (non-Javadoc)
674      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#addParticipants(org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant[])
675      */

676     public void addParticipants(ISourceLookupParticipant[] participants) {
677         for (int i = 0; i < participants.length; i++) {
678             ISourceLookupParticipant participant = participants[i];
679             addSourceLookupParticipant(participant);
680             participant.sourceContainersChanged(this);
681         }
682     }
683     /* (non-Javadoc)
684      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#removeParticipants(org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant[])
685      */

686     public void removeParticipants(ISourceLookupParticipant[] participants) {
687         for (int i = 0; i < participants.length; i++) {
688             removeSourceLookupParticipant(participants[i]);
689         }
690     }
691
692     /* (non-Javadoc)
693      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getId()
694      */

695     public String JavaDoc getId() {
696         return fId;
697     }
698     /* (non-Javadoc)
699      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getSourcePathComputer()
700      */

701     public ISourcePathComputer getSourcePathComputer() {
702         if (fComputer == null && getLaunchConfiguration() != null) {
703             try {
704                 return DebugPlugin.getDefault().getLaunchManager().getSourcePathComputer(getLaunchConfiguration());
705             } catch (CoreException e) {
706             }
707         }
708         return fComputer;
709     }
710     /* (non-Javadoc)
711      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#setSourcePathComputer(org.eclipse.debug.core.sourcelookup.ISourcePathComputer)
712      */

713     public void setSourcePathComputer(ISourcePathComputer computer) {
714         fComputer = computer;
715     }
716     /* (non-Javadoc)
717      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#findSourceElements(java.lang.Object)
718      */

719     public Object JavaDoc[] findSourceElements(Object JavaDoc object) throws CoreException {
720         SourceLookupQuery query = new SourceLookupQuery(object);
721         SafeRunner.run(query);
722         List JavaDoc sources = query.getSourceElements();
723         Throwable JavaDoc exception = query.getException();
724         query.dispose();
725         if (exception != null && sources.isEmpty()) {
726             if (exception instanceof CoreException) {
727                 throw (CoreException)exception;
728             }
729             abort(SourceLookupMessages.AbstractSourceLookupDirector_10, exception);
730         }
731         return sources.toArray();
732     }
733     /* (non-Javadoc)
734      * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#getSourceElement(java.lang.Object)
735      */

736     public Object JavaDoc getSourceElement(Object JavaDoc element) {
737         List JavaDoc sources = doSourceLookup(element);
738         if(sources.size() == 1) {
739             return sources.get(0);
740         } else if(sources.size() > 1) {
741             return resolveSourceElement(element, sources);
742         } else {
743             return null;
744         }
745     }
746 }
747
Popular Tags