KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > launching > sourcelookup > JavaSourceLocator


1 /*******************************************************************************
2  * Copyright (c) 2000, 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 package org.eclipse.jdt.launching.sourcelookup;
12
13
14 import java.io.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.StringReader JavaDoc;
17 import com.ibm.icu.text.MessageFormat;
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22
23 import javax.xml.parsers.DocumentBuilder JavaDoc;
24 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
25 import javax.xml.parsers.ParserConfigurationException JavaDoc;
26 import javax.xml.transform.TransformerException JavaDoc;
27
28 import org.eclipse.core.resources.IProject;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.resources.ResourcesPlugin;
31 import org.eclipse.core.runtime.CoreException;
32 import org.eclipse.core.runtime.IPath;
33 import org.eclipse.core.runtime.IStatus;
34 import org.eclipse.core.runtime.Path;
35 import org.eclipse.core.runtime.Status;
36 import org.eclipse.debug.core.DebugPlugin;
37 import org.eclipse.debug.core.ILaunchConfiguration;
38 import org.eclipse.debug.core.ILaunchConfigurationType;
39 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
40 import org.eclipse.debug.core.model.IPersistableSourceLocator;
41 import org.eclipse.debug.core.model.IStackFrame;
42 import org.eclipse.jdt.core.IClasspathEntry;
43 import org.eclipse.jdt.core.IJavaModel;
44 import org.eclipse.jdt.core.IJavaProject;
45 import org.eclipse.jdt.core.IPackageFragmentRoot;
46 import org.eclipse.jdt.core.JavaCore;
47 import org.eclipse.jdt.core.JavaModelException;
48 import org.eclipse.jdt.debug.core.IJavaStackFrame;
49 import org.eclipse.jdt.debug.core.IJavaThread;
50 import org.eclipse.jdt.internal.launching.LaunchingMessages;
51 import org.eclipse.jdt.internal.launching.LaunchingPlugin;
52 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
53 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
54 import org.eclipse.jdt.launching.JavaRuntime;
55 import org.w3c.dom.Document JavaDoc;
56 import org.w3c.dom.Element JavaDoc;
57 import org.w3c.dom.Node JavaDoc;
58 import org.w3c.dom.NodeList JavaDoc;
59 import org.xml.sax.InputSource JavaDoc;
60 import org.xml.sax.SAXException JavaDoc;
61 import org.xml.sax.helpers.DefaultHandler JavaDoc;
62
63
64 /**
65  * Locates source for a Java debug session by searching
66  * a configurable set of source locations.
67  * <p>
68  * This class may be instantiated; it is not intended to be subclassed.
69  * </p>
70  * @see org.eclipse.debug.core.model.ISourceLocator
71  * @since 2.0
72  * @deprecated In 3.0, the debug platform provides source lookup facilities that
73  * should be used in place of the Java source lookup support provided in 2.0.
74  * The new facilities provide a source lookup director that coordinates source
75  * lookup among a set of participants, searching a set of source containers.
76  * See the following packages: <code>org.eclipse.debug.core.sourcelookup</code>
77  * and <code>org.eclipse.debug.core.sourcelookup.containers</code>. This class
78  * has been replaced by a Java source lookup director and Java source lookup
79  * participant. To migrate to the new source lookup support clients should
80  * add two new attributes to their launch configuration type extensions:<ul>
81  * <li>sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"</li>
82  * <li>sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer"</li>
83  * </ul>
84  * The source locator id attribute specifies to use the Java source lookup director
85  * for launch configurations of the associated type, and the source path computer id
86  * attribute specifies the class to use when computing a default source lookup
87  * path for a launch configuration. The path computer referenced/provided (by the
88  * above id), computes a default source lookup path based on the support provided in
89  * the 2.0 release - i.e. a configuration's <code>ATTR_SOURCE_PATH_PROVIDER</code>
90  * attribute (if present), or a default source lookup path based on a configuration's
91  * runtime classpath. This class has been replaced by the Java source lookup
92  * director which is an internal class, but can be used via the
93  * <code>sourceLocatorId</code> attribute on a launch configuration type extension.
94  */

95 public class JavaSourceLocator implements IPersistableSourceLocator {
96     
97     /**
98      * Identifier for the 'Java Source Locator' extension
99      * (value <code>"org.eclipse.jdt.launching.javaSourceLocator"</code>).
100      */

101     public static final String JavaDoc ID_JAVA_SOURCE_LOCATOR = LaunchingPlugin.getUniqueIdentifier() + ".javaSourceLocator"; //$NON-NLS-1$
102

103     /**
104      * A collection of the source locations to search
105      */

106     private IJavaSourceLocation[] fLocations;
107
108     /**
109      * Constructs a new empty JavaSourceLocator.
110      */

111     public JavaSourceLocator() {
112         setSourceLocations(new IJavaSourceLocation[0]);
113     }
114     
115     /**
116      * Constructs a new Java source locator that looks in the
117      * specified project for source, and required projects, if
118      * <code>includeRequired</code> is <code>true</code>.
119      *
120      * @param projects the projects in which to look for source
121      * @param includeRequired whether to look in required projects
122      * as well
123      */

124     public JavaSourceLocator(IJavaProject[] projects, boolean includeRequired) throws JavaModelException {
125         ArrayList JavaDoc requiredProjects = new ArrayList JavaDoc();
126         for (int i= 0; i < projects.length; i++) {
127             if (includeRequired) {
128                 collectRequiredProjects(projects[i], requiredProjects);
129             } else {
130                 if (!requiredProjects.contains(projects[i])) {
131                     requiredProjects.add(projects[i]);
132                 }
133             }
134         }
135         
136         // only add external entries with the same location once
137
HashMap JavaDoc external = new HashMap JavaDoc();
138         ArrayList JavaDoc list = new ArrayList JavaDoc();
139         // compute the default locations for each project, and add unique ones
140
Iterator JavaDoc iter = requiredProjects.iterator();
141         while (iter.hasNext()) {
142             IJavaProject p = (IJavaProject)iter.next();
143             try {
144                 IPackageFragmentRoot[] roots = p.getPackageFragmentRoots();
145                 for (int i = 0; i < roots.length; i++) {
146                     if (roots[i].isExternal()) {
147                         IPath location = roots[i].getPath();
148                         if (external.get(location) == null) {
149                             external.put(location, location);
150                             list.add(new PackageFragmentRootSourceLocation(roots[i]));
151                         }
152                     } else {
153                         list.add(new PackageFragmentRootSourceLocation(roots[i]));
154                     }
155                 }
156             } catch (CoreException e) {
157                 if (e instanceof JavaModelException) {
158                     throw (JavaModelException)e;
159                 }
160                 throw new JavaModelException(e);
161             }
162         }
163         IJavaSourceLocation[] locations = (IJavaSourceLocation[])list.toArray(new IJavaSourceLocation[list.size()]);
164         setSourceLocations(locations);
165     }
166     
167     /**
168      * Constructs a new JavaSourceLocator that searches the
169      * specified set of source locations for source elements.
170      *
171      * @param locations the source locations to search for
172      * source, in the order they should be searched
173      */

174     public JavaSourceLocator(IJavaSourceLocation[] locations) {
175         setSourceLocations(locations);
176     }
177     
178     /**
179      * Constructs a new JavaSourceLocator that searches the
180      * default set of source locations for the given Java project.
181      *
182      * @param project Java project
183      * @exception CoreException if an exception occurs reading
184      * the classpath of the given or any required project
185      */

186     public JavaSourceLocator(IJavaProject project) throws CoreException {
187         setSourceLocations(getDefaultSourceLocations(project));
188     }
189     
190     /**
191      * Sets the locations that will be searched, in the order
192      * to be searched.
193      *
194      * @param locations the locations that will be searched, in the order
195      * to be searched
196      */

197     public void setSourceLocations(IJavaSourceLocation[] locations) {
198         fLocations = locations;
199     }
200     
201     /**
202      * Returns the locations that this source locator is currently
203      * searching, in the order that they are searched.
204      *
205      * @return the locations that this source locator is currently
206      * searching, in the order that they are searched
207      */

208     public IJavaSourceLocation[] getSourceLocations() {
209         return fLocations;
210     }
211     
212     /**
213      * Returns all source elements that correspond to the type associated with
214      * the given stack frame, or <code>null</code> if none.
215      *
216      * @param stackFrame stack frame
217      * @return all source elements that correspond to the type associated with
218      * the given stack frame, or <code>null</code> if none
219      * @since 2.1
220      */

221     public Object JavaDoc[] getSourceElements(IStackFrame stackFrame) {
222         if (stackFrame instanceof IJavaStackFrame) {
223             IJavaStackFrame frame = (IJavaStackFrame)stackFrame;
224             String JavaDoc name = null;
225             try {
226                 name = getFullyQualfiedName(frame);
227                 if (name == null) {
228                     return null;
229                 }
230             } catch (CoreException e) {
231                 // if the thread has since resumed, return null
232
if (e.getStatus().getCode() != IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
233                     LaunchingPlugin.log(e);
234                 }
235                 return null;
236             }
237             List JavaDoc list = new ArrayList JavaDoc();
238             IJavaSourceLocation[] locations = getSourceLocations();
239             for (int i = 0; i < locations.length; i++) {
240                 try {
241                     Object JavaDoc sourceElement = locations[i].findSourceElement(name);
242                     if (sourceElement != null) {
243                         list.add(sourceElement);
244                     }
245                 } catch (CoreException e) {
246                     // log the error and try the next source location
247
LaunchingPlugin.log(e);
248                 }
249             }
250             return list.toArray();
251         }
252         return null;
253     }
254             
255     /* (non-Javadoc)
256      * @see org.eclipse.debug.core.model.ISourceLocator#getSourceElement(org.eclipse.debug.core.model.IStackFrame)
257      */

258     public Object JavaDoc getSourceElement(IStackFrame stackFrame) {
259         if (stackFrame instanceof IJavaStackFrame) {
260             IJavaStackFrame frame = (IJavaStackFrame)stackFrame;
261             String JavaDoc name = null;
262             try {
263                 name = getFullyQualfiedName(frame);
264                 if (name == null) {
265                     return null;
266                 }
267             } catch (CoreException e) {
268                 // if the thread has since resumed, return null
269
if (e.getStatus().getCode() != IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
270                     LaunchingPlugin.log(e);
271                 }
272                 return null;
273             }
274             IJavaSourceLocation[] locations = getSourceLocations();
275             for (int i = 0; i < locations.length; i++) {
276                 try {
277                     Object JavaDoc sourceElement = locations[i].findSourceElement(name);
278                     if (sourceElement != null) {
279                         return sourceElement;
280                     }
281                 } catch (CoreException e) {
282                     // log the error and try the next source location
283
LaunchingPlugin.log(e);
284                 }
285             }
286         }
287         return null;
288     }
289     
290     private String JavaDoc getFullyQualfiedName(IJavaStackFrame frame) throws CoreException {
291         String JavaDoc name = null;
292         if (frame.isObsolete()) {
293             return null;
294         }
295         String JavaDoc sourceName = frame.getSourceName();
296         if (sourceName == null) {
297             // no debug attributes, guess at source name
298
name = frame.getDeclaringTypeName();
299         } else {
300             // build source name from debug attributes using
301
// the source file name and the package of the declaring
302
// type
303

304             // @see bug# 21518 - remove absolute path prefix
305
int index = sourceName.lastIndexOf('\\');
306             if (index == -1) {
307                 index = sourceName.lastIndexOf('/');
308             }
309             if (index >= 0) {
310                 sourceName = sourceName.substring(index + 1);
311             }
312                     
313             String JavaDoc declName= frame.getDeclaringTypeName();
314             index = declName.lastIndexOf('.');
315             if (index >= 0) {
316                 name = declName.substring(0, index + 1);
317             } else {
318                 name = ""; //$NON-NLS-1$
319
}
320             index = sourceName.lastIndexOf('.');
321             if (index >= 0) {
322                 name += sourceName.substring(0, index) ;
323             }
324         }
325         return name;
326     }
327     
328     /**
329      * Adds all projects required by <code>proj</code> to the list
330      * <code>res</code>
331      *
332      * @param proj the project for which to compute required
333      * projects
334      * @param res the list to add all required projects too
335      */

336     protected static void collectRequiredProjects(IJavaProject proj, ArrayList JavaDoc res) throws JavaModelException {
337         if (!res.contains(proj)) {
338             res.add(proj);
339             
340             IJavaModel model= proj.getJavaModel();
341             
342             IClasspathEntry[] entries= proj.getRawClasspath();
343             for (int i= 0; i < entries.length; i++) {
344                 IClasspathEntry curr= entries[i];
345                 if (curr.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
346                     IJavaProject ref= model.getJavaProject(curr.getPath().segment(0));
347                     if (ref.exists()) {
348                         collectRequiredProjects(ref, res);
349                     }
350                 }
351             }
352         }
353     }
354     
355     /**
356      * Returns a default collection of source locations for
357      * the given Java project. Default source locations consist
358      * of the given project and all of its required projects .
359      *
360      * @param project Java project
361      * @return a collection of source locations for all required
362      * projects
363      * @exception CoreException if an exception occurs reading
364      * computing the default locations
365      */

366     public static IJavaSourceLocation[] getDefaultSourceLocations(IJavaProject project) throws CoreException {
367         // create a temporary launch config
368
ILaunchConfigurationType type = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
369         ILaunchConfigurationWorkingCopy config = type.newInstance(null, project.getElementName());
370         config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName());
371         JavaSourceLocator locator = new JavaSourceLocator();
372         locator.initializeDefaults(config);
373         return locator.getSourceLocations();
374     }
375     
376     /* (non-Javadoc)
377      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#getMemento()
378      */

379     public String JavaDoc getMemento() throws CoreException {
380         try {
381             Document JavaDoc doc = LaunchingPlugin.getDocument();
382             Element JavaDoc node = doc.createElement("javaSourceLocator"); //$NON-NLS-1$
383
doc.appendChild(node);
384             
385             IJavaSourceLocation[] locations = getSourceLocations();
386             for (int i = 0; i < locations.length; i++) {
387                 Element JavaDoc child = doc.createElement("javaSourceLocation"); //$NON-NLS-1$
388
child.setAttribute("class", locations[i].getClass().getName()); //$NON-NLS-1$
389
child.setAttribute("memento", locations[i].getMemento()); //$NON-NLS-1$
390
node.appendChild(child);
391             }
392         
393             return LaunchingPlugin.serializeDocument(doc);
394         } catch (IOException JavaDoc e) {
395             abort(LaunchingMessages.JavaSourceLocator_Unable_to_create_memento_for_Java_source_locator__4, e);
396         } catch (ParserConfigurationException JavaDoc e) {
397             abort(LaunchingMessages.JavaSourceLocator_Unable_to_create_memento_for_Java_source_locator__4, e);
398         } catch (TransformerException JavaDoc e) {
399             abort(LaunchingMessages.JavaSourceLocator_Unable_to_create_memento_for_Java_source_locator__4, e);
400         }
401         // execution will not reach here
402
return null;
403     }
404
405     /* (non-Javadoc)
406      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeDefaults(org.eclipse.debug.core.ILaunchConfiguration)
407      */

408     public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException {
409         IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedSourceLookupPath(configuration);
410         IRuntimeClasspathEntry[] resolved = JavaRuntime.resolveSourceLookupPath(entries, configuration);
411         setSourceLocations(getSourceLocations(resolved));
412     }
413
414     /* (non-Javadoc)
415      * @see org.eclipse.debug.core.model.IPersistableSourceLocator#initializeFromMemento(java.lang.String)
416      */

417     public void initializeFromMemento(String JavaDoc memento) throws CoreException {
418         Exception JavaDoc ex = null;
419         try {
420             Element JavaDoc root = null;
421             DocumentBuilder JavaDoc parser =
422                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
423             parser.setErrorHandler(new DefaultHandler JavaDoc());
424             StringReader JavaDoc reader = new StringReader JavaDoc(memento);
425             InputSource JavaDoc source = new InputSource JavaDoc(reader);
426             root = parser.parse(source).getDocumentElement();
427                                                 
428             if (!root.getNodeName().equalsIgnoreCase("javaSourceLocator")) { //$NON-NLS-1$
429
abort(LaunchingMessages.JavaSourceLocator_Unable_to_restore_Java_source_locator___invalid_format__6, null);
430             }
431     
432             List JavaDoc sourceLocations = new ArrayList JavaDoc();
433             ClassLoader JavaDoc classLoader = LaunchingPlugin.getDefault().getDescriptor().getPluginClassLoader();
434             
435             NodeList JavaDoc list = root.getChildNodes();
436             int length = list.getLength();
437             for (int i = 0; i < length; ++i) {
438                 Node JavaDoc node = list.item(i);
439                 short type = node.getNodeType();
440                 if (type == Node.ELEMENT_NODE) {
441                     Element JavaDoc entry = (Element JavaDoc) node;
442                     if (entry.getNodeName().equalsIgnoreCase("javaSourceLocation")) { //$NON-NLS-1$
443
String JavaDoc className = entry.getAttribute("class"); //$NON-NLS-1$
444
String JavaDoc data = entry.getAttribute("memento"); //$NON-NLS-1$
445
if (isEmpty(className)) {
446                             abort(LaunchingMessages.JavaSourceLocator_Unable_to_restore_Java_source_locator___invalid_format__10, null);
447                         }
448                         Class JavaDoc clazz = null;
449                         try {
450                             clazz = classLoader.loadClass(className);
451                         } catch (ClassNotFoundException JavaDoc e) {
452                             abort(MessageFormat.format(LaunchingMessages.JavaSourceLocator_Unable_to_restore_source_location___class_not_found___0__11, new String JavaDoc[] {className}), e);
453                         }
454                         
455                         IJavaSourceLocation location = null;
456                         try {
457                             location = (IJavaSourceLocation)clazz.newInstance();
458                         } catch (IllegalAccessException JavaDoc e) {
459                             abort(LaunchingMessages.JavaSourceLocator_Unable_to_restore_source_location__12, e);
460                         } catch (InstantiationException JavaDoc e) {
461                             abort(LaunchingMessages.JavaSourceLocator_Unable_to_restore_source_location__12, e);
462                         }
463                         location.initializeFrom(data);
464                         sourceLocations.add(location);
465                     } else {
466                         abort(LaunchingMessages.JavaSourceLocator_Unable_to_restore_Java_source_locator___invalid_format__14, null);
467                     }
468                 }
469             }
470             setSourceLocations((IJavaSourceLocation[])sourceLocations.toArray(new IJavaSourceLocation[sourceLocations.size()]));
471             return;
472         } catch (ParserConfigurationException JavaDoc e) {
473             ex = e;
474         } catch (SAXException JavaDoc e) {
475             ex = e;
476         } catch (IOException JavaDoc e) {
477             ex = e;
478         }
479         abort(LaunchingMessages.JavaSourceLocator_Exception_occurred_initializing_source_locator__15, ex);
480     }
481     
482     /**
483      * Returns source locations that are associated with the given runtime classpath
484      * entries.
485      */

486     private static IJavaSourceLocation[] getSourceLocations(IRuntimeClasspathEntry[] entries) {
487         List JavaDoc locations = new ArrayList JavaDoc(entries.length);
488         for (int i = 0; i < entries.length; i++) {
489             IRuntimeClasspathEntry entry = entries[i];
490             IJavaSourceLocation location = null;
491             switch (entry.getType()) {
492                 case IRuntimeClasspathEntry.PROJECT:
493                     IProject project = (IProject)entry.getResource();
494                     if (project != null && project.exists() && project.isOpen()) {
495                         location = new JavaProjectSourceLocation(JavaCore.create(project));
496                     }
497                     break;
498                 case IRuntimeClasspathEntry.ARCHIVE:
499                     // check if the archive is in the workspace as a package fragment root
500
location = getArchiveSourceLocation(entry);
501                     if (location == null) {
502                         String JavaDoc path = entry.getSourceAttachmentLocation();
503                         if (path == null) {
504                             // if there is no source attachment, look in the archive itself
505
path = entry.getLocation();
506                         }
507                         if (path != null) {
508                             File JavaDoc file = new File JavaDoc(path);
509                             if (file.exists()) {
510                                 if (file.isDirectory()) {
511                                     location = new DirectorySourceLocation(file);
512                                 } else {
513                                     location = new ArchiveSourceLocation(path, entry.getSourceAttachmentRootLocation());
514                                 }
515                             }
516                         }
517                     }
518                     break;
519                 case IRuntimeClasspathEntry.VARIABLE:
520                     String JavaDoc source = entry.getSourceAttachmentLocation();
521                     if (source != null) {
522                         location = new ArchiveSourceLocation(source, entry.getSourceAttachmentRootLocation());
523                     }
524                     break;
525                 case IRuntimeClasspathEntry.CONTAINER:
526                     throw new IllegalArgumentException JavaDoc(LaunchingMessages.JavaSourceLocator_Illegal_to_have_a_container_resolved_to_a_container_1);
527             }
528             if (location != null) {
529                 locations.add(location);
530             }
531         }
532         return (IJavaSourceLocation[])locations.toArray(new IJavaSourceLocation[locations.size()]);
533     }
534     
535     private boolean isEmpty(String JavaDoc string) {
536         return string == null || string.length() == 0;
537     }
538     
539     /**
540      * Throws an internal error exception
541      */

542     private void abort(String JavaDoc message, Throwable JavaDoc e) throws CoreException {
543         IStatus s = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, message, e);
544         throw new CoreException(s);
545     }
546     
547     /**
548      * Returns whether the given objects are equal, allowing
549      * for <code>null</code>.
550      *
551      * @param a
552      * @param b
553      * @return whether the given objects are equal, allowing
554      * for <code>null</code>
555      */

556     private static boolean equalOrNull(Object JavaDoc a, Object JavaDoc b) {
557         if (a == null) {
558             return b == null;
559         }
560         if (b == null) {
561             return false;
562         }
563         return a.equals(b);
564     }
565     
566     /**
567      * Returns whether the source attachments of the given package fragment
568      * root and runtime classpath entry are equal.
569      *
570      * @param root package fragment root
571      * @param entry runtime classpath entry
572      * @return whether the source attachments of the given package fragment
573      * root and runtime classpath entry are equal
574      * @throws JavaModelException
575      */

576     private static boolean isSourceAttachmentEqual(IPackageFragmentRoot root, IRuntimeClasspathEntry entry) throws JavaModelException {
577         return equalOrNull(root.getSourceAttachmentPath(), entry.getSourceAttachmentPath());
578     }
579     
580     /**
581      * Determines if the given archive runtime classpath entry exists
582      * in the workspace as a package fragment root. Returns the associated
583      * package fragment root source location if possible, otherwise
584      * <code>null</code>.
585      *
586      * @param entry archive runtime classpath entry
587      * @return IJavaSourceLocation or <code>null</code>
588      */

589     private static IJavaSourceLocation getArchiveSourceLocation(IRuntimeClasspathEntry entry) {
590         IResource resource = entry.getResource();
591         if (resource == null) {
592             // Check all package fragment roots for case of external archive.
593
// External jars are shared, so it does not matter which project it
594
// originates from
595
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
596             try {
597                 IJavaProject[] jps = model.getJavaProjects();
598                 for (int i = 0; i < jps.length; i++) {
599                     IPackageFragmentRoot[] allRoots = jps[i].getPackageFragmentRoots();
600                     for (int j = 0; j < allRoots.length; j++) {
601                         IPackageFragmentRoot root = allRoots[j];
602                         if (root.isExternal() && root.getPath().equals(new Path(entry.getLocation()))) {
603                             if (isSourceAttachmentEqual(root, entry)) {
604                                 // use package fragment root
605
return new PackageFragmentRootSourceLocation(root);
606                             }
607                         }
608                     }
609                 }
610             } catch (JavaModelException e) {
611                 LaunchingPlugin.log(e);
612             }
613         } else {
614             // check if the archive is a package fragment root
615
IProject project = resource.getProject();
616             IJavaProject jp = JavaCore.create(project);
617             try {
618                 if (jp != null && jp.exists()) {
619                     IPackageFragmentRoot root = jp.getPackageFragmentRoot(resource);
620                     IPackageFragmentRoot[] allRoots = jp.getPackageFragmentRoots();
621                     for (int j = 0; j < allRoots.length; j++) {
622                         if (allRoots[j].equals(root)) {
623                             // ensure source attachment paths match
624
if (isSourceAttachmentEqual(root, entry)) {
625                                 // use package fragment root
626
return new PackageFragmentRootSourceLocation(root);
627                             }
628                         }
629                     }
630
631                 }
632                 // check all other java projects to see if another project references
633
// the archive
634
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
635                 IJavaProject[] jps = model.getJavaProjects();
636                 for (int i = 0; i < jps.length; i++) {
637                     IPackageFragmentRoot[] allRoots = jps[i].getPackageFragmentRoots();
638                     for (int j = 0; j < allRoots.length; j++) {
639                         IPackageFragmentRoot root = allRoots[j];
640                         if (!root.isExternal() && root.getPath().equals(entry.getPath())) {
641                             if (isSourceAttachmentEqual(root, entry)) {
642                                 // use package fragment root
643
return new PackageFragmentRootSourceLocation(root);
644                             }
645                         }
646                     }
647                 }
648             } catch (JavaModelException e) {
649                 LaunchingPlugin.log(e);
650             }
651         }
652         return null;
653     }
654     
655 }
656
Popular Tags