Package pspdash.reporttemp

Source Code of pspdash.reporttemp.Report4$AtEntryCategory

// Process Dashboard - Data Automation Tool for high-maturity processes
// Copyright (C) 2003 Software Process Dashboard Initiative
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// The author(s) may be contacted at:
// Process Dashboard Group
// c/o Ken Raisor
// 6137 Wardleigh Road
// Hill AFB, UT 84056-5843
//
// E-Mail POC:  processdash-devel@lists.sourceforge.net

package pspdash.reporttemp;


import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import pspdash.Defect;
import pspdash.DefectAnalyzer;
import pspdash.DefectTypeStandard;
import pspdash.HTMLUtils;
import pspdash.StringUtils;
import pspdash.Translator;



public class Report4 extends AnalysisPage implements DefectAnalyzer.Task {


    private static final String TOTAL = resources.getString("Total");

    // In the following map, keys are defect types (e.g. "Syntax") and
    // values are arrays of integers.
    protected Map defectCounts;
    protected int[] totals;
    protected List categories, injCategories, remCategories;
    protected Category atCompile, remCompile;
    protected List allPhases, develPhases, failPhases;
    protected boolean strict = true;
    protected boolean hasCompile = false;


    private static final String HEADER_TEXT =
        "<HTML><HEAD><TITLE>${R4.Title}</TITLE>%css%\n" +
        "<STYLE>\n" +
        "    TABLE { empty-cells: show }\n" +
        "    TD { text-align:center; vertical-align: baseline }\n" +
        "    .header { font-weight: bold; vertical-align:bottom }\n" +
        "    .footnote { font-size: small; font-style:italic }\n" +
        "    @media print { .doNotPrint { display: none } }\n" +
        "</STYLE></HEAD>\n" +
        "<BODY><H1>%path%</H1>";
    private static final String TITLE_TEXT =
        "<H2>${R4.Title}</H2>";

    protected static final String FOOTNOTE =
        "<P class=footnote><span class=doNotPrint>" +
        "${R4.Strict_Footnote_HTML}</span></P>";

    private static final String D24_HEADER =
        "<H3>${R4.D24.Title}</H3>\r\n" +
        "<TABLE NAME=D24 BORDER>\r\n" +
        "<TR class=header><TD>${R4.D24.Defect_Type}</TD>\r\n" +
        "<TD VALIGN=bottom>${R4.D24.Compile_Entry}</TD>" +
        "<TD VALIGN=bottom>${R4.D24.Compile_Found}</TD>" +
        "<TD VALIGN=bottom>${R4.D24.Compile_Percent}</TD></TR>\n";


    /** Generate CGI script output. */
    protected void writeContents() throws IOException {
        String path = getPrefix();
        strict = (parameters.get("strict") != null);

        initValues();
        DefectAnalyzer.run(getPSPProperties(), getDataRepository(),
                           path, parameters, this);
        eliminateEmptyValues();

        writeHTMLHeader(path);

        writeTableD23();
        if (hasCompile)
            writeTableD24();

        writeHTMLFooter();
    }


    protected void writeHTMLHeader(String path) {
      if (!parameters.containsKey(INCLUDABLE_PARAM)) {
          String header = interpolate(HEADER_TEXT, true);
          header = StringUtils.findAndReplace(header, "%css%", cssLinkHTML());
          header = StringUtils.findAndReplace
              (header, "%path%",
               HTMLUtils.escapeEntities(path));
          out.println(header);
      }
      printRes(TITLE_TEXT);
    }


    private void writeHTMLFooter() {
      if (!parameters.containsKey(INCLUDABLE_PARAM)) {
          printRes("<P class='doNotPrint'><A HREF=\"" +
                   PATH_TO_REPORTS+"excel.iqy\"><I>" +
                   "${Export_to_Excel}</I></A></P>");
          if (strict) {
              String query = (String) env.get("QUERY_STRING");
              query = StringUtils.findAndReplace(query, "strict", "notstrict");
              String script = (String) env.get("SCRIPT_NAME");
              script = script.substring(script.lastIndexOf('/')+1);
              String anchor = "<A HREF='" + script + "?" + query + "'>";
              String footnote = interpolate(FOOTNOTE, false);
              footnote = StringUtils.findAndReplace(footnote, "<A>", anchor);
              footnote = StringUtils.findAndReplace(footnote, "<a>", anchor);
              out.println("<P><HR>" + footnote);
          }
          out.println("</BODY></HTML>");
      }
    }


    private void writeTableD23() {
        // write table header
        writeD23Header();

        // write table data
        String defectLogParam = getDefectLogParam();

        Iterator defectTypes = defectCounts.keySet().iterator();
        String defectType;
        int [] row;
        while (defectTypes.hasNext()) {
            defectType = (String) defectTypes.next();
            row = (int[]) defectCounts.get(defectType);
            writeD23Row(defectLogParam, defectType, row);
        }
        writeD23Row(defectLogParam, TOTAL, totals);

        out.println("</TABLE>");
    }


  private void writeD23Header() {
        out.print("<H3>");
        out.print(resources.getHTML("R4.D23.Title"));
        out.println("</H3>");
        out.println("<TABLE NAME=D23 BORDER><TR class=header><TD></TD>");

        int injLen = injCategories.size();
        String txt =
          "<TD colspan=##>${R4.D23.Number_Injected}</TD>\r\n" +
          "<TD colspan=##>${R4.D23.Percentage_Injected}</TD>\r\n";
        txt = StringUtils.findAndReplace(txt, "##", Integer.toString(injLen));
        out.print(interpolate(txt, true));

        int remLen = remCategories.size();
        txt =
          "<TD colspan=##>${R4.D23.Number_Removed}</TD>\r\n" +
          "<TD colspan=##>${R4.D23.Percentage_Removed}</TD></TR>\r\n";
        txt = StringUtils.findAndReplace(txt, "##", Integer.toString(remLen));
        out.print(interpolate(txt, true));

        out.print("<TR><TD>");
        out.print(resources.getHTML("R4.D23.Type"));
        out.println("</TD>");
        printColHeaders(injCategories);
        printColHeaders(injCategories);
        printColHeaders(remCategories);
        printColHeaders(remCategories);
        out.println("</TR>");
    }


    private void printColHeaders(List categories) {
        for (Iterator i = categories.iterator(); i.hasNext();) {
            Category c = (Category) i.next();
            out.print("<TD>");
            out.print(HTMLUtils.escapeEntities(c.displayName()));
            out.print("</TD>");
        }
        out.println();
    }



    protected void writeD23Row(String param, String label, int [] row) {
        String dt = param;
        if (!label.startsWith(TOTAL)) {
            dt += ("&type=" + urlEncode(label));
            if (!strict &&
                    isEmptyRow(row, injCategories) &&
                    isEmptyRow(row, remCategories))
                return;
        }
        out.print("<TR><TD>");
        if (!exporting())
          out.print("<A HREF=\"" + PATH_TO_REPORTS + "defectlog.class?" + dt +"\">");
        out.print(HTMLUtils.escapeEntities(label));
        if (!exporting())
          out.print("</A>");
    out.println("</TD>");

        Iterator i;
        for (i = injCategories.iterator();   i.hasNext(); )
            out.println("<TD>" + fc(dt, row, (Category) i.next()) + "</TD>");
        for (i = injCategories.iterator();   i.hasNext(); )
            out.println("<TD>" + fp(row, (Category) i.next()) + "</TD>");

        for (i = remCategories.iterator();   i.hasNext(); )
            out.println("<TD>" + fc(dt, row, (Category) i.next()) + "</TD>");
        for (i = remCategories.iterator();   i.hasNext(); )
            out.println("<TD>" + fp(row, (Category) i.next()) + "</TD>");

        out.println("</TR>");
    }



    private void writeTableD24() {
        out.print(interpolate(D24_HEADER, true));

        Iterator defectTypes = defectCounts.keySet().iterator();
        while (defectTypes.hasNext()) {
            String defectType = (String) defectTypes.next();
            int[] row = (int[]) defectCounts.get(defectType);
            writeD24Row(defectType, row);
        }
        writeD24Row(TOTAL, totals);

        out.println("</TABLE>");
    }

    protected void writeD24Row(String label, int [] row) {
        int atCompilePos = categories.indexOf(atCompile);
        int remCompilePos = categories.indexOf(remCompile);
        if (!strict && 0 == (row[atCompilePos] +
                             row[remCompilePos]))
            return;

        out.println("<TR><TD>" +
                    HTMLUtils.escapeEntities(label) +
                    "</TD>");
        out.println("<TD>" + fc(null, row, atCompile) + "</TD>");
        out.println("<TD>" + fc(null, row, remCompile) + "</TD>");
        out.println("<TD>" + fp(row, remCompilePos,
                                atCompilePos) + "</TD></TR>");
    }



    private boolean isEmptyRow(int[] row, List categoryList) {
        Iterator i = categoryList.iterator();
        while (i.hasNext()) {
            int pos = categories.indexOf(i.next());
            if (pos >=0 && row[pos] > 0) return false;
        }

        return true;
    }


    /** format a count, found in slot col of array row. */
    protected String fc(String dt, int [] row, Category cat) {
        int col = categories.indexOf(cat);
        if (row[col] == 0) return NA;
        if (dt == null || exporting()) return Integer.toString(row[col]);
        return "<A HREF=\"" + PATH_TO_REPORTS + "defectlog.class?"
            + cat.getFilter() + "&" + dt + "\">" + row[col] + "</A>";
    }
    /** format a percentage, calculated by dividing item n of row by item d */
    protected String fp(int num, int denom) {
        if (num == 0 || denom == 0) return NA;
        return formatPercent(((double) num) / denom);
    }
    protected String fp(int [] row, Category c) {
        int n = categories.indexOf(c);
        return fp(row[n], totals[n]);
    }
    protected String fp(int [] row, int n) { return fp(row[n], totals[n]); }
    protected String fp(int [] row, int n, int d) { return fp(row[n],row[d]); }
    private static final String NA = resources.getString("R4.NA");

    protected String formatPercent(double d) {
        return Integer.toString((int) Math.round(d * 100)) + "%";
    }


    /** Initialize internal data structures to zero */
    private void initValues() {
        categories = new LinkedList();
        injCategories = new LinkedList();
        remCategories = new LinkedList();
        develPhases = getProcessListPlain("Development_Phase_List");
        failPhases = getProcessListPlain("Failure_Phase_List");
        allPhases = getProcessListPlain("Phase_List");

        for (Iterator i = develPhases.iterator(); i.hasNext();) {
            Category c = new InjCategory((String) i.next());
            categories.add(c);
            injCategories.add(c);
        }
        for (Iterator i = failPhases.iterator(); i.hasNext();) {
            Category c = new RemCategory((String) i.next());
            categories.add(c);
            remCategories.add(c);
        }
        hasCompile = allPhases.contains("Compile");
        if (hasCompile) {
            atCompile = new AtEntryCategory(allPhases, "Compile");
            remCompile = new FilteredByPhaseCategory(allPhases, "Compile");
            categories.add(atCompile);
            categories.add(remCompile);
        }

        totals = emptyRow();
        defectCounts = new TreeMap();
        if (strict) {
            DefectTypeStandard dts =
                DefectTypeStandard.get(getPrefix(), getDataRepository());
            for (int i=dts.options.size();  i-->0; )
                getRow((String) dts.options.elementAt(i));
        }
    }


    /** Discard defect categories containing no data */
    private void eliminateEmptyValues() {
        for (Iterator i = injCategories.iterator();   i.hasNext(); )
            if (totals[categories.indexOf(i.next())] == 0)
                i.remove();

        for (Iterator i = remCategories.iterator();   i.hasNext(); )
            if (totals[categories.indexOf(i.next())] == 0)
                i.remove();
    }


    /** Lookup the row for a defect type - create it if it doesn't exist. */
    private int[] getRow(String defectType) {
        int [] result = (int[]) defectCounts.get(defectType);
        if (result == null)
            defectCounts.put(defectType, result = emptyRow());
        return result;
    }

    /** Generate an empty row of the appropriate size */
    private int[] emptyRow() {
        int numCat = categories.size();
        int [] result = new int[numCat];
        for (int i=0;  i<numCat;  i++) result[i] = 0;
        return result;
    }

    /** Increment a defect count for a particular defect type */
    protected void increment(int [] row, int type) {
        totals[type]++;
        row[type]++;
    }

    /** Implement DefectAnalyzer.Task */
    public void analyze(String path, Defect d) {
        int [] row = getRow(d.defect_type);

        for (int i = categories.size();   i-- > 0; ) {
            Category c = (Category) categories.get(i);
            if (c.matches(d)) increment(row, i);
        }
    }



    private static class Category {
        protected String phaseName;
        public boolean matches(Defect d) { return false; }
        public String getFilter() { return ""; }

        protected String cleanupPhase(String phaseName) {
            int pos = phaseName.lastIndexOf('/');
            if (pos == -1)
                return phaseName;
            else
                return phaseName.substring(pos+1);
        }

        protected boolean matches(String phaseName) {
            return (this.phaseName.equals(cleanupPhase(phaseName)));
        }

        public String displayName() {
            return Translator.translate(phaseName);
        }
    }


    private static final class InjCategory extends Category {
        public InjCategory(String phaseName) {
            this.phaseName = phaseName;
        }
        public boolean matches(Defect d) {
            return matches(d.phase_injected);
        }
        public String getFilter() {
            return "inj=" + urlEncode(phaseName);
        }
    }


    private static final class RemCategory extends Category {
        public RemCategory(String phaseName) {
            this.phaseName = phaseName;
        }
        public boolean matches(Defect d) {
            return matches(d.phase_removed);
        }
        public String getFilter() {
            return "rem=" + urlEncode(phaseName);
        }
    }


    private static class AtEntryCategory extends Category {
        private List phases;
        private int phasePos;
        public AtEntryCategory (List phases, String phaseName) {
            this.phases = phases;
            this.phaseName = phaseName;
            this.phasePos = phases.indexOf(phaseName);
        }
        public boolean matches(Defect d) {
            int injPos = phases.indexOf(cleanupPhase(d.phase_injected));
            if (injPos >= phasePos) return false;

            int remPos = phases.indexOf(cleanupPhase(d.phase_removed));
            if (remPos == -1 || remPos >= phasePos) return true;

            return false;
        }
    }


    private static class FilteredByPhaseCategory extends AtEntryCategory {
        public FilteredByPhaseCategory (List phases, String phaseName) {
            super(phases, phaseName);
        }
        public boolean matches(Defect d) {
            return super.matches(d) && super.matches(d.phase_removed);
        }
    }
}
TOP

Related Classes of pspdash.reporttemp.Report4$AtEntryCategory

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