/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.core.util;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.ujmp.core.Coordinates;
import org.ujmp.core.Matrix;
import org.ujmp.core.bigdecimalmatrix.BaseBigDecimalMatrix;
public class UJMPFormat extends Format {
private static final long serialVersionUID = -557618747324763226L;
private static UJMPFormat multiLineInstance = new UJMPFormat(true, 10, true);
private static UJMPFormat singleLineInstance = new UJMPFormat(false, 100, false);
private NumberFormat defaultNumberFormat = null;
private NumberFormat exponentialNumberFormat = null;
private DateFormat dateFormat = null;
private boolean multiLine = true;
private boolean usePadding = false;
private int width = 10;
public UJMPFormat(boolean multiLine, int width, boolean usePadding) {
DecimalFormatSymbols symbols = new DecimalFormatSymbols(UJMPSettings.getLocale());
symbols.setNaN("NaN");
symbols.setInfinity("Inf");
defaultNumberFormat = new DecimalFormat("0.0000", symbols);
exponentialNumberFormat = new DecimalFormat("0.000E000", symbols);
dateFormat = new SimpleDateFormat("yyyy-mm-dd");
this.multiLine = multiLine;
this.width = width;
this.usePadding = usePadding;
}
public static final UJMPFormat getMultiLineInstance() {
return multiLineInstance;
}
public static final UJMPFormat getSingleLineInstance() {
return singleLineInstance;
}
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
if (obj == null) {
if (usePadding) {
pad(toAppendTo, ' ', width);
}
return toAppendTo;
} else if (obj instanceof String) {
return format((String) obj, toAppendTo, pos);
} else if (obj instanceof Matrix) {
return format((Matrix) obj, toAppendTo, pos);
} else if (obj instanceof Date) {
return format((Date) obj, toAppendTo, pos);
} else if (obj instanceof byte[]) {
return format((byte[]) obj, toAppendTo, pos);
} else if (obj instanceof Number) {
return format((Number) obj, toAppendTo, pos);
} else {
return format(String.valueOf(obj), toAppendTo, pos);
}
}
private StringBuffer format(Matrix obj, StringBuffer toAppendTo, FieldPosition pos) {
if (obj == null) {
if (usePadding) {
pad(toAppendTo, ' ', width);
}
return toAppendTo;
} else if (multiLine) {
return formatMultiLine(obj, toAppendTo, pos);
} else {
if (obj.getLabel() != null) {
toAppendTo.append("[" + obj.getLabel() + "]");
} else {
toAppendTo.append("[Matrix]");
}
return toAppendTo;
}
}
private StringBuffer format(Date obj, StringBuffer toAppendTo, FieldPosition pos) {
int length = toAppendTo.length();
toAppendTo = dateFormat.format(obj, toAppendTo, pos);
length = width - (toAppendTo.length() - length);
if (usePadding) {
pad(toAppendTo, ' ', length);
}
return toAppendTo;
}
private StringBuffer format(byte[] obj, StringBuffer toAppendTo, FieldPosition pos) {
for (int i = 0; i < obj.length; i++) {
toAppendTo.append(obj[i]);
}
return toAppendTo;
}
private StringBuffer pad(StringBuffer s, char c, int count) {
for (int i = 0; i < count; i++) {
s.append(c);
}
return s;
}
private StringBuffer format(String obj, StringBuffer toAppendTo, FieldPosition pos) {
if (obj != null && obj.length() > width) {
obj = obj.substring(0, width);
}
if (obj != null) {
toAppendTo.append(obj);
if (usePadding) {
pad(toAppendTo, ' ', width - obj.length());
}
return toAppendTo;
} else {
if (usePadding) {
pad(toAppendTo, ' ', width);
}
return toAppendTo;
}
}
private StringBuffer format(Number obj, StringBuffer toAppendTo, FieldPosition pos) {
String s = defaultNumberFormat.format(obj);
if (s.length() > width) {
s = exponentialNumberFormat.format(obj);
}
if (usePadding) {
pad(toAppendTo, ' ', width - s.length());
}
toAppendTo.append(s);
return toAppendTo;
}
private StringBuffer formatMultiLine(Matrix m, StringBuffer toAppendTo, FieldPosition pos) {
long maxRows = UJMPSettings.getInstance().getMaxRowsToPrint();
long maxColumns = UJMPSettings.getInstance().getMaxColumnsToPrint();
final String EOL = System.getProperty("line.separator");
long rowCount = m.getRowCount();
long columnCount = m.getColumnCount();
long[] cursor = new long[m.getDimensionCount()];
if (m.getDimensionCount() > 2) {
toAppendTo.append(m.getDimensionCount());
toAppendTo.append("D-Matrix [");
toAppendTo.append(Coordinates.toString("x", m.getSize()));
toAppendTo.append("]: only two dimensions are printed");
toAppendTo.append(EOL);
}
if (m.getMetaData() != null) {
format(m.getLabel(), toAppendTo, pos);
toAppendTo.append(" ");
for (int col = 0; col < columnCount && col < maxColumns; col++) {
format(m.getColumnLabel(col), toAppendTo, pos);
if (col < columnCount - 1) {
toAppendTo.append(' ');
}
}
toAppendTo.append(EOL);
pad(toAppendTo, '=', width);
toAppendTo.append(" ");
for (int col = 0; col < columnCount && col < maxColumns; col++) {
pad(toAppendTo, '-', width);
if (col < columnCount - 1) {
toAppendTo.append(' ');
}
}
toAppendTo.append(EOL);
}
for (cursor[Matrix.ROW] = 0; cursor[Matrix.ROW] < rowCount && cursor[Matrix.ROW] < maxRows; cursor[Matrix.ROW]++) {
if (m.getMetaData() != null) {
format(m.getRowLabel(cursor[Matrix.ROW]), toAppendTo, pos);
toAppendTo.append(" | ");
}
for (cursor[Matrix.COLUMN] = 0; cursor[Matrix.COLUMN] < columnCount
&& cursor[Matrix.COLUMN] < maxColumns; cursor[Matrix.COLUMN]++) {
Object o = m.getAsObject(cursor);
if (o == null && m instanceof BaseBigDecimalMatrix) {
toAppendTo = format(Double.NaN, toAppendTo, pos);
} else if (o instanceof Matrix) {
toAppendTo.append("[Matrix]");
} else {
toAppendTo = format(o, toAppendTo, pos);
}
if (cursor[Matrix.COLUMN] < columnCount - 1) {
toAppendTo.append(' ');
}
}
toAppendTo.append(EOL);
}
if (rowCount == 0 || columnCount == 0) {
toAppendTo.append("[" + rowCount + "x" + columnCount + "]" + EOL);
} else if (rowCount > UJMPSettings.getInstance().getMaxRowsToPrint()
|| columnCount > UJMPSettings.getInstance().getMaxColumnsToPrint()) {
toAppendTo.append("[...]");
}
return toAppendTo;
}
@Override
public Object parseObject(String source, ParsePosition pos) {
throw new RuntimeException("not implemented");
}
}