package com.instantiations.assist.eclipse.analysis.audit.writer;
 
import com.instantiations.assist.eclipse.analysis.audit.core.*;
import com.instantiations.assist.eclipse.analysis.audit.resolution.*;
import com.instantiations.assist.eclipse.analysis.audit.util.AuditResultGroup;
import com.instantiations.jlib.license.*;
import com.instantiations.jlib.xml.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
 
/**
 * Instances of the class XMLAuditWriter implement a audit writer
 * that produces XML formatted output.
 * 
 * Copyright (c) 2003, Google, Inc.
 * All Rights Reserved
 *
 * @author Dan Rubel
 * @author Brian Wilkerson
 * @version $Revision: 1.0 $
 */
public class XMLAuditWriter extends AbstractAuditWriter
{
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeHeader(AuditViolationSet)
     */
    public void writeHeader(AuditViolationSet violationSet) {
        AuditRuleSet auditRuleSet = violationSet.getAuditRuleSet();
        int[] severityCount = violationSet.getSeverityCount();
 
        _writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        _writer.println("<!-- Generated by " + Product.getMainProduct().getName() + " -->");
        _writer.println("<audit-violation-set");
        _writer.println("\ttitle=\"" + violationSet.getName() + "\"");
        if (auditRuleSet != null && !auditRuleSet.isDefault())
            _writer.println("\tusing =\"" + auditRuleSet.getName() + "\"");
        _writer.println("\tseverity-count-high=\"" + severityCount[0] + "\"");
        _writer.println("\tseverity-count-medium=\"" + severityCount[1] + "\"");
        _writer.println("\tseverity-count-low=\"" + severityCount[2] + "\">");
    }
 
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeTableOfContents(AuditResultGroup[])
     */
    public void writeTableOfContents(AuditResultGroup[] groups) {
    }
 
    /**
     * Write out information about the specified group of audit violations.
     *
     * @param violationContainer the violation container
     *        (e.g. an audit rule or a resource - not null)
     * @param violationCount the number of violations in this group
     * @param depth the depth of this group
     */
    public void writeGroupHeader(Object violationContainer, int violationCount, int depth, int maxDepth)
    {
        if (violationContainer instanceof AuditRule) {
            AuditRule auditRule = (AuditRule) violationContainer;
            printTabs(depth);
            _writer.println("<audit-rule");
            printTabs(depth + 1);
            _writer.println("name=\"" + XMLUtils.encodeData(auditRule.getName()) + "\"");
            printTabs(depth + 1);
            _writer.println("count=\"" + violationCount + "\"");
            printTabs(depth + 1);
            _writer.println("id=\"" + auditRule.getPreferenceIdentifier() + "\"");
            printTabs(depth + 1);
            _writer.println("group-id=\"" + auditRule.getGroupIdentifier() + "\">");
        } else if (violationContainer instanceof AuditRuleGroup) {
            AuditRuleGroup group = (AuditRuleGroup) violationContainer;
            printTabs(depth);
            _writer.println("<audit-rule-group");
            printTabs(depth + 1);
            _writer.println("name=\"" + XMLUtils.encodeData(group.getName()) + "\"");
            printTabs(depth + 1);
            _writer.println("count=\"" + violationCount + "\">");
        } else if (violationContainer instanceof IResource) {
            IResource res = (IResource) violationContainer;
            printTabs(depth);
            _writer.println("<resource");
            printTabs(depth + 1);
            _writer.println("path=\"" + XMLUtils.encodeData(res.getFullPath().toString()) + "\"");
            printTabs(depth + 1);
            _writer.println("count=\"" + violationCount + "\">");
        } else if (violationContainer instanceof Integer) {
            printTabs(depth);
            _writer.println("<severity");
            printTabs(depth + 1);
            _writer.println("name=\"" + XMLUtils.encodeData(AuditRule.SEVERITY_LABELS[((Integer) violationContainer).intValue()]) + "\"");
            printTabs(depth + 1);
            _writer.println("value=\"" + violationContainer + "\">");
        }
    }
 
    /**
     * Write out information about the specified violation.
     *
     * @param violation the audit violation (not null)
     * @param depth the depth of this violation
     */
    public void writeViolation(AuditViolation violation, int depth)
    {
        AuditViolationResolution[] resolutions;
        IMarker marker;
 
        // Write violation description
        printTabs(depth);
        _writer.println("<audit-violation");
        printTabs(depth + 1);
        _writer.println("description=\""
            + XMLUtils.encodeData(violation.getDescription())
            + "\"");
 
        // Write recommendtion
        if (includeRecommendations) {
            resolutions = violation.getResolutions();
            if (resolutions.length > 0) {
                printTabs(depth + 1);
                _writer.println("recommendation=\""
                    + XMLUtils.encodeData(resolutions[0].getDescription())
                    + "\"");
            }
        }
 
        // Write severity
        if (includeSeverities) {
            printTabs(depth + 1);
            _writer.println("severity=\""
                + AuditRule.SEVERITY_LABELS[violation.getSeverity()]
                + "\"");
        }
 
        // Write resource name
        printTabs(depth + 1);
        _writer.println("file=\""
            + violation.getResource().getName()
            + "\"");
 
        // Write line
        printTabs(depth + 1);
        _writer.print("line=\"");
        try {
            marker = violation.getMarker();
            if (marker == null) {
                _writer.print("??");
            } else {
                _writer.print(marker.getAttribute(IMarker.LINE_NUMBER));
            }
        } catch (CoreException exception) {
            _writer.print("??");
        }
 
        _writer.println("\"/>");
    }
 
    /**
     * Write out information about the specified group of audit violations.
     *
     * @param violationContainer the violation container
     *        (e.g. an audit rule or a resource - not null)
     * @param depth the depth of this group
     */
    public void writeGroupFooter(Object violationContainer, int depth)
    {
        if (violationContainer instanceof AuditRule) {
            printTabs(depth);
            _writer.println("</audit-rule>");
        } else if (violationContainer instanceof IResource) {
            printTabs(depth);
            _writer.println("</resource>");
        }
    }
 
    /**
     * @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeFooter(AuditViolationSet)
     */
    public void writeFooter(AuditViolationSet violationSet)
    {
        _writer.println("</audit-violation-set>");
    }
 
    ////////////////////////////////////////////////////////////////////////
    //
    // Utilities
    //
    ////////////////////////////////////////////////////////////////////////
 
    /**
     * Print the given number of tabs to the writer.
     *
     * @param count the number of tabs to be written
     */
    protected void printTabs(int count)
    {
        for (int i = 0; i < count; i++) {
            _writer.print('\t');
        }
    }
}