/** * AnalyzerBeans * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.eobjects.analyzer.result.renderer; import java.text.NumberFormat; import java.util.List; import org.eobjects.analyzer.beans.api.RendererBean; import org.eobjects.analyzer.result.Crosstab; import org.eobjects.analyzer.result.CrosstabDimension; import org.eobjects.analyzer.result.CrosstabResult; import org.eobjects.analyzer.result.ResultProducer; import org.eobjects.analyzer.util.LabelUtils; import org.eobjects.analyzer.util.ReflectionUtils; import org.apache.metamodel.util.FormatHelper; @RendererBean(TextRenderingFormat.class) public class CrosstabTextRenderer extends AbstractRenderer<CrosstabResult, String> { private static class TextCrosstabRendererCallback implements CrosstabRendererCallback<String> { private NumberFormat decimalFormat = FormatHelper.getUiNumberFormat(); private boolean leftAligned; private StringBuilder sb; private int horizontalDimensionWidth; @Override public void beginTable(Crosstab<?> crosstab, List<CrosstabDimension> horizontalDimensions, List<CrosstabDimension> verticalDimensions) { sb = new StringBuilder(); horizontalDimensionWidth = 0; for (CrosstabDimension dimension : horizontalDimensions) { List<String> categories = dimension.getCategories(); for (String category : categories) { horizontalDimensionWidth = Math.max(horizontalDimensionWidth, category.length()); } } // minimum width = 6 horizontalDimensionWidth = Math.max(horizontalDimensionWidth, 6); if (ReflectionUtils.is(crosstab.getValueClass(), Number.class)) { leftAligned = false; } else { leftAligned = true; } } @Override public void endTable() { } @Override public void beginRow() { } @Override public void endRow() { sb.append('\n'); } @Override public void horizontalHeaderCell(String category, CrosstabDimension dimension, int width) { int trailingBlanks = horizontalDimensionWidth * width - category.length(); if (leftAligned) { sb.append(category); for (int i = 0; i < trailingBlanks; i++) { sb.append(' '); } } else { for (int i = 0; i < trailingBlanks; i++) { sb.append(' '); } sb.append(category); } // separator sb.append(' '); } @Override public void verticalHeaderCell(String category, CrosstabDimension dimension, int height) { sb.append(category); int dimensionWidth = getWidth(dimension); dimensionWidth = dimensionWidth - category.length(); for (int i = 0; i < dimensionWidth; i++) { sb.append(' '); } // separator sb.append(' '); } @Override public void valueCell(Object value, ResultProducer drillToDetailResultProducer) { boolean leftAligned = this.leftAligned; String stringValue = (value == null ? null : value.toString()); stringValue = LabelUtils.getValueLabel(stringValue); if (value instanceof Number) { leftAligned = false; if (value instanceof Double || value instanceof Float) { stringValue = decimalFormat.format(value); } } int trailingBlanks = horizontalDimensionWidth - stringValue.length(); if (leftAligned) { sb.append(stringValue); for (int i = 0; i < trailingBlanks; i++) { sb.append(' '); } } else { for (int i = 0; i < trailingBlanks; i++) { sb.append(' '); } sb.append(stringValue); } // separator sb.append(' '); } @Override public void emptyHeader(CrosstabDimension verticalDimension, CrosstabDimension horizontalDimension) { int dimensionWidth = getWidth(verticalDimension); for (int i = 0; i < dimensionWidth; i++) { sb.append(' '); } // separator sb.append(' '); } private int getWidth(CrosstabDimension verticalDimension) { List<String> categories = verticalDimension.getCategories(); int longestCategory = 0; for (String category : categories) { longestCategory = Math.max(longestCategory, category.length()); } return longestCategory; } @Override public String getResult() { if (sb == null) { return ""; } return sb.toString(); } } @Override public String render(CrosstabResult result) { return render(result.getCrosstab()); } public String render(Crosstab<?> crosstab) { return new CrosstabRenderer(crosstab).render(new TextCrosstabRendererCallback()); } }