1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 
  28 package com.sun.javatest.report;
  29 
  30 import com.sun.javatest.InitialUrlFilter;
  31 import com.sun.javatest.InterviewParameters;
  32 import com.sun.javatest.JavaTestError;
  33 import com.sun.javatest.KnownFailuresList;
  34 import com.sun.javatest.LastRunFilter;
  35 import com.sun.javatest.ParameterFilter;
  36 import com.sun.javatest.Status;
  37 import com.sun.javatest.TestFilter;
  38 import com.sun.javatest.TestResult;
  39 import com.sun.javatest.TestResultTable;
  40 import com.sun.javatest.tool.Preferences;
  41 import com.sun.javatest.util.I18NResourceBundle;
  42 import com.sun.javatest.util.StringArray;
  43 import java.io.File;
  44 import java.util.Collections;
  45 import java.util.Comparator;
  46 import java.util.HashMap;
  47 import java.util.Iterator;
  48 import java.util.List;
  49 import java.util.Map;
  50 import java.util.TreeSet;
  51 
  52 /**
  53  * Specify what parts of the reports to generate.
  54  */
  55 public class ReportSettings {
  56 
  57     // preference constants
  58     private static final String PREFS_GEN_HTML = "rpt.type.html";
  59     private static final String PREFS_GEN_PLAIN = "rpt.type.plain";
  60     private static final String PREFS_GEN_XML = "rpt.type.xml";
  61     private static final String PREFS_GEN_COF = "rpt.type.cof";
  62     private static final String PREFS_COF_TC = "rpt.cof.tc";
  63     private static final String PREFS_HTML_CONFIG = "rpt.html.config";
  64     private static final String PREFS_HTML_QL = "rpt.html.ql";
  65     private static final String PREFS_HTML_ENV = "rpt.html.env";
  66     private static final String PREFS_HTML_STD = "rpt.html.std";
  67     private static final String PREFS_HTML_RES = "rpt.html.res";
  68     private static final String PREFS_HTML_KWS = "rpt.html.kws";
  69     private static final String PREFS_HTML_KFL = "rps.html.kfl";
  70     private static final String PREFS_HTML_REPORTF = "rpt.html.reportf";
  71     private static final String PREFS_HTML_INDEXF = "rpt.html.htmlf";
  72     private static final String PREFS_HTML_STATEF = "rpt.html.statef";
  73     private static final String PREFS_HTML_KFLF2E = "rps.html.kflf2e";
  74     private static final String PREFS_HTML_KFLF2F = "rpt.html.kflf2f";
  75     private static final String PREFS_HTML_KFLMISSING = "rpt.html.kflmissing";
  76     private static final String PREFS_HTML_KFLTC = "rpt.html.kfltc";
  77     private static final String PREFS_BACK = "rpt.bak.enable";
  78     private static final String PREFS_BACK_NUM = "rpt.bak.num";
  79 
  80     public ReportSettings() {
  81         for (int i = 0; i < stateFiles.length; i++) {
  82             stateFiles[i] = true;
  83         }
  84     }
  85 
  86     public ReportSettings(InterviewParameters p) {
  87         this();
  88         ip = p;
  89     }
  90 
  91     /**
  92      * Creates a new ReportEnviroment instance refers to the given file.
  93      */
  94     public ReportSettings(File xmlReportFile, File[] in) {
  95         this.xmlReportFile = xmlReportFile;
  96         this.mif = in;
  97     }
  98 
  99     public void write(Preferences prefs) {
 100         prefs.setPreference(PREFS_GEN_HTML, Boolean.toString(genHtml));
 101         prefs.setPreference(PREFS_GEN_PLAIN, Boolean.toString(genPlain));
 102         prefs.setPreference(PREFS_GEN_XML, Boolean.toString(genXml));
 103         prefs.setPreference(PREFS_GEN_COF, Boolean.toString(genCof));
 104         prefs.setPreference(PREFS_COF_TC, Boolean.toString(genCofTestCases));
 105         prefs.setPreference(PREFS_HTML_CONFIG, Boolean.toString(genConfig));
 106         prefs.setPreference(PREFS_HTML_QL, Boolean.toString(genQl));
 107         prefs.setPreference(PREFS_HTML_ENV, Boolean.toString(genEnv));
 108         prefs.setPreference(PREFS_HTML_STD, Boolean.toString(genStd));
 109         prefs.setPreference(PREFS_HTML_RES, Boolean.toString(genResults));
 110         prefs.setPreference(PREFS_HTML_KFL, Boolean.toString(genKfl));
 111         prefs.setPreference(PREFS_HTML_KWS, Boolean.toString(genKws));
 112         prefs.setPreference(PREFS_HTML_REPORTF, Boolean.toString(reportHtml));
 113         prefs.setPreference(PREFS_HTML_INDEXF, Boolean.toString(indexHtml));
 114         prefs.setPreference(PREFS_HTML_KFLF2E, Boolean.toString(kflF2e));
 115         prefs.setPreference(PREFS_HTML_KFLF2F, Boolean.toString(kflF2f));
 116         prefs.setPreference(PREFS_HTML_KFLMISSING, Boolean.toString(kflMissing));
 117         prefs.setPreference(PREFS_HTML_KFLTC, Boolean.toString(kflTestCases));
 118 
 119         // html state files
 120         // encoded as a comma sep. list
 121         StringBuffer sb = new StringBuffer();
 122         for (int i = 0; i < stateFiles.length; i++) {
 123             sb.append(Boolean.toString(stateFiles[i]));
 124             if (i + 1 < stateFiles.length) {
 125                 sb.append(",");
 126             }
 127         } // for
 128         // for
 129         prefs.setPreference(PREFS_HTML_STATEF, sb.toString());
 130         prefs.setPreference(PREFS_BACK, Boolean.toString(doBackups));
 131         prefs.setPreference(PREFS_BACK_NUM, Integer.toString(backups));
 132     }
 133 
 134     public static ReportSettings create(Preferences prefs) {
 135         ReportSettings result = new ReportSettings();
 136         // special check to see if pref settings are available
 137         // if not we will use the defaults
 138         String tst = prefs.getPreference(PREFS_GEN_HTML);
 139         if (tst == null) {
 140             return result;
 141         } else {
 142             result.genHtml = parseBoolean(tst);
 143         }
 144         result.genPlain = parseBoolean(prefs.getPreference(PREFS_GEN_PLAIN));
 145         result.genXml = parseBoolean(prefs.getPreference(PREFS_GEN_XML));
 146         result.genCof = parseBoolean(prefs.getPreference(PREFS_GEN_COF));
 147         result.genCofTestCases = parseBoolean(prefs.getPreference(PREFS_COF_TC));
 148         result.genConfig = parseBoolean(prefs.getPreference(PREFS_HTML_CONFIG));
 149         result.genQl = parseBoolean(prefs.getPreference(PREFS_HTML_QL));
 150         result.genEnv = parseBoolean(prefs.getPreference(PREFS_HTML_ENV));
 151         result.genStd = parseBoolean(prefs.getPreference(PREFS_HTML_STD));
 152         result.genResults = parseBoolean(prefs.getPreference(PREFS_HTML_RES));
 153         result.genKfl = parseBoolean(prefs.getPreference(PREFS_HTML_KFL));
 154         result.genKws = parseBoolean(prefs.getPreference(PREFS_HTML_KWS));
 155         result.reportHtml = parseBoolean(prefs.getPreference(PREFS_HTML_REPORTF));
 156         result.indexHtml = parseBoolean(prefs.getPreference(PREFS_HTML_INDEXF));
 157         result.kflF2e = parseBoolean(prefs.getPreference(PREFS_HTML_KFLF2E));
 158         result.kflF2f = parseBoolean(prefs.getPreference(PREFS_HTML_KFLF2F));
 159         result.kflMissing = parseBoolean(prefs.getPreference(PREFS_HTML_KFLMISSING));
 160         result.kflTestCases = parseBoolean(prefs.getPreference(PREFS_HTML_KFLTC));
 161         // html state files
 162         // encoded as a comma sep. list
 163         String[] states = StringArray.splitList(prefs.getPreference(PREFS_HTML_STATEF), ",");
 164         if (states != null) {
 165             for (int i = 0; i < states.length; i++) {
 166                 result.stateFiles[i] = parseBoolean(states[i]);
 167             } // for
 168             // for
 169         }
 170         result.doBackups = parseBoolean(prefs.getPreference(PREFS_BACK));
 171         try {
 172             result.backups = Integer.parseInt(prefs.getPreference(PREFS_BACK_NUM));
 173         } catch (NumberFormatException e) {
 174             // leave as default
 175             // leave as default
 176         }
 177         return result;
 178     }
 179 
 180     public void setInterview(InterviewParameters p) {
 181         ip = p;
 182     }
 183 
 184     public void setFilter(TestFilter f) {
 185         filter = f;
 186     }
 187 
 188     public void setEnableHtmlReport(boolean state) {
 189         genHtml = state;
 190     }
 191 
 192     public void setEnableXmlReport(boolean state) {
 193         genXml = state;
 194     }
 195 
 196     public void setEnablePlainReport(boolean state) {
 197         genPlain = state;
 198     }
 199 
 200     public void setEnableCOFReport(boolean state) {
 201         genCof = state;
 202     }
 203 
 204     public void setUseTestCases(boolean state) {
 205         genCofTestCases = state;
 206     }
 207 
 208     public void setShowConfigSection(boolean state) {
 209         genConfig = state;
 210     }
 211 
 212     public void setShowQuestionLog(boolean state) {
 213         genQl = state;
 214     }
 215 
 216     public void setShowEnvLog(boolean state) {
 217         genEnv = state;
 218     }
 219 
 220     public void setShowStdValues(boolean state) {
 221         genStd = state;
 222     }
 223 
 224     public void setShowResults(boolean state) {
 225         genResults = state;
 226     }
 227 
 228     public void setShowKflReport(boolean state) {
 229         genKfl = state;
 230     }
 231 
 232     public void setShowKeywordSummary(boolean state) {
 233         genKws = state;
 234     }
 235 
 236     /**
 237      * @param status PASS, FAIL, ERROR, NOT_RUN constant from Status
 238      */
 239     public void setEnableHtmlStateFile(int status, boolean state) {
 240         if (status >= stateFiles.length) {
 241             return; // error condition
 242             // error condition
 243         }
 244         stateFiles[status] = state;
 245     }
 246 
 247     public void setHtmlMainReport(boolean reporthtml, boolean indexhtml) {
 248         reportHtml = reporthtml;
 249         indexHtml = indexhtml;
 250     }
 251 
 252     public void setEnableKflF2e(boolean state) {
 253         kflF2e = state;
 254     }
 255 
 256     public void setEnableKflF2f(boolean state) {
 257         kflF2f = state;
 258     }
 259 
 260     public void setEnableKflMissing(boolean state) {
 261         kflMissing = state;
 262     }
 263 
 264     public void setEnableKflTestCases(boolean state) {
 265         kflTestCases = state;
 266     }
 267 
 268     public void setEnableBackups(boolean state) {
 269         doBackups = state;
 270     }
 271 
 272     public void setBackupLevels(int n) {
 273         if (n > 0) {
 274             backups = n;
 275         }
 276     }
 277 
 278     public boolean isHtmlEnabled() {
 279         return genHtml;
 280     }
 281 
 282     public boolean isXmlEnabled() {
 283         return genXml;
 284     }
 285 
 286     public boolean isPlainEnabled() {
 287         return genPlain;
 288     }
 289 
 290     public boolean isCOFEnabled() {
 291         return genCof;
 292     }
 293 
 294     public boolean isCOFTestCasesEnabled() {
 295         return genCofTestCases;
 296     }
 297 
 298     public boolean isConfigSectionEnabled() {
 299         return genConfig;
 300     }
 301 
 302     public boolean isQuestionLogEnabled() {
 303         return genQl;
 304     }
 305 
 306     public boolean isEnvEnabled() {
 307         return genEnv;
 308     }
 309 
 310     public boolean isStdEnabled() {
 311         return genStd;
 312     }
 313 
 314     public boolean isResultsEnabled() {
 315         return genResults;
 316     }
 317 
 318     public boolean isKflEnabled() {
 319         return genKfl;
 320     }
 321 
 322     public boolean isKeywordSummaryEnabled() {
 323         return genKws;
 324     }
 325 
 326     public boolean isIndexHtmlEnabled() {
 327         return indexHtml;
 328     }
 329 
 330     public boolean isReportHtmlEnabled() {
 331         return reportHtml;
 332     }
 333 
 334     public boolean isStateFileEnabled(int status) {
 335         if (status >= stateFiles.length) {
 336             return false; // error condition
 337             // error condition
 338         }
 339         return stateFiles[status];
 340     }
 341 
 342     public boolean isKflTestCasesEnabled() {
 343         return kflTestCases;
 344     }
 345 
 346     public boolean isKflMissingEnabled() {
 347         return kflMissing;
 348     }
 349 
 350     public boolean isKflF2eEnabled() {
 351         return kflF2e;
 352     }
 353 
 354     public boolean isKflF2fEnabled() {
 355         return kflF2f;
 356     }
 357 
 358     public boolean isBackupsEnabled() {
 359         return doBackups;
 360     }
 361 
 362     public int getBackupLevel() {
 363         return backups;
 364     }
 365 
 366     /*
 367      optimization will be enforced if filter is ParameterFilter
 368      public void setAllowInitFilesOptimize(boolean s) {
 369      optimizeInitUrl = s;
 370      }
 371      */
 372     public File[] getInitialFiles() {
 373         // Optimization: If the filter is a ParameterFilter and
 374         // rejects all tests not specified in the initial URLs
 375         // it's enough to iterate over initial URLs only
 376         if (filter instanceof ParameterFilter) {
 377             File[] initFiles;
 378             InitialUrlFilter iuf = ((ParameterFilter) filter).getIUrlFilter();
 379             if (iuf == null) {
 380                 initFiles = null;
 381             } else {
 382                 if (iuf.getInitFiles() != null) {
 383                     initFiles = iuf.getInitFiles();
 384                 } else if (iuf.getInitStrings() != null) {
 385                     String[] s = iuf.getInitStrings();
 386                     initFiles = new File[s.length];
 387                     for (int i = 0; i < s.length; i++) {
 388                         initFiles[i] = new File(s[i]);
 389                     }
 390                 } else {
 391                     initFiles = null;
 392                 }
 393             }
 394             return initFiles;
 395         } else if (filter instanceof LastRunFilter) {
 396             return ((LastRunFilter) filter).getTestURLs();
 397         }
 398         return null;
 399     }
 400 
 401     public TestFilter getTestFilter() {
 402         return filter;
 403     }
 404 
 405     public InterviewParameters getInterview() {
 406         return ip;
 407     }
 408 
 409     private static boolean parseBoolean(String s) {
 410         if (s == null) {
 411             return false;
 412         } else {
 413             return s.equalsIgnoreCase("true");
 414         }
 415     }
 416 
 417     void cleanup() {
 418         if (tmpXmlReportFile != null) {
 419             tmpXmlReportFile.delete();
 420         }
 421         if (exchangeData != null) {
 422             exchangeData.clear();
 423         }
 424     }
 425 
 426     public void setXMLReportFile(File f) {
 427         xmlReportFile = f;
 428     }
 429 
 430     public void setMergingFiles(File[] files) {
 431         mif = files;
 432     }
 433 
 434     /**
 435      * Returns array of File objects that were sources for Report Converter tool
 436      * or empty array if Report Converter was not used.
 437      *
 438      * @return array of source files
 439      */
 440     public File[] getMergingFiles() {
 441         return mif;
 442     }
 443 
 444     /**
 445      * Give Map for data exchange between custom reports during the same report
 446      * session. Can be used for sharing intermediate results between reports for
 447      * optimization.
 448      *
 449      * @return Map for data exchange
 450      */
 451     public Map<?, ?> getExchangeData() {
 452         if (exchangeData == null) {
 453             exchangeData = new HashMap<>();
 454         }
 455         return exchangeData;
 456     }
 457 
 458     void setupSortedResults() {
 459         if (sortedResults != null) {
 460             return;
 461         }
 462         TestResultTable resultTable = ip.getWorkDirectory().getTestResultTable();
 463         File[] initFiles = getInitialFiles();
 464         sortedResults = new TreeSet[Status.NUM_STATES];
 465         for (int i = 0; i < sortedResults.length; i++) {
 466             sortedResults[i] = new TreeSet<>(new TestResultsByNameComparator());
 467         }
 468         Iterator<TestResult> iter;
 469         try {
 470             TestFilter[] fs = null;
 471             // Note: settings.filter should not really be null, modernized clients
 472             //   of this class should set the filter before asking for a report.
 473             if (filter == null) {
 474                 fs = new TestFilter[0];
 475             } else {
 476                 fs = new TestFilter[]{filter};
 477             }
 478             iter = ((initFiles == null) ? resultTable.getIterator(fs) : resultTable.getIterator(initFiles, fs));
 479         } catch (TestResultTable.Fault f) {
 480             throw new JavaTestError(ReportSettings.i18n.getString("result.testResult.err"));
 481         }
 482         for (; iter.hasNext();) {
 483             TestResult tr = (iter.next());
 484             Status s = tr.getStatus();
 485             TreeSet<TestResult> list = sortedResults[s == null ? Status.NOT_RUN : s.getType()];
 486             list.add(tr);
 487         }
 488     }
 489 
 490     private static class TestResultsByNameComparator implements Comparator<TestResult> {
 491 
 492         @Override
 493         public int compare(TestResult tr1, TestResult tr2) {
 494             return tr1.getTestName().compareTo(tr2.getTestName());
 495         }
 496     }
 497 
 498     void setupKfl() {
 499         if (kflSorter != null) {
 500             return;
 501         }
 502         setupSortedResults();
 503         KnownFailuresList kfl = getInterview().getKnownFailuresList();
 504         TestResultTable resultTable = getInterview().getWorkDirectory().getTestResultTable();
 505         kflSorter = new KflSorter(kfl, resultTable, isKflTestCasesEnabled());
 506         kflSorter.setF2eEnabled(isKflF2eEnabled());
 507         kflSorter.setF2fEnabled(isKflF2fEnabled());
 508         kflSorter.setMissingEnabled(isKflMissingEnabled());
 509         kflSorter.run(sortedResults);
 510     }
 511 
 512     KflSorter getKflSorter() {
 513         return kflSorter;
 514     }
 515 
 516     TreeSet<TestResult>[] getSortedResults() {
 517         return sortedResults;
 518     }
 519 
 520     public void setCustomReports(List<CustomReport> customReportCollection) {
 521         customReports = customReportCollection;
 522     }
 523 
 524     public List<CustomReport> getCustomReports() {
 525         return customReports;
 526     }
 527 
 528     private TreeSet<TestResult>[] sortedResults;
 529     private KflSorter kflSorter;
 530     File xmlReportFile = null;
 531     File tmpXmlReportFile = null;
 532     private File[] mif = new File[0];
 533     private HashMap<?, ?> exchangeData;
 534     private InterviewParameters ip;
 535 
 536     private List<CustomReport> customReports = Collections.emptyList();
 537 
 538     TestFilter filter;
 539     // default (legacy) values provided
 540     boolean genHtml = true; // generate HTML?
 541     // generate HTML?
 542     boolean genPlain = true; // generate summary.txt?
 543     // generate summary.txt?
 544     boolean genCof = false; // generate cof.xml?
 545     // generate cof.xml?
 546     boolean genXml = false; // generate summary.xml?
 547     // generate summary.xml?
 548     private boolean genCofTestCases = true;
 549     boolean genConfig = true; // generate config section
 550     // generate config section
 551     boolean genQl = true;
 552     boolean genEnv = true;
 553     boolean genStd = true;
 554     boolean genResults = true;
 555     boolean genKfl = true;
 556     boolean genKws = true;
 557     boolean kflMissing = true;
 558     boolean kflF2e = true;
 559     boolean kflF2f = true;
 560     boolean kflTestCases = true;
 561     boolean reportHtml = true; // use report.html
 562     // use report.html
 563     boolean indexHtml = false; // use index.html
 564     // use index.html
 565     boolean[] stateFiles = new boolean[Status.NUM_STATES];
 566     boolean doBackups = true;
 567     int backups = 1; // backup levels
 568     // backup levels
 569     private static I18NResourceBundle i18n = I18NResourceBundle.getBundleForClass(ReportSettings.class);
 570 }