/*
* Copyright 2013-14 Skynav, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY SKYNAV, INC. AND ITS CONTRIBUTORS “AS IS” AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SKYNAV, INC. OR ITS CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.skynav.ttv.util;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.xml.bind.UnmarshalException;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.LocatorImpl;
public class TextReporter implements Reporter {
public static final String NAME = "text";
public static final String DEFAULT_ENCODING = "UTF-8";
/* general state */
private Map<String,Boolean> defaultWarnings;
private PrintWriter output;
private boolean outputDefaulted;
private ResourceBundle bundle;
/* options state */
private int debug;
private boolean disableWarnings;
private Set<String> disabledWarnings;
private Set<String> enabledWarnings;
private boolean hideLocation;
private boolean hidePath;
private boolean hideWarnings;
private boolean treatWarningAsError;
private int verbose;
/* per-resource state */
private Set<String> resourceDisabledWarnings;
private Set<String> resourceEnabledWarnings;
private String[] resourceLines;
private int resourceErrors;
private URI resourceUri;
private String resourceUriString;
private int resourceWarnings;
public TextReporter() {
}
public String getName() {
return NAME;
}
public boolean isOpen() {
return output != null;
}
public void open(Object... arguments) throws IOException {
Object[][] defaultWarningSpecifications;
if ((arguments.length > 0) && (arguments[0] instanceof Object[][]))
defaultWarningSpecifications = (Object[][]) arguments[0];
else
defaultWarningSpecifications = null;
PrintWriter output;
if ((arguments.length > 1) & (arguments[1] instanceof PrintWriter))
output = (PrintWriter) arguments[1];
else
output = null;
ResourceBundle bundle;
if ((arguments.length > 2) & (arguments[2] instanceof ResourceBundle))
bundle = (ResourceBundle) arguments[2];
else
bundle = null;
Map<String,Boolean> defaultWarnings = new java.util.HashMap<String,Boolean>();
if (defaultWarningSpecifications != null) {
for (Object[] spec : defaultWarningSpecifications) {
defaultWarnings.put((String) spec[0], (Boolean) spec[1]);
}
}
this.defaultWarnings = defaultWarnings;
this.disabledWarnings = new java.util.HashSet<String>();
this.enabledWarnings = new java.util.HashSet<String>();
this.hideLocation = false;
this.hidePath = false;
setOutput(output);
setBundle(bundle);
}
public void close() throws IOException {
PrintWriter output = getOutput();
if (!outputDefaulted)
output.close();
this.output = null;
}
public void resetResourceState(boolean restart) {
if (restart) {
resourceDisabledWarnings = null;
resourceEnabledWarnings = null;
} else {
resourceDisabledWarnings = new java.util.HashSet<String>(disabledWarnings);
resourceEnabledWarnings = new java.util.HashSet<String>(enabledWarnings);
}
resourceLines = null;
resourceErrors = 0;
resourceUri = null;
resourceUriString = null;
resourceWarnings = 0;
}
public void resetAllState(boolean restart) {
resetResourceState(restart);
resetOptionsState(restart);
resetGlobalState(restart);
}
private void resetGlobalState(boolean restart) {
if (!restart) {
defaultWarnings = null;
if (output != null) {
try {
close();
} catch (IOException e) {
output = null;
}
}
outputDefaulted = false;
bundle = null;
}
}
private void resetOptionsState(boolean restart) {
debug = 0;
disableWarnings = false;
disabledWarnings = new java.util.HashSet<String>();
enabledWarnings = new java.util.HashSet<String>();
hideLocation = false;
hidePath = false;
hideWarnings = false;
treatWarningAsError = false;
verbose = 0;
}
public void setResourceURI(String uri) {
resourceUriString = uri;
}
public void setResourceURI(URI uri) {
resourceUri = uri;
}
public void setLines(String[] lines) {
String[] sa = new String[lines.length];
System.arraycopy(lines, 0, sa, 0, sa.length);
resourceLines = sa;
}
public void hidePath() {
this.hidePath = true;
}
public void showPath() {
this.hidePath = false;
}
public boolean isHidingPath() {
return this.hidePath;
}
public void hideLocation() {
this.hideLocation = true;
}
public void showLocation() {
this.hideLocation = false;
}
public boolean isHidingLocation() {
return this.hideLocation;
}
public int getResourceErrors() {
return resourceErrors;
}
public int getResourceWarnings() {
return resourceWarnings;
}
public void setOutput(PrintWriter output) {
this.output = output;
}
public PrintWriter getOutput() {
if (output == null) {
Charset defaultEncoding;
try {
defaultEncoding = Charset.forName(DEFAULT_ENCODING);
} catch (RuntimeException e) {
defaultEncoding = Charset.defaultCharset();
}
output = new PrintWriter(new OutputStreamWriter(System.err, defaultEncoding));
outputDefaulted = true;
}
return output;
}
public void setBundle(ResourceBundle bundle) {
this.bundle = bundle;
}
public ResourceBundle getBundle() {
return bundle;
}
protected void out(String message) {
getOutput().print(message);
}
protected void out(ReportType reportType, String message) {
char type;
if (reportType == ReportType.Error)
type = 'E';
else if (reportType == ReportType.Warning)
type = 'W';
else if (reportType == ReportType.Info)
type = 'I';
else if (reportType == ReportType.Debug)
type = 'D';
else
type = '?';
StringBuffer sb = new StringBuffer();
sb.append('[');
sb.append(type);
sb.append(']');
sb.append(':');
sb.append(message);
sb.append('\n');
out(sb.toString());
}
protected void out(ReportType type, Message message) {
out(type, message.toText(bundle, isHidingLocation(), isHidingPath()));
}
public void flush() {
PrintWriter output = getOutput();
output.flush();
}
public void setVerbosityLevel(int verbose) {
this.verbose = verbose;
}
public void incrementVerbosityLevel() {
++this.verbose;
}
public int getVerbosityLevel() {
return this.verbose;
}
public void setDebugLevel(int debug) {
this.debug = debug;
}
public void incrementDebugLevel() {
++this.debug;
}
public int getDebugLevel() {
return this.debug;
}
private Message message(String message) {
return message((String) null, message);
}
public Message message(String key, String format, Object... arguments) {
return new Message(key, format, arguments);
}
private Message message(Locator locator, String message) {
return message(locator, (String) null, message);
}
public Message message(Locator locator, String key, String format, Object... arguments) {
String sysid = locator.getSystemId();
String uriString;
if ((sysid != null) && (sysid.length() > 0))
uriString = sysid;
else if (resourceUri != null)
uriString = resourceUri.toString();
else if (resourceUriString != null)
uriString = resourceUriString;
else
uriString = null;
return new LocatedMessage(uriString, locator.getLineNumber(), locator.getColumnNumber(), resourceLines, key, format, arguments);
}
public void logError(Message message) {
out(ReportType.Error, message);
++resourceErrors;
}
private Locator extractLocator(SAXParseException e) {
LocatorImpl locator = new LocatorImpl();
locator.setSystemId(e.getSystemId());
locator.setLineNumber(e.getLineNumber());
locator.setColumnNumber(e.getColumnNumber());
return locator;
}
private Message extractMessage(SAXParseException e) {
String message = e.getMessage();
if (message.indexOf("cvc") == 0) {
int cvcEndIndex = message.indexOf(":");
String cvcLabel = message.substring(0, cvcEndIndex);
String cvcRemainder = message.substring(cvcEndIndex + 1);
message = "XSD(" + cvcLabel + "):" + cvcRemainder;
}
return message(extractLocator(e), massageMessage(message));
}
private Locator extractLocator(UnmarshalException e) {
LocatorImpl locator = new LocatorImpl();
locator.setSystemId(resourceUriString);
return locator;
}
private Message extractMessage(UnmarshalException e) {
return message(extractLocator(e), massageMessage(e.getMessage()));
}
private Message extractMessage(Throwable e) {
if ((e.getCause() != null) && (e.getCause() != e))
return extractMessage(e.getCause());
else if (e instanceof SAXParseException)
return extractMessage((SAXParseException) e);
else if (e instanceof UnmarshalException)
return extractMessage((UnmarshalException) e);
else {
String message = e.getMessage();
if ((message == null) || (message.length() == 0))
message = e.toString();
message = massageMessage(message);
return message(message + ((debug < 2) ? "; retry with --debug-exceptions option for additional information." : "."));
}
}
private String massageMessage(String message) {
StringBuffer sb = new StringBuffer();
if (message == null)
message = "";
for (int i = 0, n = message.length(); i < n; ++i) {
char c = message.charAt(i);
if (c == '\'')
sb.append("''");
else if (c == '{')
sb.append("'{'");
else if (c == '}')
sb.append("'}'");
else if ((i == 0) && Character.isLowerCase(c))
sb.append(Character.toUpperCase(c));
else
sb.append(c);
}
if ((sb.length() > 0) && (sb.charAt(sb.length() - 1) != '.'))
sb.append('.');
return sb.toString();
}
public void logError(Exception e) {
logError(extractMessage(e));
logDebug(e);
}
public void addDefaultWarning(String token, boolean enabled) {
if (!defaultWarnings.containsKey(token))
defaultWarnings.put(token, Boolean.valueOf(enabled));
}
public boolean hasDefaultWarning(String token) {
return defaultWarnings.containsKey(token);
}
private Set<String> getEnabledWarnings() {
if (this.resourceEnabledWarnings != null)
return this.resourceEnabledWarnings;
else
return this.enabledWarnings;
}
private Set<String> getDisabledWarnings() {
if (this.resourceDisabledWarnings != null)
return this.resourceDisabledWarnings;
else
return this.disabledWarnings;
}
public void setTreatWarningAsError(boolean treatWarningAsError) {
this.treatWarningAsError = treatWarningAsError;
}
public boolean isTreatingWarningAsError() {
return this.treatWarningAsError;
}
public boolean isWarningEnabled(String token) {
boolean enabled = hasDefaultWarning(token) ? defaultWarnings.get(token) : false;
if (getEnabledWarnings().contains(token) || getEnabledWarnings().contains("all"))
enabled = true;
if (getDisabledWarnings().contains(token) || getDisabledWarnings().contains("all"))
enabled = false;
return enabled;
}
public boolean hasEnabledWarning(String token) {
return getEnabledWarnings().contains(token);
}
public void enableWarning(String token) {
if (!hasDefaultWarning(token))
addDefaultWarning(token, true);
getEnabledWarnings().add(token);
}
public boolean hasDisabledWarning(String token) {
return getDisabledWarnings().contains(token);
}
public void disableWarning(String token) {
getDisabledWarnings().add(token);
}
public void disableWarnings() {
this.disableWarnings = true;
}
public boolean areWarningsDisabled() {
return this.disableWarnings;
}
public void hideWarnings() {
this.hideWarnings = true;
}
public boolean areWarningsHidden() {
return this.hideWarnings;
}
public boolean logWarning(Message message) {
if (!disableWarnings) {
if (!hideWarnings)
out(ReportType.Warning, message);
++resourceWarnings;
}
return treatWarningAsError;
}
public boolean logWarning(Exception e) {
boolean treatedAsError = logWarning(extractMessage(e));
logDebug(e);
return treatedAsError;
}
public void logInfo(Message message) {
if (verbose > 0) {
out(ReportType.Info, message);
}
}
public void logDebug(Message message) {
if (isDebuggingEnabled()) {
out(ReportType.Debug, message);
}
}
private boolean isDebuggingEnabled(int level) {
return debug >= level;
}
private boolean isDebuggingEnabled() {
return isDebuggingEnabled(1);
}
private void logDebug(Exception e) {
if (isDebuggingEnabled(2)) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
logDebug(message(sw.toString()));
}
}
}