1336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpackage org.testng.internal;
2336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
3336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.BufferedReader;
4336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.BufferedWriter;
5336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.File;
61e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beustimport java.io.FileInputStream;
7336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.FileOutputStream;
82cb45c217aba17e967d19bb7257b067740033c5cCédric Beustimport java.io.FileWriter;
9336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.IOException;
10336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.InputStream;
111e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beustimport java.io.OutputStream;
12975d9acab06f8de7ef2791ebe784c6d1c6b4e6d9the.mindstormimport java.io.OutputStreamWriter;
13336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.PrintWriter;
14336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.StringReader;
15336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.io.StringWriter;
16336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.lang.reflect.Method;
174438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beustimport java.lang.reflect.Modifier;
1858a8328782dfbef76ae29c2143a0f38675cdfa7eCédric Beustimport java.util.Arrays;
19d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beustimport java.util.HashMap;
20336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.List;
21336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.Map;
22336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.StringTokenizer;
23336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.logging.FileHandler;
24336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.logging.Level;
25336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.logging.Logger;
26682629c7059fca8adc2cc2eacdb2d372d7a28c3dCédric Beust
2783d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.ITestNGMethod;
2883d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.TestNG;
2983d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.TestNGException;
3083d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.TestRunner;
3183d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.annotations.IConfigurationAnnotation;
3283d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.annotations.ITestAnnotation;
3383d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.collections.Lists;
3483d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.internal.annotations.AnnotationHelper;
3583d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.internal.annotations.IAnnotationFinder;
3683d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.log.TextFormatter;
37378db4c4f6664850617776c62439807f0bf4724dCédric Beustimport org.testng.reporters.XMLStringBuffer;
3883d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beustimport org.testng.xml.XmlClass;
3983d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust
40336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust/**
41336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * Helper methods to parse annotations.
42336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust *
43336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * @author Cedric Beust, Apr 26, 2004
44336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust */
45336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpublic final class Utils {
46336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private static final String LINE_SEP = System.getProperty("line.separator");
477ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust
487ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust  public static final char[] SPECIAL_CHARACTERS =
497ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust      {'*','/','\\','?','%',':',';','<','>','&','~','|'};
507ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust  public static final char CHAR_REPLACEMENT = '_';
519a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak  public static final char UNICODE_REPLACEMENT = 0xFFFD;
520f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
53336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
54336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * Hide constructor for utility class.
55336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
56336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private Utils() {
57336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Hide constructor
58336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
590f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
60336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
61336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * Splits the given String s into tokens where the separator is
620f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   * either the space character or the comma character. For example,
63336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * if s is "a,b, c" this method returns {"a", "b", "c"}
640f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   *
65336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param s the string to split
660f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   * @return the split token
670f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   */
68336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] stringToArray(String s) {
69336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // TODO CQ would s.split() be a better way of doing this?
70336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    StringTokenizer st = new StringTokenizer(s, " ,");
71336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    String[] result = new String[st.countTokens()];
72336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    for (int i = 0; i < result.length; i++) {
73336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result[i] = st.nextToken();
74336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
75336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
76336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
77336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
78336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
79474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm  public static XmlClass[] classesToXmlClasses(Class<?>[] classes) {
8001e59f7bdf6515f065bd697832db53253ca78b1aCédric Beust    List<XmlClass> result = Lists.newArrayList();
81336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
82474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm    for (Class<?> cls : classes) {
83b3515ae0025dc9296d09b056b5df6fd7fe7821ebCédric Beust      result.add(new XmlClass(cls, true /* load classes */));
84336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
85336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
86336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result.toArray(new XmlClass[classes.length]);
87336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
88336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
89336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] parseMultiLine(String line) {
900a050892401fb27d1c7629e37fe9c8796ea5a349Cédric Beust    List<String> vResult = Lists.newArrayList();
913e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    if (isStringNotBlank(line)) {
92336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      StringTokenizer st = new StringTokenizer(line, " ");
93336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      while (st.hasMoreTokens()) {
94336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        vResult.add(st.nextToken());
95336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
96336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      // Bug in split when passed " " : returns one too many result
97336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      //      result = line.split(" ");
98336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
99336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
100b1c182d51b05a40ac5350e562503a94d024a7c80nullin    return vResult.toArray(new String[vResult.size()]);
101336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
102336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1034e7a944ad9e5f98158da8106ed16945293b120afVladimir Lyubitelev  public static void writeUtf8File(@Nullable String outputDir, String fileName, XMLStringBuffer xsb, String prefix) {
104378db4c4f6664850617776c62439807f0bf4724dCédric Beust    try {
105deac4cc59caa6837f646c42c6d6aeedfa263261fVladimir Lyubitelev      final File outDir = (outputDir != null) ? new File(outputDir) : new File("").getAbsoluteFile();
106deac4cc59caa6837f646c42c6d6aeedfa263261fVladimir Lyubitelev      if (!outDir.exists()) {
107deac4cc59caa6837f646c42c6d6aeedfa263261fVladimir Lyubitelev        outDir.mkdirs();
108deac4cc59caa6837f646c42c6d6aeedfa263261fVladimir Lyubitelev      }
109d7fa06eba5704e56b6372756efbda34e1a428cfeVladimir Lyubitelev      final File file = new File(outDir, fileName);
110b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      if (!file.exists()) {
111b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin        file.createNewFile();
112f87827183fcb62a7fefa0098232415e0cbcbc1f5Ion Savin      }
113b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      final OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
114378db4c4f6664850617776c62439807f0bf4724dCédric Beust      if (prefix != null) {
115b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin        w.append(prefix);
116378db4c4f6664850617776c62439807f0bf4724dCédric Beust      }
117b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      xsb.toWriter(w);
118b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      w.close();
119378db4c4f6664850617776c62439807f0bf4724dCédric Beust    } catch(IOException ex) {
120378db4c4f6664850617776c62439807f0bf4724dCédric Beust      ex.printStackTrace();
121378db4c4f6664850617776c62439807f0bf4724dCédric Beust    }
122378db4c4f6664850617776c62439807f0bf4724dCédric Beust  }
123378db4c4f6664850617776c62439807f0bf4724dCédric Beust
124f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel  /**
1250f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   * Writes the content of the sb string to the file named filename in outDir encoding the output as UTF-8.
126975d9acab06f8de7ef2791ebe784c6d1c6b4e6d9the.mindstorm   * If outDir does not exist, it is created.
127f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   *
128975d9acab06f8de7ef2791ebe784c6d1c6b4e6d9the.mindstorm   * @param outputDir the output directory (may not exist). If <tt>null</tt> then current directory is used.
129f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   * @param fileName the filename
130f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   * @param sb the file content
131f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   */
132b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin  public static void writeUtf8File(@Nullable String outputDir, String fileName, String sb) {
133975d9acab06f8de7ef2791ebe784c6d1c6b4e6d9the.mindstorm    final String outDirPath= outputDir != null ? outputDir : "";
134975d9acab06f8de7ef2791ebe784c6d1c6b4e6d9the.mindstorm    final File outDir= new File(outDirPath);
135ef4d5686d0c38ae2511887e5746e3e90508ec8ecCédric Beust    writeFile(outDir, fileName, escapeUnicode(sb), "UTF-8", false /* don't append */);
136336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1370f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
138f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel  /**
1390f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   * Writes the content of the sb string to the file named filename in outDir. If
140f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   * outDir does not exist, it is created.
141f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   *
142df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog   * @param outputDir the output directory (may not exist). If <tt>null</tt> then current directory is used.
143f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   * @param fileName the filename
144f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   * @param sb the file content
145f0a15dd5b96f3d02be7cc50ad01bb2d0005f0c69cquezel   */
146b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin  public static void writeFile(@Nullable String outputDir, String fileName, String sb) {
1478b66d0ba217f4523a477903fb6e0198c84f6c574bileblog    final String outDirPath= outputDir != null ? outputDir : "";
1488b66d0ba217f4523a477903fb6e0198c84f6c574bileblog    final File outDir= new File(outDirPath);
149575b2838455776057d4f3b2e3eb0c8dbd25d6b9cCédric Beust    writeFile(outDir, fileName, sb, null, false /* don't append */);
15017c52218805e62a58f0a073b24f9b82386aa6c4anullin  }
1510f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
15217c52218805e62a58f0a073b24f9b82386aa6c4anullin  /**
1530f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   * Writes the content of the sb string to the file named filename in outDir. If
1548b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   * outDir does not exist, it is created.
1558b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   *
1568b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   * @param outDir the output directory (may not exist). If <tt>null</tt> then current directory is used.
1578b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   * @param fileName the filename
1588b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   * @param sb the file content
1598b66d0ba217f4523a477903fb6e0198c84f6c574bileblog   */
160b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin  private static void writeFile(@Nullable File outDir, String fileName, String sb, @Nullable String encoding, boolean append) {
161336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
162b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      if (outDir == null) {
163b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin        outDir = new File("").getAbsoluteFile();
164b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin      }
165336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (!outDir.exists()) {
166336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        outDir.mkdirs();
167336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
1680f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1697ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust      fileName = replaceSpecialCharacters(fileName);
170336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      File outputFile = new File(outDir, fileName);
17117c52218805e62a58f0a073b24f9b82386aa6c4anullin      if (!append) {
17217c52218805e62a58f0a073b24f9b82386aa6c4anullin        outputFile.delete();
17317c52218805e62a58f0a073b24f9b82386aa6c4anullin        outputFile.createNewFile();
17417c52218805e62a58f0a073b24f9b82386aa6c4anullin      }
17517c52218805e62a58f0a073b24f9b82386aa6c4anullin      writeFile(outputFile, sb, encoding, append);
176336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
177336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    catch (IOException e) {
178336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (TestRunner.getVerbose() > 1) {
179336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        e.printStackTrace();
180336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
181336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      else {
182336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        log("[Utils]", 1, e.getMessage());
183336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
184336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
185336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
186336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
187b1c39ae22168010e766a35496aaf9620784d6587Vladislav Rassokhin  private static void writeFile(File outputFile, String sb, @Nullable String encoding, boolean append) {
188336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    BufferedWriter fw = null;
189336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
19048a120cdb35746583049eb9ab953e070f99f539aUli Schlachter      fw = openWriter(outputFile, encoding, append);
191336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      fw.write(sb);
1920f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
193a6fd161c95fc8ad9c5ba22f85e9cb1387c9740cbthe.mindstorm      Utils.log("", 3, "Creating " + outputFile.getAbsolutePath());
194336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
195336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    catch(IOException ex) {
1968199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm      if (TestRunner.getVerbose() > 1) {
1978199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm        System.err.println("ERROR WHILE WRITING TO " + outputFile);
1988199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm        ex.printStackTrace();
1998199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm      }
2008199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm      else {
2018199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm        log("[Utils]", 1, "Error while writing to " + outputFile + ": " + ex.getMessage());
2028199621f3dd6adcbc12e93c4ea5508cf9f4f9055the.mindstorm      }
203336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
204336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    finally {
205336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      try {
206336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        if (fw != null) {
207336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          fw.close();
208336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
209336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
210336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      catch (IOException e) {
211336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        ; // ignore
212336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
213336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
214336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
215336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
21648a120cdb35746583049eb9ab953e070f99f539aUli Schlachter  /**
21748a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * Open a BufferedWriter for the specified file. If output directory doesn't
21848a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * exist, it is created. If the output file exists, it is deleted. The output file is
21948a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * created in any case.
22048a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * @param outputDir output directory. If <tt>null</tt>, then current directory is used
22148a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * @param fileName file name
22248a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   * @throws IOException if anything goes wrong while creating files.
22348a120cdb35746583049eb9ab953e070f99f539aUli Schlachter   */
22448a120cdb35746583049eb9ab953e070f99f539aUli Schlachter  public static BufferedWriter openWriter(@Nullable String outputDir, String fileName) throws IOException {
22548a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    String outDirPath= outputDir != null ? outputDir : "";
22648a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    File outDir= new File(outDirPath);
22748a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    if (outDir.exists()) {
22848a120cdb35746583049eb9ab953e070f99f539aUli Schlachter      outDir.mkdirs();
22948a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    }
23048a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    fileName = replaceSpecialCharacters(fileName);
23148a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    File outputFile = new File(outDir, fileName);
23248a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    outputFile.delete();
23348a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    return openWriter(outputFile, null, false);
23448a120cdb35746583049eb9ab953e070f99f539aUli Schlachter  }
23548a120cdb35746583049eb9ab953e070f99f539aUli Schlachter
23648a120cdb35746583049eb9ab953e070f99f539aUli Schlachter  private static BufferedWriter openWriter(File outputFile, @Nullable String encoding, boolean append) throws IOException {
23748a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    if (!outputFile.exists()) {
23848a120cdb35746583049eb9ab953e070f99f539aUli Schlachter      outputFile.createNewFile();
23948a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    }
24048a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    OutputStreamWriter osw= null;
24148a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    if (null != encoding) {
24248a120cdb35746583049eb9ab953e070f99f539aUli Schlachter      osw = new OutputStreamWriter(new FileOutputStream(outputFile, append), encoding);
24348a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    }
24448a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    else {
24548a120cdb35746583049eb9ab953e070f99f539aUli Schlachter      osw = new OutputStreamWriter(new FileOutputStream(outputFile, append));
24648a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    }
24748a120cdb35746583049eb9ab953e070f99f539aUli Schlachter    return new BufferedWriter(osw);
24848a120cdb35746583049eb9ab953e070f99f539aUli Schlachter  }
24948a120cdb35746583049eb9ab953e070f99f539aUli Schlachter
250336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private static void ppp(String s) {
251336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Utils.log("Utils", 0, s);
252336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
253336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
254336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
255336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param result
256336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
257474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm  public static void dumpMap(Map<?, ?> result) {
258336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    System.out.println("vvvvv");
2591963187da6a45f898e62e4e922faac6b9382b4e4nullin    for (Map.Entry<?, ?> entry : result.entrySet()) {
2601963187da6a45f898e62e4e922faac6b9382b4e4nullin      System.out.println(entry.getKey() + " => " + entry.getValue());
261336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
262336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    System.out.println("^^^^^");
263336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
264336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
265336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
266336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param allMethods
267336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
268336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void dumpMethods(List<ITestNGMethod> allMethods) {
269336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    ppp("======== METHODS:");
270336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    for (ITestNGMethod tm : allMethods) {
271336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      ppp("  " + tm);
272336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
273336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
274336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
275336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
276336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @return The list of dependent groups for this method, including the
277336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * class groups
278336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
279336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] dependentGroupsForThisMethodForTest(Method m, IAnnotationFinder finder) {
2800a050892401fb27d1c7629e37fe9c8796ea5a349Cédric Beust    List<String> vResult = Lists.newArrayList();
281474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm    Class<?> cls = m.getDeclaringClass();
282336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
283336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the class
2842d568355761a9632bf24a87984e241f8a079d724Cédric Beust    ITestAnnotation tc = AnnotationHelper.findTest(finder, cls);
285336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tc) {
286336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      for (String group : tc.getDependsOnGroups()) {
287336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        vResult.add(group);
288336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
289336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
290336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
291336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the method
2922d568355761a9632bf24a87984e241f8a079d724Cédric Beust    ITestAnnotation tm = AnnotationHelper.findTest(finder, m);
293336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tm) {
294336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      String[] groups = tm.getDependsOnGroups();
295336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
296336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      //       ppp("Method:" + m + " #Groups:" + groups.length);
297336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      for (String group : groups) {
298336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        vResult.add(group);
299336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
300336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
301336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
302ebadb61b818627fe0e9de16896c2e3215bcb0328Cédric Beust    return vResult.toArray(new String[vResult.size()]);
303336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
304336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
305336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
306336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @return The list of groups this method belongs to, including the
307336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * class groups
308336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
309336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] groupsForThisMethodForTest(Method m, IAnnotationFinder finder) {
3100a050892401fb27d1c7629e37fe9c8796ea5a349Cédric Beust    List<String> vResult = Lists.newArrayList();
311474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm    Class<?> cls = m.getDeclaringClass();
312336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
313336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the class
3142d568355761a9632bf24a87984e241f8a079d724Cédric Beust    ITestAnnotation tc = AnnotationHelper.findTest(finder, cls);
315336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tc) {
316336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      for (String group : tc.getGroups()) {
317336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        vResult.add(group);
318336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
319336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
320336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
321336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the method
3222d568355761a9632bf24a87984e241f8a079d724Cédric Beust    ITestAnnotation tm = AnnotationHelper.findTest(finder, m);
323336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tm) {
324336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      String[] groups = tm.getGroups();
325336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
326336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      //       ppp("Method:" + m + " #Groups:" + groups.length);
327336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      for (String group : groups) {
328336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        vResult.add(group);
329336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
330336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
331336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
332ebadb61b818627fe0e9de16896c2e3215bcb0328Cédric Beust    return vResult.toArray(new String[vResult.size()]);
333336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
334336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
335336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
336336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @return The list of groups this method belongs to, including the
337336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * class groups
338336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
339336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] groupsForThisMethodForConfiguration(Method m, IAnnotationFinder finder) {
340336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    String[] result = {};
341336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
342336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the method
3432d568355761a9632bf24a87984e241f8a079d724Cédric Beust    ITestAnnotation tm = AnnotationHelper.findTest(finder, m);
344336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tm) {
345336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result = tm.getGroups();
346336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
347336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
348336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
349336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
350336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
351336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
352336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @return The list of groups this method depends on, including the
353336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * class groups
354336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
355336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] dependentGroupsForThisMethodForConfiguration(Method m,
356336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust                                                                      IAnnotationFinder finder) {
357336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    String[] result = {};
358336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
359336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect groups on the method
3602d568355761a9632bf24a87984e241f8a079d724Cédric Beust    IConfigurationAnnotation tm = AnnotationHelper.findConfiguration(finder, m);
361336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (null != tm) {
362336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result = tm.getDependsOnGroups();
363336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
364336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
365336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
366336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
3670f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
368336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void log(String msg) {
369336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    log("Utils", 2, msg);
370336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
371336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
372336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
373336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * Logs the the message to System.out if level is greater than
374336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * or equal to TestRunner.getVerbose(). The message is logged as:
375336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * <pre>
376336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   *     "[cls] msg"
377336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * </pre>
378336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   *
379336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param cls the class name to prefix the log message.
380336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param level the logging level of the message.
381336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @param msg the message to log to System.out.
382336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
383336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void log(String cls, int level, String msg) {
384336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Why this coupling on a static member of TestRunner.getVerbose()?
385336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (TestRunner.getVerbose() >= level) {
386336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (cls.length() > 0) {
387aa639c5643fd78bce3f5fb8a3196cf37efc862c1the.mindstorm        System.out.println("[" + cls + "] " + msg);
388336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
389336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      else {
390336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        System.out.println(msg);
391336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
392336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
393336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
3940f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
395336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void error(String errorMessage) {
396336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    System.err.println("[Error] " + errorMessage);
397336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
398336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
399336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
400336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * @return The number of methods invoked, taking into account the number
401336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * of instances.
402336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
403902688e212ecfd13c460d1c44635eb03575870b8the.mindstorm//  public static int calculateInvokedMethodCount(IResultMap map) {
404902688e212ecfd13c460d1c44635eb03575870b8the.mindstorm//    return calculateInvokedMethodCount(
405902688e212ecfd13c460d1c44635eb03575870b8the.mindstorm//        (ITestNGMethod[]) map.getAllMethods().toArray(new ITestNGMethod[map.size()]));
406902688e212ecfd13c460d1c44635eb03575870b8the.mindstorm//  }
4070f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
408336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static int calculateInvokedMethodCount(ITestNGMethod[] methods) {
409336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return methods.length;
410336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    int result = 0;
411336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//
412336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    for (ITestNGMethod method : methods) {
413336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//      int instanceCount = method.getInvocationCount();
414336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//      result += instanceCount;
415336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    }
416336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//
417336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    return result;
418336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
419336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
420336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//  public static int calculateInvokedMethodCount(Map<ITestNGMethod, ITestResult> methods) {
421336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    return calculateInvokedMethodCount(methods.keySet().toArray(new ITestNGMethod[methods.values()
422336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//                                                                .size()]));
423336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//  }
424336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
425336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  /**
426336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   * Tokenize the string using the separator.
427336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust   */
428336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static String[] split(String string, String sep) {
429336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if ((string == null) || (string.length() == 0)) {
430336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      return new String[0];
431336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
432336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
4330f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    // TODO How different is this from:
4340f81e5c7a2b7f15fc8a44271c188bea8199b9739cquezel    // return string.split(sep);
4350f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
436336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    int start = 0;
437336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    int idx = string.indexOf(sep, start);
438336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    int len = sep.length();
4390a050892401fb27d1c7629e37fe9c8796ea5a349Cédric Beust    List<String> strings = Lists.newArrayList();
440336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
441336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    while (idx != -1) {
442336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      strings.add(string.substring(start, idx).trim());
443336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      start = idx + len;
444336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      idx = string.indexOf(sep, start);
445336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
446336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
447336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    strings.add(string.substring(start).trim());
448336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
449474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm    return strings.toArray(new String[strings.size()]);
450336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
451336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
452336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void initLogger(Logger logger, String outputLogPath) {
453336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
454336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      logger.setUseParentHandlers(false);
455336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      FileHandler fh = new FileHandler(outputLogPath);
456336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      fh.setFormatter(new TextFormatter());
457336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      fh.setLevel(Level.INFO);
458336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      logger.addHandler(fh);
459336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
460a3f78c5debcd03e7755f5ff2956a6f325e41d0b7Ryan Schmitt    catch (SecurityException | IOException se) {
461336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      se.printStackTrace();
462336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
463336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
464336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
465336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void logInvocation(String reason, Method thisMethod, Object[] parameters) {
466336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    String clsName = thisMethod.getDeclaringClass().getName();
467336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    int n = clsName.lastIndexOf(".");
468336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (n >= 0) {
469336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      clsName = clsName.substring(n + 1);
470336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
471df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog    String methodName = clsName + '.' + thisMethod.getName();
472336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (TestRunner.getVerbose() >= 2) {
473336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      StringBuffer paramString = new StringBuffer();
474336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (parameters != null) {
475336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        for (Object p : parameters) {
476df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog          paramString.append(p.toString()).append(' ');
477336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
478336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
479df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog      log("", 2, "Invoking " + reason + methodName + '(' + paramString + ')');
480336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
481336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
482336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
483336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static void writeResourceToFile(File file, String resourceName, Class<?> clasz) throws IOException {
484aa639c5643fd78bce3f5fb8a3196cf37efc862c1the.mindstorm    InputStream inputStream = clasz.getResourceAsStream("/" + resourceName);
485336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    if (inputStream == null) {
486336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      System.err.println("Couldn't find resource on the class path: " + resourceName);
487336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//      throw new IllegalArgumentException("Resource does not exist: " + resourceName);
488336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
4890f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
490336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    else {
4910f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
492336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      try {
493336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        FileOutputStream outputStream = new FileOutputStream(file);
494336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        try {
495336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          int nread;
496336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          byte[] buffer = new byte[4096];
497336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          while (0 < (nread = inputStream.read(buffer))) {
498336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust            outputStream.write(buffer, 0, nread);
499336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          }
500336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        } finally {
501336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          outputStream.close();
502336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
503336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      } finally {
504336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        inputStream.close();
505336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
506336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
507336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
508336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
5093e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  public static String defaultIfStringEmpty(String s, String defaultValue) {
5103e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    return isStringEmpty(s) ? defaultValue : s;
5113e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  }
5123e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner
5133e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  public static boolean isStringBlank(String s) {
5143e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    return s == null || "".equals(s.trim());
5153e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  }
5163e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner
517336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public static boolean isStringEmpty(String s) {
518336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return s == null || "".equals(s);
519336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
520336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
5213e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  public static boolean isStringNotBlank(String s) {
5223e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    return !isStringBlank(s);
5233e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  }
5243e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner
5253e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  public static boolean isStringNotEmpty(String s) {
5263e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    return !isStringEmpty(s);
5273e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner  }
5283e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner
52902ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust  /**
53002ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust   * @return an array of two strings: the short stack trace and the long stack trace.
53102ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust   */
53202ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust  public static String[] stackTrace(Throwable t, boolean toHtml) {
533336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    StringWriter sw = new StringWriter();
534336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    PrintWriter pw = new PrintWriter(sw);
535336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    t.printStackTrace(pw);
536336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    pw.flush();
5370f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
538336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    String fullStackTrace = sw.getBuffer().toString();
539df7f78b6a19dcc515afbb928a22e0de6295eefadbileblog    String shortStackTrace;
5400f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
54123711f3d792a14ab7aa9052c2f3a6081cccf5e36Cédric Beust    if (Boolean.getBoolean(TestNG.SHOW_TESTNG_STACK_FRAMES) || TestRunner.getVerbose() >= 2) {
542336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      shortStackTrace = fullStackTrace;
54302ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust    } else {
544336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      shortStackTrace = filterTrace(sw.getBuffer().toString());
545336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
5460f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
54702ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust    if (toHtml) {
548d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust      shortStackTrace = escapeHtml(shortStackTrace);
54902ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust      fullStackTrace = escapeHtml(fullStackTrace);
550336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
5510f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
552336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new String[] {
553336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        shortStackTrace, fullStackTrace
554336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    };
555336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
5560f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
55702ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust  private static final Map<Character, String> ESCAPES = new HashMap<Character, String>() {
5580f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    private static final long serialVersionUID = 1285607660247157523L;
5590f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
5600f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  {
561d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    put('<', "&lt;");
562d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    put('>', "&gt;");
563d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    put('\'', "&apos;");
564d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    put('"', "&quot;");
56502ecc24ccc12deb938f16c64fa57ccfe0c806febCédric Beust    put('&', "&amp;");
566d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust  }};
567d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust
568d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust  public static String escapeHtml(String s) {
5690f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    if (s == null) {
5700f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      return null;
5710f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    }
572d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust
573d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    StringBuilder result = new StringBuilder();
574d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust
575d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    for (int i = 0; i < s.length(); i++) {
576d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust      char c = s.charAt(i);
577d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust      String nc = ESCAPES.get(c);
5780f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      if (nc != null) {
5790f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        result.append(nc);
5800f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      } else {
5810f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        result.append(c);
5820f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      }
583d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    }
584d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust
585d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust    return result.toString();
5869a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak  }
5879a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak
5889a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak  public static String escapeUnicode(String s) {
5890f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    if (s == null) {
5900f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      return null;
5910f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    }
5929a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak
5939a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak    StringBuilder result = new StringBuilder();
5949a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak
5959a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak    for (int i = 0; i < s.length(); i++) {
5969a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak      char c = s.charAt(i);
5979a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak      char ca = (Character.isDefined(c)) ? c: UNICODE_REPLACEMENT;
5989a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak      result.append(ca);
5999a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak    }
6009a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak
6019a6bb5dc0c9549ab8faf0a11f08404a4ee2d6ab6Tomás Pollak    return result.toString();
602d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust  }
603d4d8c3942b02ea1bed4ec15858cd8fff26632632Cédric Beust
604336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private static String filterTrace(String trace) {
605336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    StringReader   stringReader = new StringReader(trace);
606336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    BufferedReader bufferedReader = new BufferedReader(stringReader);
607336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    StringBuffer buf = new StringBuffer();
608336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
609336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
610336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      // first line contains the thrown exception
611336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      String line = bufferedReader.readLine();
612336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if(line == null) {
613336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        return "";
614336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
615336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      buf.append(line).append(LINE_SEP);
6160f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
617336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      //
618336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      // the stack frames of the trace
619336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      //
620336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      String[] excludedStrings = new String[] {
621336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          "org.testng",
6222e50db92ab5ec4d6b26384b2427bef47ee2d9b66Abraham Lin          "reflect",
6232e50db92ab5ec4d6b26384b2427bef47ee2d9b66Abraham Lin          "org.apache.maven.surefire"
624336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      };
6250f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
626336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      int excludedCount = 0;
627336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      while((line = bufferedReader.readLine()) != null) {
628336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        boolean isExcluded = false;
629336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        for (String excluded : excludedStrings) {
630d7aa93fe6e097ba15d10217bd929896d9e8a5b9cRyan Schmitt          if(line.contains(excluded)) {
631336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust            isExcluded = true;
632336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust            excludedCount++;
633336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust            break;
634336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust           }
635336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
636336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        if (! isExcluded) {
637336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          buf.append(line).append(LINE_SEP);
638336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
639336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
640336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (excludedCount > 0) {
641336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        buf.append("... Removed " + excludedCount + " stack frames");
642336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
643336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
644336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    catch(IOException ioex) {
645336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      ; // do nothing
646336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
6470f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
648336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return buf.toString();
649336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
650c70a9debafb066e6124205609109e49078e16d94the.mindstorm
651474b8b6008b48b349d9101738587eea10dd6e820the.mindstorm  public static String toString(Object object, Class<?> objectClass) {
652c70a9debafb066e6124205609109e49078e16d94the.mindstorm    if(null == object) {
653c70a9debafb066e6124205609109e49078e16d94the.mindstorm      return "null";
654c70a9debafb066e6124205609109e49078e16d94the.mindstorm    }
655c70a9debafb066e6124205609109e49078e16d94the.mindstorm    final String toString= object.toString();
65634867ece325a47987a34160ff025ed450d3cf183Stefan Birkner    if(isStringEmpty(toString)) {
657c70a9debafb066e6124205609109e49078e16d94the.mindstorm      return "\"\"";
658c70a9debafb066e6124205609109e49078e16d94the.mindstorm    }
659c70a9debafb066e6124205609109e49078e16d94the.mindstorm    else if (String.class.equals(objectClass)) {
660aa639c5643fd78bce3f5fb8a3196cf37efc862c1the.mindstorm      return "\"" + toString + '\"';
661c70a9debafb066e6124205609109e49078e16d94the.mindstorm    }
662c70a9debafb066e6124205609109e49078e16d94the.mindstorm    else {
663c70a9debafb066e6124205609109e49078e16d94the.mindstorm      return toString;
664c70a9debafb066e6124205609109e49078e16d94the.mindstorm    }
665c70a9debafb066e6124205609109e49078e16d94the.mindstorm  }
6669a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm
6674dd3d8657dd6a9cf09617c7f5fb9338c7df316d6the.mindstorm  public static String detailedMethodName(ITestNGMethod method, boolean fqn) {
6689a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    StringBuffer buf= new StringBuffer();
6699a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    if(method.isBeforeSuiteConfiguration()) {
6709a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@BeforeSuite ");
6719a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6729a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isBeforeTestConfiguration()) {
6739a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@BeforeTest ");
6749a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6759a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isBeforeClassConfiguration()) {
6769a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@BeforeClass ");
6779a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6789a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isBeforeGroupsConfiguration()) {
6799a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@BeforeGroups ");
6809a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6819a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isBeforeMethodConfiguration()) {
6829a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@BeforeMethod ");
6839a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6849a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isAfterMethodConfiguration()) {
6859a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@AfterMethod ");
6869a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6879a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isAfterGroupsConfiguration()) {
6889a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@AfterGroups ");
6899a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6909a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isAfterClassConfiguration()) {
6919a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@AfterClass ");
6929a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6939a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isAfterTestConfiguration()) {
6949a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@AfterTest ");
6959a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6969a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    else if(method.isAfterSuiteConfiguration()) {
6979a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      buf.append("@AfterSuite ");
6989a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm    }
6990f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
7000f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    return buf.append(fqn ? method.toString() : method.getMethodName()).toString();
7019a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm  }
702a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru
703a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru  public static String arrayToString(String[] strings) {
7040b2ac5eab08098da2c2b63d4a3f87ba72ad5d6a1nullin    StringBuffer result = new StringBuffer("");
705a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru    if ((strings != null) && (strings.length > 0)) {
706a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru      for (int i = 0; i < strings.length; i++) {
7070b2ac5eab08098da2c2b63d4a3f87ba72ad5d6a1nullin        result.append(strings[i]);
708a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru        if (i < strings.length - 1) {
7090b2ac5eab08098da2c2b63d4a3f87ba72ad5d6a1nullin          result.append(", ");
710a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru        }
711a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru      }
712a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru    }
7130b2ac5eab08098da2c2b63d4a3f87ba72ad5d6a1nullin    return result.toString();
714a6f52a5ccfbe819e710ec68391027ebd220410ffcosminaru  }
7157ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust
7167ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust  /**
7177ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * If the file name contains special characters like *,/,\ and so on,
7187ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * exception will be thrown and report file will not be created.<br>
7197ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * Special characters are platform specific and they are not same for
7207ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * example on Windows and Macintosh. * is not allowed on Windows, but it is on Macintosh.<br>
7217ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * In order to have the same behavior of testng on the all platforms, characters like * will
7227ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * be replaced on all platforms whether they are causing the problem or not.
7237ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   *
7247ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * @param fileName file name that could contain special characters.
7257ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * @return fileName with special characters replaced
7267ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   * @author Borojevic
7277ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   */
7287ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust  public static String replaceSpecialCharacters(String fileName) {
7297ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   if (fileName == null || fileName.length() == 0) {
7307ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust     return fileName;
7317ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   }
7320f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin   for (char element : SPECIAL_CHARACTERS) {
7330f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin     fileName = fileName.replace(element, CHAR_REPLACEMENT);
7347ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   }
7350f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
7367ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust   return fileName;
7377ce0e7281d329e65d61087e70ffee39422cfeb17Cédric Beust  }
738e61233381684292cf7e03ee8932f4d4dadcae673Cédric Beust
73983d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust  public static <T> String join(List<T> objects, String separator) {
74083d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust    StringBuilder result = new StringBuilder();
74183d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust    for (int i = 0; i < objects.size(); i++) {
74283d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust      if (i > 0) {
74383d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust        result.append(separator);
7440f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin      }
74583d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust      result.append(objects.get(i).toString());
746e61233381684292cf7e03ee8932f4d4dadcae673Cédric Beust    }
74783d91a01e1c2e9a122d738e15a4f373e47d21eb9Cédric Beust    return result.toString();
748e61233381684292cf7e03ee8932f4d4dadcae673Cédric Beust  }
7491e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust
7501e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust  public static void copyFile(File from, File to) {
7512c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada    to.getParentFile().mkdirs();
7522c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada    try (InputStream in = new FileInputStream(from); OutputStream out = new FileOutputStream(to)) {
7532c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada      byte[] buf = new byte[1024];
7542c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada      int len;
7552c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada      while ((len = in.read(buf)) > 0) {
7562c2328384028f048721f6793726b5fc8c2520bfeTesto Nakada        out.write(buf, 0, len);
7571e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust      }
758a3f78c5debcd03e7755f5ff2956a6f325e41d0b7Ryan Schmitt    } catch(IOException e){
7591e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust      e.printStackTrace();
7601e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust    }
7611e9bc8ce01ebe5c43a975d26a7195dff1b2c7d46Cédric Beust  }
7622cb45c217aba17e967d19bb7257b067740033c5cCédric Beust
7632cb45c217aba17e967d19bb7257b067740033c5cCédric Beust  /**
7642cb45c217aba17e967d19bb7257b067740033c5cCédric Beust   * @return a temporary file with the given content.
7652cb45c217aba17e967d19bb7257b067740033c5cCédric Beust   */
7662cb45c217aba17e967d19bb7257b067740033c5cCédric Beust  public static File createTempFile(String content) {
7672cb45c217aba17e967d19bb7257b067740033c5cCédric Beust    try {
7682cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      // Create temp file.
7692cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      File result = File.createTempFile("testng-tmp", "");
7702cb45c217aba17e967d19bb7257b067740033c5cCédric Beust
7712cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      // Delete temp file when program exits.
7722cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      result.deleteOnExit();
7732cb45c217aba17e967d19bb7257b067740033c5cCédric Beust
7742cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      // Write to temp file
7752cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      BufferedWriter out = new BufferedWriter(new FileWriter(result));
7762cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      out.write(content);
7772cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      out.close();
7782cb45c217aba17e967d19bb7257b067740033c5cCédric Beust
7792cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      return result;
7802cb45c217aba17e967d19bb7257b067740033c5cCédric Beust    } catch (IOException e) {
7812cb45c217aba17e967d19bb7257b067740033c5cCédric Beust      throw new TestNGException(e);
7822cb45c217aba17e967d19bb7257b067740033c5cCédric Beust    }
7832cb45c217aba17e967d19bb7257b067740033c5cCédric Beust  }
7844438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust
7854438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust  /**
7864438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust   * Make sure that either we have an instance or if not, that the method is static
7874438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust   */
7884438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust  public static void checkInstanceOrStatic(Object instance, Method method) {
789648bfc7bd309bcd3ab6d123b48797b71b557127bJulien Herr    if (instance == null && method != null && ! Modifier.isStatic(method.getModifiers())) {
7904438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust      throw new TestNGException("Can't invoke " + method + ": either make it static or add "
7914438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust          + "a no-args constructor to your class");
7924438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust    }
7934438e4fa82ea3d7d8623d11156657d119cddaa14Cédric Beust  }
794f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin
79595b8264b249dc07afc86869a144006d086fb1225Julien Herr  public static void checkReturnType(Method method, Class<?>... returnTypes) {
79695b8264b249dc07afc86869a144006d086fb1225Julien Herr    if (method == null) {
79795b8264b249dc07afc86869a144006d086fb1225Julien Herr      return;
79895b8264b249dc07afc86869a144006d086fb1225Julien Herr    }
79995b8264b249dc07afc86869a144006d086fb1225Julien Herr    for (Class<?> returnType : returnTypes) {
80095b8264b249dc07afc86869a144006d086fb1225Julien Herr      if (method.getReturnType() == returnType) {
80195b8264b249dc07afc86869a144006d086fb1225Julien Herr        return;
80295b8264b249dc07afc86869a144006d086fb1225Julien Herr      }
80395b8264b249dc07afc86869a144006d086fb1225Julien Herr    }
80495b8264b249dc07afc86869a144006d086fb1225Julien Herr    throw new TestNGException(method.getDeclaringClass().getName() + "."
80595b8264b249dc07afc86869a144006d086fb1225Julien Herr              + method.getName() + " MUST return " + toString(returnTypes) + " but returns " + method.getReturnType().getName());
80695b8264b249dc07afc86869a144006d086fb1225Julien Herr  }
80795b8264b249dc07afc86869a144006d086fb1225Julien Herr
80895b8264b249dc07afc86869a144006d086fb1225Julien Herr  private static String toString(Class<?>[] classes) {
80995b8264b249dc07afc86869a144006d086fb1225Julien Herr    StringBuilder sb = new StringBuilder("[ ");
81095b8264b249dc07afc86869a144006d086fb1225Julien Herr    for (int i=0; i<classes.length;) {
81195b8264b249dc07afc86869a144006d086fb1225Julien Herr      Class<?> clazz = classes[i];
81295b8264b249dc07afc86869a144006d086fb1225Julien Herr      if (clazz.isArray()) {
81395b8264b249dc07afc86869a144006d086fb1225Julien Herr        sb.append(clazz.getComponentType().getName()).append("[]");
81495b8264b249dc07afc86869a144006d086fb1225Julien Herr      } else {
81595b8264b249dc07afc86869a144006d086fb1225Julien Herr        sb.append(clazz.getName());
81695b8264b249dc07afc86869a144006d086fb1225Julien Herr      }
81795b8264b249dc07afc86869a144006d086fb1225Julien Herr      if (++i < classes.length) { // increment and compare
81895b8264b249dc07afc86869a144006d086fb1225Julien Herr        sb.append(" or ");
81995b8264b249dc07afc86869a144006d086fb1225Julien Herr      }
82095b8264b249dc07afc86869a144006d086fb1225Julien Herr    }
82195b8264b249dc07afc86869a144006d086fb1225Julien Herr    sb.append(" ]");
82295b8264b249dc07afc86869a144006d086fb1225Julien Herr    return sb.toString();
82395b8264b249dc07afc86869a144006d086fb1225Julien Herr  }
82495b8264b249dc07afc86869a144006d086fb1225Julien Herr
825f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin  /**
826f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   * Returns the string representation of the specified object, transparently
827f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   * handling null references and arrays.
8284e7a944ad9e5f98158da8106ed16945293b120afVladimir Lyubitelev   *
829f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   * @param obj
830f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   *            the object
831f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   * @return the string representation
832f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin   */
833f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin  public static String toString(Object obj) {
834f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin    String result;
835f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin    if (obj != null) {
836f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      if (obj instanceof boolean[]) {
837f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((boolean[]) obj);
838f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof byte[]) {
839f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((byte[]) obj);
840f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof char[]) {
841f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((char[]) obj);
842f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof double[]) {
843f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((double[]) obj);
844f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof float[]) {
845f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((float[]) obj);
846f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof int[]) {
847f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((int[]) obj);
848f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof long[]) {
849f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((long[]) obj);
850f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof Object[]) {
851f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.deepToString((Object[]) obj);
852f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else if (obj instanceof short[]) {
853f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = Arrays.toString((short[]) obj);
854f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      } else {
855f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin        result = obj.toString();
856f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      }
857f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin    } else {
858f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin      result = "null";
859f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin    }
860f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin    return result;
861f4b6725860d1e3151af98a11be65c6af696a3e69Abraham Lin  }
862336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust}
863