nl.strohalm.cyclos.entities.settings.LocalSettings.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.entities.settings.LocalSettings.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos 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.
    
Cyclos 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 Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.entities.settings;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import nl.strohalm.cyclos.entities.members.Element;
import nl.strohalm.cyclos.entities.members.Reference.Level;
import nl.strohalm.cyclos.utils.DataObject;
import nl.strohalm.cyclos.utils.Dimensions;
import nl.strohalm.cyclos.utils.FileUnits;
import nl.strohalm.cyclos.utils.IntValuedEnum;
import nl.strohalm.cyclos.utils.MessageProcessingHelper;
import nl.strohalm.cyclos.utils.StringValuedEnum;
import nl.strohalm.cyclos.utils.TextFormat;
import nl.strohalm.cyclos.utils.TimePeriod;
import nl.strohalm.cyclos.utils.conversion.AmountConverter;
import nl.strohalm.cyclos.utils.conversion.CalendarConverter;
import nl.strohalm.cyclos.utils.conversion.CoercionHelper;
import nl.strohalm.cyclos.utils.conversion.NumberConverter;
import nl.strohalm.cyclos.utils.conversion.UnitsConverter;
import nl.strohalm.cyclos.utils.lucene.LuceneUtils;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.br.BrazilianAnalyzer;
import org.apache.lucene.analysis.de.GermanAnalyzer;
import org.apache.lucene.analysis.el.GreekAnalyzer;
import org.apache.lucene.analysis.fr.FrenchAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;

/**
 * Groups local settings
 * @author luis
 */
@SuppressWarnings("unchecked")
public class LocalSettings extends DataObject {

    /**
     * Contains possible values for csv record separators
     * @author luis
     */
    public static enum CsvRecordSeparator implements StringValuedEnum {
        LF("\n"), CR_LF("\r\n"), CR("\r");
        private final String value;

        private CsvRecordSeparator(final String value) {
            this.value = value;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    /**
     * Contains possible values for csv string quotes
     * @author luis
     */
    public static enum CsvStringQuote implements StringValuedEnum {
        DOUBLE_QUOTE("\""), SINGLE_QUOTE("'"), NONE("");
        private final String value;

        private CsvStringQuote(final String value) {
            this.value = value;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    /**
     * Contains possible values for csv value separators
     * @author luis
     */
    public static enum CsvValueSeparator implements StringValuedEnum {
        COMMA(","), SEMICOLON(";"), TAB("\t");
        private final String value;

        private CsvValueSeparator(final String value) {
            this.value = value;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    /**
     * Possible patterns for date representation
     * @author luis
     */
    public static enum DatePattern implements StringValuedEnum {
        YYYY_MM_DD_SLASH(DatePatternOrder.YMD, '/'), YYYY_MM_DD_PERIOD(DatePatternOrder.YMD,
                '.'), YYYY_MM_DD_DASH(DatePatternOrder.YMD, '-'),

        MM_DD_YYYY_SLASH(DatePatternOrder.MDY, '/'), MM_DD_YYYY_PERIOD(DatePatternOrder.MDY,
                '.'), MM_DD_YYYY_DASH(DatePatternOrder.MDY, '-'),

        DD_MM_YYYY_SLASH(DatePatternOrder.DMY, '/'), DD_MM_YYYY_PERIOD(DatePatternOrder.DMY,
                '.'), DD_MM_YYYY_DASH(DatePatternOrder.DMY, '-');

        private final DatePatternOrder order;
        private final String value;
        private final char separator;
        private final String calendarFormat;
        private final String pattern;

        private DatePattern(final DatePatternOrder order, final char separator) {
            this.order = order;
            this.separator = separator;
            value = StringUtils.join(order.getFormatParts(), separator);
            calendarFormat = StringUtils.join(order.getCalendarParts(), separator);
            final StringBuilder sb = new StringBuilder();
            for (final String part : order.getCalendarParts()) {
                if (sb.length() > 0) {
                    sb.append(separator);
                }
                sb.append(StringUtils.repeat("#", part.length()));
            }
            pattern = sb.toString();
        }

        public String getCalendarFormat() {
            return calendarFormat;
        }

        public DatePatternOrder getOrder() {
            return order;
        }

        public String getPattern() {
            return pattern;
        }

        public char getSeparator() {
            return separator;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    public static enum DatePatternOrder {
        YMD, MDY, DMY;

        public String[] getCalendarParts() {
            switch (this) {
            case DMY:
                return new String[] { "%d", "%m", "%Y" };
            case MDY:
                return new String[] { "%m", "%d", "%Y" };
            case YMD:
                return new String[] { "%Y", "%m", "%d" };
            }
            return null;
        }

        public String[] getFormatParts() {
            switch (this) {
            case DMY:
                return new String[] { "dd", "MM", "yyyy" };
            case MDY:
                return new String[] { "MM", "dd", "yyyy" };
            case YMD:
                return new String[] { "yyyy", "MM", "dd" };
            }
            return null;
        }
    }

    public static enum DecimalInputMethod {
        RTL, LTR
    }

    /**
     * Contains possible number formats
     * @author luis
     */
    public static enum Language implements StringValuedEnum {
        ENGLISH("en_US", "en"),

        SPANISH("es_ES", "es"),

        // SPANISH_TIMEBANKS("es_ES_TB", "es"),
        CZECH("cs_CZ", "cs"),

        GERMAN("de_DE", "de", new GermanAnalyzer(LuceneUtils.LUCENE_VERSION)),

        GREEK("el_GR", "el", new GreekAnalyzer(LuceneUtils.LUCENE_VERSION)),

        DUTCH("nl_NL", "nl"),

        PORTUGUESE_BRAZIL("pt_BR", "pt-br", new BrazilianAnalyzer(LuceneUtils.LUCENE_VERSION)),

        CHINESE_SIMPLIFIED("zh_CN", "zh-cn"),

        FRENCH("fr_FR", "fr", new FrenchAnalyzer(LuceneUtils.LUCENE_VERSION)),

        JAPANESE("ja_JP", "jp"),

        ITALIAN("it_IT", "it"),

        RUSSIAN("ru_RU", "ru");

        private final Locale locale;
        private final String value;
        private final String alternate;
        private final Analyzer analyzer;

        private Language(final String value, final String alternate) {
            this(value, alternate, new StandardAnalyzer(LuceneUtils.LUCENE_VERSION));
        }

        private Language(final String value, final String alternate, final Analyzer analyzer) {
            this.value = value;
            locale = CoercionHelper.coerce(Locale.class, value);
            this.alternate = alternate;
            this.analyzer = analyzer;
        }

        public String getAlternate() {
            return alternate;
        }

        public Analyzer getAnalyzer() {
            return analyzer;
        }

        public Locale getLocale() {
            return locale;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    /**
     * Determines which field will be displayed on a given result list
     * @author luis
     */
    public static enum MemberResultDisplay {
        USERNAME, NAME;

        public String getProperty() {
            return name().toLowerCase();
        }
    }

    /**
     * Contains possible number formats
     * @author luis
     */
    public static enum NumberLocale {
        PERIOD_AS_DECIMAL(Locale.US), COMMA_AS_DECIMAL(Locale.GERMANY);
        private final Locale locale;

        private NumberLocale(final Locale locale) {
            this.locale = locale;
        }

        public Locale getLocale() {
            return locale;
        }
    }

    /**
     * Indicates the number precision for the local currency
     * @author luis
     */
    public static enum Precision implements IntValuedEnum {
        ZERO(0), ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6);
        private final int value;

        private Precision(final int value) {
            this.value = value;
        }

        public MathContext getMathContext() {
            return new MathContext(value, RoundingMode.HALF_UP);
        }

        @Override
        public int getValue() {
            return value;
        }
    }

    /**
     * Defines the sort order for member lists.
     * @author rinke
     */
    public static enum SortOrder {
        CHRONOLOGICAL, ALPHABETICAL;

    }

    /**
     * Possible patterns for time representation
     * @author luis
     */
    public static enum TimePattern implements StringValuedEnum {
        HH24_MM_SS("HH:mm:ss", "HH(24):MM:SS", "%H:%M:%S"), HH24_MM("HH:mm", "HH(24):MM", "%H:%M"), HH12_MM_SS(
                "hh:mm:ss a", "HH(12):MM:SS AM/PM",
                "%I:%M:%S %p"), HH12_MM("hh:mm a", "HH(12):MM AM/PM", "%I:%M %p");
        private final String value;
        private final String description;
        private final String calendarFormat;

        private TimePattern(final String value, final String description, final String calendarFormat) {
            this.value = value;
            this.description = description;
            this.calendarFormat = calendarFormat;
        }

        public String getCalendarFormat() {
            return calendarFormat;
        }

        public String getDescription() {
            return description;
        }

        @Override
        public String getValue() {
            return value;
        }
    }

    /**
     * Contains parameters for generating a transaction number. The number is composed by 3 parts: a prefix, the padded identifier and a suffix. Both
     * prefix and suffix may contain a date pattern between #, so, for example, if the prefix TN#yy-MM# is processed on january, 2006, the result
     * would be TN06-01. To generate a # character, it must be escaped with \\#
     */
    public static class TransactionNumber implements Serializable {
        private static final long serialVersionUID = 7841112633641561669L;
        private String prefix;
        private int padLength;
        private String suffix;
        private boolean enabled;

        public TransactionNumber() {
        }

        public TransactionNumber(final String prefix, final int padLength, final String suffix) {
            this.prefix = prefix;
            this.padLength = padLength;
            this.suffix = suffix;
        }

        /**
         * Generates the number for a given transaction id and date
         */
        public String generate(final Long id, final Calendar date) {
            if (padLength <= 0) {
                throw new IllegalStateException("Cannot generate a transaction number with padLength " + padLength);
            }
            if (id == null || id <= 0L) {
                throw new IllegalArgumentException("Invalid id: " + id);
            }
            return MessageProcessingHelper.processDate(prefix, date)
                    + StringUtils.leftPad(String.valueOf(id), padLength, '0')
                    + MessageProcessingHelper.processDate(suffix, date);
        }

        public int getPadLength() {
            return padLength;
        }

        public String getPrefix() {
            return prefix;
        }

        public String getSuffix() {
            return suffix;
        }

        public boolean isEnabled() {
            return enabled;
        }

        public boolean isValid() {
            return padLength > 0;
        }

        public void setEnabled(final boolean enabled) {
            this.enabled = enabled;
        }

        public void setPadLength(final int padLength) {
            this.padLength = padLength;
        }

        public void setPrefix(final String prefix) {
            this.prefix = prefix;
        }

        public void setSuffix(final String suffix) {
            this.suffix = suffix;
        }
    }

    public static final int MAX_PRECISION = 10;
    public static final int BIG_DECIMAL_DIVISION_PRECISION = 6;

    private static final long serialVersionUID = -2880060408820762157L;
    private String applicationName = "Cyclos";
    private String cyclosId = null;
    private String applicationUsername = "The Administration";
    private Language language = Language.ENGLISH;
    private String rootUrl = "http://localhost:8080/cyclos";

    private String charset = "UTF-8";
    private NumberLocale numberLocale = NumberLocale.COMMA_AS_DECIMAL;
    private Precision precision = Precision.TWO;
    private Precision highPrecision = Precision.FOUR;
    private DecimalInputMethod decimalInputMethod = DecimalInputMethod.RTL;
    private DatePattern datePattern = DatePattern.DD_MM_YYYY_SLASH;
    private TimePattern timePattern = TimePattern.HH24_MM_SS;
    // Initially empty, meaning no time zone computation
    private TimeZone timeZone;
    private String containerUrl;

    private int maxIteratorResults = 1000;
    private int maxPageResults = 15;
    private int maxAjaxResults = 8;
    private int maxUploadSize = 5;
    private FileUnits maxUploadUnits = FileUnits.MEGA_BYTES;
    private int maxImageWidth = 800;
    private int maxImageHeight = 600;
    private int maxThumbnailWidth = 100;
    private int maxThumbnailHeight = 100;
    private int schedulingHour = 0;
    private int schedulingMinute = 0;
    private String transferListenerClass;

    private boolean csvUseHeader = true;
    private CsvRecordSeparator csvRecordSeparator = CsvRecordSeparator.LF;

    private CsvValueSeparator csvValueSeparator = CsvValueSeparator.COMMA;
    private CsvStringQuote csvStringQuote = CsvStringQuote.DOUBLE_QUOTE;
    private TransactionNumber transactionNumber = null;
    private String sendSmsWebServiceUrl = null;
    private String smsChannelName = null;

    private Long smsCustomFieldId = null;
    private boolean smsEnabled = false;

    private boolean emailRequired = true;

    private boolean emailUnique = true;

    private int referenceLevels = 5;
    private TimePeriod brokeringExpirationPeriod = new TimePeriod(0, TimePeriod.Field.YEARS);
    private TimePeriod deleteMessagesOnTrashAfter = new TimePeriod(30, TimePeriod.Field.DAYS);

    private TimePeriod deletePendingRegistrationsAfter = new TimePeriod(7, TimePeriod.Field.DAYS);
    private SortOrder memberSortOrder = SortOrder.CHRONOLOGICAL;
    private MemberResultDisplay memberResultDisplay = MemberResultDisplay.USERNAME;
    private TextFormat adDescriptionFormat = TextFormat.RICH;
    private TextFormat messageFormat = TextFormat.RICH;
    private TimePeriod maxChargebackTime = new TimePeriod(1, TimePeriod.Field.MONTHS);
    private String chargebackDescription = "Chargeback for payment at #date#\n#description#";
    private boolean showCountersInAdCategories = true;
    private transient Locale locale;
    private transient DecimalFormat decimalFormat;

    private transient NumberConverter<Long> longConverter;
    private transient DecimalFormat highPrecisionDecimalFormat;

    private transient DecimalFormatSymbols decimalSymbols;
    private transient NumberConverter<BigDecimal> numberConverter;
    private transient NumberConverter<BigDecimal> highPrecisionConverter;
    private final transient NumberConverter<BigDecimal>[] specificPrecisionConverters = new NumberConverter[MAX_PRECISION
            + 1];
    private transient AmountConverter amountConverter;
    private transient CalendarConverter rawDateConverter;
    private transient CalendarConverter dateConverter;
    private transient CalendarConverter dateConverterForGraphs;
    private transient CalendarConverter dateTimeConverter;
    private transient CalendarConverter timeConverter;
    private transient Integer maxUploadBytes;
    private transient MathContext mathContext;
    private transient Comparator<Element> memberComparator;
    private transient Dimensions maxImageDimensions;
    private transient Dimensions maxThumbnailDimensions;
    private transient List<Level> referenceLevelList;

    public TextFormat getAdDescriptionFormat() {
        return adDescriptionFormat;
    }

    public AmountConverter getAmountConverter() {
        if (amountConverter == null) {
            amountConverter = new AmountConverter(getDecimalFormat());
        }
        return amountConverter;
    }

    public AmountConverter getAmountConverter(final String unitsPattern) {
        return new AmountConverter(getDecimalFormat(), unitsPattern);
    }

    public String getApplicationName() {
        return applicationName;
    }

    public String getApplicationUsername() {
        return applicationUsername;
    }

    public TimePeriod getBrokeringExpirationPeriod() {
        return brokeringExpirationPeriod;
    }

    public String getChargebackDescription() {
        return chargebackDescription;
    }

    public String getCharset() {
        return charset;
    }

    public String getContainerUrl() {
        return containerUrl;
    }

    public CsvRecordSeparator getCsvRecordSeparator() {
        return csvRecordSeparator;
    }

    public CsvStringQuote getCsvStringQuote() {
        return csvStringQuote;
    }

    public CsvValueSeparator getCsvValueSeparator() {
        return csvValueSeparator;
    }

    public String getCyclosId() {
        return cyclosId;
    }

    public CalendarConverter getDateConverter() {
        if (dateConverter == null) {
            dateConverter = new CalendarConverter(datePattern.value, timeZone);
        }
        return dateConverter;
    }

    /**
     * gets a CalendarConverter which is derived from the normal CalendarConverter, but without the year. To be used for cewolf graphs as Strings
     * along the x-axis, where normal date labels with a year would be to long and make the x-axis too packed with labels.
     * @return a CalendarConverter without the year.
     */
    public CalendarConverter getDateConverterForGraphs() {
        if (dateConverterForGraphs == null) {
            // strip the year from the existing normal dateConverter
            final String[] formatParts = datePattern.order.getFormatParts();
            final ArrayList<String> formatPartsForGraph = new ArrayList<String>(formatParts.length - 1);
            for (final String formatPart : formatParts) {
                if (formatPart.toLowerCase().indexOf('y') == -1) {
                    formatPartsForGraph.add(formatPart);
                }
            }
            String[] formatPartsForGraphArray = new String[formatPartsForGraph.size()];
            formatPartsForGraphArray = formatPartsForGraph.toArray(formatPartsForGraphArray);
            // use array for creating new pattern value without years
            final String patternValue = StringUtils.join(formatPartsForGraphArray, datePattern.separator);
            dateConverterForGraphs = new CalendarConverter(patternValue, timeZone);
        }
        return dateConverterForGraphs;
    }

    public DatePattern getDatePattern() {
        return datePattern;
    }

    public CalendarConverter getDateTimeConverter() {
        if (dateTimeConverter == null) {
            dateTimeConverter = new CalendarConverter(datePattern.value + " " + timePattern.value, timeZone);
        }
        return dateTimeConverter;
    }

    public DecimalInputMethod getDecimalInputMethod() {
        return decimalInputMethod;
    }

    public DecimalFormatSymbols getDecimalSymbols() {
        if (decimalSymbols == null) {
            decimalSymbols = new DecimalFormatSymbols(numberLocale.getLocale());
        }
        return decimalSymbols;
    }

    public TimePeriod getDeleteMessagesOnTrashAfter() {
        return deleteMessagesOnTrashAfter;
    }

    public TimePeriod getDeletePendingRegistrationsAfter() {
        return deletePendingRegistrationsAfter;
    }

    public Precision getHighPrecision() {
        return highPrecision;
    }

    public NumberConverter<BigDecimal> getHighPrecisionConverter() {
        if (highPrecisionConverter == null) {
            highPrecisionConverter = new NumberConverter<BigDecimal>(BigDecimal.class,
                    getHighPrecisionDecimalFormat());
        }
        return highPrecisionConverter;
    }

    public DecimalFormat getHighPrecisionDecimalFormat() {
        if (highPrecisionDecimalFormat == null) {
            highPrecisionDecimalFormat = getDecimalFormat(highPrecision.value);
        }
        return highPrecisionDecimalFormat;
    }

    public Language getLanguage() {
        return language;
    }

    public Locale getLocale() {
        if (locale == null) {
            locale = language.getLocale();
        }
        return locale;
    }

    public NumberConverter<Long> getLongConverter() {
        if (longConverter == null) {
            longConverter = new NumberConverter<Long>(Long.class, getDecimalFormat(0));
        }
        return longConverter;
    }

    public MathContext getMathContext() {
        if (mathContext == null) {
            mathContext = new MathContext(BIG_DECIMAL_DIVISION_PRECISION);
        }
        return mathContext;
    }

    public int getMaxAjaxResults() {
        return maxAjaxResults;
    }

    public TimePeriod getMaxChargebackTime() {
        return maxChargebackTime;
    }

    public Dimensions getMaxImageDimensions() {
        if (maxImageDimensions == null) {
            maxImageDimensions = new Dimensions(maxImageWidth, maxImageHeight);
        }
        return maxImageDimensions;
    }

    public int getMaxImageHeight() {
        return maxImageHeight;
    }

    public int getMaxImageWidth() {
        return maxImageWidth;
    }

    public int getMaxIteratorResults() {
        return maxIteratorResults;
    }

    public int getMaxPageResults() {
        return maxPageResults;
    }

    public Dimensions getMaxThumbnailDimensions() {
        if (maxThumbnailDimensions == null) {
            maxThumbnailDimensions = new Dimensions(maxThumbnailWidth, maxThumbnailHeight);
        }
        return maxThumbnailDimensions;
    }

    public int getMaxThumbnailHeight() {
        return maxThumbnailHeight;
    }

    public int getMaxThumbnailWidth() {
        return maxThumbnailWidth;
    }

    public int getMaxUploadBytes() {
        if (maxUploadBytes == null) {
            maxUploadBytes = maxUploadUnits.calculate(maxUploadSize);
        }
        return maxUploadBytes;
    }

    public int getMaxUploadSize() {
        return maxUploadSize;
    }

    public FileUnits getMaxUploadUnits() {
        return maxUploadUnits;
    }

    public Comparator<Element> getMemberComparator() {
        if (memberComparator == null) {
            memberComparator = new BeanComparator(memberResultDisplay.getProperty());
        }
        return memberComparator;
    }

    public MemberResultDisplay getMemberResultDisplay() {
        return memberResultDisplay;
    }

    public SortOrder getMemberSortOrder() {
        return memberSortOrder;
    }

    public TextFormat getMessageFormat() {
        return messageFormat;
    }

    public NumberConverter<BigDecimal> getNumberConverter() {
        if (numberConverter == null) {
            numberConverter = new NumberConverter<BigDecimal>(BigDecimal.class, getDecimalFormat());
        }
        return numberConverter;
    }

    public NumberConverter<BigDecimal> getNumberConverterForPrecision(int precision) {
        precision = Math.max(0, Math.min(precision, MAX_PRECISION));
        if (specificPrecisionConverters[precision] == null) {
            specificPrecisionConverters[precision] = new NumberConverter<BigDecimal>(BigDecimal.class,
                    getDecimalFormat(precision));
        }
        return specificPrecisionConverters[precision];
    }

    public NumberLocale getNumberLocale() {
        return numberLocale;
    }

    public Precision getPrecision() {
        return precision;
    }

    public CalendarConverter getRawDateConverter() {
        if (rawDateConverter == null) {
            rawDateConverter = new CalendarConverter(datePattern.value);
        }
        return rawDateConverter;
    }

    public List<Level> getReferenceLevelList() {
        if (referenceLevelList == null) {
            Level[] levels;
            if (referenceLevels == 3) {
                levels = new Level[] { Level.GOOD, Level.NEUTRAL, Level.BAD };
            } else {
                levels = Level.values();
            }
            referenceLevelList = Collections.unmodifiableList(Arrays.asList(levels));
        }
        return referenceLevelList;
    }

    public int getReferenceLevels() {
        return referenceLevels;
    }

    public String getRootUrl() {
        return rootUrl;
    }

    public int getSchedulingHour() {
        return schedulingHour;
    }

    public int getSchedulingMinute() {
        return schedulingMinute;
    }

    public String getSendSmsWebServiceUrl() {
        return sendSmsWebServiceUrl;
    }

    public String getSmsChannelName() {
        return smsChannelName;
    }

    public Long getSmsCustomFieldId() {
        return smsCustomFieldId;
    }

    public CalendarConverter getTimeConverter() {
        if (timeConverter == null) {
            timeConverter = new CalendarConverter(timePattern.value, timeZone);
        }
        return timeConverter;
    }

    public TimePattern getTimePattern() {
        return timePattern;
    }

    public TimeZone getTimeZone() {
        return timeZone;
    }

    public TransactionNumber getTransactionNumber() {
        return transactionNumber;
    }

    public String getTransferListenerClass() {
        return transferListenerClass;
    }

    public UnitsConverter getUnitsConverter(final String pattern) {
        return new UnitsConverter(pattern, getNumberConverter().getNumberFormat());
    }

    public boolean isCsvUseHeader() {
        return csvUseHeader;
    }

    public boolean isEmailRequired() {
        return emailRequired;
    }

    public boolean isEmailUnique() {
        return emailUnique;
    }

    public boolean isShowCountersInAdCategories() {
        return showCountersInAdCategories;
    }

    /**
     * Returns whether the SMS commands are enabled
     */
    public boolean isSmsCommandEnabled() {
        return StringUtils.isNotEmpty(smsChannelName);
    }

    public boolean isSmsEnabled() {
        return smsEnabled;
    }

    public BigDecimal round(final BigDecimal number) {
        if (number == null) {
            return null;
        } else {
            return number.setScale(getPrecision().getValue(), RoundingMode.HALF_UP);
        }
    }

    public BigDecimal roundHighPrecision(final BigDecimal number) {
        if (number == null) {
            return null;
        } else {
            return number.setScale(getHighPrecision().getValue(), RoundingMode.HALF_UP);
        }
    }

    public void setAdDescriptionFormat(final TextFormat adDescriptionFormat) {
        this.adDescriptionFormat = adDescriptionFormat;
    }

    public void setApplicationName(final String applicationName) {
        this.applicationName = applicationName;
    }

    public void setApplicationUsername(final String applicationUsername) {
        this.applicationUsername = applicationUsername;
    }

    public void setBrokeringExpirationPeriod(final TimePeriod brokeringExpirationPeriod) {
        this.brokeringExpirationPeriod = brokeringExpirationPeriod;
    }

    public void setChargebackDescription(final String chargebackDescription) {
        this.chargebackDescription = chargebackDescription;
    }

    public void setContainerUrl(final String containerUrl) {
        this.containerUrl = containerUrl;
    }

    public void setCsvRecordSeparator(final CsvRecordSeparator csvRecordSeparator) {
        this.csvRecordSeparator = csvRecordSeparator;
    }

    public void setCsvStringQuote(final CsvStringQuote csvStringQuote) {
        this.csvStringQuote = csvStringQuote;
    }

    public void setCsvUseHeader(final boolean csvUseHeader) {
        this.csvUseHeader = csvUseHeader;
    }

    public void setCsvValueSeparator(final CsvValueSeparator csvValueSeparator) {
        this.csvValueSeparator = csvValueSeparator;
    }

    public void setCyclosId(final String cyclosId) {
        this.cyclosId = cyclosId;
    }

    public void setDatePattern(final DatePattern datePattern) {
        this.datePattern = datePattern;
        invalidateDateParams();
    }

    public void setDecimalInputMethod(final DecimalInputMethod decimalInputMethod) {
        this.decimalInputMethod = decimalInputMethod;
    }

    public void setDeleteMessagesOnTrashAfter(final TimePeriod deleteMessagesOnTrashAfter) {
        this.deleteMessagesOnTrashAfter = deleteMessagesOnTrashAfter;
    }

    public void setDeletePendingRegistrationsAfter(final TimePeriod deletePendingRegistrationsAfter) {
        this.deletePendingRegistrationsAfter = deletePendingRegistrationsAfter;
    }

    public void setEmailRequired(final boolean mailRequired) {
        emailRequired = mailRequired;
    }

    public void setEmailUnique(final boolean emailUnique) {
        this.emailUnique = emailUnique;
    }

    public void setHighPrecision(final Precision highPrecision) {
        this.highPrecision = highPrecision;
    }

    public void setLanguage(final Language language) {
        this.language = language == null ? Language.ENGLISH : language;
        invalidateLanguageParams();
    }

    public void setLocale(final Locale locale) {
        this.locale = locale;
    }

    public void setMaxAjaxResults(final int maxAjaxResults) {
        this.maxAjaxResults = maxAjaxResults;
    }

    public void setMaxChargebackTime(final TimePeriod maxChargebackTime) {
        this.maxChargebackTime = maxChargebackTime;
    }

    public void setMaxImageHeight(final int maxImageHeight) {
        this.maxImageHeight = maxImageHeight;
    }

    public void setMaxImageWidth(final int maxImageWidth) {
        this.maxImageWidth = maxImageWidth;
    }

    public void setMaxIteratorResults(final int maxIteratorPageResults) {
        maxIteratorResults = maxIteratorPageResults;
    }

    public void setMaxPageResults(final int pageSize) {
        maxPageResults = pageSize;
    }

    public void setMaxThumbnailHeight(final int maxThumbnailHeight) {
        this.maxThumbnailHeight = maxThumbnailHeight;
    }

    public void setMaxThumbnailWidth(final int maxThumbnailWidth) {
        this.maxThumbnailWidth = maxThumbnailWidth;
    }

    public void setMaxUploadSize(final int maxUploadSize) {
        this.maxUploadSize = maxUploadSize;
        maxUploadBytes = null;
    }

    public void setMaxUploadUnits(final FileUnits maxUploadUnits) {
        this.maxUploadUnits = maxUploadUnits;
        maxUploadBytes = null;
    }

    public void setMemberResultDisplay(final MemberResultDisplay adResultDisplay) {
        memberResultDisplay = adResultDisplay;
        memberComparator = null;
    }

    public void setMemberSortOrder(final SortOrder memberSortOrder) {
        this.memberSortOrder = memberSortOrder;
    }

    public void setMessageFormat(final TextFormat messageFormat) {
        this.messageFormat = messageFormat;
    }

    public void setNumberLocale(final NumberLocale numberLocale) {
        this.numberLocale = numberLocale;
        invalidateNumberParams();
    }

    public void setPrecision(final Precision precision) {
        this.precision = precision;
        invalidateNumberParams();
    }

    public void setReferenceLevels(final int referenceLevels) {
        this.referenceLevels = referenceLevels;
        referenceLevelList = null;
    }

    public void setRootUrl(final String rootUrl) {
        this.rootUrl = rootUrl;
    }

    public void setSchedulingHour(final int schedulingHour) {
        this.schedulingHour = schedulingHour;
    }

    public void setSchedulingMinute(final int schedulingMinute) {
        this.schedulingMinute = schedulingMinute;
    }

    public void setSendSmsWebServiceUrl(final String sendSmsWebServiceUrl) {
        this.sendSmsWebServiceUrl = sendSmsWebServiceUrl;
    }

    public void setShowCountersInAdCategories(final boolean showCountersInAdCategories) {
        this.showCountersInAdCategories = showCountersInAdCategories;
    }

    public void setSmsChannelName(final String smsChannelName) {
        this.smsChannelName = smsChannelName;
    }

    public void setSmsCustomFieldId(final Long smsCustomFieldId) {
        this.smsCustomFieldId = smsCustomFieldId;
    }

    public void setSmsEnabled(final boolean smsEnabled) {
        this.smsEnabled = smsEnabled;
    }

    public void setTimePattern(final TimePattern timePattern) {
        this.timePattern = timePattern;
        invalidateDateParams();
    }

    public void setTimeZone(final TimeZone timeZone) {
        this.timeZone = timeZone;
        invalidateDateParams();
    }

    public void setTransactionNumber(final TransactionNumber transactionNumber) {
        this.transactionNumber = transactionNumber;
    }

    public void setTransferListenerClass(final String transferListenerClass) {
        this.transferListenerClass = transferListenerClass;
    }

    public BigDecimal truncate(final BigDecimal number) {
        if (number == null) {
            return null;
        } else {
            return number.setScale(getPrecision().getValue(), RoundingMode.FLOOR);
        }
    }

    private DecimalFormat getDecimalFormat() {
        if (decimalFormat == null) {
            decimalFormat = getDecimalFormat(precision.value);
        }
        return decimalFormat;
    }

    private DecimalFormat getDecimalFormat(final int precision) {
        String pattern = "#,##0";
        if (precision > 0) {
            pattern += "." + StringUtils.repeat("0", precision);
        }
        return new DecimalFormat(pattern, getDecimalSymbols());
    }

    /**
     * Invalidates calculated objects using date paramters
     */
    private void invalidateDateParams() {
        rawDateConverter = null;
        dateConverter = null;
        dateTimeConverter = null;
        dateConverterForGraphs = null;
        timeConverter = null;
    }

    /**
     * Invalidates calculated objects using language parameters
     */
    private void invalidateLanguageParams() {
        locale = null;
    }

    /**
     * Invalidates calculated objects using number parameters
     */
    private void invalidateNumberParams() {
        longConverter = null;
        decimalFormat = null;
        amountConverter = null;
        highPrecisionConverter = null;
        numberConverter = null;
        decimalSymbols = null;
        mathContext = null;
        for (int i = 0; i < specificPrecisionConverters.length; i++) {
            specificPrecisionConverters[i] = null;
        }
    }

}