Package com.sun.faban.harness.webclient

Source Code of com.sun.faban.harness.webclient.RunResult

/* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* http://www.sun.com/cddl/cddl.html or
* install_dir/legal/LICENSE
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at install_dir/legal/LICENSE.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id$
*
* Copyright 2005-2009 Sun Microsystems Inc. All Rights Reserved
*/
package com.sun.faban.harness.webclient;

import com.sun.faban.common.SortDirection;
import com.sun.faban.common.SortableTableModel;
import com.sun.faban.harness.ParamRepository;
import com.sun.faban.harness.common.BenchmarkDescription;
import com.sun.faban.harness.common.Config;
import com.sun.faban.harness.common.RunId;
import com.sun.faban.harness.engine.RunQ;
import com.sun.faban.harness.security.AccessController;
import com.sun.faban.harness.util.FileHelper;
import com.sun.faban.harness.util.XMLReader;

import javax.security.auth.Subject;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* Result class scans through the output directory and compiles a list of run
* results. Enhance this to enable the user to sort it using different options.
*/
public class RunResult {

    /**
     * Status and result values when they are not available. The
     * 6 character string with all lower case 'z' is after any other
     * possible status string or result string in the collation sequence.
     */
    private static final String NOT_AVAILABLE = "zzzzzz";
    private static final String[] EMPTY_ARRAY = new String[0];
    private static final int FEED_LIMIT = 25;

    private static Logger logger = Logger.getLogger(RunResult.class.getName());
    private static ConcurrentHashMap<String, RunResult> resultCache =
            new ConcurrentHashMap<String, RunResult>(1024);

    // The format in the result file
    private SimpleDateFormat parseFormat = new SimpleDateFormat(
                              "EEE MMM dd HH:mm:ss z yyyy");

    private static SimpleDateFormat dateFormatOrig = new SimpleDateFormat(
                                    "MM/dd/yy EEE'&#160;'HH:mm:ss'&#160;'z");

    private long modTime = 0;

    /** The run id. */
    public RunId runId;

    /** The run description. */
    public String description;

    /** The result. */
    public String result;

    /** The link for the result to link to. */
    public String resultLink;

    /** The name of the scale. */
    private String scaleName;

    /** The scale value. */
    public String scale;

    /** The unit of the scale. */
    private String scaleUnit;

    /** The metric. */
    public ResultField<Double> metric = new ResultField<Double>();

    /** The unit of the metric. */
    private String metricUnit;

    /** The status of the run. */
    public String status;

    /** The link to the run logs. */
    public String logLink;

    /** The timestamp of the run. */
    public Date dateTime;

    /** The run submitter. */
    public String submitter;

    /** Tags applicable to this run. */
    public String[] tags;
    static LinkedHashMap<String, Target> targetMap = new LinkedHashMap<String, Target>();

    /**
     * This getInstance0 assumes you've checked the run id is found. It will
     * return an instance. If the run id is not there, the behavior is not
     * defined. This is why it is a private interface.
     * @param runId The run id of the run
     * @return A result instance.
     */
    private static RunResult getInstance0(RunId runId) {
        RunResult result = new RunResult(runId);
        RunResult oldResult = resultCache.putIfAbsent(runId.toString(), result);
        if (oldResult != null)
            result = oldResult;
        try {
            result.refresh();
        } catch (RuntimeException e) {
            logger.log(Level.WARNING, runId.toString() +
                    ": Error reading run.", e);
            result.description = "Error reading this result";
        }
        return result;
    }

    /**
     * Obtains the result of a certain run id.
     * @param runId The run id to query
     * @return An instance of the result, or null if such runId is not found
     */
    public static RunResult getInstance(RunId runId) {
        if (runId.getResultDir().isDirectory())
            return getInstance0(runId);
        return null;
    }

    private RunResult(RunId runId) {
        this.runId = runId;
    }

    private synchronized void refresh() {

        File resultDir = runId.getResultDir();

        long modTime = resultDir.lastModified();
        if (modTime <= this.modTime) {
            logger.finer("Run " + runId + " already cached.");
            return;
        }
        logger.finer("Fetching run " + runId + " from disk.");
        this.modTime = modTime;

        String shortName = runId.getBenchName();       

        String resultFilePath;
        String configFileName;
        BenchmarkDescription desc = BenchmarkDescription.
                getDescription(shortName, resultDir.getAbsolutePath());
        if (desc == null) {
            Map<String, BenchmarkDescription> benchMap =
                    BenchmarkDescription.getBenchDirMap();
            desc = (BenchmarkDescription) benchMap.get(shortName);
        }

        if (desc == null) {
            logger.warning(runId.toString() + ": Cannot find benchmark " +
                    "description in result and benchmark not deployed, " +
                    "trying default values");
           
            // Assigning default values;
            resultFilePath = "summary.xml";
            configFileName = "run.xml";
        } else {
            resultFilePath = desc.resultFilePath;
            configFileName = desc.configFileName;
            scaleName = desc.scaleName;
            scaleUnit = desc.scaleUnit;
            metricUnit = desc.metric;
        }

        String[] statusFileContent = readStatus(runId.toString());

        // run result and HREF to the summary or log file.
        File resultFile = new File(resultDir, "summary.xml");
        if (resultFile.exists() && resultFile.length() > 0) {
            result = "PASSED";
            resultLink = "/resultframe.jsp?runId=" +
                    this.runId + "&result=" +
                    resultFilePath;

            //Use the XMLReader and locate the <passed> elements
            XMLReader reader = new XMLReader(resultFile.
                    getAbsolutePath());

            // Obtain the metric before we break pass/fail.
            metric.text = reader.getValue("benchSummary/metric");
            if (metric.text != null && metric.text.length() > 0)
                metric.value = new Double(metric.text);
            try {
                dateTime = parseFormat.parse(
                        reader.getValue("benchSummary/endTime"));
            } catch (ParseException e) {
                // Do nothing. result.dateTime will be null and
                // later we'll use the param file's mod dateTime
                // for this field instead.
            }

            List<String> passedList = reader.getValues("passed");
            for(String passed : passedList) {
                if(passed.toUpperCase().indexOf("FALSE") != -1) {
                    result = "FAILED";
                    break;
                }
            }
        }

        status = statusFileContent[0];

        if (!"UNKNOWN".equals(status) ||
                new File(resultDir, "log.xml").isFile()) {
            StringBuilder b = new StringBuilder(
                    "/resultframe.jsp?runId=");
            b.append(this.runId);
            b.append("&result=");
            b.append(resultFilePath);
            b.append("&show=logs");
            logLink = b.toString();
        } else {
            logLink = "";
        }

        if (dateTime == null && statusFileContent[1] != null) {
            try {
                dateTime = parseFormat.parse(statusFileContent[1]);
            } catch (ParseException e) {
                // Do nothing. result.dateTime will be null and
                // later we'll use the param file's mod dateTime
                // for this field instead.
            }
        }

        String paramFileName = resultDir.getAbsolutePath() +
                File.separator + configFileName;
        File paramFile = new File(paramFileName);

        if (paramFile.isFile()) {

            // Compatible with old versions of Config.RESULT_INFO
            // Old version does not have timestamp in RESULT_INFO
            // So we need to establish it from the paramFile timestamp.
            // This block may be removed in future.
            if (dateTime == null) {
                dateTime = new Date(paramFile.lastModified());
            }
            // End compatibility block

            ParamRepository par = new ParamRepository(paramFileName, false);
            description = par.getParameter("fa:runConfig/fh:description");
            scale = par.getParameter("fa:runConfig/fa:scale");
        } else {
            logger.warning(runId.toString() +
                    ": Parameter file invalid or non-existent.");
        }
           
        File submitterFile = new File(resultDir, "META-INF" + File.separator +
                                      "submitter");
        if (submitterFile.exists())
            try {
                submitter = FileHelper.readStringFromFile(submitterFile).trim();
            } catch (IOException e) {
                logger.log(Level.WARNING, "Error reading submitter file for " +
                        "run " + runId, e);
            }

        File tagsFile = new File(resultDir, "META-INF" + File.separator +
                                            "tags");
        if (tagsFile.exists()) {
            try {
                tags = FileHelper.readArrayContentFromFile(tagsFile);
            } catch (IOException e) {
                logger.log(Level.WARNING, "Error reading tags file for " +
                        "run " + runId, e);
            }
        }else{
            tags = new String[1];
            tags[0] = "&nbsp";
        }
    }

    /**
     * Obtains the current status of a run.
     * @param runId The id of the run in question
     * @return The current status string or "UNKNOWN" in error cases
     */
    public static String[] readStatus(String runId) {
        char[] cBuf = null;
        String[] status = new String[2];
        int length = -1;
        try {
            FileReader reader = new FileReader(Config.OUT_DIR + runId +
                    '/' + Config.RESULT_INFO);
            cBuf = new char[128];
            length = reader.read(cBuf);
            reader.close();
        } catch (IOException e) {
            // Do nothing, length = -1.
        }

        if (length == -1) {
            status[0] = "UNKNOWN";
        } else {
            String content = new String(cBuf, 0, length);
            int idx = content.indexOf('\t');
            if (idx != -1) {
                status[0] = content.substring(0, idx).trim();
                status[1] = content.substring(++idx);
            } else {
                status[0] = content.trim();
            }
        }
        return status;
    }

    /**
     * Obtains the status of a given run. If it is queued, returns "QUEUED"
     * @param runId The run id to obtain status
     * @return The status string, or null if run cannot be found.
     */
    public static String getStatus(RunId runId) {
        String status = null;
        RunResult result = getInstance(runId);
        if (result == null) {
            // Perhaps the runId is still in the pending queue.
            String[] pending = RunQ.listPending();
            for (String run : pending)
                if (run.equals(runId.toString())) {
                    status = "QUEUED";
                    break;
                }
            if (status == null) {
                return null;
            }
        } else {
            status = result.status;
        }
        if (status == null) // Worse come to worse, the run dir is in bad shape.
            status = "UNKNOWN";
        return status;
    }


    /**
     * Returns the SortableTableModel with tag search.
     * @param user
     * @param tags
     * @param column
     * @param sortDirection
     * @return SortableTableModel
     * @throws java.io.IOException
     */
    public static SortableTableModel getResultTable(Subject user, String tags,
            int column, String sortDirection)
            throws IOException {
        TagEngine tagEngine;
        try {
            tagEngine = TagEngine.getInstance();
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "Cannot find tag engine class", ex);
            throw new IOException("Cannot find tag engine class", ex);
        }
        Set<String> runIds = tagEngine.search(tags);
        ArrayList<RunResult> resultList =
                new ArrayList<RunResult>(runIds.size());
        for (String runid : runIds) {
            try {
                RunId runId = new RunId(runid);
                if (!AccessController.isViewAllowed(user, runid))
                    continue;
                RunResult res = getInstance(runId);
                if (res == null){
                    try{                       
                        tagEngine.removeRun(runid);
                        tagEngine.save();
                    } catch (Exception e) {
                        logger.log(Level.WARNING, "Cannot remove run " + runid, e);
                    }
                } else
                    resultList.add(res);
            } catch (Exception e) {
                logger.log(Level.WARNING, "Cannot read result dir " + runid, e);
            }
        }
        return generateTable(resultList, column, sortDirection);
    }

    /**
     * Returns the SortableTableModel.
     * @param user The authenticated subject, if any
     * @param column The sort column id
     * @param sortDirection The sort direction
     * @return The SortableTableModel representing this table
     */
    public static SortableTableModel getResultTable(Subject user, int column,
                                                    String sortDirection) {

        File[] dirs = new File(Config.OUT_DIR).listFiles();
        ArrayList<RunResult> runs = new ArrayList<RunResult>(dirs.length);
        for (File runDir : dirs) {
            if (!runDir.isDirectory()) {
                continue;
            }
            String runIdS = runDir.getName();
            try {
                if (!AccessController.isViewAllowed(user, runIdS) || runIdS.contains("analysis")) {
                    continue;
                }
                RunId runId = new RunId(runIdS);
                RunResult result = getInstance0(runId);
                if (result == null) {
                    continue;
                }
                runs.add(result);
            } catch (Exception e) {
                logger.log(Level.WARNING, "Cannot read result dir " + runIdS,
                                                                            e);
            }
        }
        return generateTable(runs, column, sortDirection);
    }

    /**
     * Generates the table.
     * @param runs The runs to include in the table
     * @param column The sort column
     * @param sortDirection The sort direction
     * @return The SortableTableModel
     */
    static SortableTableModel generateTable(List<RunResult> runs, int column,
            String sortDirection) {

        HashSet<String> scaleNames = new HashSet<String>();
        HashSet<String> scaleUnits = new HashSet<String>();
        HashSet<String> metricUnits = new HashSet<String>();

        // 1. Scan result for scale names, units and metric units
        RunResult result0 = null;
        for (RunResult result : runs) {
                if (result.scaleName != null)
                    scaleNames.add(result.scaleName);
                else
                    scaleNames.add("Scale");
                if (result.scaleUnit != null)
                    scaleUnits.add(result.scaleUnit);

                if (result.metricUnit != null)
                    metricUnits.add(result.metricUnit);
                else
                    metricUnits.add("Metric");

                if (result0 == null)
                    result0 = result;
        }
       
        if (result0 == null) // No rows!
            return null;

        // 2. Generate table header
        SortableTableModel table = new SortableTableModel(9);
        String sort = "<img src=/img/sort_asc.gif></img>";
        if(sortDirection.equals("DESCENDING")){
             sort = "<img src=\"/img/sort_asc.gif\" border=\"0\"></img>";
        }else if(sortDirection.equals("ASCENDING")){
             sort = "<img src=\"/img/sort_desc.gif\" border=\"0\"></img>";
        }
        if(column == 0)
            table.setHeader(0, "RunID " + sort);
        else
            table.setHeader(0, "RunID");

        if(column == 1)
            table.setHeader(1, "Description " + sort);
        else
            table.setHeader(1, "Description");

        if(column == 2)
            table.setHeader(2, "Result " + sort);
        else
            table.setHeader(2, "Result");

        boolean singleScale = false;
        if (scaleNames.size() == 1 && scaleUnits.size() == 1) {
            singleScale = true;
            if (result0.scaleName.length() > 0 &&
                    result0.scaleUnit.length() > 0){
                table.setHeader(3, result0.scaleName + " (" +
                        result0.scaleUnit + ')');
            }else if (result0.scaleName.length() > 0){
                table.setHeader(3, result0.scaleName);
            }else if (result0.scaleUnit.length() > 0){
                table.setHeader(3, result0.scaleUnit);
            }else{
                if(column == 3)
                    table.setHeader(3, "Scale " + sort);
                else
                    table.setHeader(3, "Scale");
            }

        } else {
            if(column == 3)
                table.setHeader(3, "Scale " + sort);
            else
                table.setHeader(3, "Scale");
        }

        boolean singleMetric = false;
        if (metricUnits.size() == 1) {
            singleMetric = true;
            if (result0.metricUnit.length() > 0){
                table.setHeader(4, result0.metricUnit);
            }else{
                if(column == 4)
                    table.setHeader(4, "Metric " + sort);
                else
                    table.setHeader(4, "Metric");
            }
        } else {
            if(column == 4)
                table.setHeader(4, "Metric " + sort);
            else
                table.setHeader(4, "Metric");
        }

        //table.setHeader(5, "Status");
        if(column == 5)
            table.setHeader(5, "Date/Time " + sort);
        else
            table.setHeader(5, "Date/Time");

        if(column == 6)
            table.setHeader(6, "Submitter " + sort);
        else
            table.setHeader(6, "Submitter");

        if(column == 7)
            table.setHeader(7, "Tags " + sort);
        else
            table.setHeader(7, "Tags");

        // Pseudo-column for the link.
        table.setHeader(8, "Link");

        // 3. Generate table rows.
        StringBuilder b = new StringBuilder();
        // The output format.
        SimpleDateFormat dateFormat = (SimpleDateFormat) dateFormatOrig.clone();
        for (RunResult result : runs) {
            //int idx = table.newRow();
            Comparable[] row = table.newRow();
            row[0] = result.runId;
            if (result.description == null || result.description.length() == 0)
                row[1] = "UNAVAILABLE";
            else
                row[1] = result.description;

            row[8] = ""; // Initialize the link to zero string in case it does not get set.
            ResultField<String> r = new ResultField<String>();
            if (result.result != null) {
                r.value = result.result;
                if (result.resultLink != null){
                    if(result.result.equals("PASSED"))
                        r.text = "<img onmouseover=\"showtip('" + result.result.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/passed.png'></img>";
                    else if(result.result.equals("FAILED"))
                        r.text = "<img onmouseover=\"showtip('" + result.result.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/failed.png'></img>";
                    row[8] = result.resultLink;
                }
            } else if (result.status != null) {
                r.value = result.status;
                if (result.logLink != null){
                    if(result.status.equals("FAILED"))
                        r.text = "<img onmouseover=\"showtip('" + result.status.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/incomplete.png'></img>";
                    else if(result.status.equals("KILLED"))
                        r.text = "<img onmouseover=\"showtip('" + result.status.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/killed.png'></img>";
                    else if(result.status.equals("RECEIVED"))
                        r.text = "<img onmouseover=\"showtip('" + result.status.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/received.png'></img>";
                    else if(result.status.equals("STARTED"))
                        r.text = "<img onmouseover=\"showtip('" + result.status.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/running.png'></img>";
                    else if(result.status.equals("COMPLETED"))
                        r.text = "<img onmouseover=\"showtip('" + result.status.toString() + "')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/failed.png'></img>";
                    else if(result.status.equals("UNKNOWN"))
                        r.text = "<img onmouseover=\"showtip('unknown')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/unknown.png'></img>";
                    row[8] = result.logLink;
                }
            } else {
                r.value = NOT_AVAILABLE;
                r.text = "<img onmouseover=\"showtip('unknown')\" onmouseout=\"hideddrivetip()\" class=\"icon\"; src='/img/unknown.png'></img>";
            }
            row[2] = r;

            ResultField<Integer> scale = new ResultField<Integer>();
            if (result.scale == null || result.scale.length() < 1) {
                scale.text = "N/A";
                scale.value = Integer.MIN_VALUE;
            } else if (singleScale) {
                scale.text = result.scale;
                scale.value = new Integer(result.scale);
            } else {
                b.append(result.scale);
                if (result.scaleName.length() > 0)
                    b.append(' ').append(result.scaleName).append(' ');
                if (result.scaleUnit.length() > 0)
                    b.append(' ').append(result.scaleUnit);
                scale.text = b.toString();
                scale.value = new Integer(result.scale);
                b.setLength(0);
            }
            row[3] = scale;


            ResultField<Double> metric = new ResultField<Double>();
            if (result.metric.text == null) {
                metric.text = "N/A";
                metric.value = -1d;
            } else if (singleMetric) {
                metric.text = result.metric.text;
                metric.value = result.metric.value;
            } else {
                b.append(result.metric);
                if (result.metricUnit.length() > 0)
                    b.append(' ').append(result.metricUnit);
                metric.text = b.toString();
                metric.value = result.metric.value;
                b.setLength(0);
            }
            row[4] = metric;

            /*ResultField<String> status = new ResultField<String>();
            if (result.status != null) {
                status.value = result.status;
                if (result.logLink != null)
                    status.text = "<a href=\""+ result.logLink + "\">" +
                            result.status + "</a>";
                else
                    status.text = result.status;
            } else {
                status.value = NOT_AVAILABLE;
                status.text = "UNKNOWN";
            }
            row[5] = status;*/

            ResultField<Long> dateTime = new ResultField<Long>();
            if (result.dateTime != null) {
                dateTime.text = dateFormat.format(result.dateTime);
                dateTime.value = result.dateTime.getTime();
            } else {
                dateTime.text = "N/A";
                dateTime.value = 0l;
            }
            row[5] = dateTime;

            if (result.submitter != null)
                row[6] = result.submitter;
            else
                row[6] = "&nbsp;";


            if (result.tags != null && result.tags.length > 0) {
                for (String tag : result.tags) {
                    b.append(tag).append(' ');
                }
                b.setLength(b.length() - 1);
                row[7] = b.toString();
                b.setLength(0);
            } else {
                row[7] = "&nbsp;";
            }
        }

        SortDirection enumValForDirection = SortDirection.valueOf(sortDirection);
        table.sort(column, enumValForDirection);
        return table;
    }

    /*
     * Deletes a certain run.
     * @param RunId of run run to delete
     * @return true if delete succeeds, false otherwise
     */
    public boolean delete(String runIdStr) {
        RunId runId = new RunId(runIdStr);
        File f = runId.getResultDir();
        if (f.isDirectory()) {
            return(FileHelper.recursiveDelete(f));
        }
        return(true);
    }

     private static HashMap<String, String> getAchievedMetricForTarget(String tags)
            throws IOException {
        HashMap<String, String> achievedMetricMap = new HashMap<String, String>();
        TagEngine tagEngine;
        try {
            tagEngine = TagEngine.getInstance();
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "Cannot find tag engine class", ex);
            throw new IOException("Cannot find tag engine class", ex);
        }
        Set<String> runIds = tagEngine.search(tags);
        Double achievedMetric = 0.0;
        String achievedMetricUnit = " ";
        for (String runid : runIds) {
            try {
                RunId runId = new RunId(runid);
                RunResult res = getInstance(runId);
                if (res != null && achievedMetric < res.metric.value){
                    achievedMetric = res.metric.value;
                    achievedMetricUnit = res.metricUnit;
                }
            } catch (Exception e) {
                logger.log(Level.WARNING, "Cannot read result dir " + runid, e);
            }
        }
        achievedMetricMap.put("metric", achievedMetric.toString());
        achievedMetricMap.put("metricunit", achievedMetricUnit);
        return achievedMetricMap;
    }


    /**
     * Returns the target list with target search.
     * @param target
     * @return ArrayList
     * @throws java.io.IOException
     */
    public static ArrayList<Target> getTargetListForTarget(String target)
            throws IOException {
        ArrayList<Target> targetList = getTargetList();
        if(target != null ){
            targetList = new ArrayList<Target>();
            Object[] keyset = targetMap.keySet().toArray();
            for (int i = 0; i < keyset.length; i++) {
                    if (keyset[i].toString().contains(target) && targetMap.containsKey(keyset[i])) {
                        targetList.add(targetMap.get(keyset[i]));
                    }
            }
        }
        return targetList;
    }

    public static ArrayList<Target> getTargetListForUserWithTg(String target, String user)
            throws IOException {
        ArrayList<Target> list = new ArrayList<Target>();
        if(target != null && user != null){
            ArrayList<Target> targetList = getTargetListForTarget(target);
            for (int i = 0; i < targetList.size(); i++) {
                String owner = targetList.get(i).owner.toString();
                if (owner.equals(user)) {
                    list.add(targetList.get(i));
                }
            }
        }
        return list;
    }

    public static ArrayList<Target> getTargetListForUser(String user)
            throws IOException {
        ArrayList<Target> list = new ArrayList<Target>();
        if(user != null){
            ArrayList<Target> targetList = getTargetList();
            for (int i = 0; i < targetList.size(); i++) {
                String owner = targetList.get(i).owner.toString();
                if (owner.equals(user)) {
                    list.add(targetList.get(i));
                }
            }
        }
        return list;
    }


    static SortableTableModel generateTargetTable(List<Target> targets, int column,
            String sortDirection) {

        // 1. Generate table header
        SortableTableModel table = new SortableTableModel(9);

        String sort = "<img src=/img/sort_asc.gif></img>";
        if(sortDirection.equals("DESCENDING")){
             sort = "<img src=\"/img/sort_asc.gif\" border=\"0\"></img>";
        }else if(sortDirection.equals("ASCENDING")){
             sort = "<img src=\"/img/sort_desc.gif\" border=\"0\"></img>";
        }
        if(column == 0)
            table.setHeader(0, "Targets " + sort);
        else
            table.setHeader(0, "Targets");

        if(column == 1)
            table.setHeader(1, "Owner " + sort);
        else
            table.setHeader(1, "Owner");

        if(column == 2)
            table.setHeader(2, "Status " + sort);
        else
            table.setHeader(2, "Status");

        if(column == 3)
            table.setHeader(3, "Achieved Metric " + sort);
        else
            table.setHeader(3, "Achieved Metric");

        if(column == 4)
            table.setHeader(4, "Metric " + sort);
        else
            table.setHeader(4, "Metric");

        if(column == 5)
            table.setHeader(5, "Tags " + sort);
        else
            table.setHeader(5, "Tags");

        // 2. Generate table rows.
        for (Target target : targets) {
            //int idx = table.newRow();
            Comparable[] row = table.newRow();
            row[0] = target.name;
            row[1] = target.owner;
            row[2] = target.status;
            row[3] = target.achievedMetric+ " " + target.achievedMetricunit;
            row[4] = target.metric + " " + target.metricunit;
            row[5] = target.tags;
            row[6] = target.red;
            row[7] = target.orange;
            row[8] = target.yellow;
        }

        SortDirection enumValForDirection = SortDirection.valueOf(sortDirection);
        table.sort(column, enumValForDirection);
        return table;
    }

    /**
     * Obtains a list of targets currently in the system.
     * @return The list of targets or an empty list if none available
     * @throws IOException Error accessing targets file
     */
    public static ArrayList<Target> getTargetList() throws IOException{
        ArrayList<Target> targetList = new ArrayList<Target>();
        File targetFile = new File(Config.CONFIG_DIR, "targets.xml");
        if (targetFile.exists() && targetFile.length() > 0) {
            //Use the XMLReader and locate the <passed> elements
            XMLReader reader = new XMLReader(targetFile.
                    getAbsolutePath());
            if (reader != null) {
                NodeList targets = reader.getNodeListForTagName("target");
                int targetCount;
                if((targetCount = targets.getLength()) > 0) {
                    for (int i = 0; i < targetCount; i++) {
                        Target tg = new Target();
                        Node targetNode = targets.item(i);
                        if (targetNode.getNodeType() != Node.ELEMENT_NODE) {
                            continue;
                        }
                        Element se = (Element) targetNode;
                        NodeList targetNodeChildNodes =
                                                    targetNode.getChildNodes();
                        int len = targetNodeChildNodes.getLength();
                        for (int k = 0; k < len; k++) {
                            if (targetNodeChildNodes.item(k).getNodeType() ==
                                    Node.ELEMENT_NODE) {
                                String nodeName = targetNodeChildNodes.item(k).
                                                    getNodeName();
                                if ("name".equals(nodeName)) {
                                    tg.name = reader.getValue("name", se);
                                } else if ("owner".equals(nodeName)) {
                                    tg.owner = reader.getValue("owner", se);
                                } else if ("tags".equals(nodeName)) {
                                    tg.tags = reader.getValue("tags", se);
                                } else if ("metric".equals(nodeName)) {
                                    tg.metric = reader.getValue("metric", se);
                                } else if ("metricunit".equals(nodeName)) {
                                    tg.metricunit = reader.getValue(
                                            "metricunit", se);
                                } else if ("red".equals(nodeName)) {
                                    tg.red = reader.getValue("red", se);
                                } else if ("orange".equals(nodeName)) {
                                    tg.orange = reader.getValue("orange", se);
                                } else if ("yellow".equals(nodeName)) {
                                    tg.yellow = reader.getValue("yellow", se);
                                }
                            }
                        }
                        HashMap<String, String> achievedMetricMap =
                                getAchievedMetricForTarget(tg.tags);
                        tg.achievedMetric = achievedMetricMap.get("metric");
                        tg.achievedMetricunit =
                                achievedMetricMap.get("metricunit");
                        Double status = ((Double.parseDouble(tg.achievedMetric)/
                                          Double.parseDouble(tg.metric)) * 100);
                        tg.status = status.toString();
                        targetList.add(tg);
                        targetMap.put(tg.name.toString(), tg);
                    }
                }
            }
        }
        return targetList;
    }

    /**
     * A result field representing the real value of the field used for
     * sorting, and the text representation of the value.
     */
    public static class ResultField<T extends Comparable>
            implements Comparable {

        String text;
        T value;

        public int compareTo(Object o) {
            ResultField other = (ResultField) o;
            return value.compareTo(other.value);
        }

        @Override
        public String toString() {
            return text;
        }
    }

    /**
     * The feed record for the run results.
     */
    public static class FeedRecord {

        /** The feed title. */
        public String title;

        /** The feed summary. */
        public String summary;

        /** The feed id. */
        public String id;

        /** Timestamp. */
        long date;

        /** The formatted timestamp. */
        public String updated;

        /** Resource URL. */
        public String link;

        /** List of tags on the resource. */
        public String[] tags;

        FeedRecord(RunId runId, RunResult result) {
            StringBuilder b = new StringBuilder();
            b.append(runId).append(" [").append(result.scale);
            if (result.metric.value != null)
                b.append(", ").append(result.metric.text);

            // If result.result is valid, use it. Otherwise, use result.status.
            if (result.result != null)
                b.append(", ").append(result.result);
            else if (result.status != null)
                b.append(", ").append(result.status);
           
            b.append(']');
            title = b.toString();
            summary = result.description;
            id = runId.toString();

            link = "/controller/results/location/" + runId;

            date = result.dateTime.getTime();
            if (result.tags == null)
                tags = EMPTY_ARRAY;
            else
                tags = result.tags;
        }
    }

    /**
     * Obtains the list of feeds.
     * @param user
     * @return List<FeedRecord>.
     */
    public static List<FeedRecord> getFeeds(Subject user) {

        File[] dirs = new File(Config.OUT_DIR).listFiles();
        ArrayList<FeedRecord> feedList = new ArrayList<FeedRecord>(dirs.length);
        RunResult result0 = null;
        for (File runDir : dirs) {
            if (!runDir.isDirectory())
                continue;
            String runIdS = runDir.getName();
            try {
                RunId runId = new RunId(runIdS);
                if (!AccessController.isViewAllowed(user, runIdS))
                    continue;
                result0 = getInstance0(runId);
                FeedRecord feedRecord = new FeedRecord(runId, result0);
                feedList.add(feedRecord);
            } catch (Exception e) {
                logger.log(Level.WARNING, "Cannot read result dir " + runIdS,
                                                                            e);
            }
        }
        return sortAndLimit(feedList);
    }

    /**
     * Obtains the list of feeds based on tags.
     * @param user
     * @param tags
     * @return List<FeedRecord>
     * @throws java.io.IOException
     */
    public static List<FeedRecord> getFeeds(Subject user, String[] tags)
            throws IOException {

        TagEngine tagEngine;
        try {
            tagEngine = TagEngine.getInstance();
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "Cannot find tag engine class", ex);
            throw new IOException("Cannot find tag engine class", ex);
        }
        Set<String> runIds = tagEngine.search(tags);
        ArrayList<FeedRecord> feedList =
                                new ArrayList<FeedRecord>(runIds.size());
        RunResult res = null;
        boolean runRemoved = false;
        for (String runid : runIds) {
            try {
                RunId runId = new RunId(runid);
                if (!AccessController.isViewAllowed(user, runid))
                    continue;
                res = getInstance(runId);
                if (res == null){
                    tagEngine.removeRun(runid);
                    runRemoved = true;
                }
                FeedRecord feedRecord = new FeedRecord(runId, res);
                feedList.add(feedRecord);
            } catch (Exception e) {
                logger.log(Level.WARNING, "Cannot read result dir " + runid, e);
            }
        }
        if (runRemoved)
            tagEngine.save();
        return sortAndLimit(feedList);
    }

    private static List<FeedRecord> sortAndLimit(List<FeedRecord> feedList) {

        // Sort the list, newest first.
        Collections.sort(feedList, new Comparator<FeedRecord>() {
            public int compare(FeedRecord a, FeedRecord b) {
                if (a.date > b.date)
                    return -1;
                else if (a.date < b.date)
                    return 1;
                else
                    return 0;
            }
        });
       
        // Then limit to FEED_LIMIT (25) items.
        if (feedList.size() > FEED_LIMIT)
            return feedList.subList(0, FEED_LIMIT);
        return feedList;
    }

    public static class Target implements Serializable {
        public String name;
        public String owner;
        public String tags;
        public String runs;
        public String status;
        public String metric;
        public String metricunit;
        public String achievedMetric;
        public String achievedMetricunit;
        public String red;
        public String orange;
        public String yellow;
    }
}
TOP

Related Classes of com.sun.faban.harness.webclient.RunResult

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.