MZTabError.java
package uk.ac.ebi.pride.jmztab2.utils.errors;
import de.isas.mztab2.model.ValidationMessage;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static uk.ac.ebi.pride.jmztab2.model.MZTabConstants.NEW_LINE;
/**
* mzTab files can be validated to ensure that they comply with the latest
* version of the format specification. The process includes two steps: first of
* all the basic model architecture is created, including the metadata section
* and the generation of the table column headers. The second step is the
* validation of the column rows, which take most of the processing time. The
* class MZTabFileParser is used to parse and validate the mzTab files. If the
* validation is successful, an MZTabFile model will be then generated. A series
* of messages are then reported, which can help to diagnose different types of
* format-related (reporting format problems) and/or logical (reporting errors
* related to the logical relationships among the different sections in a file)
* errors. At the moment of writing, there are about sixty types of error
* messages (http://mztab.googlecode.com/wiki/jmzTab_message). The validation
* messages have a unique identifier and are classified in three levels: Info,
* Warn and Error, according to the requirements included in the specification
* document.
*
* @author qingwei
* @since 06/02/13
*
*/
public class MZTabError implements Serializable {
private int lineNumber;
private MZTabErrorType type;
private String message;
/**
* System will fill a couple of values one by one, and generate a concrete
* error message during parse {@link #lineNumber} line in mzTab file.
*
* @param type SHOULD NOT null.
* @param lineNumber SHOULD be positive integer. Except "-1", which means
* the line number unknown.
* @param values May be null, if no variable in error's original pattern.
*/
public MZTabError(MZTabErrorType type, int lineNumber, String... values) {
if (type == null) {
throw new NullPointerException("MZTabErrorType should not set null");
}
this.type = type;
this.lineNumber = lineNumber;
List<String> valueList = new ArrayList<String>();
for (String value : values) {
valueList.add(value == null ? "" : value);
}
this.message = fill(0, valueList, type.getOriginal());
}
/**
* fill "{id}" parameter list one by one.
*/
private String fill(int count, List<String> values, String message) {
String regexp = "\\{\\w\\}";
Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(message);
String value;
if (matcher.find()) {
if (count >= values.size()) {
throw new ArrayIndexOutOfBoundsException(
"Tried to replace placeholder " + (count + 1) + " but only " + values.
size() + " values are available for " + getClass().
getSimpleName() + " " + type.toString());
}
value = values.get(count);
message = matcher.replaceFirst(Matcher.quoteReplacement(value));
return fill(count + 1, values, message);
} else {
return message;
}
}
/**
* <p>Getter for the field <code>type</code>.</p>
*
* @return {@link uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorType}
* @see FormatErrorType
* @see LogicalErrorType
*/
public MZTabErrorType getType() {
return type;
}
/**
* <p>Getter for the field <code>message</code>.</p>
*
* @return a concrete error/warn message.
*/
public String getMessage() {
return message;
}
/**
* <p>Getter for the field <code>lineNumber</code>.</p>
*
* @return the line number.
*/
public int getLineNumber() {
return lineNumber;
}
/**
* {@inheritDoc}
*
* Code: Unique number for error/warn Category: Currently, there are three
* types of messages: Format, Logical Original: Message expression pattern.
* "{?}" is a couple of parameters which can be filled during validate
* processing. Cause: A readable text to describe the reason why raise this
* error/warn. Currently, these cause message coming from mztab
* specification mainly.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[").
append(type.getLevel()).
append("-").
append(type.getCode()).
append("] ");
sb.append("line ").
append(lineNumber).
append(": ");
sb.append(message).
append(NEW_LINE);
return sb.toString();
}
public ValidationMessage toValidationMessage() throws IllegalStateException {
ValidationMessage.MessageTypeEnum level = ValidationMessage.MessageTypeEnum.INFO;
switch (getType().
getLevel()) {
case Error:
level = ValidationMessage.MessageTypeEnum.ERROR;
break;
case Info:
level = ValidationMessage.MessageTypeEnum.INFO;
break;
case Warn:
level = ValidationMessage.MessageTypeEnum.WARN;
break;
default:
throw new IllegalStateException("State " +
getType().
getLevel() + " is not handled in switch/case statement!");
}
ValidationMessage.CategoryEnum category = ValidationMessage.CategoryEnum.FORMAT;
switch(getType().getCategory()) {
case Format:
category = ValidationMessage.CategoryEnum.FORMAT;
break;
case Logical:
category = ValidationMessage.CategoryEnum.LOGICAL;
break;
case CrossCheck:
category = ValidationMessage.CategoryEnum.CROSS_CHECK;
break;
default:
throw new IllegalStateException("Category " +
getType().
getCategory()+ " is not handled in switch/case statement!");
}
ValidationMessage vr = new ValidationMessage().lineNumber(
Long.valueOf(getLineNumber())).
category(category).
messageType(level).
message(getMessage()).
code(toString());
return vr;
}
}