/* * Copyright (c) 2012 Andrejs Jermakovics. * * 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: * Andrejs Jermakovics - initial implementation */ package jmockit.assist; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import jmockit.assist.prefs.Prefs; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.IValueVariable; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchesListener2; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.junit.JUnitCorePlugin; /** * Listens for JUnit launches and adds JMockit javaagent JVM argument */ @SuppressWarnings("restriction") final class JunitLaunchListener implements ILaunchesListener2 { public static final String VM_ARGS = "org.eclipse.jdt.launching.VM_ARGUMENTS"; public static final String PROJ_ATTR = "org.eclipse.jdt.launching.PROJECT_ATTR"; public static final String JMOCKIT_VAR_NAME = "jmockit_javaagent"; public static final String JMOCKIT_VAR = "${" + JMOCKIT_VAR_NAME + "}"; private final List<ILaunch> modifiedLaunches = new ArrayList<ILaunch>(); @Override public void launchesTerminated(final ILaunch[] launches) { for (ILaunch iLaunch : launches) { if (modifiedLaunches.contains(iLaunch)) { modifiedLaunches.remove(iLaunch); try { removeJavaAgentVmArg(iLaunch.getLaunchConfiguration()); } catch (CoreException e) { Activator.log(e); } } } } @Override public void launchesRemoved(final ILaunch[] launches) { } @Override public void launchesChanged(final ILaunch[] launches) { } @Override public void launchesAdded(final ILaunch[] launches) { if (Activator.getPrefStore().contains(Prefs.PROP_ADD_JAVAAGENT) && !Activator.getPrefStore().getBoolean(Prefs.PROP_ADD_JAVAAGENT)) { return; } for (ILaunch launch : launches) { ILaunchConfiguration conf = launch.getLaunchConfiguration(); try { String pluginId = conf.getType().getPluginIdentifier(); if (JUnitCorePlugin.getPluginId().equals(pluginId)) { if (addJavaAgentVmArg(conf)) { modifiedLaunches.add(launch); } } } catch (CoreException e) { Activator.log(e); } } } public void setRunConfVmArgs(final ILaunchConfiguration conf, final String vmargs) throws CoreException { ILaunchConfigurationWorkingCopy confWc = conf.getWorkingCopy(); confWc.setAttribute(JunitLaunchListener.VM_ARGS, vmargs); confWc.doSave(); } public void setOrCreateVariable(final String value) throws CoreException { IStringVariableManager varMan = VariablesPlugin.getDefault().getStringVariableManager(); IValueVariable var = varMan.getValueVariable(JunitLaunchListener.JMOCKIT_VAR_NAME); if (var == null) { var = varMan.newValueVariable(JunitLaunchListener.JMOCKIT_VAR_NAME, value, false, value); varMan.addVariables(new IValueVariable[]{var}); } else { var.setValue(value); var.setDescription(value); } } public void removeJavaAgentVmArg(final ILaunchConfiguration conf) throws CoreException { String vmargs = conf.getAttribute(JunitLaunchListener.VM_ARGS, ""); if (vmargs.endsWith(JunitLaunchListener.JMOCKIT_VAR)) { vmargs = vmargs.substring(0, vmargs.length() - JunitLaunchListener.JMOCKIT_VAR.length() - 1); setRunConfVmArgs(conf, vmargs); } } public boolean addJavaAgentVmArg(final ILaunchConfiguration conf) throws CoreException { boolean added = false; String vmargs = conf.getAttribute(JunitLaunchListener.VM_ARGS, ""); String project = conf.getAttribute(JunitLaunchListener.PROJ_ATTR, ""); IJavaModel javaModel = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); IJavaProject jproj = javaModel.getJavaProject(project); IType mockitType = jproj.findType(MockUtil.MOCK); if (mockitType == null) { mockitType = jproj.findType(MockUtil.MOCKIT); } if (mockitType != null) { IPackageFragmentRoot root = (IPackageFragmentRoot) mockitType .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (root != null && root.isArchive()) // its a jar { String jarPath = root.getPath().toOSString(); if (root.getResource() != null) { jarPath = root.getResource().getRawLocation().toString(); } if (new File(jarPath).exists()) { String javaagentArg = "-javaagent:\"" + jarPath + "\""; setOrCreateVariable(javaagentArg); if (!vmargs.contains(JunitLaunchListener.JMOCKIT_VAR) && !vmargs.contains("-javaagent")) { setRunConfVmArgs(conf, vmargs + " " + JunitLaunchListener.JMOCKIT_VAR); added = true; } } else { Activator.log(new FileNotFoundException(jarPath)); } } } return added; } }