Package DisplayProject

Source Code of DisplayProject.DataFieldFormatterFactory$DataFormatterException

/*
Copyright (c) 2003-2008 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package DisplayProject;

import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.JFormattedTextField;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.NumberFormatter;

import org.apache.log4j.Logger;

import Framework.DateTimeData;
import Framework.DecimalData;
import Framework.DomainDataValue;
import Framework.DoubleData;
import Framework.ErrorMgr;
import Framework.IntegerData;

/**
* A factory that creates formatters for data fields
*/
public class DataFieldFormatterFactory extends JFormattedTextField.AbstractFormatterFactory
{
    private static Logger logger = Logger.getLogger(DataFieldFormatterFactory.class);
    private String inputMask;
    private char maskPlaceholder;
    private String format;
    private Class<?> mappedType;

    private DelegatingMaskFormatter maskFormatterDecorator;
    private DefaultFormatter displayFormatter;
    private DefaultFormatter editFormatter;

    private FormatProvider editProvider = new FormatProvider(true);
    private FormatProvider displayProvider = new FormatProvider(false);

    /**
     * Default constructor
     */
    public DataFieldFormatterFactory()
    {
    }

    /**
     * Constructs a new factory configured to creates formatters
     * with masking behaviour.
     *
     * @see DelegatingMaskFormatter
     *
     * @param inputMask defines the input mask
     * @param maskPlaceholder defines the mask placeholder i.e *
     */
    public DataFieldFormatterFactory(String inputMask, char maskPlaceholder)
    {
        this.inputMask = inputMask;
        this.maskPlaceholder = maskPlaceholder;
    }

    /**
     * Constructs a new factory configured to creates formatters
     * with masking behaviour and an underlying <code>format</code>
     * pattern                      .
     *
     * @see DelegatingMaskFormatter
     *
     * @param inputMask defines the input mask
     * @param maskPlaceholder defines the mask placeholder i.e *
     * @param format a pattern used when creating the format object
     */
    public DataFieldFormatterFactory(String inputMask, char maskPlaceholder, String format)
    {
        this.inputMask = inputMask;
        this.maskPlaceholder = maskPlaceholder;
        this.format = format;
    }

    /**
     * Constructs a new factory configured to creates formatters
     * with masking behaviour a default mapped type.
     *
     * @see DelegatingMaskFormatter
     *
     * @param inputMask defines the input mask
     * @param maskPlaceholder defines the mask placeholder i.e *
     * @param mappedType used as the value class when the texfields value is null
     */
    public DataFieldFormatterFactory(String inputMask, char maskPlaceholder, Class<?> mappedType)
    {
        this.inputMask = inputMask;
        this.maskPlaceholder = maskPlaceholder;
        this.mappedType = mappedType;
    }

    /**
     * Constructs a new factory configured to creates formatters
     * with masking behaviour, an underlying <code>format</code>
     * pattern and a default mapped type.
     *
     * @see DelegatingMaskFormatter
     *
     * @param inputMask defines the input mask
     * @param maskPlaceholder defines the mask placeholder i.e *
     * @param format a pattern used when creating the format object
     * @param mappedType used as the value class when the text fields value is null
     */
    public DataFieldFormatterFactory(String inputMask, char maskPlaceholder, String format, Class<?> mappedType)
    {
        this.inputMask = inputMask;
        this.maskPlaceholder = maskPlaceholder;
        this.format = format;
        this.mappedType = mappedType;
    }

    /**
     * Constructs a new factory configured with an underlying <code>format</code>
     * pattern and a default mapped type.

     * @param format a pattern used when creating the format object
     * @param mappedType used as the value class when the texfields value is null
     */
    public DataFieldFormatterFactory(String format, Class<?> mappedType)
    {
        this.format = format;
        this.mappedType = mappedType;
    }

    /**
     * Constructs a new factory configured with a default mapped type.
     *
     * @param mappedType used as the value class when the texfields value is null
     */
    public DataFieldFormatterFactory(Class<?> mappedType)
    {
        this.mappedType = mappedType;
    }
   
    public DataFieldFormatterFactory(Class<?> mappedType, DefaultFormatter formatter) {
      this.mappedType = mappedType;
      this.displayFormatter = formatter;
      this.editFormatter = formatter;
    }

    /**
     * Set the mapped type to the new class type
     * @param mappedType
     */
    public void setMappedType(Class<?> mappedType) {
        this.mappedType = mappedType;
    }

    /**
     * Getter for the mapped type underlying this formatter factory
     * @return the mapped class type
     */
    public Class<?> getMappedType() {
        return this.mappedType;
    }
    /**
     * Get the formatter based on the factories configuration, the current value
     * contained within the underlying text field, and the text fields focus state.
     * <p>
     * The formatter returned is determined by first checking whether the value property
     * has been assigned. If it has, then a formatter which formats strings to the same type
     * as what is currently assigned is returned. If the value of the textfield is null, the
     * factories mapped typed is used. If this is null, the factory will see whether the textfield
     * has a BindingContext client property associated with it and use the contexts property
     * descriptor, otherwise a default formatter configured to convert everything to a string is
     * returned.
     * <p>
     * If the factory has been configuired with an input mask, the returned formatter will be wrapped
     * by a formatter that provides masking
     * <p>
     * The focus state of the text field is used to select whether the displayProvider or editProvider
     * is used to create the Format objects.
     *
     * @param tf the textfield we are getting a formatter for
     * @return a formatter ready for use
     */
    public JFormattedTextField.AbstractFormatter getFormatter(JFormattedTextField tf)
    {
        logger.info("getFormatter() [" + tf.getName() + "] value [" + tf.getValue() + "] hasFocus [" + tf.hasFocus() + "]");
        Object value = tf.getValue();
        if (value != null)
        {
            return getFormatter(value.getClass(), tf.hasFocus());
        }
        else if (mappedType != null)
        {
            return getFormatter(mappedType, tf.hasFocus());
        }
        else
        {
            return getFormatter(String.class, tf.hasFocus());
        }
    }

    public FormatProvider getDisplayProvider()
    {
        return displayProvider;
    }

    public void setDisplayProvider(FormatProvider displayProvider)
    {
        this.displayProvider = displayProvider;
    }

    public FormatProvider getEditProvider()
    {
        return editProvider;
    }

    public void setEditProvider(FormatProvider editProvider)
    {
        this.editProvider = editProvider;
    }

    public DefaultFormatter getEditFormatter()
    {
        return editFormatter;
    }

    public void setEditFormatter(DefaultFormatter editFormatter)
    {
        this.editFormatter = editFormatter;
    }

    public DefaultFormatter getDisplayFormatter()
    {
        return displayFormatter;
    }

    public void setDisplayFormatter(DefaultFormatter displayFormatter)
    {
        this.displayFormatter = displayFormatter;
    }

    private JFormattedTextField.AbstractFormatter getFormatter(Class<?> valueClass, boolean editing)
    {
        // Only create a new if we havent created one or the value class has changed
        if (!editing)
        {
            displayFormatter = createFormatter(displayFormatter, valueClass, displayProvider);
            return displayFormatter;
        }
        else
        {
            editFormatter = createFormatter(editFormatter, valueClass, editProvider);
            return editFormatter;
        }
    }

    private DefaultFormatter createFormatter(DefaultFormatter formatter, Class<?> valueClass, FormatProvider formatProvider)
    {
        // Only create a new if we havent created one or the value class has changed
        if (formatter == null || !formatter.getValueClass().equals(valueClass))
        {
            formatter = createFormatter(valueClass, formatProvider);
        }
        return formatter;
    }

    private DefaultFormatter createFormatter(Class<?> valueClass, FormatProvider formatProvider)
    {
      DefaultFormatter formatter;
      //PM:18/3/08 BMO-22
      //CraigM: 28/04/2008: Added back in so Domain classes will work
      if (DomainDataValue.class.isAssignableFrom(valueClass) && format == null) {
        // Represents a user defined DataValue
        formatter = new DataFieldFormatter();
      }
      else if (DateTimeData.class.isAssignableFrom(valueClass)) {
        if (format != null) {
          formatter = new DateTimeDataFormatter(formatProvider.getDateFormat(format));
        }
        else {
          formatter = new DateTimeDataFormatter(formatProvider.getDefaultDateFormat());
        }
      }

      // Handle DecimalDatas differently from DoubleDatas as they have a different default.  CraigM: 24/03/2008
      else if (DecimalData.class.isAssignableFrom(valueClass)) {
        if (format != null) {
          formatter = NumericDataFormatter.getDecimalDataInstance(formatProvider.getDecimalFormat(format));
        }
        else {
          formatter = NumericDataFormatter.getDecimalDataInstance(formatProvider.getDefaultDecimalFormat());
        }
      }
      else if (DoubleData.class.isAssignableFrom(valueClass)) {
        if (format != null) {
          formatter = NumericDataFormatter.getDecimalDataInstance(formatProvider.getDecimalFormat(format));
        }
        else {
          formatter = NumericDataFormatter.getDecimalDataInstance(formatProvider.getDefaultDoubleFormat());
        }
      }
      else if (IntegerData.class.isAssignableFrom(valueClass)) {
        if (format != null) {
          formatter = NumericDataFormatter.getIntegerDataInstance(formatProvider.getDecimalFormat(format));
        }
        else {
          formatter = NumericDataFormatter.getIntegerDataInstance(formatProvider.getDefaultIntegerFormat());
        }
      }
      // TF:14/10/2009:If we're using a primitive numeric type like double, we want these mapped the same as if we're using Double.class
      else if(Number.class.isAssignableFrom(valueClass) || valueClass.isPrimitive()) {
        if (format != null) {
          formatter = new ForteNumberFormatter(formatProvider.getDecimalFormat(format));
        }
        else {
          formatter = new ForteNumberFormatter(formatProvider.getDefaultDoubleFormat());
        }
      }
      else {
        formatter = new DataFieldFormatter();
      }
      formatter.setValueClass(valueClass);

        return applyInputMask(formatter);
    }

    private DefaultFormatter applyInputMask(DefaultFormatter formatter)
    {
        try
        {
            if (inputMask != null)
            {
                if (maskFormatterDecorator == null)
                    maskFormatterDecorator = new DelegatingMaskFormatter(inputMask,maskPlaceholder,formatter);
                else
                    maskFormatterDecorator.setDelegate(formatter);

                return maskFormatterDecorator;
            }

            return formatter;
        }
        catch (ParseException pe)
        {
            logger.error("Unable to create mask displayFormatter", pe);
            DataFormatterException errorVar = new DataFormatterException("Invalid mask specified for mask displayFormatter", pe);
            ErrorMgr.addError(errorVar);
            throw errorVar;
        }
    }

    /**
     * Runtime exception thrown by the factory
     */
    @SuppressWarnings("serial")
  public class DataFormatterException extends RuntimeException
    {
        public DataFormatterException(String message, Throwable cause)
        {
            super(message, cause);
        }
    }
   
    public String getFormat() {
    return format;
  }
   
    public String getInputMask() {
    return inputMask;
  }
   
    public char getMaskPlaceholder() {
    return maskPlaceholder;
  }
   
    @SuppressWarnings("serial")
    /**
     * This NumberFormatter covers the standard case of displaying numeric values, but in Forte, if a numeric
     * value was mapped on the screen to say a string, and to the underlying data model as an integer, then
     * the spaces that were allowed to be entered in the string would have no effect on the value that could
     * be retrieved from that string
     */
  public class ForteNumberFormatter extends NumberFormatter {

    public ForteNumberFormatter(NumberFormat format) {
      super(format);
    }
   
    @Override
    public Object stringToValue(String text) throws ParseException {
      // DK:09/02/2009:trim leading and trailing spaces before conversion
      text = text.trim();
      // DK:03/02/2009: Forte is excepting empty string as a zero value.
      if ("".equals(text)) {
        return convertValueToValueClass(0);
      }
      return super.stringToValue(text);
    }
     
    /**
     * Convert the passed value to a value that is compatible with the value class
     * associated with this type.
     * @param value value to convert.
     * @return value converted to the value class or null if the value is null.
     * @see #getValueClass()
     */
    private Object convertValueToValueClass(Object value) {
      if (value == null) {
        return null;
      }
      Class<?> valueClass = getValueClass();
      if (valueClass != null && value.getClass().equals(valueClass)) {
        return value;
      }
          if (valueClass != null && (value instanceof Number)) {
              if (valueClass == Integer.class) {
                return Integer.valueOf(((Number)value).intValue());
              }
              else if (valueClass == Long.class) {
                return Long.valueOf(((Number)value).longValue());
              }
              else if (valueClass == Float.class) {
                  return new Float(((Number)value).floatValue());
              }
              else if (valueClass == Double.class) {
                  return new Double(((Number)value).doubleValue());
              }
              else if (valueClass == Byte.class) {
                return Byte.valueOf(((Number)value).byteValue());
              }
              else if (valueClass == Short.class) {
                  return new Short(((Number)value).shortValue());
              }
          }
          return value;

    }

    }
}
TOP

Related Classes of DisplayProject.DataFieldFormatterFactory$DataFormatterException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.