/*
* file: MPXJFormats.java
* author: Jon Iles
* copyright: (c) Packwood Software 2006
* date: Jan 20, 2006
*/
/*
* This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
package net.sf.mpxj.mpx;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Locale;
import net.sf.mpxj.DateOrder;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.ProjectProperties;
import net.sf.mpxj.ProjectTimeFormat;
/**
* This class manages the various objects required to parse and format
* data items in MPX files.
*/
public final class MPXJFormats
{
/**
* Constructor.
*
* @param locale target locale
* @param nullText locale specific text to represent a value which has not been set, normally "NA"
* @param file parent file
*/
public MPXJFormats(Locale locale, String nullText, ProjectFile file)
{
m_locale = locale;
m_nullText = nullText;
m_projectFile = file;
update();
}
/**
* Called to update the cached formats when something changes.
*/
public void update()
{
ProjectProperties properties = m_projectFile.getProjectProperties();
char decimalSeparator = properties.getDecimalSeparator();
char thousandsSeparator = properties.getThousandsSeparator();
m_unitsDecimalFormat.applyPattern("#.##", null, decimalSeparator, thousandsSeparator);
m_decimalFormat.applyPattern("0.00#", null, decimalSeparator, thousandsSeparator);
m_durationDecimalFormat.applyPattern("#.##", null, decimalSeparator, thousandsSeparator);
m_percentageDecimalFormat.applyPattern("##0.##", null, decimalSeparator, thousandsSeparator);
updateCurrencyFormats(properties, decimalSeparator, thousandsSeparator);
updateDateTimeFormats(properties);
}
/**
* Update the currency format.
*
* @param properties project properties
* @param decimalSeparator decimal separator
* @param thousandsSeparator thousands separator
*/
private void updateCurrencyFormats(ProjectProperties properties, char decimalSeparator, char thousandsSeparator)
{
String prefix = "";
String suffix = "";
String currencySymbol = quoteFormatCharacters(properties.getCurrencySymbol());
switch (properties.getSymbolPosition())
{
case AFTER:
{
suffix = currencySymbol;
break;
}
case BEFORE:
{
prefix = currencySymbol;
break;
}
case AFTER_WITH_SPACE:
{
suffix = " " + currencySymbol;
break;
}
case BEFORE_WITH_SPACE:
{
prefix = currencySymbol + " ";
break;
}
}
StringBuilder pattern = new StringBuilder(prefix);
pattern.append("#0");
int digits = properties.getCurrencyDigits().intValue();
if (digits > 0)
{
pattern.append('.');
for (int i = 0; i < digits; i++)
{
pattern.append("0");
}
}
pattern.append(suffix);
String primaryPattern = pattern.toString();
String[] alternativePatterns = new String[7];
alternativePatterns[0] = primaryPattern + ";(" + primaryPattern + ")";
pattern.insert(prefix.length(), "#,#");
String secondaryPattern = pattern.toString();
alternativePatterns[1] = secondaryPattern;
alternativePatterns[2] = secondaryPattern + ";(" + secondaryPattern + ")";
pattern.setLength(0);
pattern.append("#0");
if (digits > 0)
{
pattern.append('.');
for (int i = 0; i < digits; i++)
{
pattern.append("0");
}
}
String noSymbolPrimaryPattern = pattern.toString();
alternativePatterns[3] = noSymbolPrimaryPattern;
alternativePatterns[4] = noSymbolPrimaryPattern + ";(" + noSymbolPrimaryPattern + ")";
pattern.insert(0, "#,#");
String noSymbolSecondaryPattern = pattern.toString();
alternativePatterns[5] = noSymbolSecondaryPattern;
alternativePatterns[6] = noSymbolSecondaryPattern + ";(" + noSymbolSecondaryPattern + ")";
m_currencyFormat.applyPattern(primaryPattern, alternativePatterns, decimalSeparator, thousandsSeparator);
}
/**
* This method is used to quote any special characters that appear in
* literal text that is required as part of the currency format.
*
* @param literal Literal text
* @return literal text with special characters in quotes
*/
private String quoteFormatCharacters(String literal)
{
StringBuilder sb = new StringBuilder();
int length = literal.length();
char c;
for (int loop = 0; loop < length; loop++)
{
c = literal.charAt(loop);
switch (c)
{
case '0':
case '#':
case '.':
case '-':
case ',':
case 'E':
case ';':
case '%':
{
sb.append("'");
sb.append(c);
sb.append("'");
break;
}
default:
{
sb.append(c);
break;
}
}
}
return (sb.toString());
}
/**
* Updates the date and time formats.
*
* @param properties project properties
*/
private void updateDateTimeFormats(ProjectProperties properties)
{
String datePattern = "";
String dateTimePattern = "";
String timePattern = getTimeElement(properties);
char datesep = properties.getDateSeparator();
DateOrder dateOrder = properties.getDateOrder();
switch (dateOrder)
{
case DMY:
{
datePattern = "dd" + datesep + "MM" + datesep + "yy";
break;
}
case MDY:
{
datePattern = "MM" + datesep + "dd" + datesep + "yy";
break;
}
case YMD:
{
datePattern = "yy" + datesep + "MM" + datesep + "dd";
break;
}
}
switch (properties.getDateFormat())
{
case DD_MM_YY_HH_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd" + datesep + "MM" + datesep + "yy " + timePattern;
break;
}
case MDY:
{
dateTimePattern = "MM" + datesep + "dd" + datesep + "yy " + timePattern;
break;
}
case YMD:
{
dateTimePattern = "yy" + datesep + "MM" + datesep + "dd " + timePattern;
break;
}
}
break;
}
case DD_MM_YY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd" + datesep + "MM" + datesep + "yy";
break;
}
case MDY:
{
dateTimePattern = "MM" + datesep + "dd" + datesep + "yy";
break;
}
case YMD:
{
dateTimePattern = "yy" + datesep + "MM" + datesep + "dd";
break;
}
}
break;
}
case DD_MMMMM_YYYY_HH_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMMMM yyyy " + timePattern;
break;
}
case MDY:
{
dateTimePattern = "MMMMM dd yyyy " + timePattern;
break;
}
case YMD:
{
dateTimePattern = "yyyy MMMMM dd " + timePattern;
break;
}
}
break;
}
case DD_MMMMM_YYYY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMMMM yyyy";
break;
}
case MDY:
{
dateTimePattern = "MMMMM dd yyyy";
break;
}
case YMD:
{
dateTimePattern = "yyyy MMMMM dd";
break;
}
}
break;
}
case DD_MMM_HH_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMM " + timePattern;
break;
}
case YMD:
case MDY:
{
dateTimePattern = " MMM dd " + timePattern;
break;
}
}
break;
}
case DD_MMM_YY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMM ''yy";
break;
}
case MDY:
{
dateTimePattern = "MMM dd ''yy";
break;
}
case YMD:
{
dateTimePattern = "''yy MMM dd";
break;
}
}
break;
}
case DD_MMMMM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMMMM";
break;
}
case YMD:
case MDY:
{
dateTimePattern = "MMMMM dd";
break;
}
}
break;
}
case DD_MMM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd MMM";
break;
}
case YMD:
case MDY:
{
dateTimePattern = "MMM dd";
break;
}
}
break;
}
case EEE_DD_MM_YY_HH_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "EEE " + "dd" + datesep + "MM" + datesep + "yy " + timePattern;
break;
}
case MDY:
{
dateTimePattern = "EEE " + "MM" + datesep + "dd" + datesep + "yy " + timePattern;
break;
}
case YMD:
{
dateTimePattern = "EEE " + "yy" + datesep + "MM" + datesep + "dd " + timePattern;
break;
}
}
break;
}
case EEE_DD_MM_YY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "EEE dd" + datesep + "MM" + datesep + "yy";
break;
}
case MDY:
{
dateTimePattern = "EEE MM" + datesep + "dd" + datesep + "yy";
break;
}
case YMD:
{
dateTimePattern = "EEE yy" + datesep + "MM" + datesep + "dd";
break;
}
}
break;
}
case EEE_DD_MMM_YY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "EEE dd MMM ''yy";
break;
}
case MDY:
{
dateTimePattern = "EEE MM dd ''yy";
break;
}
case YMD:
{
dateTimePattern = "EEE ''yy MMM dd";
break;
}
}
break;
}
case EEE_HH_MM:
{
dateTimePattern = "EEE " + timePattern;
break;
}
case DD_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd" + datesep + "MM";
break;
}
case YMD:
case MDY:
{
dateTimePattern = "MM" + datesep + "dd";
break;
}
}
break;
}
case DD:
{
dateTimePattern = "dd";
break;
}
case HH_MM:
{
dateTimePattern = timePattern;
break;
}
case EEE_DD_MMM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "EEE dd MMM";
break;
}
case YMD:
case MDY:
{
dateTimePattern = "EEE MMM dd";
break;
}
}
break;
}
case EEE_DD_MM:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "EEE dd" + datesep + "MM";
break;
}
case YMD:
case MDY:
{
dateTimePattern = "EEE MM" + datesep + "dd";
break;
}
}
break;
}
case EEE_DD:
{
dateTimePattern = "EEE dd";
break;
}
case DD_WWW:
{
dateTimePattern = "F" + datesep + "'W'ww";
break;
}
case DD_WWW_YY_HH_MM:
{
dateTimePattern = "F" + datesep + "'W'ww" + datesep + "yy " + timePattern;
break;
}
case DD_MM_YYYY:
{
switch (dateOrder)
{
case DMY:
{
dateTimePattern = "dd" + datesep + "MM" + datesep + "yyyy";
break;
}
case MDY:
{
dateTimePattern = "MM" + datesep + "dd" + datesep + "yyyy";
break;
}
case YMD:
{
dateTimePattern = "yyyy" + datesep + "MM" + datesep + "dd";
break;
}
}
break;
}
}
m_dateTimeFormat.applyPattern(dateTimePattern);
m_dateFormat.applyPattern(datePattern);
m_timeFormat.applyPattern(timePattern);
m_dateTimeFormat.setLocale(m_locale, m_nullText);
m_dateFormat.setLocale(m_locale, m_nullText);
m_timeFormat.setNullText(m_nullText);
m_dateTimeFormat.setAmPmText(properties.getAMText(), properties.getPMText());
m_timeFormat.setAmPmText(properties.getAMText(), properties.getPMText());
}
/**
* Returns time elements considering 12/24 hour formatting.
*
* @param properties project properties
* @return time formatting String
*/
private String getTimeElement(ProjectProperties properties)
{
String time;
char timesep = properties.getTimeSeparator();
ProjectTimeFormat format = properties.getTimeFormat();
if (format == null || format == ProjectTimeFormat.TWELVE_HOUR)
{
time = "hh" + timesep + "mm a";
}
else
{
time = "HH" + timesep + "mm";
}
return (time);
}
/**
* Retrieve the units decimal format.
*
* @return units decimal format
*/
public NumberFormat getUnitsDecimalFormat()
{
return (m_unitsDecimalFormat);
}
/**
* Retrieve the decimal format.
*
* @return decimal format
*/
public NumberFormat getDecimalFormat()
{
return (m_decimalFormat);
}
/**
* Retrieve the currency format.
*
* @return currency format
*/
public NumberFormat getCurrencyFormat()
{
return (m_currencyFormat);
}
/**
* Retrieve the duration decimal format.
*
* @return duration decimal format
*/
public NumberFormat getDurationDecimalFormat()
{
return (m_durationDecimalFormat);
}
/**
* Retrieve the percentage decimal format.
*
* @return percentage decimal format
*/
public NumberFormat getPercentageDecimalFormat()
{
return (m_percentageDecimalFormat);
}
/**
* Retrieve the date time format.
*
* @return date time format
*/
public DateFormat getDateTimeFormat()
{
return (m_dateTimeFormat);
}
/**
* Retrieve the date format.
*
* @return date format
*/
public DateFormat getDateFormat()
{
return (m_dateFormat);
}
/**
* Retrieve the time format.
*
* @return time format
*/
public DateFormat getTimeFormat()
{
return (m_timeFormat);
}
/**
* Retrieve the text representing a null value.
*
* @return null text
*/
public String getNullText()
{
return (m_nullText);
}
private Locale m_locale;
private String m_nullText;
private ProjectFile m_projectFile;
private MPXJNumberFormat m_unitsDecimalFormat = new MPXJNumberFormat();
private MPXJNumberFormat m_decimalFormat = new MPXJNumberFormat();
private MPXJNumberFormat m_currencyFormat = new MPXJNumberFormat();
private MPXJNumberFormat m_durationDecimalFormat = new MPXJNumberFormat();
private MPXJNumberFormat m_percentageDecimalFormat = new MPXJNumberFormat();
private MPXJDateFormat m_dateTimeFormat = new MPXJDateFormat();
private MPXJDateFormat m_dateFormat = new MPXJDateFormat();
private MPXJTimeFormat m_timeFormat = new MPXJTimeFormat();
}