/**
* Copyright (c) 2004-2010 IBM Corporation and others.
* 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:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.common.util;
import java.util.Collections;
import java.util.List;
/**
* A basic implementation of a diagnostic that that also acts as a chain.
*/
public class BasicDiagnostic implements Diagnostic, DiagnosticChain
{
/**
* The severity.
* @see #getSeverity
*/
protected int severity;
/**
* The message.
* @see #getMessage
*/
protected String message;
/**
* The message.
* @see #getMessage
*/
protected List<Diagnostic> children;
/**
* The data.
* @see #getData
*/
protected List<?> data;
/**
* The source.
* @see #getSource
*/
protected String source;
/**
* The code.
* @see #getCode
*/
protected int code;
/**
* Default Constructor (no initialization for local parameters)
*/
public BasicDiagnostic()
{
super();
}
public BasicDiagnostic(String source, int code, String message, Object[] data)
{
this.source = source;
this.code = code;
this.message = message;
this.data = dataAsList(data);
}
public BasicDiagnostic(int severity, String source, int code, String message, Object[] data)
{
this(source, code, message, data);
this.severity = severity;
}
public BasicDiagnostic(String source, int code, List<? extends Diagnostic> children, String message, Object[] data)
{
this(source, code, message, data);
if (children != null)
{
for (Diagnostic diagnostic : children)
{
add(diagnostic);
}
}
}
protected List<?> dataAsList(Object [] data)
{
if (data == null)
{
return Collections.EMPTY_LIST;
}
else
{
Object [] copy = new Object [data.length];
System.arraycopy(data, 0, copy, 0, data.length);
return new BasicEList.UnmodifiableEList<Object>(copy.length, copy);
}
}
protected void setSeverity(int severity)
{
this.severity = severity;
}
public int getSeverity()
{
return severity;
}
public String getMessage()
{
return message;
}
public List<?> getData()
{
return data;
}
public List<Diagnostic> getChildren()
{
if (children == null)
{
return Collections.emptyList();
}
else
{
return Collections.unmodifiableList(children);
}
}
protected void setSource(String source)
{
this.source = source;
}
public String getSource()
{
return source;
}
protected void setCode(int code)
{
this.code = code;
}
public int getCode()
{
return code;
}
public void add(Diagnostic diagnostic)
{
if (children == null)
{
children = new BasicEList<Diagnostic>();
}
children.add(diagnostic);
int childSeverity = diagnostic.getSeverity();
if (childSeverity > getSeverity())
{
severity = childSeverity;
}
}
public void addAll(Diagnostic diagnostic)
{
for (Diagnostic child : diagnostic.getChildren())
{
add(child);
}
}
public void merge(Diagnostic diagnostic)
{
if (diagnostic.getChildren().isEmpty())
{
add(diagnostic);
}
else
{
addAll(diagnostic);
}
}
public int recomputeSeverity()
{
if (children != null)
{
severity = OK;
for (Diagnostic child : children)
{
int childSeverity = child instanceof BasicDiagnostic ? ((BasicDiagnostic)child).recomputeSeverity() : child.getSeverity();
if (childSeverity > severity)
{
severity = childSeverity;
}
}
}
return severity;
}
/**
* Returns the first throwable object available in the {@link #data} list,
* which is set when this diagnostic is instantiated.
*/
public Throwable getException()
{
List<?> data = getData();
if (data != null)
{
for (Object datum : data)
{
if (datum instanceof Throwable)
{
return (Throwable)datum;
}
}
}
return null;
}
@Override
public String toString()
{
StringBuilder result = new StringBuilder();
result.append("Diagnostic ");
switch (severity)
{
case OK:
{
result.append("OK");
break;
}
case INFO:
{
result.append("INFO");
break;
}
case WARNING:
{
result.append("WARNING");
break;
}
case ERROR:
{
result.append("ERROR");
break;
}
case CANCEL:
{
result.append("CANCEL");
break;
}
default:
{
result.append(Integer.toHexString(severity));
break;
}
}
result.append(" source=");
result.append(source);
result.append(" code=");
result.append(code);
result.append(' ');
result.append(message);
if (data != null)
{
result.append(" data=");
result.append(data);
}
if (children != null)
{
result.append(' ');
result.append(children);
}
return result.toString();
}
/**
* Returns the throwable viewed as a {@link Diagnostic}.
*
* @param throwable
* @return {@link Diagnostic}
*/
public static Diagnostic toDiagnostic(Throwable throwable)
{
if (throwable instanceof DiagnosticException)
{
return ((DiagnosticException)throwable).getDiagnostic();
}
else if (throwable instanceof WrappedException)
{
return toDiagnostic(throwable.getCause());
}
String message = throwable.getClass().getName();
int index = message.lastIndexOf('.');
if (index >= 0)
{
message = message.substring(index + 1);
}
if (throwable.getLocalizedMessage() != null)
{
message = message + ": " + throwable.getLocalizedMessage();
}
BasicDiagnostic basicDiagnostic =
new BasicDiagnostic
(Diagnostic.ERROR,
"org.eclipse.emf.common",
0,
message,
new Object[] { throwable });
if (throwable.getCause() != null && throwable.getCause() != throwable)
{
throwable = throwable.getCause();
basicDiagnostic.add(toDiagnostic(throwable));
}
return basicDiagnostic;
}
}