001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.launching;
011:
012: import java.io.File;
013: import java.net.MalformedURLException;
014: import java.net.URL;
015:
016: import org.eclipse.core.runtime.CoreException;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.IStatus;
019: import org.eclipse.core.runtime.Path;
020: import org.eclipse.core.runtime.Status;
021: import org.eclipse.jdt.core.ClasspathContainerInitializer;
022: import org.eclipse.jdt.core.IClasspathAttribute;
023: import org.eclipse.jdt.core.IClasspathContainer;
024: import org.eclipse.jdt.core.IClasspathEntry;
025: import org.eclipse.jdt.core.IJavaProject;
026: import org.eclipse.jdt.core.JavaCore;
027: import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
028: import org.eclipse.jdt.launching.IVMInstall;
029: import org.eclipse.jdt.launching.IVMInstallType;
030: import org.eclipse.jdt.launching.JavaRuntime;
031: import org.eclipse.jdt.launching.LibraryLocation;
032: import org.eclipse.jdt.launching.VMStandin;
033: import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
034: import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
035:
036: import com.ibm.icu.text.MessageFormat;
037:
038: /**
039: * Resolves a container for a JRE classpath container entry.
040: */
041: public class JREContainerInitializer extends
042: ClasspathContainerInitializer {
043:
044: /**
045: * @see ClasspathContainerInitializer#initialize(IPath, IJavaProject)
046: */
047: public void initialize(IPath containerPath, IJavaProject project)
048: throws CoreException {
049: if (JREContainer.DEBUG_JRE_CONTAINER) {
050: System.out.println("<JRE_CONTAINER> initialize()"); //$NON-NLS-1$
051: System.out.println("\tPath: " + containerPath.toString()); //$NON-NLS-1$
052: System.out
053: .println("\tProj: " + project.getProject().getName()); //$NON-NLS-1$
054: }
055: int size = containerPath.segmentCount();
056: if (size > 0) {
057: if (containerPath.segment(0).equals(
058: JavaRuntime.JRE_CONTAINER)) {
059: IVMInstall vm = resolveVM(containerPath);
060: JREContainer container = null;
061: if (vm != null) {
062: if (JREContainer.DEBUG_JRE_CONTAINER) {
063: System.out
064: .println("\tResolved VM: " + vm.getName()); //$NON-NLS-1$
065: }
066: container = new JREContainer(vm, containerPath,
067: project);
068: } else {
069: if (JREContainer.DEBUG_JRE_CONTAINER) {
070: System.out
071: .println("\t*** FAILED RESOLVE VM ***"); //$NON-NLS-1$
072: }
073: }
074: JavaCore.setClasspathContainer(containerPath,
075: new IJavaProject[] { project },
076: new IClasspathContainer[] { container }, null);
077: } else {
078: if (JREContainer.DEBUG_JRE_CONTAINER) {
079: System.out
080: .println("\t*** INVALID JRE CONTAINER PATH ***"); //$NON-NLS-1$
081: }
082: }
083: } else {
084: if (JREContainer.DEBUG_JRE_CONTAINER) {
085: System.out
086: .println("\t*** NO SEGMENTS IN CONTAINER PATH ***"); //$NON-NLS-1$
087: }
088: }
089: }
090:
091: /**
092: * Returns the VM install associated with the container path, or <code>null</code>
093: * if it does not exist.
094: */
095: public static IVMInstall resolveVM(IPath containerPath) {
096: IVMInstall vm = null;
097: if (containerPath.segmentCount() > 1) {
098: // specific JRE
099: String id = getExecutionEnvironmentId(containerPath);
100: if (id != null) {
101: if (JREContainer.DEBUG_JRE_CONTAINER) {
102: System.out
103: .println("<JRE_CONTAINER> resolveVM(IPath)"); //$NON-NLS-1$
104: System.out.println("\tEE: " + id); //$NON-NLS-1$
105: }
106: IExecutionEnvironmentsManager manager = JavaRuntime
107: .getExecutionEnvironmentsManager();
108: IExecutionEnvironment environment = manager
109: .getEnvironment(id);
110: if (environment != null) {
111: vm = resolveVM(environment);
112: } else {
113: if (JREContainer.DEBUG_JRE_CONTAINER) {
114: System.out.println("\t*** NO ENVIRONMENT ***"); //$NON-NLS-1$
115: }
116: }
117: } else {
118: String vmTypeId = getVMTypeId(containerPath);
119: String vmName = getVMName(containerPath);
120: IVMInstallType vmType = JavaRuntime
121: .getVMInstallType(vmTypeId);
122: if (vmType != null) {
123: vm = vmType.findVMInstallByName(vmName);
124: }
125: }
126: } else {
127: // workspace default JRE
128: vm = JavaRuntime.getDefaultVMInstall();
129: }
130: return vm;
131: }
132:
133: /**
134: * Returns the VM install bound to the given execution environment
135: * or <code>null</code>.
136: *
137: * @param environment
138: * @return vm install or <code>null</code>
139: * @since 3.2
140: */
141: public static IVMInstall resolveVM(IExecutionEnvironment environment) {
142: if (JREContainer.DEBUG_JRE_CONTAINER) {
143: System.out
144: .println("<JRE_CONTAINER> resolveVM(IExecutionEnvironment)"); //$NON-NLS-1$
145: }
146: IVMInstall vm = environment.getDefaultVM();
147: if (vm == null) {
148: IVMInstall[] installs = environment.getCompatibleVMs();
149: // take the first strictly compatible vm if there is no default
150: if (installs.length == 0
151: && JREContainer.DEBUG_JRE_CONTAINER) {
152: System.out.println("\t*** NO COMPATIBLE VMS ***"); //$NON-NLS-1$
153: }
154: for (int i = 0; i < installs.length; i++) {
155: IVMInstall install = installs[i];
156: if (environment.isStrictlyCompatible(install)) {
157: vm = install;
158: if (installs.length == 0
159: && JREContainer.DEBUG_JRE_CONTAINER) {
160: System.out
161: .println("\tPerfect Match: " + vm.getName()); //$NON-NLS-1$
162: }
163: break;
164: }
165: }
166: // use the first vm failing that
167: if (vm == null && installs.length > 0) {
168: vm = installs[0];
169: if (installs.length == 0
170: && JREContainer.DEBUG_JRE_CONTAINER) {
171: System.out
172: .println("\tFirst Match: " + vm.getName()); //$NON-NLS-1$
173: }
174: }
175: } else {
176: if (JREContainer.DEBUG_JRE_CONTAINER) {
177: System.out
178: .println("\tUser Default VM: " + vm.getName()); //$NON-NLS-1$
179: }
180: }
181: return vm;
182: }
183:
184: /**
185: * Returns the segment from the path containing the execution environment id
186: * or <code>null</code>
187: *
188: * @param path container path
189: * @return ee id
190: */
191: public static String getExecutionEnvironmentId(IPath path) {
192: String name = getVMName(path);
193: if (name != null) {
194: name = decodeEnvironmentId(name);
195: IExecutionEnvironmentsManager manager = JavaRuntime
196: .getExecutionEnvironmentsManager();
197: IExecutionEnvironment environment = manager
198: .getEnvironment(name);
199: if (environment != null) {
200: return environment.getId();
201: }
202: }
203: return null;
204: }
205:
206: /**
207: * Returns whether the given path identifies a vm by exeuction environment.
208: *
209: * @param path
210: * @return whether the given path identifies a vm by exeuction environment
211: */
212: public static boolean isExecutionEnvironment(IPath path) {
213: return getExecutionEnvironmentId(path) != null;
214: }
215:
216: /**
217: * Escapes foward slashes in environment id.
218: *
219: * @param id
220: * @return esaped name
221: */
222: public static String encodeEnvironmentId(String id) {
223: return id.replace('/', '%');
224: }
225:
226: public static String decodeEnvironmentId(String id) {
227: return id.replace('%', '/');
228: }
229:
230: /**
231: * Returns the VM type identifier from the given container ID path.
232: *
233: * @return the VM type identifier from the given container ID path
234: */
235: public static String getVMTypeId(IPath path) {
236: return path.segment(1);
237: }
238:
239: /**
240: * Returns the VM name from the given container ID path.
241: *
242: * @return the VM name from the given container ID path
243: */
244: public static String getVMName(IPath path) {
245: return path.segment(2);
246: }
247:
248: /**
249: * The container can be updated if it refers to an existing VM.
250: *
251: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#canUpdateClasspathContainer(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
252: */
253: public boolean canUpdateClasspathContainer(IPath containerPath,
254: IJavaProject project) {
255: if (containerPath != null && containerPath.segmentCount() > 0) {
256: if (JavaRuntime.JRE_CONTAINER.equals(containerPath
257: .segment(0))) {
258: return resolveVM(containerPath) != null;
259: }
260: }
261: return false;
262: }
263:
264: private static final IStatus READ_ONLY = new Status(IStatus.ERROR,
265: LaunchingPlugin.ID_PLUGIN,
266: ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY,
267: new String(), null);
268: private static final IStatus NOT_SUPPORTED = new Status(
269: IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
270: ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED,
271: new String(), null);
272:
273: /* (non-Javadoc)
274: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getAccessRulesStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
275: */
276: public IStatus getAccessRulesStatus(IPath containerPath,
277: IJavaProject project) {
278: return READ_ONLY;
279: }
280:
281: /* (non-Javadoc)
282: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getSourceAttachmentStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
283: */
284: public IStatus getSourceAttachmentStatus(IPath containerPath,
285: IJavaProject project) {
286: return Status.OK_STATUS;
287: }
288:
289: /* (non-Javadoc)
290: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getAttributeStatus(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject, java.lang.String)
291: */
292: public IStatus getAttributeStatus(IPath containerPath,
293: IJavaProject project, String attributeKey) {
294: if (attributeKey
295: .equals(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME)) {
296: return Status.OK_STATUS;
297: }
298: if (attributeKey
299: .equals(JavaRuntime.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY)) {
300: return Status.OK_STATUS;
301: }
302: return NOT_SUPPORTED;
303: }
304:
305: /**
306: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#requestClasspathContainerUpdate(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject, org.eclipse.jdt.core.IClasspathContainer)
307: */
308: public void requestClasspathContainerUpdate(IPath containerPath,
309: IJavaProject project,
310: IClasspathContainer containerSuggestion)
311: throws CoreException {
312: IVMInstall vm = resolveVM(containerPath);
313: if (vm == null) {
314: IStatus status = new Status(
315: IStatus.ERROR,
316: LaunchingPlugin.getUniqueIdentifier(),
317: IJavaLaunchConfigurationConstants.ERR_VM_INSTALL_DOES_NOT_EXIST,
318: MessageFormat
319: .format(
320: LaunchingMessages.JREContainerInitializer_JRE_referenced_by_classpath_container__0__does_not_exist__1,
321: new String[] { containerPath
322: .toString() }), null);
323: throw new CoreException(status);
324: }
325: // update of the vm with new library locations
326:
327: IClasspathEntry[] entries = containerSuggestion
328: .getClasspathEntries();
329: LibraryLocation[] libs = new LibraryLocation[entries.length];
330: for (int i = 0; i < entries.length; i++) {
331: IClasspathEntry entry = entries[i];
332: if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
333: IPath path = entry.getPath();
334: File lib = path.toFile();
335: if (lib.exists() && lib.isFile()) {
336: IPath srcPath = entry.getSourceAttachmentPath();
337: if (srcPath == null) {
338: srcPath = Path.EMPTY;
339: }
340: IPath rootPath = entry
341: .getSourceAttachmentRootPath();
342: if (rootPath == null) {
343: rootPath = Path.EMPTY;
344: }
345: URL javadocLocation = null;
346: IClasspathAttribute[] extraAttributes = entry
347: .getExtraAttributes();
348: for (int j = 0; j < extraAttributes.length; j++) {
349: IClasspathAttribute attribute = extraAttributes[j];
350: if (attribute
351: .getName()
352: .equals(
353: IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME)) {
354: String url = attribute.getValue();
355: if (url != null && url.trim().length() > 0) {
356: try {
357: javadocLocation = new URL(url);
358: } catch (MalformedURLException e) {
359: LaunchingPlugin.log(e);
360: }
361: }
362: }
363: }
364: libs[i] = new LibraryLocation(path, srcPath,
365: rootPath, javadocLocation);
366: } else {
367: IStatus status = new Status(
368: IStatus.ERROR,
369: LaunchingPlugin.getUniqueIdentifier(),
370: IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
371: MessageFormat
372: .format(
373: LaunchingMessages.JREContainerInitializer_Classpath_entry__0__does_not_refer_to_an_existing_library__2,
374: new String[] { entry
375: .getPath()
376: .toString() }),
377: null);
378: throw new CoreException(status);
379: }
380: } else {
381: IStatus status = new Status(
382: IStatus.ERROR,
383: LaunchingPlugin.getUniqueIdentifier(),
384: IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
385: MessageFormat
386: .format(
387: LaunchingMessages.JREContainerInitializer_Classpath_entry__0__does_not_refer_to_a_library__3,
388: new String[] { entry.getPath()
389: .toString() }), null);
390: throw new CoreException(status);
391: }
392: }
393: VMStandin standin = new VMStandin(vm);
394: standin.setLibraryLocations(libs);
395: standin.convertToRealVM();
396: JavaRuntime.saveVMConfiguration();
397: }
398:
399: /**
400: * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getDescription(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
401: */
402: public String getDescription(IPath containerPath,
403: IJavaProject project) {
404: String tag = getExecutionEnvironmentId(containerPath);
405: if (tag == null && containerPath.segmentCount() > 2) {
406: tag = getVMName(containerPath);
407: }
408: if (tag != null) {
409: return MessageFormat
410: .format(
411: LaunchingMessages.JREContainer_JRE_System_Library_1,
412: new String[] { tag });
413: }
414: return LaunchingMessages.JREContainerInitializer_Default_System_Library_1;
415: }
416: }
|