org.xwiki.rendering.internal.macro.chart.source.AxisConfigurator.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.rendering.internal.macro.chart.source.AxisConfigurator.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This 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.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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 software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.rendering.internal.macro.chart.source;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jfree.chart.axis.Axis;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.xwiki.chart.axis.AxisType;
import org.xwiki.chart.plot.PlotType;
import org.xwiki.rendering.macro.MacroExecutionException;

/**
 * A configurator object for the axes.
 *
 * This super class provides basic parameter validation.
 *
 * @version $Id: 55363825ab755a236151a92e1d714116144dbbce $
 * @since 4.2M1
 */
public class AxisConfigurator extends AbstractConfigurator {
    /**
     * The name of the domain axis parameter.
     */
    public static final String DOMAIN_AXIS_PARAM = "domain_axis_type";

    /**
     * The name of the range axis parameter.
     */
    public static final String RANGE_AXIS_PARAM = "range_axis_type";

    /**
     * The name of the domain axis date format parameter.  Used only if the axis type is date.
     */
    public static final String DOMAIN_AXIS_DATE_FORMAT_PARAM = "domain_axis_date_format";

    /**
     * The name of the range axis date format parameter.  Used only if the axis type is date.
     */
    public static final String RANGE_AXIS_DATE_FORMAT_PARAM = "range_axis_date_format";

    /**
     * The lower limit on the domain axis.
     */
    public static final String DOMAIN_AXIS_LOWER_PARAM = "domain_axis_lower";

    /**
     * The upper limit on the domain axis.
     */
    public static final String DOMAIN_AXIS_UPPER_PARAM = "domain_axis_upper";

    /**
     * The lower limit on the range axis.
     */
    public static final String RANGE_AXIS_LOWER_PARAM = "range_axis_lower";

    /**
     * The upper limit on the range axis.
     */
    public static final String RANGE_AXIS_UPPER_PARAM = "range_axis_upper";

    /**
     * The configured axis types.
     */
    private AxisType[] axisTypes = { null, null, null };

    /**
     * The configured axis date formats.
     */
    private String[] axisDateFormat = { null, null, null };

    /**
     * The locale configuration.
     */
    private final LocaleConfiguration localeConfiguration;

    /**
     * The lower limits.
     */
    private String[] axisLowerLimit = { null, null, null };

    /**
     * The upper limits.
     */
    private String[] axisUpperLimit = { null, null, null };

    /**
     * @param localeConfiguration The locale configuration.
     */
    public AxisConfigurator(LocaleConfiguration localeConfiguration) {
        this.localeConfiguration = localeConfiguration;
    }

    @Override
    public boolean setParameter(String key, String value) throws MacroExecutionException {
        boolean claimed = true;

        if (DOMAIN_AXIS_PARAM.equals(key)) {
            AxisType type = AxisType.forName(value);
            if (type == null) {
                invalidParameterValue(DOMAIN_AXIS_PARAM, value);
            }
            setAxisType(0, type);
        } else if (DOMAIN_AXIS_DATE_FORMAT_PARAM.equals(key)) {
            setAxisDateFormat(0, value);
        } else if (RANGE_AXIS_PARAM.equals(key)) {
            AxisType type = AxisType.forName(value);
            if (type == null) {
                invalidParameterValue(RANGE_AXIS_PARAM, value);
            }
            setAxisType(1, type);
        } else if (RANGE_AXIS_DATE_FORMAT_PARAM.equals(key)) {
            setAxisDateFormat(0, value);
        } else if (!claimLimitParameters(key, value)) {
            claimed = false;
        }

        return claimed;
    }

    /**
     * Claime limit parameters.
     *
     * @param key the parameter name.
     * @param value the parameter value.
     * @return {@code true} if the parameter was claimed.
     */
    private boolean claimLimitParameters(String key, String value) {
        boolean claimed = true;

        if (DOMAIN_AXIS_LOWER_PARAM.equals(key)) {
            axisLowerLimit[0] = value;
        } else if (DOMAIN_AXIS_UPPER_PARAM.equals(key)) {
            axisUpperLimit[0] = value;
        } else if (RANGE_AXIS_LOWER_PARAM.equals(key)) {
            axisLowerLimit[1] = value;
        } else if (RANGE_AXIS_UPPER_PARAM.equals(key)) {
            axisUpperLimit[1] = value;
        } else {
            claimed = false;
        }

        return claimed;
    }

    /**
     * Set the axis type for the axis at the given index.
     *
     * @param index The index.
     * @param axisType the axis type.
     */
    private void setAxisType(int index, AxisType axisType) {
        axisTypes[index] = axisType;
    }

    /**
     * Set the date format for the axis at the given index.
     *
     * @param index The index.
     * @param dateFormatString the date format.
     * @throws MacroExecutionException if the date format string is invalid.
     */
    private void setAxisDateFormat(int index, String dateFormatString) throws MacroExecutionException {
        axisDateFormat[index] = dateFormatString;
    }

    /**
     * Set the axes in the chart model.
     *
     * @param plotType The target plot type.
     * @param chartModel The target chart model.
     * @throws MacroExecutionException if the axes are incorrectly configured.
     */
    public void setAxes(PlotType plotType, SimpleChartModel chartModel) throws MacroExecutionException {
        AxisType[] defaultAxisTypes = plotType.getDefaultAxisTypes();

        for (int i = 0; i < axisTypes.length; i++) {
            AxisType type = axisTypes[i];
            if (i >= defaultAxisTypes.length) {
                if (type != null) {
                    throw new MacroExecutionException("To many axes for plot type.");
                }
                continue;
            }
            if (type == null) {
                type = defaultAxisTypes[i];
            }

            Axis axis;

            switch (type) {
            case NUMBER:
                NumberAxis numberAxis = new NumberAxis();
                axis = numberAxis;
                setNumberLimits(numberAxis, i);
                break;
            case CATEGORY:
                axis = new CategoryAxis();
                break;
            case DATE:
                DateAxis dateAxis = new DateAxis();
                axis = dateAxis;
                dateAxis.setTickMarkPosition(DateTickMarkPosition.END);
                if (axisDateFormat[i] != null) {
                    try {
                        DateFormat dateFormat = new SimpleDateFormat(axisDateFormat[i],
                                localeConfiguration.getLocale());
                        dateAxis.setDateFormatOverride(dateFormat);
                    } catch (IllegalArgumentException e) {
                        throw new MacroExecutionException(
                                String.format("Invalid date format [%s].", axisDateFormat[i]));
                    }
                }
                setDateLimits(dateAxis, i);
                break;
            default:
                throw new MacroExecutionException(String.format("Unsupported axis type [%s]", type.getName()));
            }

            chartModel.setAxis(i, axis);
        }
    }

    /**
     * Set the limits of a number axis.
     *
     * @param axis The axis.
     * @param index The index of the axis
     * @throws MacroExecutionException if the parameters could not be parsed as numbers.
     */
    private void setNumberLimits(ValueAxis axis, int index) throws MacroExecutionException {
        try {
            if (axisLowerLimit[index] != null) {
                Number number = NumberUtils.createNumber(StringUtils.trim(axisLowerLimit[index]));
                axis.setLowerBound(number.doubleValue());
            }
            if (axisUpperLimit[index] != null) {
                Number number = NumberUtils.createNumber(StringUtils.trim(axisUpperLimit[index]));
                axis.setUpperBound(number.doubleValue());
            }
        } catch (NumberFormatException e) {
            throw new MacroExecutionException("Invalid number in axis bound.", e);
        }
    }

    /**
     * Set the limits of a date axis.
     *
     * @param axis The axis.
     * @param index The index of the axis.
     * @throws MacroExecutionException if the parameters could not be parsed as dates.
     */
    private void setDateLimits(DateAxis axis, int index) throws MacroExecutionException {
        try {
            if (axisLowerLimit[index] != null) {
                Date date = localeConfiguration.getDateFormat().parse(StringUtils.trim(axisLowerLimit[index]));
                axis.setMinimumDate(date);
            }
            if (axisUpperLimit[index] != null) {
                Date date = localeConfiguration.getDateFormat().parse(StringUtils.trim(axisUpperLimit[index]));
                axis.setMaximumDate(date);
            }
        } catch (ParseException e) {
            throw new MacroExecutionException("Invalid date in axis bound.", e);
        }
    }
}