KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > launching > DefaultProjectClasspathEntry


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.internal.launching;
12
13 import com.ibm.icu.text.MessageFormat;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.ResourcesPlugin;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.debug.core.ILaunchConfiguration;
24 import org.eclipse.jdt.core.ClasspathContainerInitializer;
25 import org.eclipse.jdt.core.IClasspathContainer;
26 import org.eclipse.jdt.core.IClasspathEntry;
27 import org.eclipse.jdt.core.IJavaProject;
28 import org.eclipse.jdt.core.JavaCore;
29 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
30 import org.eclipse.jdt.launching.IRuntimeContainerComparator;
31 import org.eclipse.jdt.launching.JavaRuntime;
32 import org.w3c.dom.Document JavaDoc;
33 import org.w3c.dom.Element JavaDoc;
34
35 /**
36  * Default user classpath entries for a Java project
37  */

38 public class DefaultProjectClasspathEntry extends AbstractRuntimeClasspathEntry {
39     
40     public static final String JavaDoc TYPE_ID = "org.eclipse.jdt.launching.classpathentry.defaultClasspath"; //$NON-NLS-1$
41

42     /**
43      * Whether only exported entries should be on the runtime classpath.
44      * By default all entries are on the runtime classpath.
45      */

46     private boolean fExportedEntriesOnly = false;
47     
48     /**
49      * Default constructor need to instantiate extensions
50      */

51     public DefaultProjectClasspathEntry() {
52     }
53     
54     /**
55      * Constructs a new classpath entry for the given project.
56      *
57      * @param project Java project
58      */

59     public DefaultProjectClasspathEntry(IJavaProject project) {
60         setJavaProject(project);
61     }
62     
63     /* (non-Javadoc)
64      * @see org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry#buildMemento(org.w3c.dom.Document, org.w3c.dom.Element)
65      */

66     protected void buildMemento(Document JavaDoc document, Element JavaDoc memento) throws CoreException {
67         memento.setAttribute("project", getJavaProject().getElementName()); //$NON-NLS-1$
68
memento.setAttribute("exportedEntriesOnly", Boolean.toString(fExportedEntriesOnly)); //$NON-NLS-1$
69
}
70     
71     /* (non-Javadoc)
72      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#initializeFrom(org.w3c.dom.Element)
73      */

74     public void initializeFrom(Element JavaDoc memento) throws CoreException {
75         String JavaDoc name = memento.getAttribute("project"); //$NON-NLS-1$
76
if (name == null) {
77             abort(LaunchingMessages.DefaultProjectClasspathEntry_3, null);
78         }
79         IJavaProject project = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(name));
80         setJavaProject(project);
81         name = memento.getAttribute("exportedEntriesOnly"); //$NON-NLS-1$
82
if (name == null) {
83             fExportedEntriesOnly = false;
84         } else {
85             fExportedEntriesOnly = Boolean.valueOf(name).booleanValue();
86         }
87     }
88     /* (non-Javadoc)
89      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getTypeId()
90      */

91     public String JavaDoc getTypeId() {
92         return TYPE_ID;
93     }
94     /* (non-Javadoc)
95      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getType()
96      */

97     public int getType() {
98         return OTHER;
99     }
100     
101     protected IProject getProject() {
102         return getJavaProject().getProject();
103     }
104     
105     /* (non-Javadoc)
106      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getLocation()
107      */

108     public String JavaDoc getLocation() {
109         return getProject().getLocation().toOSString();
110     }
111     
112     /* (non-Javadoc)
113      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getPath()
114      */

115     public IPath getPath() {
116         return getProject().getFullPath();
117     }
118     
119     /* (non-Javadoc)
120      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getResource()
121      */

122     public IResource getResource() {
123         return getProject();
124     }
125     
126     /* (non-Javadoc)
127      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getRuntimeClasspathEntries(org.eclipse.debug.core.ILaunchConfiguration)
128      */

129     public IRuntimeClasspathEntry[] getRuntimeClasspathEntries(ILaunchConfiguration configuration) throws CoreException {
130         IClasspathEntry entry = JavaCore.newProjectEntry(getJavaProject().getProject().getFullPath());
131         List JavaDoc classpathEntries = new ArrayList JavaDoc(5);
132         List JavaDoc expanding = new ArrayList JavaDoc(5);
133         expandProject(entry, classpathEntries, expanding);
134         IRuntimeClasspathEntry[] runtimeEntries = new IRuntimeClasspathEntry[classpathEntries.size()];
135         for (int i = 0; i < runtimeEntries.length; i++) {
136             Object JavaDoc e = classpathEntries.get(i);
137             if (e instanceof IClasspathEntry) {
138                 IClasspathEntry cpe = (IClasspathEntry)e;
139                 runtimeEntries[i] = new RuntimeClasspathEntry(cpe);
140             } else {
141                 runtimeEntries[i] = (IRuntimeClasspathEntry)e;
142             }
143         }
144         // remove bootpath entries - this is a default user classpath
145
List JavaDoc ordered = new ArrayList JavaDoc(runtimeEntries.length);
146         for (int i = 0; i < runtimeEntries.length; i++) {
147             if (runtimeEntries[i].getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
148                 ordered.add(runtimeEntries[i]);
149             }
150         }
151         return (IRuntimeClasspathEntry[]) ordered.toArray(new IRuntimeClasspathEntry[ordered.size()]);
152     }
153     
154     /**
155      * Returns the transitive closure of classpath entries for the
156      * given project entry.
157      *
158      * @param projectEntry project classpath entry
159      * @param expandedPath a list of entries already expanded, should be empty
160      * to begin, and contains the result
161      * @param expanding a list of projects that have been or are currently being
162      * expanded (to detect cycles)
163      * @exception CoreException if unable to expand the classpath
164      */

165     private void expandProject(IClasspathEntry projectEntry, List JavaDoc expandedPath, List JavaDoc expanding) throws CoreException {
166         expanding.add(projectEntry);
167         // 1. Get the raw classpath
168
// 2. Replace source folder entries with a project entry
169
IPath projectPath = projectEntry.getPath();
170         IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(projectPath.lastSegment());
171         if (res == null) {
172             // add project entry and return
173
expandedPath.add(projectEntry);
174             return;
175         }
176         IJavaProject project = (IJavaProject)JavaCore.create(res);
177         if (project == null || !project.getProject().isOpen() || !project.exists()) {
178             // add project entry and return
179
expandedPath.add(projectEntry);
180             return;
181         }
182         
183         IClasspathEntry[] buildPath = project.getRawClasspath();
184         List JavaDoc unexpandedPath = new ArrayList JavaDoc(buildPath.length);
185         boolean projectAdded = false;
186         for (int i = 0; i < buildPath.length; i++) {
187             IClasspathEntry classpathEntry = buildPath[i];
188             if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
189                 if (!projectAdded) {
190                     projectAdded = true;
191                     unexpandedPath.add(projectEntry);
192                 }
193             } else {
194                 // add exported entires, as configured
195
if (classpathEntry.isExported()) {
196                     unexpandedPath.add(classpathEntry);
197                 } else if (!isExportedEntriesOnly() || project.equals(getJavaProject())) {
198                     // add non exported entries from root project or if we are including all entries
199
unexpandedPath.add(classpathEntry);
200                 }
201             }
202         }
203         // 3. expand each project entry (except for the root project)
204
// 4. replace each container entry with a runtime entry associated with the project
205
Iterator JavaDoc iter = unexpandedPath.iterator();
206         while (iter.hasNext()) {
207             IClasspathEntry entry = (IClasspathEntry)iter.next();
208             if (entry == projectEntry) {
209                 expandedPath.add(entry);
210             } else {
211                 switch (entry.getEntryKind()) {
212                     case IClasspathEntry.CPE_PROJECT:
213                         if (!expanding.contains(entry)) {
214                             expandProject(entry, expandedPath, expanding);
215                         }
216                         break;
217                     case IClasspathEntry.CPE_CONTAINER:
218                         IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
219                         int property = -1;
220                         if (container != null) {
221                             switch (container.getKind()) {
222                                 case IClasspathContainer.K_APPLICATION:
223                                     property = IRuntimeClasspathEntry.USER_CLASSES;
224                                     break;
225                                 case IClasspathContainer.K_DEFAULT_SYSTEM:
226                                     property = IRuntimeClasspathEntry.STANDARD_CLASSES;
227                                     break;
228                                 case IClasspathContainer.K_SYSTEM:
229                                     property = IRuntimeClasspathEntry.BOOTSTRAP_CLASSES;
230                                     break;
231                             }
232                             IRuntimeClasspathEntry r = JavaRuntime.newRuntimeContainerClasspathEntry(entry.getPath(), property, project);
233                             // check for duplicate/redundant entries
234
boolean duplicate = false;
235                             ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(r.getPath().segment(0));
236                             for (int i = 0; i < expandedPath.size(); i++) {
237                                 Object JavaDoc o = expandedPath.get(i);
238                                 if (o instanceof IRuntimeClasspathEntry) {
239                                     IRuntimeClasspathEntry re = (IRuntimeClasspathEntry)o;
240                                     if (re.getType() == IRuntimeClasspathEntry.CONTAINER) {
241                                         if (container instanceof IRuntimeContainerComparator) {
242                                             duplicate = ((IRuntimeContainerComparator)container).isDuplicate(re.getPath());
243                                         } else {
244                                             ClasspathContainerInitializer initializer2 = JavaCore.getClasspathContainerInitializer(re.getPath().segment(0));
245                                             Object JavaDoc id1 = null;
246                                             Object JavaDoc id2 = null;
247                                             if (initializer == null) {
248                                                 id1 = r.getPath().segment(0);
249                                             } else {
250                                                 id1 = initializer.getComparisonID(r.getPath(), project);
251                                             }
252                                             if (initializer2 == null) {
253                                                 id2 = re.getPath().segment(0);
254                                             } else {
255                                                 IJavaProject context = re.getJavaProject();
256                                                 if (context == null) {
257                                                     context = project;
258                                                 }
259                                                 id2 = initializer2.getComparisonID(re.getPath(), context);
260                                             }
261                                             if (id1 == null) {
262                                                 duplicate = id2 == null;
263                                             } else {
264                                                 duplicate = id1.equals(id2);
265                                             }
266                                         }
267                                         if (duplicate) {
268                                             break;
269                                         }
270                                     }
271                                 }
272                             }
273                             if (!duplicate) {
274                                 expandedPath.add(r);
275                             }
276                         }
277                         break;
278                     case IClasspathEntry.CPE_VARIABLE:
279                         if (entry.getPath().segment(0).equals(JavaRuntime.JRELIB_VARIABLE)) {
280                             IRuntimeClasspathEntry r = JavaRuntime.newVariableRuntimeClasspathEntry(entry.getPath());
281                             r.setSourceAttachmentPath(entry.getSourceAttachmentPath());
282                             r.setSourceAttachmentRootPath(entry.getSourceAttachmentRootPath());
283                             r.setClasspathProperty(IRuntimeClasspathEntry.STANDARD_CLASSES);
284                             if (!expandedPath.contains(r)) {
285                                 expandedPath.add(r);
286                             }
287                             break;
288                         }
289                         // fall through if not the special JRELIB variable
290
default:
291                         if (!expandedPath.contains(entry)) {
292                             expandedPath.add(entry);
293                         }
294                         break;
295                 }
296             }
297         }
298         return;
299     }
300     /* (non-Javadoc)
301      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#isComposite()
302      */

303     public boolean isComposite() {
304         return true;
305     }
306     /* (non-Javadoc)
307      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getName()
308      */

309     public String JavaDoc getName() {
310         if (isExportedEntriesOnly()) {
311             return MessageFormat.format(LaunchingMessages.DefaultProjectClasspathEntry_2, new String JavaDoc[] {getJavaProject().getElementName()});
312         }
313         return MessageFormat.format(LaunchingMessages.DefaultProjectClasspathEntry_4, new String JavaDoc[] {getJavaProject().getElementName()});
314     }
315     /* (non-Javadoc)
316      * @see java.lang.Object#equals(java.lang.Object)
317      */

318     public boolean equals(Object JavaDoc obj) {
319         if (obj instanceof DefaultProjectClasspathEntry) {
320             DefaultProjectClasspathEntry entry = (DefaultProjectClasspathEntry) obj;
321             return entry.getJavaProject().equals(getJavaProject()) &&
322                 entry.isExportedEntriesOnly() == isExportedEntriesOnly();
323         }
324         return false;
325     }
326     /* (non-Javadoc)
327      * @see java.lang.Object#hashCode()
328      */

329     public int hashCode() {
330         return getJavaProject().hashCode();
331     }
332     
333     /**
334      * Sets whether the runtime classpath computaion should only
335      * include exported entries in referenced projects.
336      *
337      * @param exportedOnly
338      * @since 3.2
339      */

340     public void setExportedEntriesOnly(boolean exportedOnly) {
341         fExportedEntriesOnly = exportedOnly;
342     }
343     
344     /**
345      * Returns whether the classpath computation only includes exported
346      * entries in referenced projects.
347      *
348      * @return
349      * @since 3.2
350      */

351     public boolean isExportedEntriesOnly() {
352         return fExportedEntriesOnly;
353     }
354 }
355
Popular Tags