Package org.testng.eclipse.util

Source Code of org.testng.eclipse.util.LaunchUtil

package org.testng.eclipse.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.search.internal.ui.text.FileSearchQuery;
import org.eclipse.search.internal.ui.text.FileSearchResult;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.text.FileTextSearchScope;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.testng.eclipse.TestNGPlugin;
import org.testng.eclipse.TestNGPluginConstants;
import org.testng.eclipse.launch.TestNGLaunchConfigurationConstants;
import org.testng.eclipse.launch.TestNGLaunchConfigurationConstants.LaunchType;
import org.testng.eclipse.ui.RunInfo;
import org.testng.eclipse.ui.util.ConfigurationHelper;
import org.testng.eclipse.util.JDTUtil.MethodDefinition;
import org.testng.eclipse.util.param.ParameterSolver;
import org.testng.reporters.FailedReporter;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

/**
* An utility class that centralize the work about configuration launchers.
*
* <p/>
* <b>Implementation notes</b>:
* <ul>
* <li>
* <i>Strategy for existing launch configurations</i>: when an existing launch
* configuration already exists, its attributes are used to initialize the new
* launch configuration and then these are overwritten with the new attributes</li>
* <li>
* <i>Dependency resolving</i>:
* <ul>
* <li><b>dependsOnMethods</b>: needed only by method-based launch type</li>
* <li><b>dependsOnGroups</b>: needed by all non-suite launch types. For the
* moment a warning is displayed</li>
* <li><b>static data provider</b>: this dependency is solved by TestNG core</li>
* </ul>
* </li>
* </ul>
*
* @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
*/
public class LaunchUtil {
  private static final List<String> EMPTY_ARRAY_PARAM = Lists.newArrayList();
 
  /**
   * Suite file launcher. The file may reside outside the workbench.
   */
  public static void launchFailedSuiteConfiguration(IJavaProject javaProject,
      String runMode) {
    launchFailedSuiteConfiguration(javaProject, runMode, null, null);
  }
 

  /**
   * Suite file launcher. The file may reside outside the workbench.
   */
  public static void launchFailedSuiteConfiguration(IJavaProject javaProject,
      String runMode, ILaunchConfiguration prevConfig, Set failureDescriptions) {
    final String suiteConfName= javaProject.getElementName() + "-" + FailedReporter.TESTNG_FAILED_XML;
    final String suiteFilePath= TestNGPlugin.getPluginPreferenceStore().getOutputAbsolutePath(javaProject).toOSString() + "/" + FailedReporter.TESTNG_FAILED_XML;
   
    launchSuiteConfiguration(javaProject.getProject(),
        suiteConfName,
        suiteFilePath,
        runMode, prevConfig, failureDescriptions);
  }
 
  /**
   * Suite file launcher. The <code>IFile</code> must exist in the workbench.
   */
  public static void launchSuiteConfiguration(IFile suiteFile, String mode) {
    launchSuiteConfiguration(suiteFile, mode, null, null);
  }
 
  /**
   * Suite file launcher. The <code>IFile</code> must exist in the workbench.
   */
  public static void launchSuiteConfiguration(IFile suiteFile, String mode,
      ILaunchConfiguration prevConfig, Set failureDescriptions) {
    final IProject project= suiteFile.getProject();
    final String fileConfName= suiteFile.getProjectRelativePath().toString().replace('/', '.');
    final String suitePath= suiteFile.getLocation().toOSString();

    launchSuiteConfiguration(project, fileConfName, suitePath, mode, prevConfig, failureDescriptions);
  }
 
   
  private static void launchSuiteConfiguration(IProject project, String fileConfName,
      String suiteFilePath,
      String mode, ILaunchConfiguration prevConfig, Set failureDescriptions) {
    ILaunchConfigurationWorkingCopy configWC =
        createLaunchConfiguration(project, fileConfName, null);
    try {
      if (prevConfig != null) {
        Map<?, ?> previousEnv
            = prevConfig.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<?, ?>) null);
        configWC.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, previousEnv);
      }
    } catch (CoreException e) {
      e.printStackTrace();
    }

    configWC.setAttribute(TestNGLaunchConfigurationConstants.SUITE_TEST_LIST,
                          Collections.singletonList(suiteFilePath));
    configWC.setAttribute(TestNGLaunchConfigurationConstants.TYPE, LaunchType.SUITE.ordinal());


    // carry over jvm args from prevConfig
    // set failed test jvm args
    String jargs = ConfigurationHelper.getJvmArgs(prevConfig);
    if (jargs != null) ConfigurationHelper.setJvmArgs(configWC, jargs);
    if (failureDescriptions != null && failureDescriptions.size() > 0) {
      Iterator it = failureDescriptions.iterator();
      StringBuffer buf = new StringBuffer();
      boolean first = true;
      while (it.hasNext()) {
        if (first) first = false;
        else buf.append(",");
        buf.append (it.next());
      }
      setFailedTestsJvmArg(buf.toString(), configWC);
    }
    runConfig(configWC, mode);
  }
 
  public static void launchMapConfiguration(IProject project,
                                            String configName,
                                            Map<String, Map> launchAttributes,
                                            ICompilationUnit compilationUnit,
                                            String launchMode) {
    ILaunchConfigurationWorkingCopy workingCopy= createLaunchConfiguration(project, configName, null);

    try {
      launchAttributes.putAll(workingCopy.getAttributes());
    }
    catch(CoreException ce) {
      TestNGPlugin.log(ce);
    }

    if(null != compilationUnit) {
      Map params= solveParameters(compilationUnit);
      launchAttributes.put(TestNGLaunchConfigurationConstants.PARAMS, params);
    }

    workingCopy.setAttributes(launchAttributes);

    runConfig(workingCopy, launchMode);
  }

  /**
   * Creates a Map containing the basic properties of a new launch configuration,
   * based on types.
   */
  public static Map<String, Object> createClassLaunchConfigurationMap(IType mainType, IType[] types, String annotationType) {
    Map<String, Object> attrs= new HashMap<String, Object>();

    List<String> classNames= Lists.newArrayList();
    Multimap<String, String> classMethods = ArrayListMultimap.create();
    classMethods.get(null);

    for (IType type : types) {
      classNames.add(type.getFullyQualifiedName());
//      classMethods.put(types[i].getFullyQualifiedName(), EMPTY_ARRAY_PARAM);
    }

    attrs.put(TestNGLaunchConfigurationConstants.TYPE, LaunchType.CLASS.ordinal());
    attrs.put(TestNGLaunchConfigurationConstants.CLASS_TEST_LIST, classNames);
//    attrs.put(TestNGLaunchConfigurationConstants.TESTNG_COMPLIANCE_LEVEL_ATTR, annotationType);
    attrs.put(TestNGLaunchConfigurationConstants.ALL_METHODS_LIST,
        ConfigurationHelper.toClassMethodsMap(classMethods.asMap()));

    return attrs;
  }
 
  public static void launchPackageConfiguration(IJavaProject ijp, IPackageFragment ipf, String mode) {
    List<String> packageNames= new ArrayList<String>();
    packageNames.add(ipf.getElementName());

    try {
      if (findGroupDependencies(ipf.getCompilationUnits()).length > 0) {
        groupDependencyWarning("package " + ipf.getElementName(), null);
      }
    }
    catch(JavaModelException jmex) {
      ; // this should never happen but who knows
    }
   
    ILaunchConfigurationWorkingCopy workingCopy= createLaunchConfiguration(ijp.getProject(), "package " + ipf.getElementName(), null);

    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.CLASS_TEST_LIST,
                             EMPTY_ARRAY_PARAM);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.METHOD_TEST_LIST,
                             EMPTY_ARRAY_PARAM);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PACKAGE_TEST_LIST,
                             packageNames);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.TYPE,
        LaunchType.PACKAGE.ordinal());
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.ALL_METHODS_LIST,
        ConfigurationHelper.toClassMethodsMap(new HashMap<String, Collection<String>>()));
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PARAMS,
                             solveParameters(ipf));

    String projectName= ijp.getProject().getName();
   
    PreferenceStoreUtil storage = TestNGPlugin.getPluginPreferenceStore();
    String preDefinedListeners = storage.getPreDefinedListeners(projectName, false);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PRE_DEFINED_LISTENERS, preDefinedListeners.toString().trim());

    runConfig(workingCopy, mode);
  }
 
  public static void launchMethodConfiguration(IJavaProject javaProject,
          IMethod imethod,
          String runMode) {
    launchMethodConfiguration(javaProject, imethod, runMode, null);
  }

  private static boolean methodHasDependencies(IMethod method) throws JavaModelException {
    IAnnotation annotation = method.getAnnotation("Test");
    return annotation != null &&
        (contains(annotation.getMemberValuePairs(), "dependsOnGroups")
         || contains(annotation.getMemberValuePairs(), "dependsOnMethods"));
  }

  private static boolean contains(IMemberValuePair[] memberValuePairs, String string) {
    for (IMemberValuePair pair : memberValuePairs) {
      if (string.equals(pair.getMemberName())) {
        return true;
      }
    }

    return false;
  }

  public static void launchMethodConfiguration(IJavaProject javaProject,
          IMethod iMethod,
          String runMode,
          RunInfo runInfo) {

    Set<IMethod> methods = Sets.newHashSet(iMethod);

    try {
      if (methodHasDependencies(iMethod)) {
        DependencyInfo groupInfo = DependencyInfo.createDependencyInfo(javaProject);
        methods.addAll(findMethodTransitiveClosure(iMethod, groupInfo));
      }
    } catch (JavaModelException e) {
      TestNGPlugin.log(e);
    }

    launchMethodBasedConfiguration(javaProject, methods.toArray(new IMethod[methods.size()]),
        runMode, runInfo);
  }
  /**
   * @param elementName
   * @param groups
   */
  private static void groupDependencyWarning(String elementName, Set<String> groups) {
    ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
        "WARNING",
        elementName + " defines group dependencies that will be ignored. To reliably test methods with group dependencies use a suite definition.",
        new Status(IStatus.WARNING, TestNGPlugin.PLUGIN_ID, 3333,
            elementName + " uses group dependencies " + (groups != null ? groups.toString() : "")
            + " which due to a plugin limitation will be ignored", null));

  }


  private static void launchMethodBasedConfiguration(IJavaProject ijp,
      IMethod[] methods, String runMode, RunInfo runInfo) {
    List<String> methodNames = Lists.newArrayList();
    Multimap<String, String> classMethods = ArrayListMultimap.create();
    for (IMethod method : methods) {
      methodNames.add(method.getElementName());
      classMethods.put(method.getDeclaringType().getFullyQualifiedName(),
          method.getElementName());
    }

    final Set<IType> typesSet= new HashSet<IType>();
    for (IMethod method : methods) {
      typesSet.add(method.getDeclaringType());
    }
    final IType[] types= typesSet.toArray(new IType[typesSet.size()]);

    List<String> typeNames = new ArrayList<String>();
    for (IType type : types) {
      typeNames.add(type.getFullyQualifiedName());
    }
    String name = types[0].getTypeQualifiedName().toString() + "." + methodNames.get(0).toString();
//    final String complianceLevel= annotationType != null ? annotationType : getQuickComplianceLevel(types);

    ILaunchConfigurationWorkingCopy workingCopy= createLaunchConfiguration(ijp.getProject(), name, runInfo);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.CLASS_TEST_LIST,
                             typeNames);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.METHOD_TEST_LIST,
                             methodNames);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PACKAGE_TEST_LIST,
                             EMPTY_ARRAY_PARAM);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.TYPE,
        LaunchType.METHOD.ordinal());
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.ALL_METHODS_LIST,
                             ConfigurationHelper.toClassMethodsMap(classMethods.asMap()));
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PARAMS,
                             solveParameters(methods));
//    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.TESTNG_COMPLIANCE_LEVEL_ATTR,
//                             complianceLevel);
    String projectName= ijp.getProject().getName();
   
    PreferenceStoreUtil storage = TestNGPlugin.getPluginPreferenceStore();
    String preDefinedListeners = storage.getPreDefinedListeners(projectName, false);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PRE_DEFINED_LISTENERS, preDefinedListeners.toString().trim());

    if (runInfo != null) {
      // set the class and method
     
      // set any jvm args
      String jargs = runInfo.getJvmArgs();
      if (jargs != null) workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
          jargs);
      Map envVars = runInfo.getEnvironmentVariables();
      if (envVars != null)
        workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
            envVars);
      setFailedTestsJvmArg(runInfo.getTestDescription(), workingCopy);
    }
    runConfig(workingCopy, runMode);
  }
 
  /**
   * Launch a type-based test.
   */
  public static void launchTypeConfiguration(IJavaProject ijp, IType type, String mode) {
    launchTypeBasedConfiguration(ijp, type.getElementName(), new IType[] {type}, mode);
  }

  /**
   * Launch a compilation unit (a source file) based test.
   */
  public static void launchCompilationUnitConfiguration(IJavaProject ijp,
      List<ICompilationUnit> units, String mode) {
    List<IType> types = Lists.newArrayList();
    IType mainType = null;
    for (ICompilationUnit icu : units) {
      try {
        for (IType type : icu.getTypes()) {
          types.add(type);
        }
      }
      catch(JavaModelException jme) {
        TestNGPlugin.log(new Status(IStatus.ERROR, TestNGPlugin.PLUGIN_ID, TestNGPluginConstants.LAUNCH_ERROR, "No types in compilation unit " + icu.getElementName(), jme));
      }

      if(null == types) return;

      mainType = icu.findPrimaryType();
    }

    launchTypeBasedConfiguration(ijp, createConfName(mainType, units.size()),
        types.toArray(new IType[types.size()]), mode);
  }

  /**
   * @return the name of this configuration, which will be displayed in the menu. For
   * one type, it's the name of this type. For more than one type, just show the name
   * of the first type followed by ellipses.
   */
  private static String createConfName(IType mainType, int unitCount) {
    String result = mainType.getElementName();
    if (unitCount > 1) result = result + ", ...";

    return result;
  }

  public static void launchTypesConfiguration(IJavaProject project, List<IType> types, String mode)
  {
    launchTypeBasedConfiguration(project, createConfName(types.get(0), types.size()),
        types.toArray(new IType[types.size()]), mode);
  }

  public static boolean useStringProtocol(ILaunchConfiguration configuration) {
    String jvmArgs = ConfigurationHelper.getJvmArgs(configuration);
     return jvmArgs.indexOf("-Dtestng.eclipse.stringprotocol") >= 0;
  }

  private static void launchTypeBasedConfiguration(IJavaProject javaProject, String confName,
      IType[] types, String mode) {
   
    Multimap<String, String> classMethods = ArrayListMultimap.create();
    List<String> typeNames = Lists.newArrayList();
    Set<IType> allTypes = Sets.newHashSet();
    allTypes.addAll(Arrays.asList(types));

    Set<IMethod> allMethods = Sets.newHashSet();

    // If we depend on groups, need to add all the necessary types
    Object[] groupDependencies = findGroupDependencies(types);
    if (groupDependencies.length > 0) {
      DependencyInfo groupInfo = DependencyInfo.createDependencyInfo(javaProject);
      Set<IType> closure = findTypeTransitiveClosure(types, groupInfo);
      allTypes.addAll(closure);
      Set<IMethod> methods = findMethodTransitiveClosure(types, groupInfo);
      allMethods.addAll(methods);
    }

    for (IType type : allTypes) {
      typeNames.add(type.getFullyQualifiedName());
    }

    List<String> methodNames = Lists.newArrayList();
    for (IMethod m : allMethods) {
      methodNames.add(m.getElementName());
      classMethods.put(m.getDeclaringType().getFullyQualifiedName(), m.getElementName());
    }

    ILaunchConfigurationWorkingCopy workingCopy =
        createLaunchConfiguration(javaProject.getProject(), confName, null);

    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.TYPE,
        LaunchType.CLASS.ordinal());
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.ALL_METHODS_LIST,
                             ConfigurationHelper.toClassMethodsMap(classMethods.asMap()));
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.CLASS_TEST_LIST,
                             typeNames);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PARAMS,
                             solveParameters(allTypes.toArray(new IType[allTypes.size()])));
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.METHOD_TEST_LIST,
        methodNames);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PACKAGE_TEST_LIST,
                             EMPTY_ARRAY_PARAM);
   
    String projectName= javaProject.getProject().getName();
   
    PreferenceStoreUtil storage = TestNGPlugin.getPluginPreferenceStore();
    String preDefinedListeners = storage.getPreDefinedListeners(projectName, false);
    workingCopy.setAttribute(TestNGLaunchConfigurationConstants.PRE_DEFINED_LISTENERS, preDefinedListeners.toString().trim());


    runConfig(workingCopy, mode);
  }

  public static Set<IMethod> findMethodTransitiveClosure(IType[] types, DependencyInfo groupInfo) {
    Set<IMethod> result = Sets.newHashSet();
    for (IType type : types) {
      result.addAll(findMethodTransitiveClosure(type, groupInfo));
    }

    return result;
  }

  public static Set<IMethod> findMethodTransitiveClosure(IType type, DependencyInfo groupInfo) {
    Set<IMethod> result = Sets.newHashSet();
    try {
      for (IMethod method : type.getMethods()) {
        result.addAll(findMethodTransitiveClosure(method, groupInfo));
      }
    } catch(JavaModelException ex) {
      ex.printStackTrace();
    }

    return result;
  }

  public static Set<IMethod> findMethodTransitiveClosure(IMethod startMethod, DependencyInfo groupInfo) {
    Set<IMethod> result = Sets.newHashSet();
    Set<IMethod> currentMethods = Sets.newHashSet();
    currentMethods.add(startMethod);
    Set<IMethod> nextMethods = Sets.newHashSet();
    Set<String> initialGroups = Sets.newHashSet();

    while (! currentMethods.isEmpty()) {
      for (IMethod method : currentMethods) {
        result.add(method);

        Collection<String> groups = groupInfo.groupDependenciesByMethods.get(method);
        if (groups != null) {
          if (initialGroups.isEmpty()) initialGroups.addAll(groups);
          for (String group : groups) {
            Collection<IMethod> depMethods = groupInfo.methodsByGroups.get(group);
            if (depMethods != null) {
              for (IMethod depMethod : depMethods) {
                if (! result.contains(depMethod)) {
                  result.add(depMethod);
                  nextMethods.add(depMethod);
                }
              }
            } else {
              System.out.println("Can't find any method defining the group " + group);
            }
          }
        } else {
          System.out.println("No groups depended upon by method: " + method.getElementName());
        }

        Collection<IMethod> depMethods = groupInfo.methodsByMethods.get(method);
        if (depMethods != null) {
          for (IMethod dm : depMethods) {
            if (! result.contains(dm)) {
              result.add(dm);
              nextMethods.add(dm);
            }
          }
        }
      }

      currentMethods.clear();
      currentMethods.addAll(nextMethods);
      nextMethods.clear();
    }

    StringBuilder sb = new StringBuilder();
    for (IMethod m : result) {
      sb.append(m.getDeclaringType().getFullyQualifiedName())
          .append(".").append(m.getElementName()).append(" ");
    }
    TestNGPlugin.log("Transitive closure for method " + startMethod.getElementName()
        + ": "  + sb.toString());

    return result;
  }

  private static Set<IType> findTypeTransitiveClosure(IType[] types, DependencyInfo groupInfo) {
    Set<IType> result = Sets.newHashSet();
    Set<IType> currentTypes = Sets.newHashSet();
    currentTypes.addAll(Arrays.asList(types));
    Set<IType> nextTypes = Sets.newHashSet();
    Set<String> initialGroups = Sets.newHashSet();

    while (! currentTypes.isEmpty()) {
      for (IType type : currentTypes) {
        result.add(type);

        Collection<String> groups = groupInfo.groupDependenciesByTypes.get(type);
        if (groups != null) {
          if (initialGroups.isEmpty()) initialGroups.addAll(groups);
          for (String group : groups) {
            Collection<IType> depTypes = groupInfo.typesByGroups.get(group);
            if (depTypes != null) {
              for (IType depType : depTypes) {
                if (! result.contains(depType)) {
                  result.add(depType);
                  nextTypes.add(depType);
                }
              }
            } else {
              System.out.println("Can't find any types defining the group " + group);
            }
          }
        } else {
          System.out.println("No groups depended upon by type: " + type.getElementName());
        }
      }

      currentTypes.clear();
      currentTypes.addAll(nextTypes);
      nextTypes.clear();
    }

    StringBuilder sb = new StringBuilder();
    for (IType type : result) {
      sb.append(type.getFullyQualifiedName()).append(" ");
    }
    TestNGPlugin.log("Transitive closure for groups \"" + initialGroups + "\":"  + sb.toString());

    return result;
  }

  private static Object[] findGroupDependencies(ICompilationUnit[] units) {
    List<IResource> resources = Lists.newArrayList();
    for (ICompilationUnit unit : units) {
      try {
        resources.add(unit.getCorrespondingResource());
      }
      catch(JavaModelException jmex) {
        ;
      }
    }
    IResource[] scopeResources= resources.toArray(new IResource[resources.size()]);
    ISearchQuery query= new FileSearchQuery("@Test\\(.*\\s*dependsOnGroups\\s*=.*",
        true /*regexp*/ ,
        true /*casesensitive*/,
        FileTextSearchScope.newSearchScope(scopeResources, new String[] {"*.java"}, false));
    query.run(new NullProgressMonitor());
    FileSearchResult result= (FileSearchResult) query.getSearchResult();
    Object[] elements = result.getElements();
   
    return elements;
  }
 
  private static Object[] findGroupDependencies(IType[] types) {
    ICompilationUnit[] units= new ICompilationUnit[types.length];
    for(int i= 0; i < types.length; i++) {
      units[i]= types[i].getCompilationUnit();
    }
   
    return findGroupDependencies(units);
  }
 
  /**
   * Initialize a <code>ILaunchConfigurationWorkingCopy</code> either by using an existing one (if found),
   * or using a default configuration (for example, the one used for the most recent launch),
   * or by creating a new one based on the <code>project</code> name and the <code>confName</code>.
   *
   * @throws CoreException if getting an working copy from an existing configuration fails
   */
  private static ILaunchConfigurationWorkingCopy createLaunchConfiguration(IProject project, String confName,
      RunInfo runInfo ) {
    ILaunchManager launchManager= getLaunchManager();
    ILaunchConfiguration config= ConfigurationHelper.findConfiguration(launchManager, project, confName, runInfo);

    ILaunchConfigurationWorkingCopy configWC= null;
    if(null != config) {
      try {
        configWC= config.getWorkingCopy();
      }
      catch(CoreException cex) {
        TestNGPlugin.log(new Status(IStatus.ERROR, TestNGPlugin.PLUGIN_ID, TestNGPluginConstants.LAUNCH_ERROR,
            "Cannot create working copy of existing launcher " + config.getName(), cex));
      }
    }
    if(null == configWC) {
      if (confName == null && runInfo != null) {
        confName = runInfo.getClassName() + "." + runInfo.getMethodName();       
      }
      configWC= ConfigurationHelper.createBasicConfiguration(launchManager, project, confName);
    }

    return configWC;
  }

  private static void runConfig(ILaunchConfigurationWorkingCopy launchConfiguration, String runMode) {
    ILaunchConfiguration conf= save(launchConfiguration);
    if(null != conf) {
//      try {
//        Map attrs= conf.getAttributes();
//        System.out.println("Launch attrs:" + attrs);
//      }
//      catch(CoreException cex) { ; }
     
      DebugUITools.launch(conf, runMode);
    }
  }

  /**
   * Saves the working copy (may return <tt>null</tt> if the <code>launchWorkingCopy</code> is
   * <tt>null</tt> or the save fails).
   */
  private static ILaunchConfiguration save(ILaunchConfigurationWorkingCopy launchWorkingCopy) {
    if(null == launchWorkingCopy) return null;
   
    try {
      return launchWorkingCopy.doSave();
    }
    catch(CoreException cex) {
      TestNGPlugin.log(cex);
    }
   
    return null;
  }

  private static List<MethodDefinition> solveDependsOn(IMethod imethod) {
    return JDTUtil.solveDependencies(imethod);
  }

  private static ILaunchManager getLaunchManager() {
    return DebugPlugin.getDefault().getLaunchManager();
  }

  /**
   * Wrapper method over <code>ParameterSolver.solveParameters</code> that never
   * returns <tt>null</tt>s.
   */
  private static Map solveParameters(IJavaElement[] javaElements) {
    Map result= ParameterSolver.solveParameters(javaElements);
   
    return result != null ? result : new HashMap();
  }
 
  /**
   * Wrapper method over <code>ParameterSolver.solveParameters</code> that never
   * returns <tt>null</tt>s.
   */
  private static Map solveParameters(IJavaElement javaElement) {
    return solveParameters(new IJavaElement[] {javaElement});
  }
 
  /**
   * Uses the Eclipse search support to look for @Test annotation and decide
   * if the compliance level should be set to JDK or JAVADOC.
   */
//  private static String getQuickComplianceLevel(IType[] types) {
//    List resources= new ArrayList();
//    for(int i= 0; i < types.length; i++) {
//      try {
//        resources.add(types[i].getCompilationUnit().getCorrespondingResource());
//      }
//      catch(JavaModelException jmex) {
//        ;
//      }
//    }
//    IResource[] scopeResources= (IResource[]) resources.toArray(new IResource[resources.size()]);
//    ISearchQuery query= new FileSearchQuery("@(Test|Before|After|Factory)(\\(.+)?",
//        true /*regexp*/ ,
//        true /*casesensitive*/,
//        FileTextSearchScope.newSearchScope(scopeResources, getJavaLikeExtensions(), false));
//    query.run(new NullProgressMonitor());
//    FileSearchResult result= (FileSearchResult) query.getSearchResult();
//    Object[] elements= result.getElements();
//   
//    return elements != null && elements.length > 0 ? TestNG.JDK_ANNOTATION_TYPE : TestNG.JAVADOC_ANNOTATION_TYPE;
//  }
 
  private static String[] getJavaLikeExtensions() {
    char[][] exts = Util.getJavaLikeExtensions();
    if (exts != null && exts.length > 0) {
      String[] extStrs = new String[exts.length];
      for (int i = 0; i < exts.length; i++) {
        extStrs[i] = "*." + String.valueOf(exts[i]);
      }
      return extStrs;
    } else {
      return new String[] {"*.java"};
    }
  }

  public static ILaunchConfigurationWorkingCopy setFailedTestsJvmArg (String value,
      ILaunchConfigurationWorkingCopy config) {
    try {
      String key = TestNGPlugin.getFailedTestsKey();
      String jvmargs = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "");     
      String newarg = key + "=\"" + value + "\" ";
      if (!key.startsWith("-D")) newarg = "-D" + newarg;
      // if there is no value, then remove this jvm arg if there is one.
      if (value == "") newarg = " ";
      else newarg = " " + newarg;
      if (jvmargs.equals("")) {
        // simplest case: set the attribute
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, newarg);
      }
      else if (jvmargs.indexOf(key) == -1) {
        // nothing to replace; just add
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, jvmargs + newarg);
      }
      else {
        // find the new arg in the existing jvm args and replace it
        int start = jvmargs.indexOf(key);
        int next = jvmargs.indexOf("-D", start + 1);
        StringBuffer buf = new StringBuffer();
        buf.append(newarg)
        .append (jvmargs.substring(0,start));
        if (next > start) {
          buf.append(jvmargs.substring(next));
        }
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, buf.toString());
      }
    }
    catch (CoreException ce) {}
    return config;
  }
 
  /**
   * Create a working copy from the launcher arg, and set a jvm arg with the supplied
   * key and value.
   * @param key
   * @param value
   * @param config
   * @return
   */
  public static ILaunchConfigurationWorkingCopy addJvmArg (String key, String value,
      ILaunchConfigurationWorkingCopy config) {   
    try {
      String jvmargs = config.getAttribute(
          IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "");     
      String newarg = key + "=\"" + value + "\" ";
      if (!key.startsWith("-D")) newarg = "-D" + newarg;
      // if there is no value, then remove this jvm arg if there is one.
      if (value == "") newarg = " ";
      else newarg = " " + newarg;
      if (jvmargs.equals("")) {
        // simplest case: set the attribute     
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, newarg);
      }
      else if (jvmargs.indexOf(key) == -1) {
        // nothing to replace; just add
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, jvmargs + newarg);
      }
      else {
        // find the new arg in the existing jvm args and replace it
        int start = jvmargs.indexOf(key);
        int next = jvmargs.indexOf("-D", start + 1);
        StringBuffer buf = new StringBuffer();
        buf.append(newarg)
        .append (jvmargs.substring(0,start));
        if (next > start) {
          buf.append(jvmargs.substring(next));
        }
        config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, buf.toString());
      }
    }
    catch (CoreException ce) {}
    return config;
  }

  public static void errorDialog(String string, Throwable ex) {
    ErrorDialog.openError(Display.getCurrent().getActiveShell(),
        "Fatal error",
        string + (ex.getMessage() != null ? ": " + ex.getMessage() : ""),
        new Status(IStatus.ERROR, TestNGPlugin.PLUGIN_ID, 0,
            "Status Error Message", null));
    TestNGPlugin.log(ex);
  }

}
TOP

Related Classes of org.testng.eclipse.util.LaunchUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.