edu.ku.brc.af.ui.forms.formatters.UIFieldFormatter.java Source code

Java tutorial

Introduction

Here is the source code for edu.ku.brc.af.ui.forms.formatters.UIFieldFormatter.java

Source

/* Copyright (C) 2015, University of Kansas Center for Research
 * 
 * Specify Software Project, specify@ku.edu, Biodiversity Institute,
 * 1345 Jayhawk Boulevard, Lawrence, Kansas, 66045, USA
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package edu.ku.brc.af.ui.forms.formatters;

import static edu.ku.brc.helpers.XMLHelper.xmlAttr;
import static org.apache.commons.lang.StringUtils.isAlpha;
import static org.apache.commons.lang.StringUtils.isAlphanumeric;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.isNotEmpty;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import edu.ku.brc.af.core.db.AutoNumberIFace;
import edu.ku.brc.af.prefs.AppPrefsCache;
import edu.ku.brc.ui.DateWrapper;
import edu.ku.brc.ui.UIRegistry;
import edu.ku.brc.util.Pair;

/**
 * This class describes a format for a string. The format is divided up into fields and each field has a type
 * describing what kind of values it can accept.
 * 
 * @author rods
 *
 * @code_status Beta
 *
 * Created Date: Jan 17, 2007
 *
 */
public class UIFieldFormatter implements UIFieldFormatterIFace, Cloneable {
    private static final Logger log = Logger.getLogger(UIFieldFormatter.class);
    protected static DateWrapper scrDateFormat = AppPrefsCache.getDateWrapper("ui", "formatting", "scrdateformat");

    public static int[] daysInMon = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    protected static final String deftitle = UIRegistry.getResourceString("FFE_DEFAULT");
    protected static final String systitle = UIRegistry.getResourceString("FFE_SYSTEM");

    protected String fieldName;
    protected String name;
    protected boolean isSystem;
    protected boolean isExternal;
    protected String title;
    protected Class<?> dataClass;
    protected FormatterType type;
    protected PartialDateEnum partialDateType;
    protected boolean isDefault;
    protected Vector<UIFieldFormatterField> fields;
    protected boolean isIncrementer;
    protected DateWrapper dateWrapper = null;
    protected AutoNumberIFace autoNumber = null;

    protected int precision = 0;
    protected int scale = 0;

    protected Number minValue = null;
    protected Number maxValue = null;
    protected Boolean hasDash = null;

    // Transient
    private Integer fieldLength = null;

    /**
     * Default constructor
     */
    public UIFieldFormatter() {
        fields = new Vector<UIFieldFormatterField>();
        this.isExternal = false;
    }

    /**
     * Constructor.
     * @param name the unique name of the formatter
     * @param isDate whether it is a date formatter
     * @param partialDateType the type of date formatter (if it is one)
     * @param dataClass the class of data that it operates on
     * @param isDefault whether it is the default formatter
     * @param isIncrementer whether it can/should increment the value
     * @param fields the list of fields that make up the formatter
     */
    public UIFieldFormatter(final String name, final boolean isSystem, final String fieldName,
            final FormatterType type, final PartialDateEnum partialDateType, final Class<?> dataClass,
            final boolean isDefault, final boolean isIncrementer, final Vector<UIFieldFormatterField> fields) {
        this.name = name;
        this.isSystem = isSystem;
        this.isExternal = false;
        this.fieldName = fieldName;
        this.dataClass = dataClass;
        this.partialDateType = partialDateType;
        this.type = type;
        this.isDefault = isDefault;
        this.fields = fields;
        this.isIncrementer = isIncrementer;
    }

    /**
     * @return the BG text
     */
    public String getText() {
        return toPattern();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isSystem()
     */
    @Override
    public boolean isSystem() {
        return isSystem;
    }

    /**
     * @return the isExternal
     */
    public boolean isExternal() {
        return isExternal;
    }

    /**
     * @param isExternal the isExternal to set
     */
    public void setExternal(boolean isExternal) {
        this.isExternal = isExternal;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getTitle()
     */
    @Override
    public String getTitle() {
        return title == null ? name : title;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setTitle(java.lang.String)
     */
    @Override
    public void setTitle(String title) {
        this.title = title;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getFieldName()
     */
    @Override
    public String getFieldName() {
        return fieldName;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getFields()
     */
    @Override
    public Vector<UIFieldFormatterField> getFields() {
        return fields;
    }

    /*
     * Adds a field to the formatter
     * @param field Field being added
     */
    public void addField(UIFieldFormatterField field) {
        fieldLength = null;
        if (fields == null) {
            resetFields();
        }

        fields.add(field);
    }

    /*
     * Resets formatter fields
     */
    public void resetFields() {
        fieldLength = null;
        fields = new Vector<UIFieldFormatterField>();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getYear()
     */
    @Override
    public UIFieldFormatterField getYear() {
        UIFieldFormatterField year = null;
        for (UIFieldFormatterField field : fields) {
            if (field.getType() == UIFieldFormatterField.FieldType.year) {
                if (year != null) {
                    if (field.isByYear()) {
                        return field;
                    }
                } else if (field.isByYear()) {
                    return field;
                } else {
                    year = field;
                }
            }
        }
        return year;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#byYearApplies()
     */
    @Override
    public boolean byYearApplies() {
        boolean hasYearField = false;
        boolean hasAutoNumber = false;

        for (UIFieldFormatterField field : fields) {
            hasYearField |= field.isCurrentYear();
            hasAutoNumber |= field.isIncrementer();
        }

        return (hasYearField && hasAutoNumber);
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getByYear()
     */
    @Override
    public boolean getByYear() {
        for (UIFieldFormatterField field : fields) {
            if (field.isByYear())
                return true;
        }

        return false;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setByYear(boolean)
     */
    public void setByYear(boolean byYear) {
        if (!byYearApplies())
            return;

        for (UIFieldFormatterField field : fields) {
            if (field.isCurrentYear()) {
                field.setByYear(byYear);
            }
        }
    }

    /**
     * @param minValue the minValue to set
     */
    public void setMinValue(Number minValue) {
        this.minValue = minValue;
    }

    /**
     * @param maxValue the maxValue to set
     */
    public void setMaxValue(Number maxValue) {
        this.maxValue = maxValue;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setName(java.lang.String)
     */
    public void setName(final String name) {
        this.name = name;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getName()
     */
    public String getName() {
        return name;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isDate()
     */
    @Override
    public boolean isDate() {
        return type == FormatterType.date && (partialDateType == null || partialDateType != PartialDateEnum.Search);
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isNumeric()
     */
    @Override
    public boolean isNumeric() {
        return type == FormatterType.numeric;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getMaxValue()
     */
    @Override
    public Number getMaxValue() {
        if (maxValue == null && dataClass == BigDecimal.class) {
            // This is kind lame, but it works
            if (precision > 0 && (precision - scale) > 0) {
                String nines = "99999999999999999999";
                String mask = nines.substring(0, precision - scale) + "." + nines.substring(0, scale);
                //System.err.println(mask);
                maxValue = new BigDecimal(Double.parseDouble(mask));
            } else {
                maxValue = Double.MAX_VALUE;
            }
        }
        return maxValue;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getMinValue()
     */
    public Number getMinValue() {
        if (minValue == null && dataClass == BigDecimal.class) {
            minValue = Double.MIN_VALUE;
        }
        return minValue;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getDataClass()
     */
    public Class<?> getDataClass() {
        return dataClass;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isDefault()
     */
    public boolean isDefault() {
        return isDefault;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setDefault(boolean)
     */
    public void setDefault(boolean isDefault) {
        this.isDefault = isDefault;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isIncrementer()
     */
    public boolean isIncrementer() {
        return isIncrementer;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setIncrementer(boolean)
     */
    public void setIncrementer(boolean isIncrementer) {
        this.isIncrementer = isIncrementer;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getPartialDateType()
     */
    public PartialDateEnum getPartialDateType() {
        return partialDateType;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#setPartialDateType(edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace.PartialDateEnum)
     */
    @Override
    public void setPartialDateType(PartialDateEnum partialDateType) {
        this.partialDateType = partialDateType;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getLength()
     */
    @Override
    public int getLength() {
        if (fieldLength == null) {
            int len = 0;
            for (UIFieldFormatterField field : fields) {
                len += field.getSize();
            }
            fieldLength = len;
        }
        return fieldLength;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#resetLength()
     */
    @Override
    public void resetLength() {
        fieldLength = null;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getUILength()
     */
    @Override
    public int getUILength() {
        return getLength();
    }

    /* (non-Javadoc)
    * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#setLength(int)
    */
    @Override
    public void setLength(int length) {
    }

    /* (non-Javadoc)
      * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getIncPosition()
      */
    @Override
    public Pair<Integer, Integer> getIncPosition() {
        int len = 0;
        for (UIFieldFormatterField field : fields) {
            if (field.isIncrementer()) {
                return new Pair<Integer, Integer>(len, len + field.getSize());
            }
            len += field.getSize();
        }
        return null;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getYearPosition()
     */
    @Override
    public Pair<Integer, Integer> getYearPosition() {
        int len = 0;
        for (UIFieldFormatterField field : fields) {
            if (field.getType() == UIFieldFormatterField.FieldType.year) {
                return new Pair<Integer, Integer>(len, len + field.getSize());
            }
            len += field.getSize();
        }
        return null;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#toPattern()
     */
    @Override
    public String toPattern() {
        StringBuilder str = new StringBuilder();
        for (UIFieldFormatterField field : fields) {
            str.append(field.getValue());
        }
        return str.toString();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getSample()
     */
    @Override
    public String getSample() {
        StringBuilder str = new StringBuilder();
        for (UIFieldFormatterField field : fields) {
            str.append(field.getSample());
        }
        return str.toString();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getDateWrapper()
     */
    @Override
    public DateWrapper getDateWrapper() {
        return dateWrapper;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#setDateWrapper(edu.ku.brc.ui.DateWrapper)
     */
    public void setDateWrapper(final DateWrapper dateWrapper) {
        this.dateWrapper = dateWrapper;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isOutBoundFormatter()
     */
    @Override
    public boolean isFromUIFormatter() {
        return false;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#formatOutBound(java.lang.Object)
     */
    @Override
    public Object formatFromUI(final Object data) {
        // Just pass it on through
        return data;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getAutoNumber()
     */
    @Override
    public AutoNumberIFace getAutoNumber() {
        return autoNumber;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getAutoNumber(edu.ku.brc.dbsupport.AutoNumberIFace)
     */
    @Override
    public void setAutoNumber(AutoNumberIFace autoNumber) {
        this.autoNumber = autoNumber;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#getNextNumber(java.lang.String)
     */
    @Override
    public String getNextNumber(String value) {
        return getNextNumber(value, false);
    }

    /* (non-Javadoc)
    * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#getNextNumber(java.lang.String, boolean)
    */
    @Override
    public String getNextNumber(String value, boolean incrementValue) {
        if (autoNumber != null) {
            String number = autoNumber.getNextNumber(this, value, incrementValue);
            if (number == null && autoNumber.isInError()) {
                UIRegistry.showError(autoNumber.getErrorMsg());
            } else {
                return number;
            }
        }
        return null;
    }

    /* (non-Javadoc)
      * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#formatInBound(java.lang.Object)
      */
    @Override
    public Object formatToUI(Object... datas) {
        Object data = datas[0];
        boolean isStr = data instanceof String;

        if (autoNumber != null && isStr && isEmpty((String) data)) {
            String pattern = toPattern();
            UIFieldFormatterField yearField = getYear();
            if (yearField != null) {
                Pair<Integer, Integer> pos = getYearPosition();
                if (pos != null) {
                    StringBuilder sb = new StringBuilder(pattern);
                    Calendar cal = Calendar.getInstance();
                    sb.replace(pos.first, pos.second, Integer.toString(cal.get(Calendar.YEAR)));
                    return sb.toString();
                }
            }
            return pattern;

        } else if (data instanceof Number) {
            /*
             * This block modified to fix #10238
            * the entire block actually seems kind of unnecessary because
            * the same code for displaying values in view mode could be used instead.
            */

            //int    size = fields.get(0).getSize();
            //String fmt;
            if (data instanceof Float || data instanceof Double) {
                //fmt = "%" + (size-2) + ".2f";
                //this results in a display that matches the
                return String.valueOf(data);

            } else if (data instanceof BigDecimal) {
                //fmt = "%" + (size-2) + ".2f";

                /*
                 * using doubleValue() eliminates trailing zeroes but 
                 * that leads to conflict with the way big decimals are
                 * displayed in view mode on forms and in query results
                 */
                //return String.valueOf(((Number )data).doubleValue());

                return String.valueOf(data);
            } else {
                //fmt = "%d";
                return String.format("%d", data).trim();
            }

        } else if (data instanceof Calendar) {
            return scrDateFormat.format((Calendar) data);

        } else if (data instanceof Date) {
            return scrDateFormat.format((Date) data);
        }
        return data;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isInBoundFormatter()
     */
    @Override
    public boolean isInBoundFormatter() {
        return autoNumber != null;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder(getTitle());
        str.append(" [");
        for (UIFieldFormatterField field : fields) {
            String val = field.getValue();
            if (StringUtils.isEmpty(val)) {
                val = field.getSample();
            }
            str.append(val);
        }
        str.append("]");

        if (isSystem || isDefault) {
            str.append(" (");

            str.append(isDefault ? deftitle : "");
            str.append(isSystem ? ((isDefault ? ", " : "") + systitle) : "");

            str.append(")");
        }

        return str.toString();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isUserInputNeeded()
     */
    @Override
    public boolean isUserInputNeeded() {
        for (UIFieldFormatterField f : fields) {
            UIFieldFormatterField.FieldType typ = f.getType();
            if (typ == UIFieldFormatterField.FieldType.alphanumeric || typ == UIFieldFormatterField.FieldType.alpha
                    || typ == UIFieldFormatterField.FieldType.anychar) {
                return true;

            } else if (typ == UIFieldFormatterField.FieldType.numeric && !f.isIncrementer()) {
                return true;

            } else if (typ == UIFieldFormatterField.FieldType.year) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return the type
     */
    public FormatterType getType() {
        return type;
    }

    /**
     * @return the scale
     */
    public int getScale() {
        return scale;
    }

    /**
     * @param scale the scale to set
     */
    public void setScale(int scale) {
        this.scale = scale;
    }

    /**
     * @return the precision
     */
    public int getPrecision() {
        return precision;
    }

    /**
     * @param precision the precision to set
     */
    public void setPrecision(int precision) {
        this.precision = precision;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isValid(java.lang.String)
     */
    @Override
    public boolean isValid(final String text) {
        return isValid(this, text, false);
    }

    /**
     * @param year
     * @return
     */
    protected static boolean isLeapYear(final int year) {
        if (year % 4 == 0) {
            if (year % 100 == 0) {
                if (year % 400 == 0) {
                    return true;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * @param formatter
     * @param text
     * @return
     */
    private static boolean isDateValid(final UIFieldFormatterIFace formatter, final String text) {
        UIFieldFormatterField month = null;
        UIFieldFormatterField day = null;
        UIFieldFormatterField year = null;

        int monthInx = 0;
        int dayInx = 0;
        int yearInx = 0;
        int inx = 0;

        for (UIFieldFormatterField field : formatter.getFields()) {
            if (month == null && field.getValue().equals("MM")) {
                month = field;
                monthInx = inx;

            } else if (day == null && field.getValue().equals("DD")) {
                day = field;
                dayInx = inx;

            } else if (year == null && field.getValue().equals("YYYY")) {
                year = field;
                yearInx = inx;
            }
            inx += field.getSize();
        }

        int yearVal = -1;
        if (year != null) {
            String val = text.substring(yearInx, yearInx + year.getSize());
            if (StringUtils.isNumericSpace(val)) {
                yearVal = Integer.parseInt(val);
                if (yearVal == 0 || yearVal > 2500) {
                    return false;
                }
            } else {
                return false;
            }
        }

        if (month != null) {
            int monVal = 0;
            String val = text.substring(monthInx, monthInx + month.getSize()).trim();
            if (StringUtils.isNumericSpace(val)) {
                monVal = Integer.parseInt(val);
                if (monVal < 1 || monVal > 12) {
                    return false;
                }
            } else {
                return false;
            }

            if (day != null) {
                daysInMon[1] = isLeapYear(yearVal) ? 29 : 28;

                val = text.substring(dayInx, dayInx + day.getSize());
                if (StringUtils.isNumericSpace(val)) {
                    int dayVal = Integer.parseInt(val);
                    if (dayVal < 1 || dayVal > daysInMon[monVal - 1]) {
                        return false;
                    }
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Validates with any formatter that has fields defined and an inputed string
     * @param formatter the formatter 
     * @param text the text to be validated.
     * @return true if it is valid
     */
    public static boolean isValid(final UIFieldFormatterIFace formatter, final String text,
            final boolean doValidateAll) {
        if (isNotEmpty(text)) {
            int txtLen = text.length();
            if (formatter.isLengthOK(txtLen)) {
                if (formatter.isDate()) {
                    return isDateValid(formatter, text);
                }

                int inx = 0;
                int pos = 0;
                for (UIFieldFormatterField field : formatter.getFields()) {
                    if (pos < txtLen) {
                        if (!field.isIncrementer() || doValidateAll) {
                            //numeric, alphanumeric, alpha, separator, year
                            String val = text.substring(pos, Math.min(pos + field.getSize(), txtLen));
                            switch (field.getType()) {
                            case numeric: {
                                String str1 = StringUtils.remove(val, '.');
                                String str2 = StringUtils.remove(str1, '-');

                                if (StringUtils.isNumeric(str2)) {
                                    Class<?> cls = formatter.getDataClass();
                                    if (cls == java.lang.Integer.class || cls == java.lang.Long.class
                                            || cls == java.lang.Short.class || cls == java.lang.Byte.class) {
                                        return str1.length() == val.length();
                                    }
                                    return true;
                                }
                                return false;
                            }

                            case alphanumeric:
                                if (!isAlphanumeric(val)) {
                                    return false;
                                }
                                break;

                            case alpha:
                                if (!isAlpha(val)) {
                                    return false;
                                }
                                break;

                            case year:
                                if (!StringUtils.isNumeric(val)) {
                                    return false;
                                }
                                int year = Integer.parseInt(val);
                                return year > 0 && year < 2100;

                            case constant:
                            case separator:
                                if (!val.equals(field.getValue())) {
                                    return false;
                                }
                                break;

                            default:
                                break;
                            }
                        }
                    } else {
                        return false;
                    }
                    pos += field.getSize();
                    inx++;
                }
                return true;
            }
        }
        return false;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#isLengthOK(int)
     */
    @Override
    public boolean isLengthOK(int lengthOfData) {
        if (type == FormatterType.numeric) {
            return lengthOfData < getLength();
        }
        return lengthOfData == getLength();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.formatters.UIFieldFormatterIFace#toXML(java.lang.StringBuilder)
     */
    @Override
    public void toXML(final StringBuilder sb) {
        sb.append("  <format");
        xmlAttr(sb, "system", isSystem);
        xmlAttr(sb, "name", name);

        if (dataClass != null) {
            xmlAttr(sb, "class", dataClass.getName());
        }
        if (isNotEmpty(fieldName) && !fieldName.equals("*")) {
            xmlAttr(sb, "fieldname", fieldName);
        }

        if (isDefault) {
            xmlAttr(sb, "default", isDefault);
        }

        if (type != FormatterType.generic && type != null) {
            xmlAttr(sb, "type", type.toString());
        }

        if (partialDateType != null && partialDateType != PartialDateEnum.None) {
            xmlAttr(sb, "partialdate", partialDateType.toString());
        }

        sb.append(">\n");
        if (autoNumber != null) {
            autoNumber.toXML(sb);
        }

        if (type != FormatterType.date) {
            for (UIFieldFormatterField field : fields) {
                field.toXML(sb);
            }
        }
        if (isExternal) {
            sb.append("    <external>");
            sb.append("    <external>");
            sb.append("    </extneral>\n");
        }
        sb.append("  </format>\n\n");
    }

    public void setSystem(boolean isSystem) {
        this.isSystem = isSystem;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#setDataClass(java.lang.Class)
     */
    @Override
    public void setDataClass(Class<?> dataClass) {
        this.dataClass = dataClass;
    }

    /**
     * @param type
     */
    public void setType(FormatterType type) {
        this.type = type;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.af.ui.forms.formatters.UIFieldFormatterIFace#hasDash()
     */
    @Override
    public boolean hasDash() {
        if (hasDash == null) {
            hasDash = false;
            for (UIFieldFormatterField fld : getFields()) {
                if ((fld.isSeparator() || fld.isConstant()) && fld.getValue().equals("-")) {
                    hasDash = true;
                    break;
                }
            }
        }
        return hasDash;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#clone()
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        UIFieldFormatter uif = (UIFieldFormatter) super.clone();
        uif.fields = new Vector<UIFieldFormatterField>();
        for (UIFieldFormatterField fld : fields) {
            uif.fields.add((UIFieldFormatterField) fld.clone());
        }
        return uif;
    }

}