/************************************************************************************* * Copyright (c) 2008-2011 Red Hat, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * JBoss by Red Hat - Initial implementation. ************************************************************************************/ package org.jboss.tools.common.jdt.debug; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.internal.launching.SocketAttachConnector; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IVMConnector; import org.eclipse.jdt.launching.JavaRuntime; import org.jboss.tools.common.jdt.debug.internal.RemoteDebugLaunchUtil; import org.jboss.tools.common.jdt.debug.internal.SourceLookupUtil; import org.jboss.tools.common.jdt.debug.internal.VmModelCache; import org.jboss.tools.common.jdt.debug.sourcelookup.DebugLaunchConfigurationListener; import org.jboss.tools.common.jdt.debug.sourcelookup.RemoteDebugSourcePathComputer; import org.jboss.tools.common.jdt.debug.tools.ToolsCore; import org.jboss.tools.common.jdt.debug.tools.ToolsCoreException; import org.jboss.tools.common.jdt.debug.tools.internal.Tools; import org.jboss.tools.foundation.core.plugin.BaseCorePlugin; import org.jboss.tools.foundation.core.plugin.log.IPluginLog; import org.jboss.tools.foundation.core.plugin.log.StatusFactory; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; public class RemoteDebugActivator extends BaseCorePlugin { public static final String PLUGIN_ID = "org.jboss.tools.common.jdt.debug"; //$NON-NLS-1$ public static final String UNKNOWN = "<Unknown>"; public static final String LOCALHOST = "localhost"; //$NON-NLS-1$ public static final String LAUNCH_CONFIGURATION_ID = "org.jboss.tools.common.jdt.debug.launching.JBossRemoteJavaApplication"; //$NON-NLS-1$ public static final String REMOTE_JAVA_APPLICATION_ID = IJavaLaunchConfigurationConstants.ID_REMOTE_JAVA_APPLICATION; public static final String JBOSS_REMOTE_JAVA_APPLICATION = "JBossRemoteJavaApplication"; //$NON-NLS-1$ public static final String JBOSS_SOURCE_PATH_COMPUTER_ID = "org.jboss.tools.common.jdt.debug.sourceLookup.remoteDebugSourcePathComputer"; //$NON-NLS-1$ public static final String DT_SOCKET = "dt_socket"; //$NON-NLS-1$ public static final String LAUNCH_CATEGORY = "org.eclipse.debug.ui.launchGroup.debug"; //$NON-NLS-1$ public static final String ATTR_SELECTED_PROJECTS = "selectedProjects"; //$NON-NLS-1$ public static final String MAVEN_SOURCEPATH_PROVIDER = "org.eclipse.m2e.launchconfig.sourcepathProvider"; //$NON-NLS-1$ public static final String MAVEN_CLASSPATH_PROVIDER = "org.eclipse.m2e.launchconfig.classpathProvider"; //$NON-NLS-1$ private static final String MAVEN_PLUGIN_ID = "org.eclipse.m2e.core"; //$NON-NLS-1$ public static final String MAVEN_NATURE = MAVEN_PLUGIN_ID + ".maven2Nature"; //$NON-NLS-1$ @Deprecated public static final String SET_AS_DEFAULT = IPropertyKeys.SET_AS_DEFAULT; @Deprecated public static final String JDT_JAVA_APPLICATION = RemoteDebugSourcePathComputer.JDT_JAVA_APPLICATION; @Deprecated public static final String JDT_JUNIT_TEST = RemoteDebugSourcePathComputer.JDT_JUNIT_TEST; @Deprecated // Should not be public; replacement is private in RemoteDebugLaunchUtil.DEFAULT_REMOTE_JBOSS_APP public static final String DEFAULT_REMOTE_JBOSS_APP = "Remote myapp"; //$NON-NLS-1$ @Deprecated // Should not be public; replacement is private in RemoteDebugLaunchUtil.JBOSS_TEMP_JAVA_APPLICATION public static final String JBOSS_TEMP_JAVA_APPLICATION = "jbossTempJavaApplication"; //$NON-NLS-1$ private static RemoteDebugActivator plugin; private static BundleContext context; private DebugLaunchConfigurationListener listener; static BundleContext getContext() { return context; } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext bundleContext) throws Exception { RemoteDebugActivator.context = bundleContext; plugin = this; listener= new DebugLaunchConfigurationListener(); DebugPlugin.getDefault().getLaunchManager().addLaunchConfigurationListener(listener); } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext bundleContext) throws Exception { RemoteDebugActivator.context = null; DebugPlugin.getDefault().getLaunchManager().removeLaunchConfigurationListener(listener); } public static RemoteDebugActivator getDefault() { return plugin; } private List<VmModel> getVmModels(String hostname, IProgressMonitor monitor) { if (monitor == null) { monitor = new NullProgressMonitor(); } List<VmModel> models = new ArrayList<VmModel>(); try { Set<Integer> vmPids = ToolsCore.getActiveVmPids(hostname); int i = 1; int size = vmPids.size(); monitor.beginTask("Discovering Remote Aplications", vmPids.size() + 1); for (Integer vmPid : vmPids) { monitor.worked(1); monitor.setTaskName(i++ + " out of " + size + ": Discovering port, main class and arguments for process id " + vmPid); VmModel model = getVmModel(hostname, vmPid, true, monitor); if (model != null) { models.add(model); } } } catch(ToolsCoreException tce) { pluginLog().logError(tce); } return models; } public VmModel getCachedVmModel(String hostname, Integer vmPid) { return VmModelCache.getDefault().getModel(hostname, vmPid); } public VmModel getVmModel(String hostname, Integer vmPid, IProgressMonitor monitor) { VmModel model = getVmModelsUsingTools(hostname, vmPid, monitor); VmModelCache.getDefault().cacheModel(hostname, vmPid.intValue(), model); return model; } public VmModel getVmModel(String hostname, Integer vmPid, boolean useCommand, IProgressMonitor monitor) { return getVmModel(hostname, vmPid, monitor); } private VmModel getVmModelsUsingTools(String hostname, Integer vmPid, IProgressMonitor monitor) { if (monitor == null) { monitor = new NullProgressMonitor(); } if (monitor.isCanceled()) { return null; } boolean monitorable = false; try { monitorable = ToolsCore.processIsMonitorable(hostname, vmPid); } catch(ToolsCoreException c ) { pluginLog().logWarning(c); } if( monitorable ) { VmModel model = new VmModel(); model.setPid(String.valueOf(vmPid)); // If process is suspended (launched with suspend=y waiting for debugger) these may fail... try { model.setJvmArgs(ToolsCore.getJvmArgs(hostname, vmPid)); model.setMainClass(ToolsCore.getMainClass(hostname, vmPid)); model.setMainArgs(ToolsCore.getMainArgs(hostname, vmPid)); } catch (ToolsCoreException e) { // Ignore, expected in case of suspended vm } return model; } return null; } public VmModel getDebugModel(String hostname, int pid, boolean useCommand, IProgressMonitor monitor) { VmModel model = getVmModel(hostname, pid, useCommand, monitor); if( model != null && isDebugModel(model)) { return model; } return null; } public boolean isDebugModel(VmModel model) { if (model != null && model.getDebugPort() != null && DT_SOCKET.equals(model.getTransport())) { return true; } return false; } public VmModel[] getDebugModels(String hostname, IProgressMonitor monitor) { List<VmModel> debugModels = new ArrayList<VmModel>(); List<VmModel> models = getVmModels(hostname, monitor); if (models == null) { return null; } for (VmModel model:models) { if (isDebugModel(model)) { debugModels.add(model); } } return debugModels.toArray(new VmModel[0]); } /** * Returns whether a jdk has been found and set from which * the proper sun classes can be accessed * @return */ public boolean isJdk() { return Tools.getInstance().isReady(); } public static IVMConnector getDefaultVMConnector() { IVMConnector[] connectors = JavaRuntime.getVMConnectors(); for (IVMConnector connector:connectors) { if (connector instanceof SocketAttachConnector) { return connector; } } return null; } public VmModel[] getDebugModels(IProgressMonitor monitor) { return getDebugModels(LOCALHOST, monitor); } public static boolean m2eExists() { Bundle bundle = Platform.getBundle(MAVEN_PLUGIN_ID); return bundle != null; } /* * Methods related to launch configs */ public ILaunchConfiguration getDefaultLaunchConfiguration() { return RemoteDebugLaunchUtil.getDefaultLaunchConfiguration(); } public ILaunchConfiguration[] getLaunchConfigurations() { return RemoteDebugLaunchUtil.getLaunchConfigurations(); } public static boolean isRemoteDebuggerConnected(String host, int port) { return getExistingRemoteDebugLaunch(host,port) != null; } public static ILaunch getExistingRemoteDebugLaunch(String host, int port) { return RemoteDebugLaunchUtil.getExistingRemoteDebugLaunch(host, port); } public static ILaunchConfiguration createTemporaryLaunchConfiguration(String projectName, String typeId) throws CoreException { return RemoteDebugLaunchUtil.createTemporaryLaunchConfiguration(projectName, typeId); } public static ILaunchConfigurationWorkingCopy createNewLaunchConfiguration(ILaunchConfigurationType type) throws CoreException { return RemoteDebugLaunchUtil.createNewLaunchConfiguration(type); } public static ILaunchConfigurationType getRemoteJavaApplicationConfigurationType() { return RemoteDebugLaunchUtil.getRemoteJavaApplicationConfigurationType(); } public static ILaunchConfiguration createOrGetDefaultLaunchConfiguration(String port, String host, IJavaProject javaProject, IJavaElement[] selection) throws CoreException { return RemoteDebugLaunchUtil.createOrGetDefaultLaunchConfiguration(port, host, javaProject, selection); } public static void configureSourceLookup(ILaunchConfigurationWorkingCopy wc, IJavaElement[] selection, IJavaProject javaProject) throws CoreException { new SourceLookupUtil().addSelectedProjects(wc, selection, javaProject); } /** * Get the IPluginLog for this plugin. This method * helps to make logging easier, for example: * * FoundationCorePlugin.pluginLog().logError(etc) * * @return IPluginLog object */ public static IPluginLog pluginLog() { return getDefault().pluginLogInternal(); } /** * Get a status factory for this plugin * @return status factory */ public static StatusFactory statusFactory() { return getDefault().statusFactoryInternal(); } }