Source Code Cross Referenced for JavaRuntime.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » launching » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.launching 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.jdt.launching;
0011:
0012:        import java.io.BufferedInputStream;
0013:        import java.io.ByteArrayInputStream;
0014:        import java.io.File;
0015:        import java.io.FileInputStream;
0016:        import java.io.IOException;
0017:        import java.io.InputStream;
0018:        import java.io.StringReader;
0019:        import java.net.MalformedURLException;
0020:        import java.net.URL;
0021:        import java.util.ArrayList;
0022:        import java.util.HashMap;
0023:        import java.util.HashSet;
0024:        import java.util.Hashtable;
0025:        import java.util.Iterator;
0026:        import java.util.List;
0027:        import java.util.Map;
0028:        import java.util.Set;
0029:
0030:        import javax.xml.parsers.DocumentBuilder;
0031:
0032:        import org.eclipse.core.resources.IProject;
0033:        import org.eclipse.core.resources.IResource;
0034:        import org.eclipse.core.resources.IWorkspaceRoot;
0035:        import org.eclipse.core.resources.ResourcesPlugin;
0036:        import org.eclipse.core.runtime.CoreException;
0037:        import org.eclipse.core.runtime.IConfigurationElement;
0038:        import org.eclipse.core.runtime.IExtensionPoint;
0039:        import org.eclipse.core.runtime.IPath;
0040:        import org.eclipse.core.runtime.IProgressMonitor;
0041:        import org.eclipse.core.runtime.IStatus;
0042:        import org.eclipse.core.runtime.MultiStatus;
0043:        import org.eclipse.core.runtime.Path;
0044:        import org.eclipse.core.runtime.Platform;
0045:        import org.eclipse.core.runtime.Preferences;
0046:        import org.eclipse.core.runtime.Status;
0047:        import org.eclipse.core.variables.IStringVariableManager;
0048:        import org.eclipse.core.variables.VariablesPlugin;
0049:        import org.eclipse.debug.core.ILaunchConfiguration;
0050:        import org.eclipse.debug.core.sourcelookup.ISourceContainer;
0051:        import org.eclipse.jdt.core.IClasspathAttribute;
0052:        import org.eclipse.jdt.core.IClasspathContainer;
0053:        import org.eclipse.jdt.core.IClasspathEntry;
0054:        import org.eclipse.jdt.core.IJavaModel;
0055:        import org.eclipse.jdt.core.IJavaProject;
0056:        import org.eclipse.jdt.core.JavaCore;
0057:        import org.eclipse.jdt.internal.launching.CompositeId;
0058:        import org.eclipse.jdt.internal.launching.DefaultEntryResolver;
0059:        import org.eclipse.jdt.internal.launching.DefaultProjectClasspathEntry;
0060:        import org.eclipse.jdt.internal.launching.JREContainerInitializer;
0061:        import org.eclipse.jdt.internal.launching.JavaSourceLookupUtil;
0062:        import org.eclipse.jdt.internal.launching.LaunchingMessages;
0063:        import org.eclipse.jdt.internal.launching.LaunchingPlugin;
0064:        import org.eclipse.jdt.internal.launching.ListenerList;
0065:        import org.eclipse.jdt.internal.launching.RuntimeClasspathEntry;
0066:        import org.eclipse.jdt.internal.launching.RuntimeClasspathEntryResolver;
0067:        import org.eclipse.jdt.internal.launching.RuntimeClasspathProvider;
0068:        import org.eclipse.jdt.internal.launching.SocketAttachConnector;
0069:        import org.eclipse.jdt.internal.launching.StandardVMType;
0070:        import org.eclipse.jdt.internal.launching.VMDefinitionsContainer;
0071:        import org.eclipse.jdt.internal.launching.VMListener;
0072:        import org.eclipse.jdt.internal.launching.VariableClasspathEntry;
0073:        import org.eclipse.jdt.internal.launching.environments.EnvironmentsManager;
0074:        import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
0075:        import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
0076:        import org.w3c.dom.Element;
0077:        import org.w3c.dom.Node;
0078:        import org.w3c.dom.NodeList;
0079:        import org.xml.sax.InputSource;
0080:        import org.xml.sax.SAXException;
0081:
0082:        import com.ibm.icu.text.MessageFormat;
0083:
0084:        /**
0085:         * The central access point for launching support. This class manages
0086:         * the registered VM types contributed through the 
0087:         * <code>"org.eclipse.jdt.launching.vmType"</code> extension point.
0088:         * As well, this class provides VM install change notification,
0089:         * and computes class paths and source lookup paths for launch
0090:         * configurations.
0091:         * <p>
0092:         * This class provides static methods only; it is not intended to be
0093:         * instantiated or sub-classed by clients.
0094:         * </p>
0095:         */
0096:        public final class JavaRuntime {
0097:
0098:            /**
0099:             * Classpath variable name used for the default JRE's library
0100:             * (value <code>"JRE_LIB"</code>).
0101:             */
0102:            public static final String JRELIB_VARIABLE = "JRE_LIB"; //$NON-NLS-1$
0103:
0104:            /**
0105:             * Classpath variable name used for the default JRE's library source
0106:             * (value <code>"JRE_SRC"</code>).
0107:             */
0108:            public static final String JRESRC_VARIABLE = "JRE_SRC"; //$NON-NLS-1$
0109:
0110:            /**
0111:             * Classpath variable name used for the default JRE's library source root
0112:             * (value <code>"JRE_SRCROOT"</code>).
0113:             */
0114:            public static final String JRESRCROOT_VARIABLE = "JRE_SRCROOT"; //$NON-NLS-1$
0115:
0116:            /**
0117:             * Simple identifier constant (value <code>"runtimeClasspathEntryResolvers"</code>) for the
0118:             * runtime classpath entry resolvers extension point.
0119:             * 
0120:             * @since 2.0
0121:             */
0122:            public static final String EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRY_RESOLVERS = "runtimeClasspathEntryResolvers"; //$NON-NLS-1$	
0123:
0124:            /**
0125:             * Simple identifier constant (value <code>"classpathProviders"</code>) for the
0126:             * runtime classpath providers extension point.
0127:             * 
0128:             * @since 2.0
0129:             */
0130:            public static final String EXTENSION_POINT_RUNTIME_CLASSPATH_PROVIDERS = "classpathProviders"; //$NON-NLS-1$		
0131:
0132:            /**
0133:             * Simple identifier constant (value <code>"executionEnvironments"</code>) for the
0134:             * execution environments extension point.
0135:             * 
0136:             * @since 3.2
0137:             */
0138:            public static final String EXTENSION_POINT_EXECUTION_ENVIRONMENTS = "executionEnvironments"; //$NON-NLS-1$
0139:
0140:            /**
0141:             * Simple identifier constant (value <code>"vmInstalls"</code>) for the
0142:             * VM installs extension point.
0143:             * 
0144:             * @since 3.2
0145:             */
0146:            public static final String EXTENSION_POINT_VM_INSTALLS = "vmInstalls"; //$NON-NLS-1$		
0147:
0148:            /**
0149:             * Classpath container used for a project's JRE
0150:             * (value <code>"org.eclipse.jdt.launching.JRE_CONTAINER"</code>). A
0151:             * container is resolved in the context of a specific Java project, to one
0152:             * or more system libraries contained in a JRE. The container can have zero
0153:             * or two path segments following the container name. When no segments
0154:             * follow the container name, the workspace default JRE is used to build a
0155:             * project. Otherwise the segments identify a specific JRE used to build a
0156:             * project:
0157:             * <ol>
0158:             * <li>VM Install Type Identifier - identifies the type of JRE used to build the
0159:             * 	project. For example, the standard VM.</li>
0160:             * <li>VM Install Name - a user defined name that identifies that a specific VM
0161:             * 	of the above kind. For example, <code>IBM 1.3.1</code>. This information is
0162:             *  shared in a projects classpath file, so teams must agree on JRE naming
0163:             * 	conventions.</li>
0164:             * </ol>
0165:             * <p>
0166:             * Since 3.2, the path may also identify an execution environment as follows:
0167:             * <ol>
0168:             * <li>Execution environment extension point name
0169:             * (value <code>executionEnvironments</code>)</li>
0170:             * <li>Identifier of a contributed execution environment</li>
0171:             * </ol>
0172:             * </p>
0173:             * @since 2.0
0174:             */
0175:            public static final String JRE_CONTAINER = LaunchingPlugin
0176:                    .getUniqueIdentifier()
0177:                    + ".JRE_CONTAINER"; //$NON-NLS-1$
0178:
0179:            /**
0180:             * A status code indicating that a JRE could not be resolved for a project.
0181:             * When a JRE cannot be resolved for a project by this plug-in's container
0182:             * initializer, an exception is thrown with this status code. A status handler
0183:             * may be registered for this status code. The <code>source</code> object provided
0184:             * to the status handler is the Java project for which the path could not be
0185:             * resolved. The status handler must return an <code>IVMInstall</code> or <code>null</code>.
0186:             * The container resolver will re-set the project's classpath if required.
0187:             * 
0188:             * @since 2.0
0189:             */
0190:            public static final int ERR_UNABLE_TO_RESOLVE_JRE = 160;
0191:
0192:            /**
0193:             * Preference key for launch/connect timeout. VM Runners should honor this timeout
0194:             * value when attempting to launch and connect to a debuggable VM. The value is
0195:             * an int, indicating a number of milliseconds.
0196:             * 
0197:             * @since 2.0
0198:             */
0199:            public static final String PREF_CONNECT_TIMEOUT = LaunchingPlugin
0200:                    .getUniqueIdentifier()
0201:                    + ".PREF_CONNECT_TIMEOUT"; //$NON-NLS-1$
0202:
0203:            /**
0204:             * Preference key for the String of XML that defines all installed VMs.
0205:             * 
0206:             * @since 2.1
0207:             */
0208:            public static final String PREF_VM_XML = LaunchingPlugin
0209:                    .getUniqueIdentifier()
0210:                    + ".PREF_VM_XML"; //$NON-NLS-1$
0211:
0212:            /**
0213:             * Default launch/connect timeout (ms).
0214:             * 
0215:             * @since 2.0
0216:             */
0217:            public static final int DEF_CONNECT_TIMEOUT = 20000;
0218:
0219:            /**
0220:             * Attribute key for a process property. The class
0221:             * <code>org.eclipse.debug.core.model.IProcess</code> allows attaching
0222:             * String properties to processes.
0223:             * The value of this attribute is the command line a process
0224:             * was launched with. Implementers of <code>IVMRunner</code> should use
0225:             * this attribute key to attach the command lines to the processes they create.
0226:             * 
0227:             * @deprecated - use <code>IProcess.ATTR_CMDLINE</code>
0228:             */
0229:            public final static String ATTR_CMDLINE = LaunchingPlugin
0230:                    .getUniqueIdentifier()
0231:                    + ".launcher.cmdLine"; //$NON-NLS-1$
0232:
0233:            /**
0234:             * Attribute key for a classpath attribute referencing a
0235:             * list of shared libraries that should appear on the
0236:             * <code>-Djava.library.path</code> system property.
0237:             * <p>
0238:             * The factory methods <code>newLibraryPathsAttribute(String[])</code>
0239:             * and <code>getLibraryPaths(IClasspathAttribute)</code> should be used to
0240:             * encode and decode the attribute value. 
0241:             * </p>
0242:             * <p>
0243:             * Each string is used to create an <code>IPath</code> using the constructor
0244:             * <code>Path(String)</code>, and may contain <code>IStringVariable</code>'s.
0245:             * Variable substitution is performed on the string prior to constructing
0246:             * a path from the string.
0247:             * If the resulting <code>IPath</code> is a relative path, it is interpreted
0248:             * as relative to the workspace location. If the path is absolute, it is 
0249:             * interpreted as an absolute path in the local file system.
0250:             * </p>
0251:             * @since 3.1
0252:             * @see org.eclipse.jdt.core.IClasspathAttribute
0253:             */
0254:            public static final String CLASSPATH_ATTR_LIBRARY_PATH_ENTRY = LaunchingPlugin
0255:                    .getUniqueIdentifier()
0256:                    + ".CLASSPATH_ATTR_LIBRARY_PATH_ENTRY"; //$NON-NLS-1$
0257:
0258:            // lock for vm initialization
0259:            private static Object fgVMLock = new Object();
0260:            private static boolean fgInitializingVMs = false;
0261:
0262:            private static HashSet fgVMTypes = null;
0263:            private static String fgDefaultVMId = null;
0264:            private static String fgDefaultVMConnectorId = null;
0265:
0266:            /**
0267:             * Resolvers keyed by variable name, container id,
0268:             * and runtime classpath entry id.
0269:             */
0270:            private static Map fgVariableResolvers = null;
0271:            private static Map fgContainerResolvers = null;
0272:            private static Map fgRuntimeClasspathEntryResolvers = null;
0273:
0274:            /**
0275:             * Path providers keyed by id
0276:             */
0277:            private static Map fgPathProviders = null;
0278:
0279:            /**
0280:             * Default classpath and source path providers.
0281:             */
0282:            private static IRuntimeClasspathProvider fgDefaultClasspathProvider = new StandardClasspathProvider();
0283:            private static IRuntimeClasspathProvider fgDefaultSourcePathProvider = new StandardSourcePathProvider();
0284:
0285:            /**
0286:             * VM change listeners
0287:             */
0288:            private static ListenerList fgVMListeners = new ListenerList(5);
0289:
0290:            /**
0291:             * Cache of already resolved projects in container entries. Used to avoid
0292:             * cycles in project dependencies when resolving classpath container entries.
0293:             * Counters used to know when entering/exiting to clear cache
0294:             */
0295:            private static ThreadLocal fgProjects = new ThreadLocal(); // Lists
0296:            private static ThreadLocal fgEntryCount = new ThreadLocal(); // Integers
0297:
0298:            /**
0299:             *  Set of IDs of VMs contributed via vmInstalls extension point.
0300:             */
0301:            private static Set fgContributedVMs = new HashSet();
0302:
0303:            /**
0304:             * This class contains only static methods, and is not intended
0305:             * to be instantiated.
0306:             */
0307:            private JavaRuntime() {
0308:            }
0309:
0310:            /**
0311:             * Initializes vm type extensions.
0312:             */
0313:            private static void initializeVMTypeExtensions() {
0314:                IExtensionPoint extensionPoint = Platform
0315:                        .getExtensionRegistry().getExtensionPoint(
0316:                                LaunchingPlugin.ID_PLUGIN, "vmInstallTypes"); //$NON-NLS-1$
0317:                if (extensionPoint != null) {
0318:                    IConfigurationElement[] configs = extensionPoint
0319:                            .getConfigurationElements();
0320:                    MultiStatus status = new MultiStatus(LaunchingPlugin
0321:                            .getUniqueIdentifier(), IStatus.OK,
0322:                            "Exceptions occurred", null); //$NON-NLS-1$
0323:                    fgVMTypes = new HashSet();
0324:                    for (int i = 0; i < configs.length; i++) {
0325:                        try {
0326:                            fgVMTypes.add(configs[i]
0327:                                    .createExecutableExtension("class")); //$NON-NLS-1$
0328:                        } catch (CoreException e) {
0329:                            status.add(e.getStatus());
0330:                        }
0331:                    }
0332:                    if (!status.isOK()) {
0333:                        //only happens on a CoreException
0334:                        LaunchingPlugin.log(status);
0335:                    }
0336:                } else {
0337:                    LaunchingPlugin.log(new Status(IStatus.ERROR,
0338:                            LaunchingPlugin.getUniqueIdentifier(),
0339:                            "VM Install extension point not found", null)); //$NON-NLS-1$
0340:                }
0341:            }
0342:
0343:            /**
0344:             * Returns the VM assigned to build the given Java project.
0345:             * The project must exist. The VM assigned to a project is
0346:             * determined from its build path.
0347:             * 
0348:             * @param project the project to retrieve the VM from
0349:             * @return the VM instance that is assigned to build the given Java project
0350:             * 		   Returns <code>null</code> if no VM is referenced on the project's build path.
0351:             * @throws CoreException if unable to determine the project's VM install
0352:             */
0353:            public static IVMInstall getVMInstall(IJavaProject project)
0354:                    throws CoreException {
0355:                // check the classpath
0356:                IVMInstall vm = null;
0357:                IClasspathEntry[] classpath = project.getRawClasspath();
0358:                IRuntimeClasspathEntryResolver resolver = null;
0359:                IClasspathEntry entry = null;
0360:                for (int i = 0; i < classpath.length; i++) {
0361:                    entry = classpath[i];
0362:                    switch (entry.getEntryKind()) {
0363:                    case IClasspathEntry.CPE_VARIABLE:
0364:                        resolver = getVariableResolver(entry.getPath().segment(
0365:                                0));
0366:                        if (resolver != null) {
0367:                            vm = resolver.resolveVMInstall(entry);
0368:                        }
0369:                        break;
0370:                    case IClasspathEntry.CPE_CONTAINER:
0371:                        resolver = getContainerResolver(entry.getPath()
0372:                                .segment(0));
0373:                        if (resolver != null) {
0374:                            vm = resolver.resolveVMInstall(entry);
0375:                        }
0376:                        break;
0377:                    }
0378:                    if (vm != null) {
0379:                        return vm;
0380:                    }
0381:                }
0382:                return null;
0383:            }
0384:
0385:            /**
0386:             * Returns the VM install type with the given unique id. 
0387:             * @param id the VM install type unique id
0388:             * @return	The VM install type for the given id, or <code>null</code> if no
0389:             * 			VM install type with the given id is registered.
0390:             */
0391:            public static IVMInstallType getVMInstallType(String id) {
0392:                IVMInstallType[] vmTypes = getVMInstallTypes();
0393:                for (int i = 0; i < vmTypes.length; i++) {
0394:                    if (vmTypes[i].getId().equals(id)) {
0395:                        return vmTypes[i];
0396:                    }
0397:                }
0398:                return null;
0399:            }
0400:
0401:            /**
0402:             * Sets a VM as the system-wide default VM, and notifies registered VM install
0403:             * change listeners of the change.
0404:             * 
0405:             * @param vm	The vm to make the default. May be <code>null</code> to clear 
0406:             * 				the default.
0407:             * @param monitor progress monitor or <code>null</code>
0408:             */
0409:            public static void setDefaultVMInstall(IVMInstall vm,
0410:                    IProgressMonitor monitor) throws CoreException {
0411:                setDefaultVMInstall(vm, monitor, true);
0412:            }
0413:
0414:            /**
0415:             * Sets a VM as the system-wide default VM, and notifies registered VM install
0416:             * change listeners of the change.
0417:             * 
0418:             * @param vm	The vm to make the default. May be <code>null</code> to clear 
0419:             * 				the default.
0420:             * @param monitor progress monitor or <code>null</code>
0421:             * @param savePreference If <code>true</code>, update workbench preferences to reflect
0422:             * 		   				  the new default VM.
0423:             * @since 2.1
0424:             */
0425:            public static void setDefaultVMInstall(IVMInstall vm,
0426:                    IProgressMonitor monitor, boolean savePreference)
0427:                    throws CoreException {
0428:                IVMInstall previous = null;
0429:                if (fgDefaultVMId != null) {
0430:                    previous = getVMFromCompositeId(fgDefaultVMId);
0431:                }
0432:                fgDefaultVMId = getCompositeIdFromVM(vm);
0433:                if (savePreference) {
0434:                    saveVMConfiguration();
0435:                }
0436:                IVMInstall current = null;
0437:                if (fgDefaultVMId != null) {
0438:                    current = getVMFromCompositeId(fgDefaultVMId);
0439:                }
0440:                if (previous != current) {
0441:                    notifyDefaultVMChanged(previous, current);
0442:                }
0443:            }
0444:
0445:            /**
0446:             * Sets a VM connector as the system-wide default VM. This setting is persisted when
0447:             * saveVMConfiguration is called. 
0448:             * @param	connector The connector to make the default. May be <code>null</code> to clear 
0449:             * 				the default.
0450:             * @param monitor The progress monitor to use
0451:             * @since 2.0
0452:             * @throws CoreException Thrown if saving the new default setting fails
0453:             */
0454:            public static void setDefaultVMConnector(IVMConnector connector,
0455:                    IProgressMonitor monitor) throws CoreException {
0456:                fgDefaultVMConnectorId = connector.getIdentifier();
0457:                saveVMConfiguration();
0458:            }
0459:
0460:            /**
0461:             * Return the default VM set with <code>setDefaultVM()</code>.
0462:             * @return	Returns the default VM. May return <code>null</code> when no default
0463:             * 			VM was set or when the default VM has been disposed.
0464:             */
0465:            public static IVMInstall getDefaultVMInstall() {
0466:                IVMInstall install = getVMFromCompositeId(getDefaultVMId());
0467:                if (install != null && install.getInstallLocation().exists()) {
0468:                    return install;
0469:                }
0470:                // if the default JRE goes missing, re-detect
0471:                if (install != null) {
0472:                    install.getVMInstallType()
0473:                            .disposeVMInstall(install.getId());
0474:                }
0475:                synchronized (fgVMLock) {
0476:                    fgDefaultVMId = null;
0477:                    fgVMTypes = null;
0478:                    initializeVMs();
0479:                }
0480:                return getVMFromCompositeId(getDefaultVMId());
0481:            }
0482:
0483:            /**
0484:             * Return the default VM connector.
0485:             * @return	Returns the default VM connector.
0486:             * @since 2.0
0487:             */
0488:            public static IVMConnector getDefaultVMConnector() {
0489:                String id = getDefaultVMConnectorId();
0490:                IVMConnector connector = null;
0491:                if (id != null) {
0492:                    connector = getVMConnector(id);
0493:                }
0494:                if (connector == null) {
0495:                    connector = new SocketAttachConnector();
0496:                }
0497:                return connector;
0498:            }
0499:
0500:            /**
0501:             * Returns the list of registered VM types. VM types are registered via
0502:             * <code>"org.eclipse.jdt.launching.vmTypes"</code> extension point.
0503:             * Returns an empty list if there are no registered VM types.
0504:             * 
0505:             * @return the list of registered VM types
0506:             */
0507:            public static IVMInstallType[] getVMInstallTypes() {
0508:                initializeVMs();
0509:                return (IVMInstallType[]) fgVMTypes
0510:                        .toArray(new IVMInstallType[fgVMTypes.size()]);
0511:            }
0512:
0513:            /**
0514:             * Returns the default VM id determined during the initialization of the vm types
0515:             * @return the id of the default VM
0516:             */
0517:            private static String getDefaultVMId() {
0518:                initializeVMs();
0519:                return fgDefaultVMId;
0520:            }
0521:
0522:            /**
0523:             * Returns the default VM connector id determined during the initialization of the vm types
0524:             * @return the id of the default VM connector
0525:             */
0526:            private static String getDefaultVMConnectorId() {
0527:                initializeVMs();
0528:                return fgDefaultVMConnectorId;
0529:            }
0530:
0531:            /** 
0532:             * Returns a String that uniquely identifies the specified VM across all VM types.
0533:             * 
0534:             * @param vm the instance of IVMInstallType to be identified
0535:             * 
0536:             * @since 2.1
0537:             */
0538:            public static String getCompositeIdFromVM(IVMInstall vm) {
0539:                if (vm == null) {
0540:                    return null;
0541:                }
0542:                IVMInstallType vmType = vm.getVMInstallType();
0543:                String typeID = vmType.getId();
0544:                CompositeId id = new CompositeId(new String[] { typeID,
0545:                        vm.getId() });
0546:                return id.toString();
0547:            }
0548:
0549:            /**
0550:             * Return the VM corresponding to the specified composite Id.  The id uniquely
0551:             * identifies a VM across all vm types.  
0552:             * 
0553:             * @param idString the composite id that specifies an instance of IVMInstall
0554:             * 
0555:             * @since 2.1
0556:             */
0557:            public static IVMInstall getVMFromCompositeId(String idString) {
0558:                if (idString == null || idString.length() == 0) {
0559:                    return null;
0560:                }
0561:                CompositeId id = CompositeId.fromString(idString);
0562:                if (id.getPartCount() == 2) {
0563:                    IVMInstallType vmType = getVMInstallType(id.get(0));
0564:                    if (vmType != null) {
0565:                        return vmType.findVMInstall(id.get(1));
0566:                    }
0567:                }
0568:                return null;
0569:            }
0570:
0571:            /**
0572:             * Returns a new runtime classpath entry for the given expression that
0573:             * may contain string substitution variable references. The resulting expression
0574:             * refers to an archive (jar or directory) containing class files.
0575:             * 
0576:             * @param expression an expression that resolves to the location of an archive
0577:             * @return runtime classpath entry
0578:             * @since 3.0
0579:             */
0580:            public static IRuntimeClasspathEntry newStringVariableClasspathEntry(
0581:                    String expression) {
0582:                return new VariableClasspathEntry(expression);
0583:            }
0584:
0585:            /**
0586:             * Returns a new runtime classpath entry containing the default classpath
0587:             * for the specified Java project. 
0588:             * 
0589:             * @param project Java project
0590:             * @return runtime classpath entry
0591:             * @since 3.0
0592:             */
0593:            public static IRuntimeClasspathEntry newDefaultProjectClasspathEntry(
0594:                    IJavaProject project) {
0595:                return new DefaultProjectClasspathEntry(project);
0596:            }
0597:
0598:            /**
0599:             * Returns a new runtime classpath entry for the given project.
0600:             * 
0601:             * @param project Java project
0602:             * @return runtime classpath entry
0603:             * @since 2.0
0604:             */
0605:            public static IRuntimeClasspathEntry newProjectRuntimeClasspathEntry(
0606:                    IJavaProject project) {
0607:                return newRuntimeClasspathEntry(JavaCore
0608:                        .newProjectEntry(project.getProject().getFullPath()));
0609:            }
0610:
0611:            /**
0612:             * Returns a new runtime classpath entry for the given archive.
0613:             * 
0614:             * @param resource archive resource
0615:             * @return runtime classpath entry
0616:             * @since 2.0
0617:             */
0618:            public static IRuntimeClasspathEntry newArchiveRuntimeClasspathEntry(
0619:                    IResource resource) {
0620:                return newRuntimeClasspathEntry(JavaCore.newLibraryEntry(
0621:                        resource.getFullPath(), null, null));
0622:            }
0623:
0624:            /**
0625:             * Returns a new runtime classpath entry for the given archive (possibly
0626:             * external).
0627:             * 
0628:             * @param path absolute path to an archive
0629:             * @return runtime classpath entry
0630:             * @since 2.0
0631:             */
0632:            public static IRuntimeClasspathEntry newArchiveRuntimeClasspathEntry(
0633:                    IPath path) {
0634:                return newRuntimeClasspathEntry(JavaCore.newLibraryEntry(path,
0635:                        null, null));
0636:            }
0637:
0638:            /**
0639:             * Returns a new runtime classpath entry for the classpath
0640:             * variable with the given path.
0641:             * 
0642:             * @param path variable path; first segment is the name of the variable; 
0643:             * 	trailing segments are appended to the resolved variable value
0644:             * @return runtime classpath entry
0645:             * @since 2.0
0646:             */
0647:            public static IRuntimeClasspathEntry newVariableRuntimeClasspathEntry(
0648:                    IPath path) {
0649:                return newRuntimeClasspathEntry(JavaCore.newVariableEntry(path,
0650:                        null, null));
0651:            }
0652:
0653:            /**
0654:             * Returns a runtime classpath entry for the given container path with the given
0655:             * classpath property.
0656:             * 
0657:             * @param path container path
0658:             * @param classpathProperty the type of entry - one of <code>USER_CLASSES</code>,
0659:             * 	<code>BOOTSTRAP_CLASSES</code>, or <code>STANDARD_CLASSES</code>
0660:             * @return runtime classpath entry
0661:             * @exception CoreException if unable to construct a runtime classpath entry
0662:             * @since 2.0
0663:             */
0664:            public static IRuntimeClasspathEntry newRuntimeContainerClasspathEntry(
0665:                    IPath path, int classpathProperty) throws CoreException {
0666:                return newRuntimeContainerClasspathEntry(path,
0667:                        classpathProperty, null);
0668:            }
0669:
0670:            /**
0671:             * Returns a runtime classpath entry for the given container path with the given
0672:             * classpath property to be resolved in the context of the given Java project.
0673:             * 
0674:             * @param path container path
0675:             * @param classpathProperty the type of entry - one of <code>USER_CLASSES</code>,
0676:             * 	<code>BOOTSTRAP_CLASSES</code>, or <code>STANDARD_CLASSES</code>
0677:             * @param project Java project context used for resolution, or <code>null</code>
0678:             *  if to be resolved in the context of the launch configuration this entry
0679:             *  is referenced in
0680:             * @return runtime classpath entry
0681:             * @exception CoreException if unable to construct a runtime classpath entry
0682:             * @since 3.0
0683:             */
0684:            public static IRuntimeClasspathEntry newRuntimeContainerClasspathEntry(
0685:                    IPath path, int classpathProperty, IJavaProject project)
0686:                    throws CoreException {
0687:                RuntimeClasspathEntry entry = new RuntimeClasspathEntry(
0688:                        JavaCore.newContainerEntry(path), classpathProperty);
0689:                entry.setJavaProject(project);
0690:                return entry;
0691:            }
0692:
0693:            /**
0694:             * Returns a runtime classpath entry constructed from the given memento.
0695:             * 
0696:             * @param memento a memento for a runtime classpath entry
0697:             * @return runtime classpath entry
0698:             * @exception CoreException if unable to construct a runtime classpath entry
0699:             * @since 2.0
0700:             */
0701:            public static IRuntimeClasspathEntry newRuntimeClasspathEntry(
0702:                    String memento) throws CoreException {
0703:                try {
0704:                    Element root = null;
0705:                    DocumentBuilder parser = LaunchingPlugin.getParser();
0706:                    StringReader reader = new StringReader(memento);
0707:                    InputSource source = new InputSource(reader);
0708:                    root = parser.parse(source).getDocumentElement();
0709:
0710:                    String id = root.getAttribute("id"); //$NON-NLS-1$
0711:                    if (id == null || id.length() == 0) {
0712:                        // assume an old format
0713:                        return new RuntimeClasspathEntry(root);
0714:                    }
0715:                    // get the extension & create a new one
0716:                    IRuntimeClasspathEntry2 entry = LaunchingPlugin
0717:                            .getDefault().newRuntimeClasspathEntry(id);
0718:                    NodeList list = root.getChildNodes();
0719:                    Node node = null;
0720:                    Element element = null;
0721:                    for (int i = 0; i < list.getLength(); i++) {
0722:                        node = list.item(i);
0723:                        if (node.getNodeType() == Node.ELEMENT_NODE) {
0724:                            element = (Element) node;
0725:                            if ("memento".equals(element.getNodeName())) { //$NON-NLS-1$
0726:                                entry.initializeFrom(element);
0727:                            }
0728:                        }
0729:                    }
0730:                    return entry;
0731:                } catch (SAXException e) {
0732:                    abort(LaunchingMessages.JavaRuntime_31, e);
0733:                } catch (IOException e) {
0734:                    abort(LaunchingMessages.JavaRuntime_32, e);
0735:                }
0736:                return null;
0737:            }
0738:
0739:            /**
0740:             * Returns a runtime classpath entry that corresponds to the given
0741:             * classpath entry. The classpath entry may not be of type <code>CPE_SOURCE</code>
0742:             * or <code>CPE_CONTAINER</code>.
0743:             * 
0744:             * @param entry a classpath entry
0745:             * @return runtime classpath entry
0746:             * @since 2.0
0747:             */
0748:            private static IRuntimeClasspathEntry newRuntimeClasspathEntry(
0749:                    IClasspathEntry entry) {
0750:                return new RuntimeClasspathEntry(entry);
0751:            }
0752:
0753:            /**
0754:             * Computes and returns the default unresolved runtime classpath for the
0755:             * given project.
0756:             * 
0757:             * @return runtime classpath entries
0758:             * @exception CoreException if unable to compute the runtime classpath
0759:             * @see IRuntimeClasspathEntry
0760:             * @since 2.0
0761:             */
0762:            public static IRuntimeClasspathEntry[] computeUnresolvedRuntimeClasspath(
0763:                    IJavaProject project) throws CoreException {
0764:                IClasspathEntry[] entries = project.getRawClasspath();
0765:                List classpathEntries = new ArrayList(3);
0766:                for (int i = 0; i < entries.length; i++) {
0767:                    IClasspathEntry entry = entries[i];
0768:                    switch (entry.getEntryKind()) {
0769:                    case IClasspathEntry.CPE_CONTAINER:
0770:                        IClasspathContainer container = JavaCore
0771:                                .getClasspathContainer(entry.getPath(), project);
0772:                        if (container != null) {
0773:                            switch (container.getKind()) {
0774:                            case IClasspathContainer.K_APPLICATION:
0775:                                // don't look at application entries
0776:                                break;
0777:                            case IClasspathContainer.K_DEFAULT_SYSTEM:
0778:                                classpathEntries
0779:                                        .add(newRuntimeContainerClasspathEntry(
0780:                                                container.getPath(),
0781:                                                IRuntimeClasspathEntry.STANDARD_CLASSES,
0782:                                                project));
0783:                                break;
0784:                            case IClasspathContainer.K_SYSTEM:
0785:                                classpathEntries
0786:                                        .add(newRuntimeContainerClasspathEntry(
0787:                                                container.getPath(),
0788:                                                IRuntimeClasspathEntry.BOOTSTRAP_CLASSES,
0789:                                                project));
0790:                                break;
0791:                            }
0792:                        }
0793:                        break;
0794:                    case IClasspathEntry.CPE_VARIABLE:
0795:                        if (JRELIB_VARIABLE.equals(entry.getPath().segment(0))) {
0796:                            IRuntimeClasspathEntry jre = newVariableRuntimeClasspathEntry(entry
0797:                                    .getPath());
0798:                            jre
0799:                                    .setClasspathProperty(IRuntimeClasspathEntry.STANDARD_CLASSES);
0800:                            classpathEntries.add(jre);
0801:                        }
0802:                        break;
0803:                    default:
0804:                        break;
0805:                    }
0806:                }
0807:                classpathEntries.add(newDefaultProjectClasspathEntry(project));
0808:                return (IRuntimeClasspathEntry[]) classpathEntries
0809:                        .toArray(new IRuntimeClasspathEntry[classpathEntries
0810:                                .size()]);
0811:            }
0812:
0813:            /**
0814:             * Computes and returns the unresolved source lookup path for the given launch
0815:             * configuration.
0816:             * 
0817:             * @param configuration launch configuration
0818:             * @return runtime classpath entries
0819:             * @exception CoreException if unable to compute the source lookup path
0820:             * @since 2.0
0821:             */
0822:            public static IRuntimeClasspathEntry[] computeUnresolvedSourceLookupPath(
0823:                    ILaunchConfiguration configuration) throws CoreException {
0824:                return getSourceLookupPathProvider(configuration)
0825:                        .computeUnresolvedClasspath(configuration);
0826:            }
0827:
0828:            /**
0829:             * Resolves the given source lookup path, returning the resolved source lookup path
0830:             * in the context of the given launch configuration.
0831:             * 
0832:             * @param entries unresolved entries
0833:             * @param configuration launch configuration
0834:             * @return resolved entries
0835:             * @exception CoreException if unable to resolve the source lookup path
0836:             * @since 2.0
0837:             */
0838:            public static IRuntimeClasspathEntry[] resolveSourceLookupPath(
0839:                    IRuntimeClasspathEntry[] entries,
0840:                    ILaunchConfiguration configuration) throws CoreException {
0841:                return getSourceLookupPathProvider(configuration)
0842:                        .resolveClasspath(entries, configuration);
0843:            }
0844:
0845:            /**
0846:             * Returns the classpath provider for the given launch configuration.
0847:             * 
0848:             * @param configuration launch configuration
0849:             * @return classpath provider
0850:             * @exception CoreException if unable to resolve the path provider
0851:             * @since 2.0
0852:             */
0853:            public static IRuntimeClasspathProvider getClasspathProvider(
0854:                    ILaunchConfiguration configuration) throws CoreException {
0855:                String providerId = configuration
0856:                        .getAttribute(
0857:                                IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER,
0858:                                (String) null);
0859:                IRuntimeClasspathProvider provider = null;
0860:                if (providerId == null) {
0861:                    provider = fgDefaultClasspathProvider;
0862:                } else {
0863:                    provider = (IRuntimeClasspathProvider) getClasspathProviders()
0864:                            .get(providerId);
0865:                    if (provider == null) {
0866:                        abort(MessageFormat.format(
0867:                                LaunchingMessages.JavaRuntime_26,
0868:                                new String[] { providerId }), null);
0869:                    }
0870:                }
0871:                return provider;
0872:            }
0873:
0874:            /**
0875:             * Returns the source lookup path provider for the given launch configuration.
0876:             * 
0877:             * @param configuration launch configuration
0878:             * @return source lookup path provider
0879:             * @exception CoreException if unable to resolve the path provider
0880:             * @since 2.0
0881:             */
0882:            public static IRuntimeClasspathProvider getSourceLookupPathProvider(
0883:                    ILaunchConfiguration configuration) throws CoreException {
0884:                String providerId = configuration
0885:                        .getAttribute(
0886:                                IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER,
0887:                                (String) null);
0888:                IRuntimeClasspathProvider provider = null;
0889:                if (providerId == null) {
0890:                    provider = fgDefaultSourcePathProvider;
0891:                } else {
0892:                    provider = (IRuntimeClasspathProvider) getClasspathProviders()
0893:                            .get(providerId);
0894:                    if (provider == null) {
0895:                        abort(MessageFormat.format(
0896:                                LaunchingMessages.JavaRuntime_27,
0897:                                new String[] { providerId }), null);
0898:                    }
0899:                }
0900:                return provider;
0901:            }
0902:
0903:            /**
0904:             * Returns resolved entries for the given entry in the context of the given
0905:             * launch configuration. If the entry is of kind
0906:             * <code>VARIABLE</code> or <code>CONTAINER</code>, variable and container
0907:             * resolvers are consulted. If the entry is of kind <code>PROJECT</code>,
0908:             * and the associated Java project specifies non-default output locations,
0909:             * the corresponding output locations are returned. Otherwise, the given
0910:             * entry is returned.
0911:             * <p>
0912:             * If the given entry is a variable entry, and a resolver is not registered,
0913:             * the entry itself is returned. If the given entry is a container, and a
0914:             * resolver is not registered, resolved runtime classpath entries are calculated
0915:             * from the associated container classpath entries, in the context of the project
0916:             * associated with the given launch configuration.
0917:             * </p>
0918:             * @param entry runtime classpath entry
0919:             * @param configuration launch configuration
0920:             * @return resolved runtime classpath entry
0921:             * @exception CoreException if unable to resolve
0922:             * @see IRuntimeClasspathEntryResolver
0923:             * @since 2.0
0924:             */
0925:            public static IRuntimeClasspathEntry[] resolveRuntimeClasspathEntry(
0926:                    IRuntimeClasspathEntry entry,
0927:                    ILaunchConfiguration configuration) throws CoreException {
0928:                switch (entry.getType()) {
0929:                case IRuntimeClasspathEntry.PROJECT:
0930:                    // if the project has multiple output locations, they must be returned
0931:                    IResource resource = entry.getResource();
0932:                    if (resource instanceof  IProject) {
0933:                        IProject p = (IProject) resource;
0934:                        IJavaProject project = JavaCore.create(p);
0935:                        if (project == null || !p.isOpen() || !project.exists()) {
0936:                            return new IRuntimeClasspathEntry[0];
0937:                        }
0938:                        IRuntimeClasspathEntry[] entries = resolveOutputLocations(
0939:                                project, entry.getClasspathProperty());
0940:                        if (entries != null) {
0941:                            return entries;
0942:                        }
0943:                    } else {
0944:                        // could not resolve project
0945:                        abort(
0946:                                MessageFormat
0947:                                        .format(
0948:                                                LaunchingMessages.JavaRuntime_Classpath_references_non_existant_project___0__3,
0949:                                                new String[] { entry.getPath()
0950:                                                        .lastSegment() }), null);
0951:                    }
0952:                    break;
0953:                case IRuntimeClasspathEntry.VARIABLE:
0954:                    IRuntimeClasspathEntryResolver resolver = getVariableResolver(entry
0955:                            .getVariableName());
0956:                    if (resolver == null) {
0957:                        IRuntimeClasspathEntry[] resolved = resolveVariableEntry(
0958:                                entry, null, configuration);
0959:                        if (resolved != null) {
0960:                            return resolved;
0961:                        }
0962:                        break;
0963:                    }
0964:                    return resolver.resolveRuntimeClasspathEntry(entry,
0965:                            configuration);
0966:                case IRuntimeClasspathEntry.CONTAINER:
0967:                    resolver = getContainerResolver(entry.getVariableName());
0968:                    if (resolver == null) {
0969:                        return computeDefaultContainerEntries(entry,
0970:                                configuration);
0971:                    }
0972:                    return resolver.resolveRuntimeClasspathEntry(entry,
0973:                            configuration);
0974:                case IRuntimeClasspathEntry.ARCHIVE:
0975:                    // verify the archive exists
0976:                    String location = entry.getLocation();
0977:                    if (location == null) {
0978:                        abort(
0979:                                MessageFormat
0980:                                        .format(
0981:                                                LaunchingMessages.JavaRuntime_Classpath_references_non_existant_archive___0__4,
0982:                                                new String[] { entry.getPath()
0983:                                                        .toString() }), null);
0984:                    }
0985:                    File file = new File(location);
0986:                    if (!file.exists()) {
0987:                        abort(
0988:                                MessageFormat
0989:                                        .format(
0990:                                                LaunchingMessages.JavaRuntime_Classpath_references_non_existant_archive___0__4,
0991:                                                new String[] { entry.getPath()
0992:                                                        .toString() }), null);
0993:                    }
0994:                    break;
0995:                case IRuntimeClasspathEntry.OTHER:
0996:                    resolver = getContributedResolver(((IRuntimeClasspathEntry2) entry)
0997:                            .getTypeId());
0998:                    return resolver.resolveRuntimeClasspathEntry(entry,
0999:                            configuration);
1000:                default:
1001:                    break;
1002:                }
1003:                return new IRuntimeClasspathEntry[] { entry };
1004:            }
1005:
1006:            /**
1007:             * Default resolution for a classpath variable - resolve to an archive. Only
1008:             * one of project/configuration can be non-null.
1009:             * 
1010:             * @param entry
1011:             * @param project the project context or <code>null</code>
1012:             * @param configuration configuration context or <code>null</code>
1013:             * @return IRuntimeClasspathEntry[]
1014:             * @throws CoreException
1015:             */
1016:            private static IRuntimeClasspathEntry[] resolveVariableEntry(
1017:                    IRuntimeClasspathEntry entry, IJavaProject project,
1018:                    ILaunchConfiguration configuration) throws CoreException {
1019:                // default resolution - an archive
1020:                IPath archPath = JavaCore.getClasspathVariable(entry
1021:                        .getVariableName());
1022:                if (archPath != null) {
1023:                    if (entry.getPath().segmentCount() > 1) {
1024:                        archPath = archPath.append(entry.getPath()
1025:                                .removeFirstSegments(1));
1026:                    }
1027:                    IPath srcPath = null;
1028:                    IPath srcVar = entry.getSourceAttachmentPath();
1029:                    IPath srcRootPath = null;
1030:                    IPath srcRootVar = entry.getSourceAttachmentRootPath();
1031:                    if (archPath != null && !archPath.isEmpty()) {
1032:                        if (srcVar != null && !srcVar.isEmpty()) {
1033:                            srcPath = JavaCore.getClasspathVariable(srcVar
1034:                                    .segment(0));
1035:                            if (srcPath != null) {
1036:                                if (srcVar.segmentCount() > 1) {
1037:                                    srcPath = srcPath.append(srcVar
1038:                                            .removeFirstSegments(1));
1039:                                }
1040:                                if (srcRootVar != null && !srcRootVar.isEmpty()) {
1041:                                    srcRootPath = JavaCore
1042:                                            .getClasspathVariable(srcRootVar
1043:                                                    .segment(0));
1044:                                    if (srcRootPath != null) {
1045:                                        if (srcRootVar.segmentCount() > 1) {
1046:                                            srcRootPath = srcRootPath
1047:                                                    .append(srcRootVar
1048:                                                            .removeFirstSegments(1));
1049:                                        }
1050:                                    }
1051:                                }
1052:                            }
1053:                        }
1054:                        // now resolve the archive (recursively)
1055:                        IClasspathEntry archEntry = JavaCore.newLibraryEntry(
1056:                                archPath, srcPath, srcRootPath, entry
1057:                                        .getClasspathEntry().isExported());
1058:                        IRuntimeClasspathEntry runtimeArchEntry = newRuntimeClasspathEntry(archEntry);
1059:                        runtimeArchEntry.setClasspathProperty(entry
1060:                                .getClasspathProperty());
1061:                        if (configuration == null) {
1062:                            return resolveRuntimeClasspathEntry(
1063:                                    runtimeArchEntry, project);
1064:                        }
1065:                        return resolveRuntimeClasspathEntry(runtimeArchEntry,
1066:                                configuration);
1067:                    }
1068:                }
1069:                return null;
1070:            }
1071:
1072:            /**
1073:             * Returns runtime classpath entries corresponding to the output locations
1074:             * of the given project, or null if the project only uses the default
1075:             * output location.
1076:             * 
1077:             * @param project
1078:             * @param classpathProperty the type of classpath entries to create
1079:             * @return IRuntimeClasspathEntry[] or <code>null</code>
1080:             * @throws CoreException
1081:             */
1082:            private static IRuntimeClasspathEntry[] resolveOutputLocations(
1083:                    IJavaProject project, int classpathProperty)
1084:                    throws CoreException {
1085:                List nonDefault = new ArrayList();
1086:                if (project.exists() && project.getProject().isOpen()) {
1087:                    IClasspathEntry entries[] = project.getRawClasspath();
1088:                    for (int i = 0; i < entries.length; i++) {
1089:                        IClasspathEntry classpathEntry = entries[i];
1090:                        if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
1091:                            IPath path = classpathEntry.getOutputLocation();
1092:                            if (path != null) {
1093:                                nonDefault.add(path);
1094:                            }
1095:                        }
1096:                    }
1097:                }
1098:                if (nonDefault.isEmpty()) {
1099:                    return null;
1100:                }
1101:                // add the default location if not already included
1102:                IPath def = project.getOutputLocation();
1103:                if (!nonDefault.contains(def)) {
1104:                    nonDefault.add(def);
1105:                }
1106:                IRuntimeClasspathEntry[] locations = new IRuntimeClasspathEntry[nonDefault
1107:                        .size()];
1108:                for (int i = 0; i < locations.length; i++) {
1109:                    IClasspathEntry newEntry = JavaCore.newLibraryEntry(
1110:                            (IPath) nonDefault.get(i), null, null);
1111:                    locations[i] = new RuntimeClasspathEntry(newEntry);
1112:                    locations[i].setClasspathProperty(classpathProperty);
1113:                }
1114:                return locations;
1115:            }
1116:
1117:            /**
1118:             * Returns resolved entries for the given entry in the context of the given
1119:             * Java project. If the entry is of kind
1120:             * <code>VARIABLE</code> or <code>CONTAINER</code>, variable and container
1121:             * resolvers are consulted. If the entry is of kind <code>PROJECT</code>,
1122:             * and the associated Java project specifies non-default output locations,
1123:             * the corresponding output locations are returned. Otherwise, the given
1124:             * entry is returned.
1125:             * <p>
1126:             * If the given entry is a variable entry, and a resolver is not registered,
1127:             * the entry itself is returned. If the given entry is a container, and a
1128:             * resolver is not registered, resolved runtime classpath entries are calculated
1129:             * from the associated container classpath entries, in the context of the 
1130:             * given project.
1131:             * </p>
1132:             * @param entry runtime classpath entry
1133:             * @param project Java project context
1134:             * @return resolved runtime classpath entry
1135:             * @exception CoreException if unable to resolve
1136:             * @see IRuntimeClasspathEntryResolver
1137:             * @since 2.0
1138:             */
1139:            public static IRuntimeClasspathEntry[] resolveRuntimeClasspathEntry(
1140:                    IRuntimeClasspathEntry entry, IJavaProject project)
1141:                    throws CoreException {
1142:                switch (entry.getType()) {
1143:                case IRuntimeClasspathEntry.PROJECT:
1144:                    // if the project has multiple output locations, they must be returned
1145:                    IResource resource = entry.getResource();
1146:                    if (resource instanceof  IProject) {
1147:                        IProject p = (IProject) resource;
1148:                        IJavaProject jp = JavaCore.create(p);
1149:                        if (jp != null && p.isOpen() && jp.exists()) {
1150:                            IRuntimeClasspathEntry[] entries = resolveOutputLocations(
1151:                                    jp, entry.getClasspathProperty());
1152:                            if (entries != null) {
1153:                                return entries;
1154:                            }
1155:                        } else {
1156:                            return new IRuntimeClasspathEntry[0];
1157:                        }
1158:                    }
1159:                    break;
1160:                case IRuntimeClasspathEntry.VARIABLE:
1161:                    IRuntimeClasspathEntryResolver resolver = getVariableResolver(entry
1162:                            .getVariableName());
1163:                    if (resolver == null) {
1164:                        IRuntimeClasspathEntry[] resolved = resolveVariableEntry(
1165:                                entry, project, null);
1166:                        if (resolved != null) {
1167:                            return resolved;
1168:                        }
1169:                        break;
1170:                    }
1171:                    return resolver
1172:                            .resolveRuntimeClasspathEntry(entry, project);
1173:                case IRuntimeClasspathEntry.CONTAINER:
1174:                    resolver = getContainerResolver(entry.getVariableName());
1175:                    if (resolver == null) {
1176:                        return computeDefaultContainerEntries(entry, project);
1177:                    }
1178:                    return resolver
1179:                            .resolveRuntimeClasspathEntry(entry, project);
1180:                case IRuntimeClasspathEntry.OTHER:
1181:                    resolver = getContributedResolver(((IRuntimeClasspathEntry2) entry)
1182:                            .getTypeId());
1183:                    return resolver
1184:                            .resolveRuntimeClasspathEntry(entry, project);
1185:                default:
1186:                    break;
1187:                }
1188:                return new IRuntimeClasspathEntry[] { entry };
1189:            }
1190:
1191:            /**
1192:             * Performs default resolution for a container entry.
1193:             * Delegates to the Java model.
1194:             */
1195:            private static IRuntimeClasspathEntry[] computeDefaultContainerEntries(
1196:                    IRuntimeClasspathEntry entry, ILaunchConfiguration config)
1197:                    throws CoreException {
1198:                IJavaProject project = entry.getJavaProject();
1199:                if (project == null) {
1200:                    project = getJavaProject(config);
1201:                }
1202:                return computeDefaultContainerEntries(entry, project);
1203:            }
1204:
1205:            /**
1206:             * Performs default resolution for a container entry.
1207:             * Delegates to the Java model.
1208:             */
1209:            private static IRuntimeClasspathEntry[] computeDefaultContainerEntries(
1210:                    IRuntimeClasspathEntry entry, IJavaProject project)
1211:                    throws CoreException {
1212:                if (project == null || entry == null) {
1213:                    // cannot resolve without entry or project context
1214:                    return new IRuntimeClasspathEntry[0];
1215:                }
1216:                IClasspathContainer container = JavaCore.getClasspathContainer(
1217:                        entry.getPath(), project);
1218:                if (container == null) {
1219:                    abort(
1220:                            MessageFormat
1221:                                    .format(
1222:                                            LaunchingMessages.JavaRuntime_Could_not_resolve_classpath_container___0__1,
1223:                                            new String[] { entry.getPath()
1224:                                                    .toString() }), null);
1225:                    // execution will not reach here - exception will be thrown
1226:                    return null;
1227:                }
1228:                IClasspathEntry[] cpes = container.getClasspathEntries();
1229:                int property = -1;
1230:                switch (container.getKind()) {
1231:                case IClasspathContainer.K_APPLICATION:
1232:                    property = IRuntimeClasspathEntry.USER_CLASSES;
1233:                    break;
1234:                case IClasspathContainer.K_DEFAULT_SYSTEM:
1235:                    property = IRuntimeClasspathEntry.STANDARD_CLASSES;
1236:                    break;
1237:                case IClasspathContainer.K_SYSTEM:
1238:                    property = IRuntimeClasspathEntry.BOOTSTRAP_CLASSES;
1239:                    break;
1240:                }
1241:                List resolved = new ArrayList(cpes.length);
1242:                List projects = (List) fgProjects.get();
1243:                Integer count = (Integer) fgEntryCount.get();
1244:                if (projects == null) {
1245:                    projects = new ArrayList();
1246:                    fgProjects.set(projects);
1247:                    count = new Integer(0);
1248:                }
1249:                int intCount = count.intValue();
1250:                intCount++;
1251:                fgEntryCount.set(new Integer(intCount));
1252:                try {
1253:                    for (int i = 0; i < cpes.length; i++) {
1254:                        IClasspathEntry cpe = cpes[i];
1255:                        if (cpe.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
1256:                            IProject p = ResourcesPlugin.getWorkspace()
1257:                                    .getRoot().getProject(
1258:                                            cpe.getPath().segment(0));
1259:                            IJavaProject jp = JavaCore.create(p);
1260:                            if (!projects.contains(jp)) {
1261:                                projects.add(jp);
1262:                                IRuntimeClasspathEntry classpath = newDefaultProjectClasspathEntry(jp);
1263:                                IRuntimeClasspathEntry[] entries = resolveRuntimeClasspathEntry(
1264:                                        classpath, jp);
1265:                                for (int j = 0; j < entries.length; j++) {
1266:                                    IRuntimeClasspathEntry e = entries[j];
1267:                                    if (!resolved.contains(e)) {
1268:                                        resolved.add(entries[j]);
1269:                                    }
1270:                                }
1271:                            }
1272:                        } else {
1273:                            IRuntimeClasspathEntry e = newRuntimeClasspathEntry(cpe);
1274:                            if (!resolved.contains(e)) {
1275:                                resolved.add(e);
1276:                            }
1277:                        }
1278:                    }
1279:                } finally {
1280:                    intCount--;
1281:                    if (intCount == 0) {
1282:                        fgProjects.set(null);
1283:                        fgEntryCount.set(null);
1284:                    } else {
1285:                        fgEntryCount.set(new Integer(intCount));
1286:                    }
1287:                }
1288:                // set classpath property
1289:                IRuntimeClasspathEntry[] result = new IRuntimeClasspathEntry[resolved
1290:                        .size()];
1291:                for (int i = 0; i < result.length; i++) {
1292:                    result[i] = (IRuntimeClasspathEntry) resolved.get(i);
1293:                    result[i].setClasspathProperty(property);
1294:                }
1295:                return result;
1296:            }
1297:
1298:            /**
1299:             * Computes and returns the unresolved class path for the given launch configuration.
1300:             * Variable and container entries are unresolved.
1301:             * 
1302:             * @param configuration launch configuration
1303:             * @return unresolved runtime classpath entries
1304:             * @exception CoreException if unable to compute the classpath
1305:             * @since 2.0
1306:             */
1307:            public static IRuntimeClasspathEntry[] computeUnresolvedRuntimeClasspath(
1308:                    ILaunchConfiguration configuration) throws CoreException {
1309:                return getClasspathProvider(configuration)
1310:                        .computeUnresolvedClasspath(configuration);
1311:            }
1312:
1313:            /**
1314:             * Resolves the given classpath, returning the resolved classpath
1315:             * in the context of the given launch configuration.
1316:             *
1317:             * @param entries unresolved classpath
1318:             * @param configuration launch configuration
1319:             * @return resolved runtime classpath entries
1320:             * @exception CoreException if unable to compute the classpath
1321:             * @since 2.0
1322:             */
1323:            public static IRuntimeClasspathEntry[] resolveRuntimeClasspath(
1324:                    IRuntimeClasspathEntry[] entries,
1325:                    ILaunchConfiguration configuration) throws CoreException {
1326:                return getClasspathProvider(configuration).resolveClasspath(
1327:                        entries, configuration);
1328:            }
1329:
1330:            /**
1331:             * Return the <code>IJavaProject</code> referenced in the specified configuration or
1332:             * <code>null</code> if none.
1333:             *
1334:             * @exception CoreException if the referenced Java project does not exist
1335:             * @since 2.0
1336:             */
1337:            public static IJavaProject getJavaProject(
1338:                    ILaunchConfiguration configuration) throws CoreException {
1339:                String projectName = configuration.getAttribute(
1340:                        IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
1341:                        (String) null);
1342:                if ((projectName == null) || (projectName.trim().length() < 1)) {
1343:                    return null;
1344:                }
1345:                IJavaProject javaProject = getJavaModel().getJavaProject(
1346:                        projectName);
1347:                if (javaProject != null && javaProject.getProject().exists()
1348:                        && !javaProject.getProject().isOpen()) {
1349:                    abort(
1350:                            MessageFormat.format(
1351:                                    LaunchingMessages.JavaRuntime_28,
1352:                                    new String[] { configuration.getName(),
1353:                                            projectName }),
1354:                            IJavaLaunchConfigurationConstants.ERR_PROJECT_CLOSED,
1355:                            null);
1356:                }
1357:                if ((javaProject == null) || !javaProject.exists()) {
1358:                    abort(
1359:                            MessageFormat
1360:                                    .format(
1361:                                            LaunchingMessages.JavaRuntime_Launch_configuration__0__references_non_existing_project__1___1,
1362:                                            new String[] {
1363:                                                    configuration.getName(),
1364:                                                    projectName }),
1365:                            IJavaLaunchConfigurationConstants.ERR_NOT_A_JAVA_PROJECT,
1366:                            null);
1367:                }
1368:                return javaProject;
1369:            }
1370:
1371:            /**
1372:             * Convenience method to get the java model.
1373:             */
1374:            private static IJavaModel getJavaModel() {
1375:                return JavaCore
1376:                        .create(ResourcesPlugin.getWorkspace().getRoot());
1377:            }
1378:
1379:            /**
1380:             * Returns the VM install for the given launch configuration.
1381:             * The VM install is determined in the following prioritized way:
1382:             * <ol>
1383:             * <li>The VM install is explicitly specified on the launch configuration
1384:             *  via the <code>ATTR_JRE_CONTAINER_PATH</code> attribute (since 3.2).</li>
1385:             * <li>The VM install is explicitly specified on the launch configuration
1386:             * 	via the <code>ATTR_VM_INSTALL_TYPE</code> and <code>ATTR_VM_INSTALL_ID</code>
1387:             *  attributes.</li>
1388:             * <li>If no explicit VM install is specified, the VM install associated with
1389:             * 	the launch configuration's project is returned.</li>
1390:             * <li>If no project is specified, or the project does not specify a custom
1391:             * 	VM install, the workspace default VM install is returned.</li>
1392:             * </ol>
1393:             * 
1394:             * @param configuration launch configuration
1395:             * @return vm install
1396:             * @exception CoreException if unable to compute a vm install
1397:             * @since 2.0
1398:             */
1399:            public static IVMInstall computeVMInstall(
1400:                    ILaunchConfiguration configuration) throws CoreException {
1401:                String jreAttr = configuration
1402:                        .getAttribute(
1403:                                IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH,
1404:                                (String) null);
1405:                if (jreAttr == null) {
1406:                    String type = configuration
1407:                            .getAttribute(
1408:                                    IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE,
1409:                                    (String) null);
1410:                    if (type == null) {
1411:                        IJavaProject proj = getJavaProject(configuration);
1412:                        if (proj != null) {
1413:                            IVMInstall vm = getVMInstall(proj);
1414:                            if (vm != null) {
1415:                                return vm;
1416:                            }
1417:                        }
1418:                    } else {
1419:                        String name = configuration
1420:                                .getAttribute(
1421:                                        IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME,
1422:                                        (String) null);
1423:                        return resolveVM(type, name, configuration);
1424:                    }
1425:                } else {
1426:                    IPath jrePath = Path.fromPortableString(jreAttr);
1427:                    IClasspathEntry entry = JavaCore.newContainerEntry(jrePath);
1428:                    IRuntimeClasspathEntryResolver2 resolver = getVariableResolver(jrePath
1429:                            .segment(0));
1430:                    if (resolver != null) {
1431:                        return resolver.resolveVMInstall(entry);
1432:                    } else {
1433:                        resolver = getContainerResolver(jrePath.segment(0));
1434:                        if (resolver != null) {
1435:                            return resolver.resolveVMInstall(entry);
1436:                        }
1437:                    }
1438:                }
1439:
1440:                return getDefaultVMInstall();
1441:            }
1442:
1443:            /**
1444:             * Returns the VM of the given type with the specified name.
1445:             *  
1446:             * @param type vm type identifier
1447:             * @param name vm name
1448:             * @return vm install
1449:             * @exception CoreException if unable to resolve
1450:             * @since 3.2
1451:             */
1452:            private static IVMInstall resolveVM(String type, String name,
1453:                    ILaunchConfiguration configuration) throws CoreException {
1454:                IVMInstallType vt = getVMInstallType(type);
1455:                if (vt == null) {
1456:                    // error type does not exist
1457:                    abort(
1458:                            MessageFormat
1459:                                    .format(
1460:                                            LaunchingMessages.JavaRuntime_Specified_VM_install_type_does_not_exist___0__2,
1461:                                            new String[] { type }), null);
1462:                }
1463:                IVMInstall vm = null;
1464:                // look for a name
1465:                if (name == null) {
1466:                    // error - type specified without a specific install (could be an old config that specified a VM ID)
1467:                    // log the error, but choose the default VM.  
1468:                    LaunchingPlugin
1469:                            .log(new Status(
1470:                                    IStatus.WARNING,
1471:                                    LaunchingPlugin.getUniqueIdentifier(),
1472:                                    IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_VM_INSTALL,
1473:                                    MessageFormat
1474:                                            .format(
1475:                                                    "VM not fully specified in launch configuration {0} - missing VM name. Reverting to default VM.", new String[] { configuration.getName() }), null)); //$NON-NLS-1$
1476:                    return getDefaultVMInstall();
1477:                }
1478:                vm = vt.findVMInstallByName(name);
1479:                if (vm == null) {
1480:                    // error - install not found
1481:                    abort(
1482:                            MessageFormat
1483:                                    .format(
1484:                                            LaunchingMessages.JavaRuntime_Specified_VM_install_not_found__type__0___name__1__2,
1485:                                            new String[] { vt.getName(), name }),
1486:                            null);
1487:                } else {
1488:                    return vm;
1489:                }
1490:                // won't reach here
1491:                return null;
1492:            }
1493:
1494:            /**
1495:             * Throws a core exception with an internal error status.
1496:             * 
1497:             * @param message the status message
1498:             * @param exception lower level exception associated with the
1499:             *  error, or <code>null</code> if none
1500:             */
1501:            private static void abort(String message, Throwable exception)
1502:                    throws CoreException {
1503:                abort(message,
1504:                        IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
1505:                        exception);
1506:            }
1507:
1508:            /**
1509:             * Throws a core exception with an internal error status.
1510:             * 
1511:             * @param message the status message
1512:             * @param code status code
1513:             * @param exception lower level exception associated with the
1514:             * 
1515:             *  error, or <code>null</code> if none
1516:             */
1517:            private static void abort(String message, int code,
1518:                    Throwable exception) throws CoreException {
1519:                throw new CoreException(new Status(IStatus.ERROR,
1520:                        LaunchingPlugin.getUniqueIdentifier(), code, message,
1521:                        exception));
1522:            }
1523:
1524:            /**
1525:             * Computes the default application classpath entries for the given 
1526:             * project.
1527:             * 
1528:             * @param	jproject The project to compute the classpath for
1529:             * @return	The computed classpath. May be empty, but not null.
1530:             * @throws	CoreException if unable to compute the default classpath
1531:             */
1532:            public static String[] computeDefaultRuntimeClassPath(
1533:                    IJavaProject jproject) throws CoreException {
1534:                IRuntimeClasspathEntry[] unresolved = computeUnresolvedRuntimeClasspath(jproject);
1535:                // 1. remove bootpath entries
1536:                // 2. resolve & translate to local file system paths
1537:                List resolved = new ArrayList(unresolved.length);
1538:                for (int i = 0; i < unresolved.length; i++) {
1539:                    IRuntimeClasspathEntry entry = unresolved[i];
1540:                    if (entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
1541:                        IRuntimeClasspathEntry[] entries = resolveRuntimeClasspathEntry(
1542:                                entry, jproject);
1543:                        for (int j = 0; j < entries.length; j++) {
1544:                            String location = entries[j].getLocation();
1545:                            if (location != null) {
1546:                                resolved.add(location);
1547:                            }
1548:                        }
1549:                    }
1550:                }
1551:                return (String[]) resolved.toArray(new String[resolved.size()]);
1552:            }
1553:
1554:            /**
1555:             * Saves the VM configuration information to the preferences. This includes
1556:             * the following information:
1557:             * <ul>
1558:             * <li>The list of all defined IVMInstall instances.</li>
1559:             * <li>The default VM</li>
1560:             * <ul>
1561:             * This state will be read again upon first access to VM
1562:             * configuration information.
1563:             */
1564:            public static void saveVMConfiguration() throws CoreException {
1565:                if (fgVMTypes == null) {
1566:                    // if the VM types have not been instantiated, there can be no changes.
1567:                    return;
1568:                }
1569:                String xml = getVMsAsXML();
1570:                getPreferences().setValue(PREF_VM_XML, xml);
1571:                savePreferences();
1572:            }
1573:
1574:            /**
1575:             * Returns the listing of currently installed VMs as a single XML file
1576:             * @return an XML representation of all of the currently installed VMs
1577:             * @throws CoreException
1578:             */
1579:            private static String getVMsAsXML() throws CoreException {
1580:                VMDefinitionsContainer container = new VMDefinitionsContainer();
1581:                container.setDefaultVMInstallCompositeID(getDefaultVMId());
1582:                container
1583:                        .setDefaultVMInstallConnectorTypeID(getDefaultVMConnectorId());
1584:                IVMInstallType[] vmTypes = getVMInstallTypes();
1585:                IVMInstall[] vms = null;
1586:                for (int i = 0; i < vmTypes.length; ++i) {
1587:                    vms = vmTypes[i].getVMInstalls();
1588:                    for (int j = 0; j < vms.length; j++) {
1589:                        container.addVM(vms[j]);
1590:                    }
1591:                }
1592:                return container.getAsXML();
1593:            }
1594:
1595:            /**
1596:             * This method loads installed JREs based an existing user preference
1597:             * or old vm configurations file. The VMs found in the preference
1598:             * or vm configurations file are added to the given VM definitions container.
1599:             * 
1600:             * Returns whether the user preferences should be set - i.e. if it was
1601:             * not already set when initialized.
1602:             */
1603:            private static boolean addPersistedVMs(VMDefinitionsContainer vmDefs)
1604:                    throws IOException {
1605:                // Try retrieving the VM preferences from the preference store
1606:                String vmXMLString = getPreferences().getString(PREF_VM_XML);
1607:
1608:                // If the preference was found, load VMs from it into memory
1609:                if (vmXMLString.length() > 0) {
1610:                    try {
1611:                        ByteArrayInputStream inputStream = new ByteArrayInputStream(
1612:                                vmXMLString.getBytes("UTF8")); //$NON-NLS-1$
1613:                        VMDefinitionsContainer.parseXMLIntoContainer(
1614:                                inputStream, vmDefs);
1615:                        return false;
1616:                    } catch (IOException ioe) {
1617:                        LaunchingPlugin.log(ioe);
1618:                    }
1619:                } else {
1620:                    // Otherwise, look for the old file that previously held the VM definitions
1621:                    IPath stateLocation = LaunchingPlugin.getDefault()
1622:                            .getStateLocation();
1623:                    IPath stateFile = stateLocation
1624:                            .append("vmConfiguration.xml"); //$NON-NLS-1$
1625:                    File file = new File(stateFile.toOSString());
1626:
1627:                    if (file.exists()) {
1628:                        // If file exists, load VM definitions from it into memory and write the definitions to
1629:                        // the preference store WITHOUT triggering any processing of the new value
1630:                        InputStream fileInputStream = new BufferedInputStream(
1631:                                new FileInputStream(file));
1632:                        VMDefinitionsContainer.parseXMLIntoContainer(
1633:                                fileInputStream, vmDefs);
1634:                    }
1635:                }
1636:                return true;
1637:            }
1638:
1639:            /**
1640:             * Loads contributed VM installs
1641:             * @since 3.2
1642:             */
1643:            private static void addVMExtensions(VMDefinitionsContainer vmDefs) {
1644:                IExtensionPoint extensionPoint = Platform
1645:                        .getExtensionRegistry().getExtensionPoint(
1646:                                LaunchingPlugin.ID_PLUGIN,
1647:                                JavaRuntime.EXTENSION_POINT_VM_INSTALLS);
1648:                IConfigurationElement[] configs = extensionPoint
1649:                        .getConfigurationElements();
1650:                for (int i = 0; i < configs.length; i++) {
1651:                    IConfigurationElement element = configs[i];
1652:                    try {
1653:                        if ("vmInstall".equals(element.getName())) { //$NON-NLS-1$
1654:                            String vmType = element
1655:                                    .getAttribute("vmInstallType"); //$NON-NLS-1$
1656:                            if (vmType == null) {
1657:                                abort(
1658:                                        MessageFormat
1659:                                                .format(
1660:                                                        "Missing required vmInstallType attribute for vmInstall contributed by {0}", //$NON-NLS-1$
1661:                                                        new String[] { element
1662:                                                                .getContributor()
1663:                                                                .getName() }),
1664:                                        null);
1665:                            }
1666:                            String id = element.getAttribute("id"); //$NON-NLS-1$
1667:                            if (id == null) {
1668:                                abort(
1669:                                        MessageFormat
1670:                                                .format(
1671:                                                        "Missing required id attribute for vmInstall contributed by {0}", //$NON-NLS-1$
1672:                                                        new String[] { element
1673:                                                                .getContributor()
1674:                                                                .getName() }),
1675:                                        null);
1676:                            }
1677:                            IVMInstallType installType = getVMInstallType(vmType);
1678:                            if (installType == null) {
1679:                                abort(
1680:                                        MessageFormat
1681:                                                .format(
1682:                                                        "vmInstall {0} contributed by {1} references undefined VM install type {2}", //$NON-NLS-1$
1683:                                                        new String[] {
1684:                                                                id,
1685:                                                                element
1686:                                                                        .getContributor()
1687:                                                                        .getName(),
1688:                                                                vmType }), null);
1689:                            }
1690:                            IVMInstall install = installType.findVMInstall(id);
1691:                            if (install == null) {
1692:                                // only load/create if first time we've seen this VM install
1693:                                String name = element.getAttribute("name"); //$NON-NLS-1$
1694:                                if (name == null) {
1695:                                    abort(
1696:                                            MessageFormat
1697:                                                    .format(
1698:                                                            "vmInstall {0} contributed by {1} missing required attribute name", //$NON-NLS-1$
1699:                                                            new String[] {
1700:                                                                    id,
1701:                                                                    element
1702:                                                                            .getContributor()
1703:                                                                            .getName() }),
1704:                                            null);
1705:                                }
1706:                                String home = element.getAttribute("home"); //$NON-NLS-1$
1707:                                if (home == null) {
1708:                                    abort(
1709:                                            MessageFormat
1710:                                                    .format(
1711:                                                            "vmInstall {0} contributed by {1} missing required attribute home", //$NON-NLS-1$
1712:                                                            new String[] {
1713:                                                                    id,
1714:                                                                    element
1715:                                                                            .getContributor()
1716:                                                                            .getName() }),
1717:                                            null);
1718:                                }
1719:                                String javadoc = element
1720:                                        .getAttribute("javadocURL"); //$NON-NLS-1$
1721:                                String vmArgs = element.getAttribute("vmArgs"); //$NON-NLS-1$
1722:                                VMStandin standin = new VMStandin(installType,
1723:                                        id);
1724:                                standin.setName(name);
1725:                                home = substitute(home);
1726:                                File homeDir = new File(home);
1727:                                if (homeDir.exists()) {
1728:                                    try {
1729:                                        // adjust for relative path names
1730:                                        home = homeDir.getCanonicalPath();
1731:                                        homeDir = new File(home);
1732:                                    } catch (IOException e) {
1733:                                    }
1734:                                }
1735:                                IStatus status = installType
1736:                                        .validateInstallLocation(homeDir);
1737:                                if (!status.isOK()) {
1738:                                    abort(
1739:                                            MessageFormat
1740:                                                    .format(
1741:                                                            "Illegal install location {0} for vmInstall {1} contributed by {2}: {3}", //$NON-NLS-1$
1742:                                                            new String[] {
1743:                                                                    home,
1744:                                                                    id,
1745:                                                                    element
1746:                                                                            .getContributor()
1747:                                                                            .getName(),
1748:                                                                    status
1749:                                                                            .getMessage() }),
1750:                                            null);
1751:                                }
1752:                                standin.setInstallLocation(homeDir);
1753:                                if (javadoc != null) {
1754:                                    try {
1755:                                        standin.setJavadocLocation(new URL(
1756:                                                javadoc));
1757:                                    } catch (MalformedURLException e) {
1758:                                        abort(
1759:                                                MessageFormat
1760:                                                        .format(
1761:                                                                "Illegal javadocURL attribute for vmInstall {0} contributed by {1}", //$NON-NLS-1$
1762:                                                                new String[] {
1763:                                                                        id,
1764:                                                                        element
1765:                                                                                .getContributor()
1766:                                                                                .getName() }),
1767:                                                e);
1768:                                    }
1769:                                }
1770:                                // allow default arguments to be specified by vm install type if no explicit arguments
1771:                                if (vmArgs == null) {
1772:                                    if (installType instanceof  AbstractVMInstallType) {
1773:                                        AbstractVMInstallType type = (AbstractVMInstallType) installType;
1774:                                        vmArgs = type
1775:                                                .getDefaultVMArguments(homeDir);
1776:                                    }
1777:                                }
1778:                                if (vmArgs != null) {
1779:                                    standin.setVMArgs(vmArgs);
1780:                                }
1781:                                IConfigurationElement[] libraries = element
1782:                                        .getChildren("library"); //$NON-NLS-1$
1783:                                LibraryLocation[] locations = null;
1784:                                if (libraries.length > 0) {
1785:                                    locations = new LibraryLocation[libraries.length];
1786:                                    for (int j = 0; j < libraries.length; j++) {
1787:                                        IConfigurationElement library = libraries[j];
1788:                                        String libPathStr = library
1789:                                                .getAttribute("path"); //$NON-NLS-1$
1790:                                        if (libPathStr == null) {
1791:                                            abort(
1792:                                                    MessageFormat
1793:                                                            .format(
1794:                                                                    "library for vmInstall {0} contributed by {1} missing required attribute libPath", //$NON-NLS-1$
1795:                                                                    new String[] {
1796:                                                                            id,
1797:                                                                            element
1798:                                                                                    .getContributor()
1799:                                                                                    .getName() }),
1800:                                                    null);
1801:                                        }
1802:                                        String sourcePathStr = library
1803:                                                .getAttribute("sourcePath"); //$NON-NLS-1$
1804:                                        String packageRootStr = library
1805:                                                .getAttribute("packageRootPath"); //$NON-NLS-1$
1806:                                        String javadocOverride = library
1807:                                                .getAttribute("javadocURL"); //$NON-NLS-1$
1808:                                        URL url = null;
1809:                                        if (javadocOverride != null) {
1810:                                            try {
1811:                                                url = new URL(javadocOverride);
1812:                                            } catch (MalformedURLException e) {
1813:                                                abort(
1814:                                                        MessageFormat
1815:                                                                .format(
1816:                                                                        "Illegal javadocURL attribute specified for library {0} for vmInstall {1} contributed by {2}" //$NON-NLS-1$
1817:                                                                        ,
1818:                                                                        new String[] {
1819:                                                                                libPathStr,
1820:                                                                                id,
1821:                                                                                element
1822:                                                                                        .getContributor()
1823:                                                                                        .getName() }),
1824:                                                        e);
1825:                                            }
1826:                                        }
1827:                                        IPath homePath = new Path(home);
1828:                                        IPath libPath = homePath
1829:                                                .append(substitute(libPathStr));
1830:                                        IPath sourcePath = Path.EMPTY;
1831:                                        if (sourcePathStr != null) {
1832:                                            sourcePath = homePath
1833:                                                    .append(substitute(sourcePathStr));
1834:                                        }
1835:                                        IPath packageRootPath = Path.EMPTY;
1836:                                        if (packageRootStr != null) {
1837:                                            packageRootPath = new Path(
1838:                                                    substitute(packageRootStr));
1839:                                        }
1840:                                        locations[j] = new LibraryLocation(
1841:                                                libPath, sourcePath,
1842:                                                packageRootPath, url);
1843:                                    }
1844:                                }
1845:                                standin.setLibraryLocations(locations);
1846:                                // in case the contributed JRE attributes changed, remove it first, then add
1847:                                vmDefs.removeVM(standin);
1848:                                vmDefs.addVM(standin);
1849:                            }
1850:                            fgContributedVMs.add(id);
1851:                        } else {
1852:                            abort(
1853:                                    MessageFormat
1854:                                            .format(
1855:                                                    "Illegal element {0} in vmInstalls extension contributed by {1}", //$NON-NLS-1$
1856:                                                    new String[] {
1857:                                                            element.getName(),
1858:                                                            element
1859:                                                                    .getContributor()
1860:                                                                    .getName() }),
1861:                                    null);
1862:                        }
1863:                    } catch (CoreException e) {
1864:                        LaunchingPlugin.log(e);
1865:                    }
1866:                }
1867:            }
1868:
1869:            /**
1870:             * Performs string substitution on the given expression.
1871:             * 
1872:             * @param expression
1873:             * @return expression after string substitution 
1874:             * @throws CoreException
1875:             * @since 3.2
1876:             */
1877:            private static String substitute(String expression)
1878:                    throws CoreException {
1879:                return VariablesPlugin.getDefault().getStringVariableManager()
1880:                        .performStringSubstitution(expression);
1881:            }
1882:
1883:            /**
1884:             * Returns whether the VM install with the specified id was contributed via
1885:             * the vmInstalls extension point.
1886:             * 
1887:             * @param id vm id
1888:             * @return whether the vm install was contributed via extension point
1889:             * @since 3.2
1890:             */
1891:            public static boolean isContributedVMInstall(String id) {
1892:                getVMInstallTypes(); // ensure VMs are initialized
1893:                return fgContributedVMs.contains(id);
1894:            }
1895:
1896:            /**
1897:             * Evaluates library locations for a IVMInstall. If no library locations are set on the install, a default
1898:             * location is evaluated and checked if it exists.
1899:             * @return library locations with paths that exist or are empty
1900:             * @since 2.0
1901:             */
1902:            public static LibraryLocation[] getLibraryLocations(IVMInstall vm) {
1903:                IPath[] libraryPaths;
1904:                IPath[] sourcePaths;
1905:                IPath[] sourceRootPaths;
1906:                URL[] javadocLocations;
1907:                LibraryLocation[] locations = vm.getLibraryLocations();
1908:                if (locations == null) {
1909:                    URL defJavaDocLocation = vm.getJavadocLocation();
1910:                    LibraryLocation[] dflts = vm
1911:                            .getVMInstallType()
1912:                            .getDefaultLibraryLocations(vm.getInstallLocation());
1913:                    libraryPaths = new IPath[dflts.length];
1914:                    sourcePaths = new IPath[dflts.length];
1915:                    sourceRootPaths = new IPath[dflts.length];
1916:                    javadocLocations = new URL[dflts.length];
1917:                    for (int i = 0; i < dflts.length; i++) {
1918:                        libraryPaths[i] = dflts[i].getSystemLibraryPath();
1919:                        if (defJavaDocLocation == null) {
1920:                            javadocLocations[i] = dflts[i].getJavadocLocation();
1921:                        } else {
1922:                            javadocLocations[i] = defJavaDocLocation;
1923:                        }
1924:                        if (!libraryPaths[i].toFile().isFile()) {
1925:                            libraryPaths[i] = Path.EMPTY;
1926:                        }
1927:
1928:                        sourcePaths[i] = dflts[i].getSystemLibrarySourcePath();
1929:                        if (sourcePaths[i].toFile().isFile()) {
1930:                            sourceRootPaths[i] = dflts[i].getPackageRootPath();
1931:                        } else {
1932:                            sourcePaths[i] = Path.EMPTY;
1933:                            sourceRootPaths[i] = Path.EMPTY;
1934:                        }
1935:                    }
1936:                } else {
1937:                    libraryPaths = new IPath[locations.length];
1938:                    sourcePaths = new IPath[locations.length];
1939:                    sourceRootPaths = new IPath[locations.length];
1940:                    javadocLocations = new URL[locations.length];
1941:                    for (int i = 0; i < locations.length; i++) {
1942:                        libraryPaths[i] = locations[i].getSystemLibraryPath();
1943:                        sourcePaths[i] = locations[i]
1944:                                .getSystemLibrarySourcePath();
1945:                        sourceRootPaths[i] = locations[i].getPackageRootPath();
1946:                        javadocLocations[i] = locations[i].getJavadocLocation();
1947:                    }
1948:                }
1949:                locations = new LibraryLocation[sourcePaths.length];
1950:                for (int i = 0; i < sourcePaths.length; i++) {
1951:                    locations[i] = new LibraryLocation(libraryPaths[i],
1952:                            sourcePaths[i], sourceRootPaths[i],
1953:                            javadocLocations[i]);
1954:                }
1955:                return locations;
1956:            }
1957:
1958:            /**
1959:             * Detect the VM that Eclipse is running on.
1960:             * 
1961:             * @return a VM standin representing the VM that Eclipse is running on, or
1962:             * <code>null</code> if unable to detect the runtime VM
1963:             */
1964:            private static VMStandin detectEclipseRuntime() {
1965:                VMStandin detectedVMStandin = null;
1966:                // Try to detect a VM for each declared VM type
1967:                IVMInstallType[] vmTypes = getVMInstallTypes();
1968:                for (int i = 0; i < vmTypes.length; i++) {
1969:
1970:                    File detectedLocation = vmTypes[i].detectInstallLocation();
1971:                    if (detectedLocation != null && detectedVMStandin == null) {
1972:
1973:                        // Make sure the VM id is unique
1974:                        long unique = System.currentTimeMillis();
1975:                        IVMInstallType vmType = vmTypes[i];
1976:                        while (vmType.findVMInstall(String.valueOf(unique)) != null) {
1977:                            unique++;
1978:                        }
1979:
1980:                        // Create a standin for the detected VM and add it to the result collector
1981:                        String vmID = String.valueOf(unique);
1982:                        detectedVMStandin = new VMStandin(vmType, vmID);
1983:                        detectedVMStandin.setInstallLocation(detectedLocation);
1984:                        detectedVMStandin
1985:                                .setName(generateDetectedVMName(detectedVMStandin));
1986:                        if (vmType instanceof  AbstractVMInstallType) {
1987:                            AbstractVMInstallType abs = (AbstractVMInstallType) vmType;
1988:                            URL url = abs
1989:                                    .getDefaultJavadocLocation(detectedLocation);
1990:                            detectedVMStandin.setJavadocLocation(url);
1991:                            String arguments = abs
1992:                                    .getDefaultVMArguments(detectedLocation);
1993:                            if (arguments != null) {
1994:                                detectedVMStandin.setVMArgs(arguments);
1995:                            }
1996:                        }
1997:                    }
1998:                }
1999:                return detectedVMStandin;
2000:            }
2001:
2002:            /**
2003:             * Returns whether the specified option is the same in both option maps.
2004:             * 
2005:             * @param optionName name of option to test
2006:             * @param defaultOptions map of default options
2007:             * @param options map of other options
2008:             * @return whether the options are the same in both maps
2009:             */
2010:            private static boolean equals(String optionName,
2011:                    Map defaultOptions, Map options) {
2012:                if (defaultOptions.containsKey(optionName)) {
2013:                    return options.containsKey(optionName)
2014:                            && equals(defaultOptions.get(optionName), options
2015:                                    .get(optionName));
2016:                } else {
2017:                    return !options.containsKey(optionName);
2018:                }
2019:            }
2020:
2021:            /**
2022:             * Returns whether the objects are equal or both <code>null</code>
2023:             * 
2024:             * @param o1 an object
2025:             * @param o2 an object
2026:             * @return whether the objects are equal or both <code>null</code>
2027:             */
2028:            private static boolean equals(Object o1, Object o2) {
2029:                if (o1 == null) {
2030:                    return o2 == null;
2031:                } else {
2032:                    return o1.equals(o2);
2033:                }
2034:            }
2035:
2036:            /**
2037:             * Make the name of a detected VM stand out.
2038:             */
2039:            private static String generateDetectedVMName(IVMInstall vm) {
2040:                String name = vm.getInstallLocation().getName();
2041:                name = name.trim();
2042:                if (name.length() == 0) {
2043:                    name = LaunchingMessages.JavaRuntime_25;
2044:                }
2045:                return name;
2046:            }
2047:
2048:            /**
2049:             * Creates and returns a classpath entry describing
2050:             * the JRE_LIB classpath variable.
2051:             * 
2052:             * @return a new IClasspathEntry that describes the JRE_LIB classpath variable
2053:             */
2054:            public static IClasspathEntry getJREVariableEntry() {
2055:                return JavaCore.newVariableEntry(new Path(JRELIB_VARIABLE),
2056:                        new Path(JRESRC_VARIABLE),
2057:                        new Path(JRESRCROOT_VARIABLE));
2058:            }
2059:
2060:            /**
2061:             * Creates and returns a classpath entry describing
2062:             * the default JRE container entry.
2063:             * 
2064:             * @return a new IClasspathEntry that describes the default JRE container entry
2065:             * @since 2.0
2066:             */
2067:            public static IClasspathEntry getDefaultJREContainerEntry() {
2068:                return JavaCore.newContainerEntry(newDefaultJREContainerPath());
2069:            }
2070:
2071:            /**
2072:             * Returns a path for the JRE classpath container identifying the 
2073:             * default VM install.
2074:             * 
2075:             * @return classpath container path
2076:             * @since 3.2
2077:             */
2078:            public static IPath newDefaultJREContainerPath() {
2079:                return new Path(JRE_CONTAINER);
2080:            }
2081:
2082:            /**
2083:             * Returns a path for the JRE classpath container identifying the 
2084:             * specified VM install by type and name.
2085:             * 
2086:             * @param vm vm install
2087:             * @return classpath container path
2088:             * @since 3.2
2089:             */
2090:            public static IPath newJREContainerPath(IVMInstall vm) {
2091:                return newJREContainerPath(vm.getVMInstallType().getId(), vm
2092:                        .getName());
2093:            }
2094:
2095:            /**
2096:             * Returns a path for the JRE classpath container identifying the 
2097:             * specified VM install by type and name.
2098:             * 
2099:             * @param typeId vm install type identifier
2100:             * @param name vm install name
2101:             * @return classpath container path
2102:             * @since 3.2
2103:             */
2104:            public static IPath newJREContainerPath(String typeId, String name) {
2105:                IPath path = newDefaultJREContainerPath();
2106:                path = path.append(typeId);
2107:                path = path.append(name);
2108:                return path;
2109:            }
2110:
2111:            /**
2112:             * Returns a path for the JRE classpath container identifying the 
2113:             * specified execution environment.
2114:             * 
2115:             * @param environment execution environment
2116:             * @return classpath container path
2117:             * @since 3.2
2118:             */
2119:            public static IPath newJREContainerPath(
2120:                    IExecutionEnvironment environment) {
2121:                IPath path = newDefaultJREContainerPath();
2122:                path = path.append(StandardVMType.ID_STANDARD_VM_TYPE);
2123:                path = path.append(JREContainerInitializer
2124:                        .encodeEnvironmentId(environment.getId()));
2125:                return path;
2126:            }
2127:
2128:            /**
2129:             * Returns the JRE referenced by the specified JRE classpath container
2130:             * path or <code>null</code> if none.
2131:             *  
2132:             * @param jreContainerPath
2133:             * @return JRE referenced by the specified JRE classpath container
2134:             *  path or <code>null</code>
2135:             * @since 3.2
2136:             */
2137:            public static IVMInstall getVMInstall(IPath jreContainerPath) {
2138:                return JREContainerInitializer.resolveVM(jreContainerPath);
2139:            }
2140:
2141:            /**
2142:             * Returns the identifier of the VM install type referenced by the
2143:             * given JRE classpath container path, or <code>null</code> if none.
2144:             * 
2145:             * @param jreContainerPath
2146:             * @return vm install type identifier or <code>null</code>
2147:             * @since 3.2
2148:             */
2149:            public static String getVMInstallTypeId(IPath jreContainerPath) {
2150:                if (JREContainerInitializer
2151:                        .isExecutionEnvironment(jreContainerPath)) {
2152:                    return null;
2153:                }
2154:                return JREContainerInitializer.getVMTypeId(jreContainerPath);
2155:            }
2156:
2157:            /**
2158:             * Returns the name of the VM install referenced by the
2159:             * given JRE classpath container path, or <code>null</code> if none.
2160:             * 
2161:             * @param jreContainerPath
2162:             * @return vm name or <code>null</code>
2163:             * @since 3.2
2164:             */
2165:            public static String getVMInstallName(IPath jreContainerPath) {
2166:                if (JREContainerInitializer
2167:                        .isExecutionEnvironment(jreContainerPath)) {
2168:                    return null;
2169:                }
2170:                return JREContainerInitializer.getVMName(jreContainerPath);
2171:            }
2172:
2173:            /**
2174:             * Returns the execution environment identifier in the following JRE
2175:             * classpath container path, or <code>null</code> if none.
2176:             *  
2177:             * @param jreContainerPath classpath container path
2178:             * @return execution environment identifier or <code>null</code>
2179:             * @since 3.2
2180:             */
2181:            public static String getExecutionEnvironmentId(
2182:                    IPath jreContainerPath) {
2183:                return JREContainerInitializer
2184:                        .getExecutionEnvironmentId(jreContainerPath);
2185:            }
2186:
2187:            /**
2188:             * Returns a runtime classpath entry identifying the JRE to use when launching the specified
2189:             * configuration or <code>null</code> if none is specified. The entry returned represents a
2190:             * either a classpath variable or classpath container that resolves to a JRE.
2191:             * <p>
2192:             * The entry is resolved as follows:
2193:             * <ol>
2194:             * <li>If the <code>ATTR_JRE_CONTAINER_PATH</code> is present, it is used to create
2195:             *  a classpath container referring to a JRE.</li>
2196:             * <li>Next, if the <code>ATTR_VM_INSTALL_TYPE</code> and <code>ATTR_VM_INSTALL_NAME</code>
2197:             * attributes are present, they are used to create a classpath container.</li>
2198:             * <li>When none of the above attributes are specified, a default entry is
2199:             * created which refers to the JRE referenced by the build path of the configuration's
2200:             * associated Java project. This could be a classpath variable or classpath container.</li>
2201:             * <li>When there is no Java project associated with a configuration, the workspace
2202:             * default JRE is used to create a container path.</li>
2203:             * </ol>
2204:             * </p>
2205:             * @param configuration
2206:             * @return classpath container path identifying a JRE or <code>null</code>
2207:             * @exception org.eclipse.core.runtime.CoreException if an exception occurs retrieving
2208:             *  attributes from the specified launch configuration
2209:             * @since 3.2
2210:             */
2211:            public static IRuntimeClasspathEntry computeJREEntry(
2212:                    ILaunchConfiguration configuration) throws CoreException {
2213:                String jreAttr = configuration
2214:                        .getAttribute(
2215:                                IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH,
2216:                                (String) null);
2217:                IPath containerPath = null;
2218:                if (jreAttr == null) {
2219:                    String type = configuration
2220:                            .getAttribute(
2221:                                    IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE,
2222:                                    (String) null);
2223:                    if (type == null) {
2224:                        // default JRE for the launch configuration
2225:                        IJavaProject proj = getJavaProject(configuration);
2226:                        if (proj == null) {
2227:                            containerPath = newDefaultJREContainerPath();
2228:                        } else {
2229:                            return computeJREEntry(proj);
2230:                        }
2231:                    } else {
2232:                        String name = configuration
2233:                                .getAttribute(
2234:                                        IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME,
2235:                                        (String) null);
2236:                        if (name != null) {
2237:                            containerPath = newDefaultJREContainerPath()
2238:                                    .append(type).append(name);
2239:                        }
2240:                    }
2241:                } else {
2242:                    containerPath = Path.fromPortableString(jreAttr);
2243:                }
2244:                if (containerPath != null) {
2245:                    return newRuntimeContainerClasspathEntry(containerPath,
2246:                            IRuntimeClasspathEntry.STANDARD_CLASSES);
2247:                }
2248:                return null;
2249:            }
2250:
2251:            /**
2252:             * Returns a runtime classpath entry identifying the JRE referenced by the specified
2253:             * project, or <code>null</code> if none. The entry returned represents a either a
2254:             * classpath variable or classpath container that resolves to a JRE.
2255:             * 
2256:             * @param project Java project
2257:             * @return JRE runtime classpath entry or <code>null</code>
2258:             * @exception org.eclipse.core.runtime.CoreException if an exception occurs
2259:             * 	accessing the project's classpath
2260:             * @since 3.2
2261:             */
2262:            public static IRuntimeClasspathEntry computeJREEntry(
2263:                    IJavaProject project) throws CoreException {
2264:                IClasspathEntry[] rawClasspath = project.getRawClasspath();
2265:                IRuntimeClasspathEntryResolver2 resolver = null;
2266:                for (int i = 0; i < rawClasspath.length; i++) {
2267:                    IClasspathEntry entry = rawClasspath[i];
2268:                    switch (entry.getEntryKind()) {
2269:                    case IClasspathEntry.CPE_VARIABLE:
2270:                        resolver = getVariableResolver(entry.getPath().segment(
2271:                                0));
2272:                        if (resolver != null) {
2273:                            if (resolver.isVMInstallReference(entry)) {
2274:                                return newRuntimeClasspathEntry(entry);
2275:                            }
2276:                        }
2277:                        break;
2278:                    case IClasspathEntry.CPE_CONTAINER:
2279:                        resolver = getContainerResolver(entry.getPath()
2280:                                .segment(0));
2281:                        if (resolver != null) {
2282:                            if (resolver.isVMInstallReference(entry)) {
2283:                                IClasspathContainer container = JavaCore
2284:                                        .getClasspathContainer(entry.getPath(),
2285:                                                project);
2286:                                if (container != null) {
2287:                                    switch (container.getKind()) {
2288:                                    case IClasspathContainer.K_APPLICATION:
2289:                                        break;
2290:                                    case IClasspathContainer.K_DEFAULT_SYSTEM:
2291:                                        return newRuntimeContainerClasspathEntry(
2292:                                                entry.getPath(),
2293:                                                IRuntimeClasspathEntry.STANDARD_CLASSES);
2294:                                    case IClasspathContainer.K_SYSTEM:
2295:                                        return newRuntimeContainerClasspathEntry(
2296:                                                entry.getPath(),
2297:                                                IRuntimeClasspathEntry.BOOTSTRAP_CLASSES);
2298:                                    }
2299:                                }
2300:                            }
2301:                        }
2302:                        break;
2303:                    }
2304:
2305:                }
2306:                return null;
2307:            }
2308:
2309:            /**
2310:             * Returns whether the given runtime classpath entry refers to a vm install.
2311:             * 
2312:             * @param entry
2313:             * @return whether the given runtime classpath entry refers to a vm install
2314:             * @since 3.2
2315:             */
2316:            public static boolean isVMInstallReference(
2317:                    IRuntimeClasspathEntry entry) {
2318:                IClasspathEntry classpathEntry = entry.getClasspathEntry();
2319:                if (classpathEntry != null) {
2320:                    switch (classpathEntry.getEntryKind()) {
2321:                    case IClasspathEntry.CPE_VARIABLE:
2322:                        IRuntimeClasspathEntryResolver2 resolver = getVariableResolver(classpathEntry
2323:                                .getPath().segment(0));
2324:                        if (resolver != null) {
2325:                            return resolver
2326:                                    .isVMInstallReference(classpathEntry);
2327:                        }
2328:                        break;
2329:                    case IClasspathEntry.CPE_CONTAINER:
2330:                        resolver = getContainerResolver(classpathEntry
2331:                                .getPath().segment(0));
2332:                        if (resolver != null) {
2333:                            return resolver
2334:                                    .isVMInstallReference(classpathEntry);
2335:                        }
2336:                        break;
2337:                    }
2338:                }
2339:                return false;
2340:            }
2341:
2342:            /**
2343:             * Returns the VM connector defined with the specified identifier,
2344:             * or <code>null</code> if none.
2345:             * 
2346:             * @param id VM connector identifier
2347:             * @return VM connector or <code>null</code> if none
2348:             * @since 2.0
2349:             */
2350:            public static IVMConnector getVMConnector(String id) {
2351:                return LaunchingPlugin.getDefault().getVMConnector(id);
2352:            }
2353:
2354:            /**
2355:             * Returns all VM connector extensions.
2356:             *
2357:             * @return VM connectors
2358:             * @since 2.0
2359:             */
2360:            public static IVMConnector[] getVMConnectors() {
2361:                return LaunchingPlugin.getDefault().getVMConnectors();
2362:            }
2363:
2364:            /**
2365:             * Returns the preference store for the launching plug-in.
2366:             * 
2367:             * @return the preference store for the launching plug-in
2368:             * @since 2.0
2369:             */
2370:            public static Preferences getPreferences() {
2371:                return LaunchingPlugin.getDefault().getPluginPreferences();
2372:            }
2373:
2374:            /**
2375:             * Saves the preferences for the launching plug-in.
2376:             * 
2377:             * @since 2.0
2378:             */
2379:            public static void savePreferences() {
2380:                LaunchingPlugin.getDefault().savePluginPreferences();
2381:            }
2382:
2383:            /**
2384:             * Registers the given resolver for the specified variable.
2385:             * 
2386:             * @param resolver runtime classpath entry resolver
2387:             * @param variableName variable name to register for
2388:             * @since 2.0
2389:             */
2390:            public static void addVariableResolver(
2391:                    IRuntimeClasspathEntryResolver resolver, String variableName) {
2392:                Map map = getVariableResolvers();
2393:                map.put(variableName, resolver);
2394:            }
2395:
2396:            /**
2397:             * Registers the given resolver for the specified container.
2398:             * 
2399:             * @param resolver runtime classpath entry resolver
2400:             * @param containerIdentifier identifier of the classpath container to register for
2401:             * @since 2.0
2402:             */
2403:            public static void addContainerResolver(
2404:                    IRuntimeClasspathEntryResolver resolver,
2405:                    String containerIdentifier) {
2406:                Map map = getContainerResolvers();
2407:                map.put(containerIdentifier, resolver);
2408:            }
2409:
2410:            /**
2411:             * Returns all registered variable resolvers.
2412:             */
2413:            private static Map getVariableResolvers() {
2414:                if (fgVariableResolvers == null) {
2415:                    initializeResolvers();
2416:                }
2417:                return fgVariableResolvers;
2418:            }
2419:
2420:            /**
2421:             * Returns all registered container resolvers.
2422:             */
2423:            private static Map getContainerResolvers() {
2424:                if (fgContainerResolvers == null) {
2425:                    initializeResolvers();
2426:                }
2427:                return fgContainerResolvers;
2428:            }
2429:
2430:            /**
2431:             * Returns all registered runtime classpath entry resolvers.
2432:             */
2433:            private static Map getEntryResolvers() {
2434:                if (fgRuntimeClasspathEntryResolvers == null) {
2435:                    initializeResolvers();
2436:                }
2437:                return fgRuntimeClasspathEntryResolvers;
2438:            }
2439:
2440:            /**
2441:             * Initializes the listing of runtime classpath entry resolvers
2442:             */
2443:            private static void initializeResolvers() {
2444:                IExtensionPoint point = Platform
2445:                        .getExtensionRegistry()
2446:                        .getExtensionPoint(LaunchingPlugin.ID_PLUGIN,
2447:                                EXTENSION_POINT_RUNTIME_CLASSPATH_ENTRY_RESOLVERS);
2448:                IConfigurationElement[] extensions = point
2449:                        .getConfigurationElements();
2450:                fgVariableResolvers = new HashMap(extensions.length);
2451:                fgContainerResolvers = new HashMap(extensions.length);
2452:                fgRuntimeClasspathEntryResolvers = new HashMap(
2453:                        extensions.length);
2454:                for (int i = 0; i < extensions.length; i++) {
2455:                    RuntimeClasspathEntryResolver res = new RuntimeClasspathEntryResolver(
2456:                            extensions[i]);
2457:                    String variable = res.getVariableName();
2458:                    String container = res.getContainerId();
2459:                    String entryId = res.getRuntimeClasspathEntryId();
2460:                    if (variable != null) {
2461:                        fgVariableResolvers.put(variable, res);
2462:                    }
2463:                    if (container != null) {
2464:                        fgContainerResolvers.put(container, res);
2465:                    }
2466:                    if (entryId != null) {
2467:                        fgRuntimeClasspathEntryResolvers.put(entryId, res);
2468:                    }
2469:                }
2470:            }
2471:
2472:            /**
2473:             * Returns all registered classpath providers.
2474:             */
2475:            private static Map getClasspathProviders() {
2476:                if (fgPathProviders == null) {
2477:                    initializeProviders();
2478:                }
2479:                return fgPathProviders;
2480:            }
2481:
2482:            /**
2483:             * Initializes the listing of classpath providers
2484:             */
2485:            private static void initializeProviders() {
2486:                IExtensionPoint point = Platform.getExtensionRegistry()
2487:                        .getExtensionPoint(LaunchingPlugin.ID_PLUGIN,
2488:                                EXTENSION_POINT_RUNTIME_CLASSPATH_PROVIDERS);
2489:                IConfigurationElement[] extensions = point
2490:                        .getConfigurationElements();
2491:                fgPathProviders = new HashMap(extensions.length);
2492:                for (int i = 0; i < extensions.length; i++) {
2493:                    RuntimeClasspathProvider res = new RuntimeClasspathProvider(
2494:                            extensions[i]);
2495:                    fgPathProviders.put(res.getIdentifier(), res);
2496:                }
2497:            }
2498:
2499:            /**
2500:             * Returns the resolver registered for the given variable, or
2501:             * <code>null</code> if none.
2502:             * 
2503:             * @param variableName the variable to determine the resolver for
2504:             * @return the resolver registered for the given variable, or
2505:             * <code>null</code> if none
2506:             */
2507:            private static IRuntimeClasspathEntryResolver2 getVariableResolver(
2508:                    String variableName) {
2509:                return (IRuntimeClasspathEntryResolver2) getVariableResolvers()
2510:                        .get(variableName);
2511:            }
2512:
2513:            /**
2514:             * Returns the resolver registered for the given container id, or
2515:             * <code>null</code> if none.
2516:             * 
2517:             * @param containerId the container to determine the resolver for
2518:             * @return the resolver registered for the given container id, or
2519:             * <code>null</code> if none
2520:             */
2521:            private static IRuntimeClasspathEntryResolver2 getContainerResolver(
2522:                    String containerId) {
2523:                return (IRuntimeClasspathEntryResolver2) getContainerResolvers()
2524:                        .get(containerId);
2525:            }
2526:
2527:            /**
2528:             * Returns the resolver registered for the given contributed classpath
2529:             * entry type.
2530:             * 
2531:             * @param typeId the id of the contributed classpath entry
2532:             * @return the resolver registered for the given classpath entry
2533:             */
2534:            private static IRuntimeClasspathEntryResolver getContributedResolver(
2535:                    String typeId) {
2536:                IRuntimeClasspathEntryResolver resolver = (IRuntimeClasspathEntryResolver) getEntryResolvers()
2537:                        .get(typeId);
2538:                if (resolver == null) {
2539:                    return new DefaultEntryResolver();
2540:                }
2541:                return resolver;
2542:            }
2543:
2544:            /**
2545:             * Adds the given listener to the list of registered VM install changed
2546:             * listeners. Has no effect if an identical listener is already registered.
2547:             * 
2548:             * @param listener the listener to add
2549:             * @since 2.0
2550:             */
2551:            public static void addVMInstallChangedListener(
2552:                    IVMInstallChangedListener listener) {
2553:                fgVMListeners.add(listener);
2554:            }
2555:
2556:            /**
2557:             * Removes the given listener from the list of registered VM install changed
2558:             * listeners. Has no effect if an identical listener is not already registered.
2559:             * 
2560:             * @param listener the listener to remove
2561:             * @since 2.0
2562:             */
2563:            public static void removeVMInstallChangedListener(
2564:                    IVMInstallChangedListener listener) {
2565:                fgVMListeners.remove(listener);
2566:            }
2567:
2568:            /**
2569:             * Notifies registered listeners that the default VM has changed
2570:             * @param previous the previous VM
2571:             * @param current the new current default VM
2572:             */
2573:            private static void notifyDefaultVMChanged(IVMInstall previous,
2574:                    IVMInstall current) {
2575:                Object[] listeners = fgVMListeners.getListeners();
2576:                for (int i = 0; i < listeners.length; i++) {
2577:                    IVMInstallChangedListener listener = (IVMInstallChangedListener) listeners[i];
2578:                    listener.defaultVMInstallChanged(previous, current);
2579:                }
2580:            }
2581:
2582:            /**
2583:             * Notifies all VM install changed listeners of the given property change.
2584:             * 
2585:             * @param event event describing the change.
2586:             * @since 2.0
2587:             */
2588:            public static void fireVMChanged(PropertyChangeEvent event) {
2589:                Object[] listeners = fgVMListeners.getListeners();
2590:                for (int i = 0; i < listeners.length; i++) {
2591:                    IVMInstallChangedListener listener = (IVMInstallChangedListener) listeners[i];
2592:                    listener.vmChanged(event);
2593:                }
2594:            }
2595:
2596:            /**
2597:             * Notifies all VM install changed listeners of the VM addition
2598:             * 
2599:             * @param vm the VM that has been added
2600:             * @since 2.0
2601:             */
2602:            public static void fireVMAdded(IVMInstall vm) {
2603:                if (!fgInitializingVMs) {
2604:                    Object[] listeners = fgVMListeners.getListeners();
2605:                    for (int i = 0; i < listeners.length; i++) {
2606:                        IVMInstallChangedListener listener = (IVMInstallChangedListener) listeners[i];
2607:                        listener.vmAdded(vm);
2608:                    }
2609:                }
2610:            }
2611:
2612:            /**
2613:             * Notifies all VM install changed listeners of the VM removal
2614:             * 
2615:             * @param vm the VM that has been removed
2616:             * @since 2.0
2617:             */
2618:            public static void fireVMRemoved(IVMInstall vm) {
2619:                Object[] listeners = fgVMListeners.getListeners();
2620:                for (int i = 0; i < listeners.length; i++) {
2621:                    IVMInstallChangedListener listener = (IVMInstallChangedListener) listeners[i];
2622:                    listener.vmRemoved(vm);
2623:                }
2624:            }
2625:
2626:            /**
2627:             * Return the String representation of the default output directory of the
2628:             * launch config's project or <code>null</code> if there is no config, no
2629:             * project or some sort of problem.
2630:             * 
2631:             * @return the default output directory for the specified launch
2632:             * configuration's project
2633:             * @since 2.1
2634:             */
2635:            public static String getProjectOutputDirectory(
2636:                    ILaunchConfiguration config) {
2637:                try {
2638:                    if (config != null) {
2639:                        IJavaProject javaProject = JavaRuntime
2640:                                .getJavaProject(config);
2641:                        if (javaProject != null) {
2642:                            IWorkspaceRoot root = ResourcesPlugin
2643:                                    .getWorkspace().getRoot();
2644:                            IPath outputLocation = javaProject
2645:                                    .getOutputLocation();
2646:                            IResource resource = root
2647:                                    .findMember(outputLocation);
2648:                            if (resource != null) {
2649:                                IPath path = resource.getFullPath();
2650:                                if (path != null) {
2651:                                    return path.makeRelative().toString();
2652:                                }
2653:                            }
2654:                        }
2655:                    }
2656:                } catch (CoreException ce) {
2657:                }
2658:                return null;
2659:            }
2660:
2661:            /**
2662:             * Returns a collection of source containers corresponding to the given
2663:             * resolved runtime classpath entries.
2664:             * <p>
2665:             * Note that the entries must be resolved to ARCHIVE and PROJECT entries,
2666:             * as source containers cannot be determined for unresolved entries.
2667:             * </p>
2668:             * @param entries entries to translate
2669:             * @return source containers corresponding to the given runtime classpath entries
2670:             * @since 3.1
2671:             */
2672:            public static ISourceContainer[] getSourceContainers(
2673:                    IRuntimeClasspathEntry[] entries) {
2674:                return JavaSourceLookupUtil.translate(entries);
2675:            }
2676:
2677:            /**
2678:             * Returns a collection of paths that should be appended to the given project's
2679:             * <code>java.library.path</code> system property when launched. Entries are
2680:             * searched for on the project's build path as extra classpath attributes.
2681:             * Each entry represents an absolute path in the local file system.
2682:             *
2683:             * @param project the project to compute the <code>java.library.path</code> for
2684:             * @param requiredProjects whether to consider entries in required projects
2685:             * @return a collection of paths representing entries that should be appended
2686:             *  to the given project's <code>java.library.path</code>
2687:             * @throws CoreException if unable to compute the Java library path
2688:             * @since 3.1
2689:             * @see org.eclipse.jdt.core.IClasspathAttribute
2690:             * @see JavaRuntime#CLASSPATH_ATTR_LIBRARY_PATH_ENTRY
2691:             */
2692:            public static String[] computeJavaLibraryPath(IJavaProject project,
2693:                    boolean requiredProjects) throws CoreException {
2694:                Set visited = new HashSet();
2695:                List entries = new ArrayList();
2696:                gatherJavaLibraryPathEntries(project, requiredProjects,
2697:                        visited, entries);
2698:                List resolved = new ArrayList(entries.size());
2699:                Iterator iterator = entries.iterator();
2700:                IStringVariableManager manager = VariablesPlugin.getDefault()
2701:                        .getStringVariableManager();
2702:                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
2703:                while (iterator.hasNext()) {
2704:                    String entry = (String) iterator.next();
2705:                    String resolvedEntry = manager
2706:                            .performStringSubstitution(entry);
2707:                    IPath path = new Path(resolvedEntry);
2708:                    if (path.isAbsolute()) {
2709:                        File file = path.toFile();
2710:                        resolved.add(file.getAbsolutePath());
2711:                    } else {
2712:                        IResource resource = root.findMember(path);
2713:                        if (resource != null) {
2714:                            IPath location = resource.getLocation();
2715:                            if (location != null) {
2716:                                resolved.add(location.toFile()
2717:                                        .getAbsolutePath());
2718:                            }
2719:                        }
2720:                    }
2721:                }
2722:                return (String[]) resolved.toArray(new String[resolved.size()]);
2723:            }
2724:
2725:            /**
2726:             * Gathers all Java library entries for the given project and optionally its required
2727:             * projects.
2728:             * 
2729:             * @param project project to gather entries for
2730:             * @param requiredProjects whether to consider required projects 
2731:             * @param visited projects already considered
2732:             * @param entries collection to add library entries to
2733:             * @throws CoreException if unable to gather classpath entries
2734:             * @since 3.1
2735:             */
2736:            private static void gatherJavaLibraryPathEntries(
2737:                    IJavaProject project, boolean requiredProjects,
2738:                    Set visited, List entries) throws CoreException {
2739:                if (visited.contains(project)) {
2740:                    return;
2741:                }
2742:                visited.add(project);
2743:                IClasspathEntry[] rawClasspath = project.getRawClasspath();
2744:                IClasspathEntry[] required = processJavaLibraryPathEntries(
2745:                        project, requiredProjects, rawClasspath, entries);
2746:                if (required != null) {
2747:                    IWorkspaceRoot root = ResourcesPlugin.getWorkspace()
2748:                            .getRoot();
2749:                    for (int i = 0; i < required.length; i++) {
2750:                        IClasspathEntry entry = required[i];
2751:                        String projectName = entry.getPath().segment(0);
2752:                        IProject p = root.getProject(projectName);
2753:                        if (p.exists()) {
2754:                            IJavaProject requiredProject = JavaCore.create(p);
2755:                            if (requiredProject != null) {
2756:                                gatherJavaLibraryPathEntries(requiredProject,
2757:                                        requiredProjects, visited, entries);
2758:                            }
2759:                        }
2760:                    }
2761:                }
2762:            }
2763:
2764:            /**
2765:             * Adds all java library path extra classpath entry values to the given entries collection
2766:             * specified on the given project's classpath, and returns a collection of required
2767:             * projects, or <code>null</code>.
2768:             *  
2769:             * @param project project being processed
2770:             * @param collectRequired whether to collect required projects
2771:             * @param classpathEntries the project's raw classpath
2772:             * @param entries collection to add java library path entries to
2773:             * @return required project classpath entries or <code>null</code>
2774:             * @throws CoreException
2775:             * @since 3.1
2776:             */
2777:            private static IClasspathEntry[] processJavaLibraryPathEntries(
2778:                    IJavaProject project, boolean collectRequired,
2779:                    IClasspathEntry[] classpathEntries, List entries)
2780:                    throws CoreException {
2781:                List req = null;
2782:                for (int i = 0; i < classpathEntries.length; i++) {
2783:                    IClasspathEntry entry = classpathEntries[i];
2784:                    IClasspathAttribute[] extraAttributes = entry
2785:                            .getExtraAttributes();
2786:                    for (int j = 0; j < extraAttributes.length; j++) {
2787:                        String[] paths = getLibraryPaths(extraAttributes[j]);
2788:                        if (paths != null) {
2789:                            for (int k = 0; k < paths.length; k++) {
2790:                                entries.add(paths[k]);
2791:                            }
2792:                        }
2793:                    }
2794:                    if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
2795:                        IClasspathContainer container = JavaCore
2796:                                .getClasspathContainer(entry.getPath(), project);
2797:                        if (container != null) {
2798:                            IClasspathEntry[] requiredProjects = processJavaLibraryPathEntries(
2799:                                    project, collectRequired, container
2800:                                            .getClasspathEntries(), entries);
2801:                            if (requiredProjects != null) {
2802:                                if (req == null) {
2803:                                    req = new ArrayList();
2804:                                }
2805:                                for (int j = 0; j < requiredProjects.length; j++) {
2806:                                    req.add(requiredProjects[j]);
2807:                                }
2808:                            }
2809:                        }
2810:                    } else if (collectRequired
2811:                            && entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
2812:                        if (req == null) {
2813:                            req = new ArrayList();
2814:                        }
2815:                        req.add(entry);
2816:                    }
2817:                }
2818:                if (req != null) {
2819:                    return (IClasspathEntry[]) req
2820:                            .toArray(new IClasspathEntry[req.size()]);
2821:                }
2822:                return null;
2823:            }
2824:
2825:            /**
2826:             * Creates a new classpath attribute referencing a list of shared libraries that should
2827:             * appear on the <code>-Djava.library.path</code> system property at runtime
2828:             * for an associated {@link IClasspathEntry}.
2829:             * <p>
2830:             * The factory methods <code>newLibraryPathsAttribute(String[])</code>
2831:             * and <code>getLibraryPaths(IClasspathAttribute)</code> should be used to
2832:             * encode and decode the attribute value.
2833:             * </p>
2834:             * @param paths an array of strings representing paths of shared libraries.
2835:             * Each string is used to create an <code>IPath</code> using the constructor
2836:             * <code>Path(String)</code>, and may contain <code>IStringVariable</code>'s.
2837:             * Variable substitution is performed on each string before a path is constructed
2838:             * from a string.
2839:             * @return a classpath attribute with the name <code>CLASSPATH_ATTR_LIBRARY_PATH_ENTRY</code>
2840:             * and an value encoded to the specified paths.
2841:             * @since 3.1
2842:             */
2843:            public static IClasspathAttribute newLibraryPathsAttribute(
2844:                    String[] paths) {
2845:                StringBuffer value = new StringBuffer();
2846:                for (int i = 0; i < paths.length; i++) {
2847:                    value.append(paths[i]);
2848:                    if (i < (paths.length - 1)) {
2849:                        value.append("|"); //$NON-NLS-1$
2850:                    }
2851:                }
2852:                return JavaCore.newClasspathAttribute(
2853:                        CLASSPATH_ATTR_LIBRARY_PATH_ENTRY, value.toString());
2854:            }
2855:
2856:            /**
2857:             * Returns an array of strings referencing shared libraries that should
2858:             * appear on the <code>-Djava.library.path</code> system property at runtime
2859:             * for an associated {@link IClasspathEntry}, or <code>null</code> if the
2860:             * given attribute is not a <code>CLASSPATH_ATTR_LIBRARY_PATH_ENTRY</code>.
2861:             * Each string is used to create an <code>IPath</code> using the constructor
2862:             * <code>Path(String)</code>, and may contain <code>IStringVariable</code>'s. 
2863:             * <p>
2864:             * The factory methods <code>newLibraryPathsAttribute(String[])</code>
2865:             * and <code>getLibraryPaths(IClasspathAttribute)</code> should be used to
2866:             * encode and decode the attribute value. 
2867:             * </p>
2868:             * @param attribute a <code>CLASSPATH_ATTR_LIBRARY_PATH_ENTRY</code> classpath attribute
2869:             * @return an array of strings referencing shared libraries that should
2870:             * appear on the <code>-Djava.library.path</code> system property at runtime
2871:             * for an associated {@link IClasspathEntry}, or <code>null</code> if the
2872:             * given attribute is not a <code>CLASSPATH_ATTR_LIBRARY_PATH_ENTRY</code>.
2873:             * Each string is used to create an <code>IPath</code> using the constructor
2874:             * <code>Path(String)</code>, and may contain <code>IStringVariable</code>'s.
2875:             * @since 3.1
2876:             */
2877:            public static String[] getLibraryPaths(IClasspathAttribute attribute) {
2878:                if (CLASSPATH_ATTR_LIBRARY_PATH_ENTRY.equals(attribute
2879:                        .getName())) {
2880:                    String value = attribute.getValue();
2881:                    return value.split("\\|"); //$NON-NLS-1$
2882:                }
2883:                return null;
2884:            }
2885:
2886:            /**
2887:             * Returns the execution environments manager.
2888:             * 
2889:             * @return execution environments manager
2890:             * @since 3.2
2891:             */
2892:            public static IExecutionEnvironmentsManager getExecutionEnvironmentsManager() {
2893:                return EnvironmentsManager.getDefault();
2894:            }
2895:
2896:            /**
2897:             * Perform VM type and VM install initialization. Does not hold locks
2898:             * while performing change notification.
2899:             * 
2900:             * @since 3.2
2901:             */
2902:            private static void initializeVMs() {
2903:                VMDefinitionsContainer vmDefs = null;
2904:                boolean setPref = false;
2905:                boolean updateCompliance = false;
2906:                synchronized (fgVMLock) {
2907:                    if (fgVMTypes == null) {
2908:                        try {
2909:                            fgInitializingVMs = true;
2910:                            // 1. load VM type extensions
2911:                            initializeVMTypeExtensions();
2912:                            try {
2913:                                vmDefs = new VMDefinitionsContainer();
2914:                                // 2. add persisted VMs
2915:                                setPref = addPersistedVMs(vmDefs);
2916:                                IStatus status = vmDefs.getStatus();
2917:                                if (status != null) {
2918:                                    if (status.isMultiStatus()) {
2919:                                        MultiStatus multi = (MultiStatus) status;
2920:                                        IStatus[] children = multi
2921:                                                .getChildren();
2922:                                        for (int i = 0; i < children.length; i++) {
2923:                                            IStatus child = children[i];
2924:                                            if (!child.isOK()) {
2925:                                                LaunchingPlugin.log(child);
2926:                                            }
2927:                                        }
2928:                                    } else if (!status.isOK()) {
2929:                                        LaunchingPlugin.log(status);
2930:                                    }
2931:                                }
2932:
2933:                                // 3. if there are none, detect the eclipse runtime
2934:                                if (vmDefs.getValidVMList().isEmpty()) {
2935:                                    // calling out to detectEclipseRuntime() could allow clients to change
2936:                                    // VM settings (i.e. call back into change VM settings).
2937:                                    VMListener listener = new VMListener();
2938:                                    addVMInstallChangedListener(listener);
2939:                                    setPref = true;
2940:                                    VMStandin runtime = detectEclipseRuntime();
2941:                                    removeVMInstallChangedListener(listener);
2942:                                    if (!listener.isChanged()) {
2943:                                        if (runtime != null) {
2944:                                            updateCompliance = true;
2945:                                            vmDefs.addVM(runtime);
2946:                                            vmDefs
2947:                                                    .setDefaultVMInstallCompositeID(getCompositeIdFromVM(runtime));
2948:                                        }
2949:                                    } else {
2950:                                        // VMs were changed - reflect current settings
2951:                                        addPersistedVMs(vmDefs);
2952:                                        vmDefs
2953:                                                .setDefaultVMInstallCompositeID(fgDefaultVMId);
2954:                                        updateCompliance = fgDefaultVMId != null;
2955:                                    }
2956:                                }
2957:                                // 4. load contributed VM installs
2958:                                addVMExtensions(vmDefs);
2959:                                // 5. verify default VM is valid
2960:                                String defId = vmDefs
2961:                                        .getDefaultVMInstallCompositeID();
2962:                                boolean validDef = false;
2963:                                if (defId != null) {
2964:                                    Iterator iterator = vmDefs.getValidVMList()
2965:                                            .iterator();
2966:                                    while (iterator.hasNext()) {
2967:                                        IVMInstall vm = (IVMInstall) iterator
2968:                                                .next();
2969:                                        if (getCompositeIdFromVM(vm).equals(
2970:                                                defId)) {
2971:                                            validDef = true;
2972:                                            break;
2973:                                        }
2974:                                    }
2975:                                }
2976:                                if (!validDef) {
2977:                                    // use the first as the default
2978:                                    setPref = true;
2979:                                    List list = vmDefs.getValidVMList();
2980:                                    if (!list.isEmpty()) {
2981:                                        IVMInstall vm = (IVMInstall) list
2982:                                                .get(0);
2983:                                        vmDefs
2984:                                                .setDefaultVMInstallCompositeID(getCompositeIdFromVM(vm));
2985:                                    }
2986:                                }
2987:                                fgDefaultVMId = vmDefs
2988:                                        .getDefaultVMInstallCompositeID();
2989:                                fgDefaultVMConnectorId = vmDefs
2990:                                        .getDefaultVMInstallConnectorTypeID();
2991:
2992:                                // Create the underlying VMs for each valid VM
2993:                                List vmList = vmDefs.getValidVMList();
2994:                                Iterator vmListIterator = vmList.iterator();
2995:                                while (vmListIterator.hasNext()) {
2996:                                    VMStandin vmStandin = (VMStandin) vmListIterator
2997:                                            .next();
2998:                                    vmStandin.convertToRealVM();
2999:                                }
3000:
3001:                            } catch (IOException e) {
3002:                                LaunchingPlugin.log(e);
3003:                            }
3004:                        } finally {
3005:                            fgInitializingVMs = false;
3006:                        }
3007:                    }
3008:                }
3009:                if (vmDefs != null) {
3010:                    // notify of initial VMs for backwards compatibility
3011:                    IVMInstallType[] installTypes = getVMInstallTypes();
3012:                    for (int i = 0; i < installTypes.length; i++) {
3013:                        IVMInstallType type = installTypes[i];
3014:                        IVMInstall[] installs = type.getVMInstalls();
3015:                        for (int j = 0; j < installs.length; j++) {
3016:                            fireVMAdded(installs[j]);
3017:                        }
3018:                    }
3019:
3020:                    // save settings if required
3021:                    if (setPref) {
3022:                        try {
3023:                            String xml = vmDefs.getAsXML();
3024:                            LaunchingPlugin.getDefault().getPluginPreferences()
3025:                                    .setValue(PREF_VM_XML, xml);
3026:                        } catch (CoreException e) {
3027:                            LaunchingPlugin.log(e);
3028:                        }
3029:
3030:                    }
3031:
3032:                    // update compliance if required
3033:                    if (updateCompliance) {
3034:                        updateCompliance(getDefaultVMInstall());
3035:                    }
3036:                }
3037:            }
3038:
3039:            /**
3040:             * Update compiler compliance settings based on the given vm.
3041:             * 
3042:             * @param vm
3043:             */
3044:            private static void updateCompliance(IVMInstall vm) {
3045:                if (vm instanceof  IVMInstall2) {
3046:                    String javaVersion = ((IVMInstall2) vm).getJavaVersion();
3047:                    if (javaVersion != null) {
3048:                        String compliance = null;
3049:                        if (javaVersion.startsWith(JavaCore.VERSION_1_5)) {
3050:                            compliance = JavaCore.VERSION_1_5;
3051:                        } else if (javaVersion.startsWith(JavaCore.VERSION_1_6)) {
3052:                            compliance = JavaCore.VERSION_1_6;
3053:                        } else if (javaVersion.startsWith(JavaCore.VERSION_1_7)) {
3054:                            compliance = JavaCore.VERSION_1_7;
3055:                        }
3056:                        if (compliance != null) {
3057:                            Hashtable defaultOptions = JavaCore
3058:                                    .getDefaultOptions();
3059:                            Hashtable options = JavaCore.getOptions();
3060:                            boolean isDefault = equals(
3061:                                    JavaCore.COMPILER_COMPLIANCE,
3062:                                    defaultOptions, options)
3063:                                    && equals(JavaCore.COMPILER_SOURCE,
3064:                                            defaultOptions, options)
3065:                                    && equals(
3066:                                            JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
3067:                                            defaultOptions, options)
3068:                                    && equals(
3069:                                            JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
3070:                                            defaultOptions, options)
3071:                                    && equals(
3072:                                            JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
3073:                                            defaultOptions, options);
3074:                            // only update the compliance settings if they are default settings, otherwise the
3075:                            // settings have already been modified by a tool or user
3076:                            if (isDefault) {
3077:                                JavaCore.setComplianceOptions(compliance,
3078:                                        options);
3079:                                JavaCore.setOptions(options);
3080:                            }
3081:                        }
3082:                    }
3083:                }
3084:            }
3085:
3086:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.