com.univocity.parsers.common.DataProcessingException Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of univocity-parsers Show documentation
Show all versions of univocity-parsers Show documentation
univocity's open source parsers for processing different text formats using a consistent API
/*******************************************************************************
* Copyright 2015 Univocity Software Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.univocity.parsers.common;
import com.univocity.parsers.common.processor.*;
import java.util.*;
/**
* A {@code DataProcessingException} is an error thrown during the processing of a record successfully parsed.
* This type of error usually indicates that the input text has been parsed correctly, but the subsequent
* transformations applied over the input (generally via a {@link RowProcessor}} failed.
*
* @author Univocity Software Pty Ltd - [email protected]
*/
public class DataProcessingException extends TextParsingException {
private static final long serialVersionUID = 1410975527141918215L;
private String columnName;
private int columnIndex;
private Object[] row;
private Object value;
private Map values = new HashMap();
private boolean fatal = true;
private boolean handled = false;
private String details = null;
/**
* Creates a new exception with an error message only.
*
* @param message the error message
*/
public DataProcessingException(String message) {
this(message, -1, null, null);
}
/**
* Creates a new exception with an error message and error cause
*
* @param message the error message
* @param cause the cause of the error
*/
public DataProcessingException(String message, Throwable cause) {
this(message, -1, null, cause);
}
/**
* Creates a new exception with an error message and the row that could not be processed.
*
* @param message the error message
* @param row the row that could not be processed.
*/
public DataProcessingException(String message, Object[] row) {
this(message, -1, row, null);
}
/**
* Creates a new exception with an error message, the row that could not be processed, and the error cause.
*
* @param message the error message
* @param row the row that could not be processed.
* @param cause the cause of the error
*/
public DataProcessingException(String message, Object[] row, Throwable cause) {
this(message, -1, row, cause);
}
/**
* Creates a new exception with an error message and the column that could not be processed.
*
* @param message the error message
* @param columnIndex index of the column that could not be processed.
*/
public DataProcessingException(String message, int columnIndex) {
this(message, columnIndex, null, null);
}
/**
* Creates a new exception with an error message, the column that could not be processed
* the row that could not be processed, and the error cause.
*
* @param message the error message
* @param columnIndex index of the column that could not be processed.
* @param row the row that could not be processed.
* @param cause the cause of the error
*/
public DataProcessingException(String message, int columnIndex, Object[] row, Throwable cause) {
super(null, message, cause);
setColumnIndex(columnIndex);
this.row = row;
}
@Override
protected String getErrorDescription() {
return "Error processing parsed input";
}
@Override
protected String getDetails() {
String details = (this.details == null ? "" : this.details + '\n') + super.getDetails();
Object[] row = getRow();
if (row != null) {
row = row.clone();
for (int i = 0; i < row.length; i++) {
row[i] = restrictContent(row[i]);
}
}
details = printIfNotEmpty(details, "row", row);
details = printIfNotEmpty(details, "value", restrictContent(getValue()));
details = printIfNotEmpty(details, "columnName", getColumnName());
details = printIfNotEmpty(details, "columnIndex", getColumnIndex());
return details;
}
/**
* Returns the name of the column from where the error occurred, if available.
*
* @return the name of the column from where the error occurred.
*/
public String getColumnName() {
if (columnName != null) {
return columnName;
}
String[] headers = getHeaders();
if (headers != null && getExtractedColumnIndex() != -1 && getExtractedColumnIndex() < headers.length) {
return headers[getExtractedColumnIndex()];
}
return null;
}
/**
* Returns the index of the column from where the error occurred, if available.
*
* @return the index of the column from where the error occurred.
*/
public final int getColumnIndex() {
return columnIndex;
}
/**
* Returns the record being processed when the error occurred, if available.
*
* @return the record being processed when error occurred, if available.
*/
public final Object[] getRow() {
return restrictContent(row);
}
/**
* Defines the value being processed when the error occurred.
*
* @param value the value being processed when error occurred.
*/
public final void setValue(Object value) {
if (errorContentLength == 0) {
value = null;
}
if (value == null) {
value = "null";
}
this.value = value;
}
/**
* Associates a label in the exception message (idenfied in curly braces) with a value being processed when the error occurred.
* Used for formatting the exception message
*
* @param label a label in the exception message - any string enclosed by curly braces.
* @param value the value being processed when error occurred, that should be replaced by the label in the exception message.
*/
public final void setValue(String label, Object value) {
if (errorContentLength == 0) {
value = null;
}
this.values.put(label, value);
}
/**
* Returns the value being processed when the error occurred, if available.
*
* @return the value being processed when the error occurred, if available.
*/
public final Object getValue() {
if (errorContentLength == 0) {
return null;
}
if (value != null) {
return value;
}
if (row != null && columnIndex != -1 && columnIndex < row.length) {
return row[columnIndex];
}
return null;
}
/**
* Defines the column index being processed when the error occurred.
*
* @param columnIndex the column index being processed when error occurred.
*/
public final void setColumnIndex(int columnIndex) {
this.columnIndex = columnIndex;
}
private int getExtractedColumnIndex() {
if (this.extractedIndexes != null && columnIndex < extractedIndexes.length && columnIndex > -1) {
return extractedIndexes[columnIndex];
}
return columnIndex;
}
/**
* Defines the name of the column being processed when the error occurred.
*
* @param columnName the name of the column being processed when error occurred.
*/
public final void setColumnName(String columnName) {
this.columnName = columnName;
}
/**
* Updates the exception with the record being processed when the error occurred.
*
* @param row the record data processed when the error occurred.
*/
public final void setRow(Object[] row) {
if (errorContentLength == 0) {
row = null;
}
this.row = row;
}
/**
* Returns a flag indicating whether this error is fatal and the process must stop as it is impossible to proceed.
*
* @return a flag indicating whether this error is fatal and the process must stop as it is impossible to proceed.
*/
final boolean isFatal() {
return fatal;
}
/**
* Marks the error as non fatal and the parsing process might proceed.
*/
public final void markAsNonFatal() {
this.fatal = false;
}
/**
* Marks the error as handled so it doesn't trigger a {@link ProcessorErrorHandler} again.
* @param handler the {@link ProcessorErrorHandler} used to handle this exception.
*/
public final void markAsHandled(ProcessorErrorHandler handler) {
this.handled = handler != null && !(handler instanceof NoopProcessorErrorHandler) && !(handler instanceof NoopRowProcessorErrorHandler);
}
/**
* Returns a flag indicating this exception has been handled by a user-provided {@link ProcessorErrorHandler}
*
* @return {@code true} if this exception has been handled to a user-provided {@link ProcessorErrorHandler},
* otherwise {@code false}
*/
public boolean isHandled() {
return handled;
}
public void setDetails(String details) {
this.details = details == null || details.trim().isEmpty() ? null : details;
}
@Override
protected final String updateMessage(String msg) {
if (errorContentLength == 0 || msg == null) {
return msg; //doesn't replace labels enclosed within { and }.
}
StringBuilder out = new StringBuilder(msg.length());
int previous = 0;
int start = 0;
while (true) {
start = msg.indexOf('{', start);
if (start == -1) {
break;
}
int end = msg.indexOf('}', start);
if (end == -1) {
break;
}
String label = msg.substring(start + 1, end);
Object value = null;
if ("value".equals(label)) {
value = this.value;
} else if (values.containsKey(label)) {
value = values.get(label);
}
if (value != null) {
String content = restrictContent(value);
out.append(msg, previous, start);
out.append(content);
previous = end;
}
start = end;
}
out.append(msg, previous == 0 ? 0 : previous + 1, msg.length());
return out.toString();
}
}