1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2002, 2013, 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 package com.sun.javatest.report;
  28 
  29 import java.io.File;
  30 import java.io.IOException;
  31 import java.util.Arrays;
  32 import java.util.HashMap;
  33 import java.util.Iterator;
  34 import java.util.Map;
  35 import java.util.Vector;
  36 
  37 import com.sun.javatest.JavaTestError;
  38 import com.sun.javatest.Status;
  39 import com.sun.javatest.TestDescription;
  40 import com.sun.javatest.TestFilter;
  41 import com.sun.javatest.TestResult;
  42 import com.sun.javatest.TestResultTable;
  43 import com.sun.javatest.util.I18NResourceBundle;
  44 import com.sun.javatest.util.StringArray;
  45 
  46 class StatisticsSection extends HTMLSection {
  47     StatisticsSection(HTMLReport parent, ReportSettings set, File dir, I18NResourceBundle i18n) {
  48         super(i18n.getString("stats.title"), set, dir, parent);
  49         this.i18n = i18n;
  50 
  51         headings = new String[] {
  52             i18n.getString("stats.heading.passed"),
  53             i18n.getString("stats.heading.failed"),
  54             i18n.getString("stats.heading.error"),
  55             i18n.getString("stats.heading.notRun")};
  56 
  57         initFiles = settings.getInitialFiles();
  58 
  59         resultTable = settings.getInterview().getWorkDirectory().getTestResultTable();
  60         Iterator<TestResult> iter =  null;
  61         try {
  62             iter = (initFiles == null) ?
  63                         resultTable.getIterator(new TestFilter[] {settings.filter}) :
  64                         resultTable.getIterator(initFiles, new TestFilter[]
  65                                                 {settings.filter});
  66         }
  67         catch (TestResultTable.Fault f) {
  68             throw new JavaTestError(i18n.getString("stats.testResult.err"));
  69         }       // catch
  70 
  71         for (; iter.hasNext(); ) {
  72             TestResult tr = iter.next();
  73 
  74             try {
  75                 Status s = tr.getStatus();
  76                 TestDescription td = tr.getDescription();
  77 
  78                 String[] keys = td.getKeywords();
  79                 Arrays.sort(keys);
  80                 String sortedKeys = StringArray.join(keys);
  81 
  82                 int[] v = keywordTable.get(sortedKeys);
  83                 if (v == null) {
  84                     v = new int[Status.NUM_STATES];
  85                     keywordTable.put(sortedKeys, v);
  86                 }
  87                 v[s.getType()]++;
  88 
  89                 statusTotals[s.getType()]++;
  90             }
  91             catch (TestResult.Fault ex) {
  92                 // hmmm. Could count problem files here and report on them later
  93             }
  94         }
  95     }
  96 
  97     void writeContents(ReportWriter out) throws IOException {
  98         // arguably, this should be conditional on whether
  99         // the test suite has tests that use keywords!
 100 
 101         super.writeContents(out);
 102 
 103         out.startTag(HTMLWriterEx.UL);
 104         out.startTag(HTMLWriterEx.LI);
 105         out.writeLink("#" + HTMLReport.anchors[HTMLReport.KEYWORD_ANCHOR],
 106                       i18n.getString("stats.keywordValue"));
 107         out.endTag(HTMLWriterEx.UL);
 108         out.newLine();
 109     }
 110 
 111     void writeSummary(ReportWriter out) throws IOException {
 112         // arguably, this should be conditional on whether
 113         // the test suite has tests that use keywords!
 114 
 115         super.writeSummary(out);
 116         writeKeywordSummary(out);
 117     }
 118 
 119     private void writeKeywordSummary(ReportWriter out) throws IOException {
 120         // arguably, the following logic to create the keyword table
 121         // should be done in the constructor, so that we can optimize
 122         // out the contents and summary if the do not provide any
 123         // significant data
 124         // -- or else, we could just report "test suite does not use keywords"
 125         // instead of a mostly empty table
 126 
 127         // compute the keyword statistics
 128 
 129         int ncols = 2; // keywords, total
 130         for (int i = 0; i < statusTotals.length; i++)
 131             if (statusTotals[i] > 0)
 132                 ncols++;
 133 
 134         String[] head = new String[ncols];
 135         {
 136             int c = 0;
 137             head[c++] = i18n.getString("stats.keyword");
 138             for (int i = 0; i < statusTotals.length; i++)
 139                 if (statusTotals[i] > 0)
 140                     head[c++] = headings[i];
 141             head[c] = i18n.getString("stats.total");
 142         }
 143 
 144         Vector<String[]> v = new Vector<>();
 145         for (Iterator iter = keywordTable.entrySet().iterator(); iter.hasNext(); ) {
 146             Map.Entry e = (Map.Entry) (iter.next());
 147             String k = (String) (e.getKey());
 148             int[] kv = (int[]) (e.getValue());
 149             String[] newEntry = new String[ncols];
 150             int c = 0, total = 0;
 151             newEntry[c++] = k;
 152             for (int i = 0; i < kv.length; i++) {
 153                 if (statusTotals[i] != 0)
 154                     newEntry[c++] = (kv[i] == 0 ? "" : Integer.toString(kv[i]));
 155                 total += kv[i];
 156             }
 157             newEntry[c] = Integer.toString(total);
 158 
 159         sortedInsert:
 160             {
 161                 for (int i = 0; i < v.size(); i++) {
 162                     String[] entry = v.elementAt(i);
 163                     if (k.compareTo(entry[0]) < 0) {
 164                         v.insertElementAt(newEntry, i);
 165                         break sortedInsert;
 166                     }
 167                 }
 168                 v.addElement(newEntry);
 169             }
 170         }
 171 
 172         {
 173             String[] totalsEntry = new String[ncols];
 174             int c = 0, total = 0;
 175             totalsEntry[c++] = i18n.getString("stats.total");
 176             for (int i = 0; i < statusTotals.length; i++) {
 177                 if (statusTotals[i] != 0)
 178                     totalsEntry[c++] = Integer.toString(statusTotals[i]);
 179                 total += statusTotals[i];
 180             }
 181             totalsEntry[c] = Integer.toString(total);
 182             v.addElement(totalsEntry);
 183         }
 184 
 185         String[][] table = new String[v.size()][];
 186         v.copyInto(table);
 187 
 188         // write out the keyword statistics
 189 
 190         out.startTag(HTMLWriterEx.H3);
 191         out.writeLinkDestination(HTMLReport.anchors[HTMLReport.KEYWORD_ANCHOR],
 192                       i18n.getString("stats.keywordValue"));
 193         out.endTag(HTMLWriterEx.H3);
 194         out.newLine();
 195 
 196         // write out the table of keyword statistics
 197 
 198         out.startTag(HTMLWriterEx.TABLE);
 199         out.writeAttr(HTMLWriterEx.BORDER, 1);
 200 
 201         // headers
 202         out.startTag(HTMLWriterEx.TR);
 203         for (int c = 0; c < head.length; c++) {
 204             out.startTag(HTMLWriterEx.TH);
 205             out.writeAttr(HTMLWriterEx.STYLE, c == 0 ? HTMLWriterEx.TEXT_LEFT : HTMLWriterEx.TEXT_RIGHT);
 206             out.write(head[c]);
 207             out.endTag(HTMLWriterEx.TH);
 208         }
 209         out.endTag(HTMLWriterEx.TR);
 210 
 211         // table content
 212         // column 1 left aligned, others right
 213         for (int r = 0; r < table.length; r++) {
 214             out.startTag(HTMLWriterEx.TR);
 215             for (int c = 0; c < table[r].length; c++) {
 216                 out.startTag(HTMLWriterEx.TD);
 217                 out.writeAttr(HTMLWriterEx.STYLE, c == 0 ? HTMLWriterEx.TEXT_LEFT : HTMLWriterEx.TEXT_RIGHT);
 218                 if (table[r][c] == null || table[r][c].equals(""))
 219                     out.writeEntity("&nbsp;");
 220                 else
 221                     out.write(table[r][c]);
 222                 out.endTag(HTMLWriterEx.TD);
 223             }
 224             out.endTag(HTMLWriterEx.TR);
 225         }
 226         out.endTag(HTMLWriterEx.TABLE);
 227     }
 228 
 229     //-----------------------------------------------------------------------
 230 
 231     private TestResultTable resultTable;
 232     private File[] initFiles;
 233     private Map<String, int[]> keywordTable = new HashMap<>();
 234     private int[] statusTotals = new int[Status.NUM_STATES];
 235     private final I18NResourceBundle i18n;
 236 
 237     private final String[] headings;
 238 
 239 }