KickJava   Java API By Example, From Geeks To Geeks.

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


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  * BEA - Daniel R Somerfield - Bug 88939
11  *******************************************************************************/

12 package org.eclipse.jdt.internal.launching;
13
14
15 import java.io.IOException JavaDoc;
16 import com.ibm.icu.text.MessageFormat;
17
18 import javax.xml.parsers.ParserConfigurationException JavaDoc;
19 import javax.xml.transform.TransformerException JavaDoc;
20
21 import org.eclipse.core.resources.IContainer;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.IWorkspaceRoot;
26 import org.eclipse.core.resources.ResourcesPlugin;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.IStatus;
30 import org.eclipse.core.runtime.Path;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.jdt.core.ClasspathContainerInitializer;
33 import org.eclipse.jdt.core.IClasspathEntry;
34 import org.eclipse.jdt.core.IJavaProject;
35 import org.eclipse.jdt.core.JavaCore;
36 import org.eclipse.jdt.core.JavaModelException;
37 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
38 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
39 import org.eclipse.jdt.launching.JavaRuntime;
40 import org.w3c.dom.Document JavaDoc;
41 import org.w3c.dom.Element JavaDoc;
42
43 /**
44  * An entry on the runtime classpath that the user can manipulate
45  * and share in a launch configuration.
46  *
47  * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry
48  * @since 2.0
49  */

50 public class RuntimeClasspathEntry implements IRuntimeClasspathEntry {
51
52     /**
53      * This entry's type - must be set on creation.
54      */

55     private int fType = -1;
56     
57     /**
58      * This entry's classpath property.
59      */

60     private int fClasspathProperty = -1;
61     
62     /**
63      * This entry's associated build path entry.
64      */

65     private IClasspathEntry fClasspathEntry = null;
66     
67     /**
68      * The entry's resolved entry (lazily initialized)
69      */

70     private IClasspathEntry fResolvedEntry = null;
71     
72     /**
73      * Associated Java project, or <code>null</code>
74      */

75     private IJavaProject fJavaProject = null;
76     
77     /**
78      * The path if the entry was invalid and fClasspathEntry is null
79      */

80     private IPath fInvalidPath;
81     
82     /**
83      * Constructs a new runtime classpath entry based on the
84      * (build) classpath entry.
85      *
86      * @param entry the associated classpath entry
87      */

88     public RuntimeClasspathEntry(IClasspathEntry entry) {
89         switch (entry.getEntryKind()) {
90             case IClasspathEntry.CPE_PROJECT:
91                 setType(PROJECT);
92                 break;
93             case IClasspathEntry.CPE_LIBRARY:
94                 setType(ARCHIVE);
95                 break;
96             case IClasspathEntry.CPE_VARIABLE:
97                 setType(VARIABLE);
98                 break;
99             default:
100                 throw new IllegalArgumentException JavaDoc(MessageFormat.format(LaunchingMessages.RuntimeClasspathEntry_Illegal_classpath_entry__0__1, new String JavaDoc[] {entry.toString()}));
101         }
102         setClasspathEntry(entry);
103         initializeClasspathProperty();
104     }
105     
106     /**
107      * Constructs a new container entry in the context of the given project
108      *
109      * @param entry classpath entry
110      * @param classpathProperty this entry's classpath property
111      */

112     public RuntimeClasspathEntry(IClasspathEntry entry, int classpathProperty) {
113         switch (entry.getEntryKind()) {
114             case IClasspathEntry.CPE_CONTAINER:
115                 setType(CONTAINER);
116                 break;
117             default:
118                 throw new IllegalArgumentException JavaDoc(MessageFormat.format(LaunchingMessages.RuntimeClasspathEntry_Illegal_classpath_entry__0__1, new String JavaDoc[] {entry.toString()}));
119         }
120         setClasspathEntry(entry);
121         setClasspathProperty(classpathProperty);
122     }
123
124     /**
125      * Reconstructs a runtime classpath entry from the given
126      * XML document root not.
127      *
128      * @param root a memento root doc element created by this class
129      * @exception CoreException if unable to restore from the given memento
130      */

131     public RuntimeClasspathEntry(Element JavaDoc root) throws CoreException {
132         try {
133             setType(Integer.parseInt(root.getAttribute("type"))); //$NON-NLS-1$
134
} catch (NumberFormatException JavaDoc e) {
135             abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry_type_2, e);
136         }
137         try {
138             setClasspathProperty(Integer.parseInt(root.getAttribute("path"))); //$NON-NLS-1$
139
} catch (NumberFormatException JavaDoc e) {
140             abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry_location_3, e);
141         }
142
143         // source attachment
144
IPath sourcePath = null;
145         IPath rootPath = null;
146         String JavaDoc path = root.getAttribute("sourceAttachmentPath"); //$NON-NLS-1$
147
if (path != null && path.length() > 0) {
148             sourcePath = new Path(path);
149         }
150         path = root.getAttribute("sourceRootPath"); //$NON-NLS-1$
151
if (path != null && path.length() > 0) {
152             rootPath = new Path(path);
153         }
154
155         switch (getType()) {
156             case PROJECT :
157                 String JavaDoc name = root.getAttribute("projectName"); //$NON-NLS-1$
158
if (isEmpty(name)) {
159                     abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry___missing_project_name_4, null);
160                 } else {
161                     IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
162                     setClasspathEntry(JavaCore.newProjectEntry(proj.getFullPath()));
163                 }
164                 break;
165             case ARCHIVE :
166                 path = root.getAttribute("externalArchive"); //$NON-NLS-1$
167
if (isEmpty(path)) {
168                     // internal
169
path = root.getAttribute("internalArchive"); //$NON-NLS-1$
170
if (isEmpty(path)) {
171                         abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry___missing_archive_path_5, null);
172                     } else {
173                         setClasspathEntry(createLibraryEntry(sourcePath, rootPath, path));
174                     }
175                 } else {
176                     // external
177
setClasspathEntry(createLibraryEntry(sourcePath, rootPath, path));
178                 }
179                 break;
180             case VARIABLE :
181                 String JavaDoc var = root.getAttribute("containerPath"); //$NON-NLS-1$
182
if (isEmpty(var)) {
183                     abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry___missing_variable_name_6, null);
184                 } else {
185                     setClasspathEntry(JavaCore.newVariableEntry(new Path(var), sourcePath, rootPath));
186                 }
187                 break;
188             case CONTAINER :
189                 var = root.getAttribute("containerPath"); //$NON-NLS-1$
190
if (isEmpty(var)) {
191                     abort(LaunchingMessages.RuntimeClasspathEntry_Unable_to_recover_runtime_class_path_entry___missing_variable_name_6, null);
192                 } else {
193                     setClasspathEntry(JavaCore.newContainerEntry(new Path(var)));
194                 }
195                 break;
196         }
197         
198         String JavaDoc name = root.getAttribute("javaProject"); //$NON-NLS-1$
199
if (isEmpty(name)) {
200             fJavaProject = null;
201         } else {
202             IProject project2 = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
203             fJavaProject = JavaCore.create(project2);
204         }
205     }
206
207     private IClasspathEntry createLibraryEntry(IPath sourcePath, IPath rootPath, String JavaDoc path) {
208         Path p = new Path(path);
209         if (!p.isAbsolute())
210         {
211             fInvalidPath = p;
212             return null;
213             //abort("There was a problem with path \" " + path + "\": paths must be absolute.", null);
214
}
215         return JavaCore.newLibraryEntry(p, sourcePath, rootPath);
216     }
217     
218     /**
219      * Throws an internal error exception
220      */

221     protected void abort(String JavaDoc message, Throwable JavaDoc e) throws CoreException {
222         IStatus s = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, message, e);
223         throw new CoreException(s);
224     }
225
226     /**
227      * @see IRuntimeClasspathEntry#getType()
228      */

229     public int getType() {
230         return fType;
231     }
232
233     /**
234      * Sets this entry's type
235      *
236      * @param type this entry's type
237      */

238     private void setType(int type) {
239         fType = type;
240     }
241
242     /**
243      * Sets the classpath entry associated with this runtime classpath entry.
244      * Clears the cache of the resolved entry.
245      *
246      * @param entry the classpath entry associated with this runtime classpath entry
247      */

248     private void setClasspathEntry(IClasspathEntry entry) {
249         fClasspathEntry = entry;
250         fResolvedEntry = null;
251     }
252
253     /**
254      * @see IRuntimeClasspathEntry#getClasspathEntry()
255      */

256     public IClasspathEntry getClasspathEntry() {
257         return fClasspathEntry;
258     }
259
260     /**
261      * @see IRuntimeClasspathEntry#getMemento()
262      */

263     public String JavaDoc getMemento() throws CoreException {
264     
265         Document JavaDoc doc;
266         try {
267             doc = LaunchingPlugin.getDocument();
268         } catch (ParserConfigurationException JavaDoc e) {
269             IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, LaunchingMessages.RuntimeClasspathEntry_An_exception_occurred_generating_runtime_classpath_memento_8, e);
270             throw new CoreException(status);
271         }
272         Element JavaDoc node = doc.createElement("runtimeClasspathEntry"); //$NON-NLS-1$
273
doc.appendChild(node);
274         node.setAttribute("type", (new Integer JavaDoc(getType())).toString()); //$NON-NLS-1$
275
node.setAttribute("path", (new Integer JavaDoc(getClasspathProperty())).toString()); //$NON-NLS-1$
276
switch (getType()) {
277             case PROJECT :
278                 node.setAttribute("projectName", getPath().lastSegment()); //$NON-NLS-1$
279
break;
280             case ARCHIVE :
281                 IResource res = getResource();
282                 if (res == null) {
283                     node.setAttribute("externalArchive", getPath().toString()); //$NON-NLS-1$
284
} else {
285                     node.setAttribute("internalArchive", res.getFullPath().toString()); //$NON-NLS-1$
286
}
287                 break;
288             case VARIABLE :
289             case CONTAINER :
290                 node.setAttribute("containerPath", getPath().toString()); //$NON-NLS-1$
291
break;
292         }
293         if (getSourceAttachmentPath() != null) {
294             node.setAttribute("sourceAttachmentPath", getSourceAttachmentPath().toString()); //$NON-NLS-1$
295
}
296         if (getSourceAttachmentRootPath() != null) {
297             node.setAttribute("sourceRootPath", getSourceAttachmentRootPath().toString()); //$NON-NLS-1$
298
}
299         if (getJavaProject() != null) {
300             node.setAttribute("javaProject", getJavaProject().getElementName()); //$NON-NLS-1$
301
}
302         try {
303             return LaunchingPlugin.serializeDocument(doc);
304         } catch (IOException JavaDoc e) {
305             IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, LaunchingMessages.RuntimeClasspathEntry_An_exception_occurred_generating_runtime_classpath_memento_8, e);
306             throw new CoreException(status);
307         } catch (TransformerException JavaDoc e) {
308             IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, LaunchingMessages.RuntimeClasspathEntry_An_exception_occurred_generating_runtime_classpath_memento_8, e);
309             throw new CoreException(status);
310         }
311     }
312
313     /**
314      * @see IRuntimeClasspathEntry#getPath()
315      */

316     public IPath getPath() {
317         IClasspathEntry entry = getClasspathEntry();
318         return entry != null ? entry.getPath() : fInvalidPath;
319     }
320
321     /**
322      * @see IRuntimeClasspathEntry#getResource()
323      */

324     public IResource getResource() {
325         switch (getType()) {
326             case CONTAINER:
327             case VARIABLE:
328                 return null;
329             default:
330                 return getResource(getPath());
331         }
332     }
333     
334     /**
335      * Returns the resource in the workspace assciated with the given
336      * absolute path, or <code>null</code> if none. The path may have
337      * a device.
338      *
339      * @param path absolute path, or <code>null</code>
340      * @return resource or <code>null</code>
341      */

342     protected IResource getResource(IPath path) {
343         if (path != null) {
344             IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
345             if (path.getDevice() == null) {
346                 // search relative to the workspace if no device present
347
return root.findMember(path);
348             }
349             // look for files or folders with the given path
350
IFile[] files = root.findFilesForLocation(path);
351             if (files.length > 0) {
352                 return files[0];
353             }
354             IContainer[] containers = root.findContainersForLocation(path);
355             if (containers.length > 0) {
356                 return containers[0];
357             }
358         }
359         return null;
360     }
361
362     /**
363      * @see IRuntimeClasspathEntry#getSourceAttachmentPath()
364      */

365     public IPath getSourceAttachmentPath() {
366         IClasspathEntry entry = getClasspathEntry();
367         return entry != null ? entry.getSourceAttachmentPath() : null;
368     }
369
370     /**
371      * @see IRuntimeClasspathEntry#setSourceAttachmentPath(IPath)
372      */

373     public void setSourceAttachmentPath(IPath path) {
374         if (path != null && path.isEmpty()) {
375             path = null;
376         }
377         updateClasspathEntry(getPath(), path, getSourceAttachmentRootPath());
378     }
379     
380     /**
381      * @see IRuntimeClasspathEntry#getSourceAttachmentRootPath()
382      */

383     public IPath getSourceAttachmentRootPath() {
384         IClasspathEntry entry = getClasspathEntry();
385         IPath path = entry != null ? getClasspathEntry().getSourceAttachmentRootPath() : null;
386         if (path == null && getSourceAttachmentPath() != null) {
387             return Path.EMPTY;
388         }
389         return path;
390     }
391
392     /**
393      * @see IRuntimeClasspathEntry#setSourceAttachmentPath(IPath)
394      */

395     public void setSourceAttachmentRootPath(IPath path) {
396         if (path != null && path.isEmpty()) {
397             path = null;
398         }
399         updateClasspathEntry(getPath(), getSourceAttachmentPath(), path);
400     }
401     
402     /**
403      * Initlaizes the classpath property based on this entry's type.
404      */

405     private void initializeClasspathProperty() {
406         switch (getType()) {
407             case VARIABLE:
408                 if (getVariableName().equals(JavaRuntime.JRELIB_VARIABLE)) {
409                     setClasspathProperty(STANDARD_CLASSES);
410                 } else {
411                     setClasspathProperty(USER_CLASSES);
412                 }
413                 break;
414             case PROJECT:
415             case ARCHIVE:
416                 setClasspathProperty(USER_CLASSES);
417                 break;
418             default:
419                 break;
420         }
421     }
422     
423     
424     /**
425      * @see IRuntimeClasspathEntry#setClasspathProperty(int)
426      */

427     public void setClasspathProperty(int location) {
428         fClasspathProperty = location;
429     }
430
431     /**
432      * @see IRuntimeClasspathEntry#setClasspathProperty(int)
433      */

434     public int getClasspathProperty() {
435         return fClasspathProperty;
436     }
437
438     /**
439      * @see IRuntimeClasspathEntry#getLocation()
440      */

441     public String JavaDoc getLocation() {
442
443         IPath path = null;
444         switch (getType()) {
445             case PROJECT :
446                 IJavaProject pro = (IJavaProject) JavaCore.create(getResource());
447                 if (pro != null) {
448                     try {
449                         path = pro.getOutputLocation();
450                     } catch (JavaModelException e) {
451                         LaunchingPlugin.log(e);
452                     }
453                 }
454                 break;
455             case ARCHIVE :
456                 path = getPath();
457                 break;
458             case VARIABLE :
459                 IClasspathEntry resolved = getResolvedClasspathEntry();
460                 if (resolved != null) {
461                     path = resolved.getPath();
462                 }
463                 break;
464             case CONTAINER :
465                 break;
466         }
467         return resolveToOSPath(path);
468     }
469     
470     /**
471      * Returns the OS path for the given aboslute or workspace relative path
472      */

473     protected String JavaDoc resolveToOSPath(IPath path) {
474         if (path != null) {
475             IResource res = null;
476             if (path.getDevice() == null) {
477                 // if there is no device specified, find the resource
478
res = getResource(path);
479             }
480             if (res == null) {
481                 return path.toOSString();
482             }
483             IPath location = res.getLocation();
484             if (location != null) {
485                 return location.toOSString();
486             }
487         }
488         return null;
489     }
490
491     /**
492      * @see IRuntimeClasspathEntry#getVariableName()
493      */

494     public String JavaDoc getVariableName() {
495         if (getType() == IRuntimeClasspathEntry.VARIABLE || getType() == IRuntimeClasspathEntry.CONTAINER) {
496             return getPath().segment(0);
497         }
498         return null;
499     }
500
501     /**
502      * @see Object#equals(Object)
503      */

504     public boolean equals(Object JavaDoc obj) {
505         if (obj instanceof IRuntimeClasspathEntry) {
506             IRuntimeClasspathEntry r = (IRuntimeClasspathEntry)obj;
507             if (getType() == r.getType() && getClasspathProperty() == r.getClasspathProperty()) {
508                 if (getType() == IRuntimeClasspathEntry.CONTAINER) {
509                     String JavaDoc id = getPath().segment(0);
510                     ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(id);
511                     IJavaProject javaProject1 = getJavaProject();
512                     IJavaProject javaProject2 = r.getJavaProject();
513                     if (initializer == null || javaProject1 == null || javaProject2 == null) {
514                         // containers are equal if their ID is equal by default
515
return getPath().equals(r.getPath());
516                     }
517                     Object JavaDoc comparisonID1 = initializer.getComparisonID(getPath(), javaProject1);
518                     Object JavaDoc comparisonID2 = initializer.getComparisonID(r.getPath(), javaProject2);
519                     return comparisonID1.equals(comparisonID2);
520                 } else if (getPath() != null && getPath().equals(r.getPath())) {
521                     IPath sa1 = getSourceAttachmentPath();
522                     IPath root1 = getSourceAttachmentRootPath();
523                     IPath sa2 = r.getSourceAttachmentPath();
524                     IPath root2 = r.getSourceAttachmentRootPath();
525                     return equal(sa1, sa2) && equal(root1, root2);
526                 }
527             }
528         }
529         return false;
530     }
531
532     /**
533      * Returns whether the given objects are equal, accounting for null
534      */

535     protected boolean equal(Object JavaDoc one, Object JavaDoc two) {
536         if (one == null) {
537             return two == null;
538         }
539         return one.equals(two);
540     }
541     
542     /**
543      * @see Object#hashCode()
544      */

545     public int hashCode() {
546         if (getType() == CONTAINER) {
547             return getPath().segment(0).hashCode() + getType();
548         }
549         return getPath().hashCode() + getType();
550     }
551
552     /**
553      * @see IRuntimeClasspathEntry#getSourceAttachmentLocation()
554      */

555     public String JavaDoc getSourceAttachmentLocation() {
556         IPath path = null;
557         switch (getType()) {
558             case VARIABLE :
559             case ARCHIVE :
560                 IClasspathEntry resolved = getResolvedClasspathEntry();
561                 if (resolved != null) {
562                     path = resolved.getSourceAttachmentPath();
563                 }
564                 break;
565             default :
566                 break;
567         }
568         return resolveToOSPath(path);
569     }
570
571     /**
572      * @see IRuntimeClasspathEntry#getSourceAttachmentRootLocation()
573      */

574     public String JavaDoc getSourceAttachmentRootLocation() {
575         IPath path = null;
576         switch (getType()) {
577             case VARIABLE :
578             case ARCHIVE :
579                 IClasspathEntry resolved = getResolvedClasspathEntry();
580                 if (resolved != null) {
581                     path = resolved.getSourceAttachmentRootPath();
582                 }
583                 break;
584             default :
585                 break;
586         }
587         if (path != null) {
588             return path.toOSString();
589         }
590         return null;
591     }
592
593     /**
594      * Creates a new underlying classpath entry for this runtime classpath entry
595      * with the given paths, due to a change in source attachment.
596      */

597     protected void updateClasspathEntry(IPath path, IPath sourcePath, IPath rootPath) {
598         IClasspathEntry entry = null;
599         IClasspathEntry original = getClasspathEntry();
600         switch (getType()) {
601             case ARCHIVE:
602                 entry = JavaCore.newLibraryEntry(path, sourcePath, rootPath, original.getAccessRules(), original.getExtraAttributes(), original.isExported());
603                 break;
604             case VARIABLE:
605                 entry = JavaCore.newVariableEntry(path, sourcePath, rootPath);
606                 break;
607             default:
608                 return;
609         }
610         setClasspathEntry(entry);
611     }
612     
613     /**
614      * Returns the resolved classpath entry associated with this runtime
615      * entry, resolving if required.
616      */

617     protected IClasspathEntry getResolvedClasspathEntry() {
618         if (fResolvedEntry == null) {
619             fResolvedEntry = JavaCore.getResolvedClasspathEntry(getClasspathEntry());
620         }
621         return fResolvedEntry;
622     }
623         
624     protected boolean isEmpty(String JavaDoc string) {
625         return string == null || string.length() == 0;
626     }
627     
628     public String JavaDoc toString() {
629         if (fClasspathEntry != null) {
630             return fClasspathEntry.toString();
631         }
632         return super.toString();
633         
634     }
635     /* (non-Javadoc)
636      * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getJavaProject()
637      */

638     public IJavaProject getJavaProject() {
639         return fJavaProject;
640     }
641     
642     /**
643      * Sets the Java project associated with this classpath entry.
644      *
645      * @param project Java project
646      */

647     public void setJavaProject(IJavaProject project) {
648         fJavaProject = project;
649     }
650 }
651
Popular Tags