/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso 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 3 of the License, or * (at your option) any later version. * * Jspresso 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 Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.model.descriptor.basic; import java.math.BigDecimal; import java.math.RoundingMode; import org.jspresso.framework.model.descriptor.IDecimalPropertyDescriptor; /** * Describes a decimal property. Property value is either stored as a * {@code Double} or as a {@code BigDecimal} depending on the * {@code usingBigDecimal} property. * * @author Vincent Vandenschrick */ public class BasicDecimalPropertyDescriptor extends BasicNumberPropertyDescriptor implements IDecimalPropertyDescriptor { private Integer maxFractionDigit; private Boolean usingBigDecimal; /** * {@inheritDoc} */ @Override public BasicDecimalPropertyDescriptor clone() { BasicDecimalPropertyDescriptor clonedDescriptor = (BasicDecimalPropertyDescriptor) super .clone(); return clonedDescriptor; } /** * {@inheritDoc} */ @Override public Integer getMaxFractionDigit() { if (maxFractionDigit == null) { return DEFAULT_MAX_FRACTION_DIGIT; } return maxFractionDigit; } /** * {@inheritDoc} */ @Override public Class<?> getModelType() { if (isUsingBigDecimal()) { return BigDecimal.class; } return Double.class; } /** * Returns false by default. * <p> * {@inheritDoc} */ @Override public boolean isUsingBigDecimal() { if (usingBigDecimal != null) { return usingBigDecimal; } return false; } /** * Configures the precision of the decimal property. Default value is * {@code 2}. * * @param maxFractionDigit * the maxFractionDigit to set. */ public void setMaxFractionDigit(Integer maxFractionDigit) { this.maxFractionDigit = maxFractionDigit; } /** * Configures the property to be managed using * {@code java.math.BigDecimal}. Default value is {@code false} * which means {@code java.lang.Double} will be used. * * @param usingBigDecimal * the usingBigDecimal to set. */ public void setUsingBigDecimal(boolean usingBigDecimal) { this.usingBigDecimal = usingBigDecimal; // Re-compute default value because it may change type (between Double and BigDecimal) setDefaultValue(getDefaultValue()); } /** * {@inheritDoc} */ @Override public BigDecimal getMinValue() { BigDecimal min = super.getMinValue(); if (min == null) { min = new BigDecimal(-Double.MAX_VALUE); } return min; } /** * {@inheritDoc} */ @Override public BigDecimal getMaxValue() { BigDecimal max = super.getMaxValue(); if (max == null) { max = new BigDecimal(Double.MAX_VALUE); } return max; } /** * {@inheritDoc} */ @Override protected boolean isDefault(BigDecimal boundValue) { if (boundValue != null) { return boundValue.doubleValue() == Double.MAX_VALUE || boundValue.doubleValue() == -Double.MAX_VALUE; } return super.isDefault(null); } /** * Handle BigDecimal precision. * <p> * {@inheritDoc} */ @Override public Object interceptSetter(Object component, Object newValue) { Object actualNewValue = newValue; if (getMaxFractionDigit() != null) { if (actualNewValue instanceof Double) { actualNewValue = new BigDecimal(actualNewValue.toString()) .setScale(getMaxFractionDigit(), RoundingMode.HALF_EVEN) .doubleValue(); } else if (actualNewValue instanceof BigDecimal) { actualNewValue = ((BigDecimal) actualNewValue).setScale( getMaxFractionDigit(), RoundingMode.HALF_EVEN); } } return super.interceptSetter(component, actualNewValue); } }