/*
* file: DatatypeConverter.java
* author: Jon Iles
* copyright: (c) Packwood Software 2005
* date: Mar 30, 2005
*/
/*
* 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.mspdi;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import net.sf.mpxj.AccrueType;
import net.sf.mpxj.BookingType;
import net.sf.mpxj.ConstraintType;
import net.sf.mpxj.CurrencySymbolPosition;
import net.sf.mpxj.DataType;
import net.sf.mpxj.Day;
import net.sf.mpxj.Duration;
import net.sf.mpxj.EarnedValueMethod;
import net.sf.mpxj.FieldContainer;
import net.sf.mpxj.FieldType;
import net.sf.mpxj.Priority;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.ProjectProperties;
import net.sf.mpxj.Rate;
import net.sf.mpxj.ResourceType;
import net.sf.mpxj.TaskType;
import net.sf.mpxj.TimeUnit;
import net.sf.mpxj.WorkContour;
import net.sf.mpxj.WorkGroup;
import net.sf.mpxj.common.NumberHelper;
/**
* This class contains methods used to perform the datatype conversions
* required to read and write MSPDI files.
*/
public final class DatatypeConverter
{
/**
* Print an extended attribute currency value.
*
* @param value currency value
* @return string representation
*/
public static final String printExtendedAttributeCurrency(Number value)
{
return (value == null ? null : getNumberFormat().format(value.doubleValue() * 100));
}
/**
* Parse an extended attribute currency value.
*
* @param value string representation
* @return currency value
*/
public static final Number parseExtendedAttributeCurrency(String value)
{
Number result;
if (value == null)
{
result = null;
}
else
{
result = NumberHelper.getDouble(Double.parseDouble(value) / 100);
}
return result;
}
/**
* Print an extended attribute numeric value.
*
* @param value numeric value
* @return string representation
*/
public static final String printExtendedAttributeNumber(Number value)
{
return (getNumberFormat().format(value.doubleValue()));
}
/**
* Parse and extended attribute numeric value.
*
* @param value string representation
* @return numeric value
*/
public static final Number parseExtendedAttributeNumber(String value)
{
return (Double.valueOf(value));
}
/**
* Print an extended attribute boolean value.
*
* @param value boolean value
* @return string representation
*/
public static final String printExtendedAttributeBoolean(Boolean value)
{
return (value.booleanValue() ? "1" : "0");
}
/**
* Parse an extended attribute boolean value.
*
* @param value string representation
* @return boolean value
*/
public static final Boolean parseExtendedAttributeBoolean(String value)
{
return ((value.equals("1") ? Boolean.TRUE : Boolean.FALSE));
}
/**
* Print an extended attribute date value.
*
* @param value date value
* @return string representation
*/
public static final String printExtendedAttributeDate(Date value)
{
return (value == null ? null : getDateFormat().format(value));
}
/**
* Parse an extended attribute date value.
*
* @param value string representation
* @return date value
*/
public static final Date parseExtendedAttributeDate(String value)
{
Date result = null;
if (value != null)
{
try
{
result = getDateFormat().parse(value);
}
catch (ParseException ex)
{
// ignore exceptions
}
}
return (result);
}
/**
* Print an extended attribute value.
*
* @param writer parent MSPDIWriter instance
* @param value attribute value
* @param type type of the value being passed
* @return string representation
*/
public static final String printExtendedAttribute(MSPDIWriter writer, Object value, DataType type)
{
String result;
if (type == DataType.DATE)
{
result = printExtendedAttributeDate((Date) value);
}
else
{
if (value instanceof Boolean)
{
result = printExtendedAttributeBoolean((Boolean) value);
}
else
{
if (value instanceof Duration)
{
result = printDuration(writer, (Duration) value);
}
else
{
if (type == DataType.CURRENCY)
{
result = printExtendedAttributeCurrency((Number) value);
}
else
{
if (value instanceof Number)
{
result = printExtendedAttributeNumber((Number) value);
}
else
{
result = value.toString();
}
}
}
}
}
return (result);
}
/**
* Parse an extended attribute value.
*
* @param file parent file
* @param mpx parent entity
* @param value string value
* @param mpxFieldID field ID
* @param durationFormat duration format associated with the extended attribute
*/
public static final void parseExtendedAttribute(ProjectFile file, FieldContainer mpx, String value, FieldType mpxFieldID, TimeUnit durationFormat)
{
if (mpxFieldID != null)
{
switch (mpxFieldID.getDataType())
{
case STRING:
{
mpx.set(mpxFieldID, value);
break;
}
case DATE:
{
mpx.set(mpxFieldID, parseExtendedAttributeDate(value));
break;
}
case CURRENCY:
{
mpx.set(mpxFieldID, parseExtendedAttributeCurrency(value));
break;
}
case BOOLEAN:
{
mpx.set(mpxFieldID, parseExtendedAttributeBoolean(value));
break;
}
case NUMERIC:
{
mpx.set(mpxFieldID, parseExtendedAttributeNumber(value));
break;
}
case DURATION:
{
mpx.set(mpxFieldID, parseDuration(file, durationFormat, value));
break;
}
default:
{
break;
}
}
}
}
/**
* Prints a currency symbol position value.
*
* @param value CurrencySymbolPosition instance
* @return currency symbol position
*/
public static final String printCurrencySymbolPosition(CurrencySymbolPosition value)
{
String result;
switch (value)
{
default:
case BEFORE:
{
result = "0";
break;
}
case AFTER:
{
result = "1";
break;
}
case BEFORE_WITH_SPACE:
{
result = "2";
break;
}
case AFTER_WITH_SPACE:
{
result = "3";
break;
}
}
return (result);
}
/**
* Parse a currency symbol position value.
*
* @param value currency symbol position
* @return CurrencySymbolPosition instance
*/
public static final CurrencySymbolPosition parseCurrencySymbolPosition(String value)
{
CurrencySymbolPosition result = CurrencySymbolPosition.BEFORE;
switch (NumberHelper.getInt(value))
{
case 0:
{
result = CurrencySymbolPosition.BEFORE;
break;
}
case 1:
{
result = CurrencySymbolPosition.AFTER;
break;
}
case 2:
{
result = CurrencySymbolPosition.BEFORE_WITH_SPACE;
break;
}
case 3:
{
result = CurrencySymbolPosition.AFTER_WITH_SPACE;
break;
}
}
return (result);
}
/**
* Print an accrue type.
*
* @param value AccrueType instance
* @return accrue type value
*/
public static final String printAccrueType(AccrueType value)
{
return (Integer.toString(value == null ? AccrueType.PRORATED.getValue() : value.getValue()));
}
/**
* Parse an accrue type.
*
* @param value accrue type value
* @return AccrueType instance
*/
public static final AccrueType parseAccrueType(String value)
{
return (AccrueType.getInstance(NumberHelper.getInt(value)));
}
/**
* Print a resource type.
*
* @param value ResourceType instance
* @return resource type value
*/
public static final String printResourceType(ResourceType value)
{
return (Integer.toString(value == null ? ResourceType.WORK.getValue() : value.getValue()));
}
/**
* Parse a resource type.
*
* @param value resource type value
* @return ResourceType instance
*/
public static final ResourceType parseResourceType(String value)
{
return (ResourceType.getInstance(NumberHelper.getInt(value)));
}
/**
* Print a work group.
*
* @param value WorkGroup instance
* @return work group value
*/
public static final String printWorkGroup(WorkGroup value)
{
return (Integer.toString(value == null ? WorkGroup.DEFAULT.getValue() : value.getValue()));
}
/**
* Parse a work group.
*
* @param value work group value
* @return WorkGroup instance
*/
public static final WorkGroup parseWorkGroup(String value)
{
return (WorkGroup.getInstance(NumberHelper.getInt(value)));
}
/**
* Print a work contour.
*
* @param value WorkContour instance
* @return work contour value
*/
public static final String printWorkContour(WorkContour value)
{
return (Integer.toString(value == null ? WorkContour.FLAT.getValue() : value.getValue()));
}
/**
* Parse a work contour.
*
* @param value work contour value
* @return WorkContour instance
*/
public static final WorkContour parseWorkContour(String value)
{
return (WorkContour.getInstance(NumberHelper.getInt(value)));
}
/**
* Print a booking type.
*
* @param value BookingType instance
* @return booking type value
*/
public static final String printBookingType(BookingType value)
{
return (Integer.toString(value == null ? BookingType.COMMITTED.getValue() : value.getValue()));
}
/**
* Parse a booking type.
*
* @param value booking type value
* @return BookingType instance
*/
public static final BookingType parseBookingType(String value)
{
return (BookingType.getInstance(NumberHelper.getInt(value)));
}
/**
* Print a task type.
*
* @param value TaskType instance
* @return task type value
*/
public static final String printTaskType(TaskType value)
{
return (Integer.toString(value == null ? TaskType.FIXED_UNITS.getValue() : value.getValue()));
}
/**
* Parse a task type.
*
* @param value task type value
* @return TaskType instance
*/
public static final TaskType parseTaskType(String value)
{
return (TaskType.getInstance(NumberHelper.getInt(value)));
}
/**
* Print an earned value method.
*
* @param value EarnedValueMethod instance
* @return earned value method value
*/
public static final BigInteger printEarnedValueMethod(EarnedValueMethod value)
{
return (value == null ? BigInteger.valueOf(EarnedValueMethod.PERCENT_COMPLETE.getValue()) : BigInteger.valueOf(value.getValue()));
}
/**
* Parse an earned value method.
*
* @param value earned value method
* @return EarnedValueMethod instance
*/
public static final EarnedValueMethod parseEarnedValueMethod(Number value)
{
return (EarnedValueMethod.getInstance(NumberHelper.getInt(value)));
}
/**
* Print units.
*
* @param value units value
* @return units value
*/
public static final BigDecimal printUnits(Number value)
{
return (value == null ? BIGDECIMAL_ONE : new BigDecimal(value.doubleValue() / 100));
}
/**
* Parse units.
*
* @param value units value
* @return units value
*/
public static final Number parseUnits(Number value)
{
return (value == null ? null : NumberHelper.getDouble(value.doubleValue() * 100));
}
/**
* Print time unit.
*
* @param value TimeUnit instance
* @return time unit value
*/
public static final BigInteger printTimeUnit(TimeUnit value)
{
return (BigInteger.valueOf(value == null ? TimeUnit.DAYS.getValue() + 1 : value.getValue() + 1));
}
/**
* Parse time unit.
*
* @param value time unit value
* @return TimeUnit instance
*/
public static final TimeUnit parseTimeUnit(Number value)
{
return (TimeUnit.getInstance(NumberHelper.getInt(value) - 1));
}
/**
* Print date.
*
* @param value Date value
* @return Calendar value
*/
public static final Calendar printDate(Date value)
{
Calendar cal = null;
if (value != null)
{
cal = Calendar.getInstance();
cal.setTime(value);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
}
return (cal);
}
/**
* Parse date.
*
* @param value Calendar value
* @return Date value
*/
public static final Date parseDate(Calendar value)
{
Date result = null;
if (value != null)
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, value.get(Calendar.YEAR));
cal.set(Calendar.MONTH, value.get(Calendar.MONTH));
cal.set(Calendar.DAY_OF_MONTH, value.get(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, value.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, value.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, value.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, value.get(Calendar.MILLISECOND));
result = cal.getTime();
}
return (result);
}
/**
* Print time.
*
* @param value time value
* @return calendar value
*/
public static final Calendar printTime(Date value)
{
Calendar cal = null;
if (value != null)
{
cal = Calendar.getInstance();
cal.setTime(value);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
}
return (cal);
}
/**
* Parse time.
*
* @param value Calendar value
* @return time value
*/
public static final Date parseTime(Calendar value)
{
Date result = null;
if (value != null)
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, value.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, value.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, value.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, value.get(Calendar.MILLISECOND));
result = cal.getTime();
}
return (result);
}
/**
* Parse work units.
*
* @param value work units value
* @return TimeUnit instance
*/
public static final TimeUnit parseWorkUnits(BigInteger value)
{
TimeUnit result = TimeUnit.HOURS;
if (value != null)
{
switch (value.intValue())
{
case 1:
{
result = TimeUnit.MINUTES;
break;
}
case 3:
{
result = TimeUnit.DAYS;
break;
}
case 4:
{
result = TimeUnit.WEEKS;
break;
}
case 5:
{
result = TimeUnit.MONTHS;
break;
}
case 7:
{
result = TimeUnit.YEARS;
break;
}
default:
case 2:
{
result = TimeUnit.HOURS;
break;
}
}
}
return (result);
}
/**
* Print work units.
*
* @param value TimeUnit instance
* @return work units value
*/
public static final BigInteger printWorkUnits(TimeUnit value)
{
int result;
if (value == null)
{
value = TimeUnit.HOURS;
}
switch (value)
{
case MINUTES:
{
result = 1;
break;
}
case DAYS:
{
result = 3;
break;
}
case WEEKS:
{
result = 4;
break;
}
case MONTHS:
{
result = 5;
break;
}
case YEARS:
{
result = 7;
break;
}
default:
case HOURS:
{
result = 2;
break;
}
}
return (BigInteger.valueOf(result));
}
/**
* Parse a duration.
*
* @param file parent file
* @param defaultUnits default time units for the resulting duration
* @param value duration value
* @return Duration instance
*/
public static final Duration parseDuration(ProjectFile file, TimeUnit defaultUnits, String value)
{
Duration result = null;
if (value != null && value.length() != 0)
{
XsdDuration xsd = new XsdDuration(value);
TimeUnit units = TimeUnit.DAYS;
if (xsd.getSeconds() != 0 || xsd.getMinutes() != 0)
{
units = TimeUnit.MINUTES;
}
if (xsd.getHours() != 0)
{
units = TimeUnit.HOURS;
}
if (xsd.getDays() != 0)
{
units = TimeUnit.DAYS;
}
if (xsd.getMonths() != 0)
{
units = TimeUnit.MONTHS;
}
if (xsd.getYears() != 0)
{
units = TimeUnit.YEARS;
}
double duration = 0;
switch (units)
{
case YEARS:
{
//
// Calculate the number of years
//
duration += xsd.getYears();
duration += ((double) xsd.getMonths() / 12);
duration += ((double) xsd.getDays() / 365);
duration += ((double) xsd.getHours() / (365 * 24));
duration += ((double) xsd.getMinutes() / (365 * 24 * 60));
duration += (xsd.getSeconds() / (365 * 24 * 60 * 60));
break;
}
case ELAPSED_YEARS:
{
//
// Calculate the number of years
//
duration += xsd.getYears();
duration += ((double) xsd.getMonths() / 12);
duration += ((double) xsd.getDays() / 365);
duration += ((double) xsd.getHours() / (365 * 24));
duration += ((double) xsd.getMinutes() / (365 * 24 * 60));
duration += (xsd.getSeconds() / (365 * 24 * 60 * 60));
break;
}
case MONTHS:
{
//
// Calculate the number of months
//
duration += (xsd.getYears() * 12);
duration += xsd.getMonths();
duration += ((double) xsd.getDays() / 30);
duration += ((double) xsd.getHours() / (30 * 24));
duration += ((double) xsd.getMinutes() / (30 * 24 * 60));
duration += (xsd.getSeconds() / (30 * 24 * 60 * 60));
break;
}
case ELAPSED_MONTHS:
{
//
// Calculate the number of months
//
duration += (xsd.getYears() * 12);
duration += xsd.getMonths();
duration += ((double) xsd.getDays() / 30);
duration += ((double) xsd.getHours() / (30 * 24));
duration += ((double) xsd.getMinutes() / (30 * 24 * 60));
duration += (xsd.getSeconds() / (30 * 24 * 60 * 60));
break;
}
case WEEKS:
{
//
// Calculate the number of weeks
//
duration += (xsd.getYears() * 52);
duration += (xsd.getMonths() * 4);
duration += ((double) xsd.getDays() / 7);
duration += ((double) xsd.getHours() / (7 * 24));
duration += ((double) xsd.getMinutes() / (7 * 24 * 60));
duration += (xsd.getSeconds() / (7 * 24 * 60 * 60));
break;
}
case ELAPSED_WEEKS:
{
//
// Calculate the number of weeks
//
duration += (xsd.getYears() * 52);
duration += (xsd.getMonths() * 4);
duration += ((double) xsd.getDays() / 7);
duration += ((double) xsd.getHours() / (7 * 24));
duration += ((double) xsd.getMinutes() / (7 * 24 * 60));
duration += (xsd.getSeconds() / (7 * 24 * 60 * 60));
break;
}
case DAYS:
{
//
// Calculate the number of days
//
duration += (xsd.getYears() * 365);
duration += (xsd.getMonths() * 30);
duration += xsd.getDays();
duration += ((double) xsd.getHours() / 24);
duration += ((double) xsd.getMinutes() / (24 * 60));
duration += (xsd.getSeconds() / (24 * 60 * 60));
break;
}
case ELAPSED_DAYS:
{
//
// Calculate the number of days
//
duration += (xsd.getYears() * 365);
duration += (xsd.getMonths() * 30);
duration += xsd.getDays();
duration += ((double) xsd.getHours() / 24);
duration += ((double) xsd.getMinutes() / (24 * 60));
duration += (xsd.getSeconds() / (24 * 60 * 60));
break;
}
case HOURS:
case ELAPSED_HOURS:
{
//
// Calculate the number of hours
//
duration += (xsd.getYears() * (365 * 24));
duration += (xsd.getMonths() * (30 * 24));
duration += (xsd.getDays() * 24);
duration += xsd.getHours();
duration += ((double) xsd.getMinutes() / 60);
duration += (xsd.getSeconds() / (60 * 60));
break;
}
case MINUTES:
case ELAPSED_MINUTES:
{
//
// Calculate the number of minutes
//
duration += (xsd.getYears() * (365 * 24 * 60));
duration += (xsd.getMonths() * (30 * 24 * 60));
duration += (xsd.getDays() * (24 * 60));
duration += (xsd.getHours() * 60);
duration += xsd.getMinutes();
duration += (xsd.getSeconds() / 60);
break;
}
default:
{
break;
}
}
//
// Convert from a duration in hours to a duration
// expressed in the default duration units
//
ProjectProperties properties = file.getProjectProperties();
if (defaultUnits == null)
{
defaultUnits = properties.getDefaultDurationUnits();
}
result = Duration.convertUnits(duration, units, defaultUnits, properties);
}
return (result);
}
/**
* Print duration.
*
* Note that Microsoft's xsd:duration parser implementation does not
* appear to recognise durations other than those expressed in hours.
* We use the compatibility flag to determine whether the output
* is adjusted for the benefit of Microsoft Project.
*
* @param writer parent MSPDIWriter instance
* @param duration Duration value
* @return xsd:duration value
*/
public static final String printDuration(MSPDIWriter writer, Duration duration)
{
String result = null;
if (duration != null && duration.getDuration() != 0)
{
result = printDurationMandatory(writer, duration);
}
return (result);
}
/**
* Print duration.
*
* Note that Microsoft's xsd:duration parser implementation does not
* appear to recognise durations other than those expressed in hours.
* We use the compatibility flag to determine whether the output
* is adjusted for the benefit of Microsoft Project.
*
* @param writer parent MSPDIWriter instance
* @param duration Duration value
* @return xsd:duration value
*/
public static final String printDurationMandatory(MSPDIWriter writer, Duration duration)
{
String result = null;
if (duration != null)
{
TimeUnit durationType = duration.getUnits();
if (durationType == TimeUnit.HOURS || durationType == TimeUnit.ELAPSED_HOURS)
{
result = new XsdDuration(duration).toString();
}
else
{
duration = duration.convertUnits(TimeUnit.HOURS, writer.getProjectFile().getProjectProperties());
result = new XsdDuration(duration).toString();
}
}
return (result);
}
/**
* Print duration time units.
*
* @param duration Duration value
* @param estimated is this an estimated duration
* @return time units value
*/
public static final BigInteger printDurationTimeUnits(Duration duration, boolean estimated)
{
BigInteger result = null;
if (duration != null)
{
result = printDurationTimeUnits(duration.getUnits(), estimated);
}
return (result);
}
/**
* Parse currency.
*
* @param value currency value
* @return currency value
*/
public static final Double parseCurrency(Number value)
{
return (value == null ? null : NumberHelper.getDouble(value.doubleValue() / 100));
}
/**
* Print currency.
*
* @param value currency value
* @return currency value
*/
public static final BigDecimal printCurrency(Number value)
{
return (value == null || value.doubleValue() == 0 ? null : new BigDecimal(value.doubleValue() * 100));
}
/**
* Parse duration time units.
*
* Note that we don't differentiate between confirmed and unconfirmed
* durations. Unrecognised duration types are default to hours.
*
* @param value BigInteger value
* @return Duration units
*/
public static final TimeUnit parseDurationTimeUnits(BigInteger value)
{
return parseDurationTimeUnits(value, TimeUnit.HOURS);
}
/**
* Parse duration time units.
*
* Note that we don't differentiate between confirmed and unconfirmed
* durations. Unrecognised duration types are default the supplied default value.
*
* @param value BigInteger value
* @param defaultValue if value is null, use this value as the result
* @return Duration units
*/
public static final TimeUnit parseDurationTimeUnits(BigInteger value, TimeUnit defaultValue)
{
TimeUnit result = defaultValue;
if (value != null)
{
switch (value.intValue())
{
case 3:
case 35:
{
result = TimeUnit.MINUTES;
break;
}
case 4:
case 36:
{
result = TimeUnit.ELAPSED_MINUTES;
break;
}
case 5:
case 37:
{
result = TimeUnit.HOURS;
break;
}
case 6:
case 38:
{
result = TimeUnit.ELAPSED_HOURS;
break;
}
case 7:
case 39:
case 53:
{
result = TimeUnit.DAYS;
break;
}
case 8:
case 40:
{
result = TimeUnit.ELAPSED_DAYS;
break;
}
case 9:
case 41:
{
result = TimeUnit.WEEKS;
break;
}
case 10:
case 42:
{
result = TimeUnit.ELAPSED_WEEKS;
break;
}
case 11:
case 43:
{
result = TimeUnit.MONTHS;
break;
}
case 12:
case 44:
{
result = TimeUnit.ELAPSED_MONTHS;
break;
}
case 19:
case 51:
{
result = TimeUnit.PERCENT;
break;
}
case 20:
case 52:
{
result = TimeUnit.ELAPSED_PERCENT;
break;
}
default:
{
result = PARENT_FILE.get().getProjectProperties().getDefaultDurationUnits();
break;
}
}
}
return (result);
}
/**
* Print duration time units.
*
* Note that we don't differentiate between confirmed and unconfirmed
* durations. Unrecognised duration types are default to hours.
*
* @param value Duration units
* @param estimated is this an estimated duration
* @return BigInteger value
*/
public static final BigInteger printDurationTimeUnits(TimeUnit value, boolean estimated)
{
int result;
if (value == null)
{
value = TimeUnit.HOURS;
}
switch (value)
{
case MINUTES:
{
result = (estimated ? 35 : 3);
break;
}
case ELAPSED_MINUTES:
{
result = (estimated ? 36 : 4);
break;
}
case ELAPSED_HOURS:
{
result = (estimated ? 38 : 6);
break;
}
case DAYS:
{
result = (estimated ? 39 : 7);
break;
}
case ELAPSED_DAYS:
{
result = (estimated ? 40 : 8);
break;
}
case WEEKS:
{
result = (estimated ? 41 : 9);
break;
}
case ELAPSED_WEEKS:
{
result = (estimated ? 42 : 10);
break;
}
case MONTHS:
{
result = (estimated ? 43 : 11);
break;
}
case ELAPSED_MONTHS:
{
result = (estimated ? 44 : 12);
break;
}
case PERCENT:
{
result = (estimated ? 51 : 19);
break;
}
case ELAPSED_PERCENT:
{
result = (estimated ? 52 : 20);
break;
}
default:
case HOURS:
{
result = (estimated ? 37 : 5);
break;
}
}
return (BigInteger.valueOf(result));
}
/**
* Parse priority.
*
*
* @param priority priority value
* @return Priority instance
*/
public static final Priority parsePriority(BigInteger priority)
{
return (priority == null ? null : Priority.getInstance(priority.intValue()));
}
/**
* Print priority.
*
* @param priority Priority instance
* @return priority value
*/
public static final BigInteger printPriority(Priority priority)
{
int result = Priority.MEDIUM;
if (priority != null)
{
result = priority.getValue();
}
return (BigInteger.valueOf(result));
}
/**
* Parse duration represented in thousandths of minutes.
*
* @param value duration value
* @return Duration instance
*/
public static final Duration parseDurationInThousanthsOfMinutes(Number value)
{
return parseDurationInFractionsOfMinutes(null, value, TimeUnit.MINUTES, 1000);
}
/**
* Parse duration represented in tenths of minutes.
*
* @param value duration value
* @return Duration instance
*/
public static final Duration parseDurationInTenthsOfMinutes(Number value)
{
return parseDurationInFractionsOfMinutes(null, value, TimeUnit.MINUTES, 10);
}
/**
* Parse duration represented in thousandths of minutes.
*
* @param properties project properties
* @param value duration value
* @param targetTimeUnit required output time units
* @return Duration instance
*/
public static final Duration parseDurationInThousanthsOfMinutes(ProjectProperties properties, Number value, TimeUnit targetTimeUnit)
{
return parseDurationInFractionsOfMinutes(properties, value, targetTimeUnit, 1000);
}
/**
* Parse duration represented as tenths of minutes.
*
* @param properties project properties
* @param value duration value
* @param targetTimeUnit required output time units
* @return Duration instance
*/
public static final Duration parseDurationInTenthsOfMinutes(ProjectProperties properties, Number value, TimeUnit targetTimeUnit)
{
return parseDurationInFractionsOfMinutes(properties, value, targetTimeUnit, 10);
}
/**
* Print duration in thousandths of minutes.
*
* @param duration Duration instance
* @return duration in thousandths of minutes
*/
public static final BigInteger printDurationInIntegerThousandthsOfMinutes(Duration duration)
{
BigInteger result = null;
if (duration != null && duration.getDuration() != 0)
{
result = BigInteger.valueOf((long) printDurationFractionsOfMinutes(duration, 1000));
}
return result;
}
/**
* Print duration in thousandths of minutes.
*
* @param duration Duration instance
* @return duration in thousandths of minutes
*/
public static final BigDecimal printDurationInDecimalThousandthsOfMinutes(Duration duration)
{
BigDecimal result = null;
if (duration != null && duration.getDuration() != 0)
{
result = BigDecimal.valueOf(printDurationFractionsOfMinutes(duration, 1000));
}
return result;
}
/**
* Print duration in tenths of minutes.
*
* @param duration Duration instance
* @return duration in tenths of minutes
*/
public static final BigInteger printDurationInIntegerTenthsOfMinutes(Duration duration)
{
BigInteger result = null;
if (duration != null && duration.getDuration() != 0)
{
result = BigInteger.valueOf((long) printDurationFractionsOfMinutes(duration, 10));
}
return result;
}
/**
* Parse duration represented as an arbitrary fraction of minutes.
*
* @param properties project properties
* @param value duration value
* @param targetTimeUnit required output time units
* @param factor required fraction of a minute
* @return Duration instance
*/
private static final Duration parseDurationInFractionsOfMinutes(ProjectProperties properties, Number value, TimeUnit targetTimeUnit, int factor)
{
Duration result = null;
if (value != null)
{
result = Duration.getInstance(value.intValue() / factor, TimeUnit.MINUTES);
if (targetTimeUnit != result.getUnits())
{
result = result.convertUnits(targetTimeUnit, properties);
}
}
return (result);
}
/**
* Print a duration represented by an arbitrary fraction of minutes.
*
* @param duration Duration instance
* @param factor required factor
* @return duration represented as an arbitrary fraction of minutes
*/
private static final double printDurationFractionsOfMinutes(Duration duration, int factor)
{
double result = 0;
if (duration != null)
{
result = duration.getDuration();
switch (duration.getUnits())
{
case HOURS:
case ELAPSED_HOURS:
{
result *= 60;
break;
}
case DAYS:
{
result *= (60 * 8);
break;
}
case ELAPSED_DAYS:
{
result *= (60 * 24);
break;
}
case WEEKS:
{
result *= (60 * 8 * 5);
break;
}
case ELAPSED_WEEKS:
{
result *= (60 * 24 * 7);
break;
}
case MONTHS:
{
result *= (60 * 8 * 5 * 4);
break;
}
case ELAPSED_MONTHS:
{
result *= (60 * 24 * 30);
break;
}
case YEARS:
{
result *= (60 * 8 * 5 * 52);
break;
}
case ELAPSED_YEARS:
{
result *= (60 * 24 * 365);
break;
}
default:
{
break;
}
}
}
result *= factor;
return (result);
}
/**
* Print rate.
*
* @param rate Rate instance
* @return rate value
*/
public static final BigDecimal printRate(Rate rate)
{
BigDecimal result = null;
if (rate != null && rate.getAmount() != 0)
{
result = new BigDecimal(rate.getAmount());
}
return result;
}
/**
* Parse rate.
*
* @param value rate value
* @return Rate instance
*/
public static final Rate parseRate(BigDecimal value)
{
Rate result = null;
if (value != null)
{
result = new Rate(value, TimeUnit.HOURS);
}
return (result);
}
/**
* Print a day.
*
* @param day Day instance
* @return day value
*/
public static final BigInteger printDay(Day day)
{
return (day == null ? null : BigInteger.valueOf(day.getValue() - 1));
}
/**
* Parse a day.
*
* @param value day value
* @return Day instance
*/
public static final Day parseDay(Number value)
{
return (Day.getInstance(NumberHelper.getInt(value) + 1));
}
/**
* Parse a constraint type.
*
* @param value constraint type value
* @return ConstraintType instance
*/
public static final ConstraintType parseConstraintType(Number value)
{
return (ConstraintType.getInstance(value));
}
/**
* Print a constraint type.
*
* @param value ConstraintType instance
* @return constraint type value
*/
public static final BigInteger printConstraintType(ConstraintType value)
{
return (value == null ? null : BigInteger.valueOf(value.getValue()));
}
/**
* Print a task UID.
*
* @param value task UID
* @return task UID string
*/
public static final String printTaskUID(Integer value)
{
ProjectFile file = PARENT_FILE.get();
if (file != null)
{
file.getEventManager().fireTaskWrittenEvent(file.getTaskByUniqueID(value));
}
return (value.toString());
}
/**
* Parse a task UID.
*
* @param value task UID string
* @return task UID
*/
public static final Integer parseTaskUID(String value)
{
return (Integer.valueOf(value));
}
/**
* Print a resource UID.
*
* @param value resource UID value
* @return resource UID string
*/
public static final String printResourceUID(Integer value)
{
ProjectFile file = PARENT_FILE.get();
if (file != null)
{
file.getEventManager().fireResourceWrittenEvent(file.getResourceByUniqueID(value));
}
return (value.toString());
}
/**
* Parse a resource UID.
*
* @param value resource UID string
* @return resource UID value
*/
public static final Integer parseResourceUID(String value)
{
return (Integer.valueOf(value));
}
/**
* Print a boolean.
*
* @param value boolean
* @return boolean value
*/
public static final String printBoolean(Boolean value)
{
return (value == null || !value.booleanValue() ? "0" : "1");
}
/**
* Parse a boolean.
*
* @param value boolean
* @return Boolean value
*/
public static final Boolean parseBoolean(String value)
{
return (value == null || value.charAt(0) != '1' ? Boolean.FALSE : Boolean.TRUE);
}
/**
* Print a time value.
*
* @param value time value
* @return time value
*/
public static final String printTime(Calendar value)
{
return (value == null ? null : getTimeFormat().format(value.getTime()));
}
/**
* Parse a time value.
*
* @param value time value
* @return time value
*/
public static final Calendar parseTime(String value)
{
Calendar cal = null;
if (value != null && value.length() != 0)
{
cal = Calendar.getInstance();
try
{
cal.setTime(getTimeFormat().parse(value));
}
catch (ParseException ex)
{
cal = null;
}
}
return (cal);
}
/**
* Print a date time value.
*
* @param value date time value
* @return string representation
*/
public static final String printDateTime(Calendar value)
{
return (value == null ? null : getDateFormat().format(value.getTime()));
}
/**
* Parse a date time value.
*
* @param value string representation
* @return date time value
*/
public static final Calendar parseDateTime(String value)
{
Calendar result = null;
if (value != null && value.length() != 0)
{
try
{
result = Calendar.getInstance();
result.setTime(getDateFormat().parse(value));
}
catch (ParseException ex)
{
result = null;
}
}
return (result);
}
/**
* Print method for a string: returns the string unchanged.
* This is used to enable to string representation of an
* xsd:datetime to be generated by MPXJ.
*
* @param value string value
* @return string value
*/
public static final String printString(String value)
{
return (value);
}
/**
* Parse method for a string: returns the string unchanged.
* This is used to enable to string representation of an
* xsd:datetime to be processed by MPXJ.
* @param value string value
* @return string value
*/
public static final String parseString(String value)
{
return (value);
}
/**
* This method is called to set the parent file for the current
* write operation. This allows task and resource write events
* to be captured and passed to any file listeners.
*
* @param file parent file instance
*/
public static final void setParentFile(ProjectFile file)
{
PARENT_FILE.set(file);
}
/**
* Retrieve a number formatter.
*
* @return NumberFormat instance
*/
private static final NumberFormat getNumberFormat()
{
NumberFormat format = NUMBER_FORMAT.get();
if (format == null)
{
// XML numbers should use . as decimal separator and no grouping.
format = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US));
format.setGroupingUsed(false);
NUMBER_FORMAT.set(format);
}
return (format);
}
/**
* Retrieve a date formatter.
*
* @return DateFormat instance
*/
private static final DateFormat getDateFormat()
{
DateFormat df = DATE_FORMAT.get();
if (df == null)
{
df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
df.setLenient(false);
}
return (df);
}
/**
* Retrieve a time formatter.
*
* @return DateFormat instance
*/
private static final DateFormat getTimeFormat()
{
DateFormat df = TIME_FORMAT.get();
if (df == null)
{
df = new SimpleDateFormat("HH:mm:ss");
df.setLenient(false);
}
return (df);
}
private static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>();
private static final ThreadLocal<DateFormat> TIME_FORMAT = new ThreadLocal<DateFormat>();
private static final ThreadLocal<NumberFormat> NUMBER_FORMAT = new ThreadLocal<NumberFormat>();
private static final BigDecimal BIGDECIMAL_ONE = BigDecimal.valueOf(1);
private static final ThreadLocal<ProjectFile> PARENT_FILE = new ThreadLocal<ProjectFile>();
}