/**
* Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.validation.formatting;
import java.io.OutputStream;
import java.io.PrintStream;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.cloudsmith.geppetto.diagnostic.DetailedFileDiagnostic;
import org.cloudsmith.geppetto.validation.runner.BuildResult;
/**
* Formats diagnostics information as textual output. The general format is:<br/>
* <code>SOURCE:SEVERITY:RESOURCEPATH:LOCATION:CODE:MESSAGE</code></br> where <code>LOCATION</code> is one of:
* <ul>
* <li>LINE</li>
* <li>LINE(OFFSET)</li>
* <li>LINE(OFFSET,LENGTH)</li>
* </ul>
* and LINE is either a line number (starting with 1) or '-' if line number is
* not available, and where OFFSET (character count from start of file), and
* LENGTH are included if set.
*
*/
public class TextualValidationResultFormatter implements IValidationResultFormatter {
@Override
public void format(BuildResult buildResult, BasicDiagnostic diagnostics, OutputStream out) {
PrintStream p = out instanceof PrintStream
? (PrintStream) out
: new PrintStream(out);
formatDignostics(diagnostics, p);
p.flush();
}
/**
* SOURCE:SEVERITY:RESOURCEPATH:LOCATION:CODE:MESSAGE
*
* @param d
* @param detail
* @param p
*/
private void formatDetail(Diagnostic d, DetailedFileDiagnostic detail, PrintStream p) {
String source = d.getSource();
String message = d.getMessage();
String severity = severityLabel(d);
String resourcePath = detail.getFile().getPath();
String locationLabel = locationLabel(detail);
String code = detail.getIssue();
p.printf("%s:%s:%s:%s:%s:%s", source, severity, resourcePath, locationLabel, code, message);
}
/**
* @param diagnostics
* @param p
*/
private void formatDignostics(BasicDiagnostic diagnostics, PrintStream p) {
for(Diagnostic d : diagnostics.getChildren()) {
DetailedFileDiagnostic detail = getDetail(d);
if(detail == null)
formatExceptionDiagnostic(d, p);
else
formatDetail(d, detail, p);
}
}
/**
* Outputs
*
* <pre>
* SOURCE:SEVERITY:MESSAGE
* STACK TRACE
* ---
* </pre>
*
* @param d
* @param p
*/
private void formatExceptionDiagnostic(Diagnostic d, PrintStream p) {
String source = d.getSource();
String message = d.getMessage();
String severity = severityLabel(d);
p.printf("%s:%s:%s\n", source, severity, message);
d.getException().printStackTrace(p);
p.print("---\n");
}
private DetailedFileDiagnostic getDetail(Diagnostic d) {
if(d.getData().size() < 1)
return null;
Object x = d.getData().get(0);
if(x instanceof DetailedFileDiagnostic)
return (DetailedFileDiagnostic) x;
return null;
}
/**
* Formats location as LINE(OFFSET,LENGTH), or if LINE is -1 using '-'. If
* offset is >= 0 the () section is included, the ", length" part is only
* produced if length >= 0.
*
* @param detail
* @return
*/
private String locationLabel(DetailedFileDiagnostic detail) {
int lineNumber = detail.getLineNumber();
int offset = detail.getOffset();
int length = detail.getLength();
StringBuilder builder = new StringBuilder();
if(lineNumber > 0)
builder.append(lineNumber);
else
builder.append("-");
if(offset >= 0) {
builder.append("(");
builder.append(offset);
if(length >= 0) {
builder.append(",");
builder.append(length);
}
builder.append(")");
}
return builder.toString();
}
protected String severityLabel(Diagnostic d) {
String label = "unknown severity";
switch(d.getSeverity()) {
case Diagnostic.CANCEL:
label = "canceled";
break;
case Diagnostic.WARNING:
label = "warning";
break;
case Diagnostic.ERROR:
label = "error";
break;
case Diagnostic.INFO:
label = "info";
break;
case Diagnostic.OK:
label = "ok";
break;
}
return label;
}
}