Author: adrianc
Date: Tue Nov 3 21:58:00 2009
New Revision: 832574
URL: http://svn.apache.org/viewvc?rev=832574&view=rev
Log:
TimeDuration.java improvements. This is the first step in a duration data type
implementation discussed here -
https://issues.apache.org/jira/browse/OFBIZ-3125.
Modified:
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ObjectType.java
ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java
Modified:
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java?rev=832574&r1=832573&r2=832574&view=diff
==============================================================================
---
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
(original)
+++
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/ICalConverter.java
Tue Nov 3 21:58:00 2009
@@ -96,8 +96,7 @@
if (reminderStamp != null) {
alarm = new VAlarm(new DateTime(reminderStamp));
} else {
- long reminderOffset =
workEffortEventReminder.get("reminderOffset") == null ? 0 :
workEffortEventReminder.getLong("reminderOffset").longValue();
- TimeDuration duration = TimeDuration.fromLong(reminderOffset);
+ TimeDuration duration =
workEffortEventReminder.getDuration("reminderOffset");
alarm = new VAlarm(new Dur(duration.days(), duration.hours(),
duration.minutes(), duration.seconds()));
}
return alarm;
@@ -949,7 +948,7 @@
if (javaObj == null) {
return null;
}
- TimeDuration duration = TimeDuration.fromLong(javaObj.longValue());
+ TimeDuration duration = TimeDuration.fromNumber(javaObj);
return new Duration(new Dur(duration.days(), duration.hours(),
duration.minutes(), duration.seconds()));
}
Modified:
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java?rev=832574&r1=832573&r2=832574&view=diff
==============================================================================
---
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
(original)
+++
ofbiz/trunk/applications/workeffort/src/org/ofbiz/workeffort/workeffort/WorkEffortServices.java
Tue Nov 3 21:58:00 2009
@@ -637,9 +637,8 @@
for (DateRange periodRange : periodRanges) {
if (periodRange.includesDate(occurrence)) {
GenericValue cloneWorkEffort =
(GenericValue) workEffort.clone();
- Double durationMillis =
workEffort.getDouble("estimatedMilliSeconds");
- if (durationMillis != null) {
- TimeDuration duration =
TimeDuration.fromLong(durationMillis.longValue());
+ TimeDuration duration =
workEffort.getDuration("estimatedMilliSeconds");
+ if (!duration.isZero()) {
Calendar endCal =
UtilDateTime.toCalendar(occurrence, timeZone, locale);
Date endDate =
duration.addToCalendar(endCal).getTime();
cloneWorkEffort.set("estimatedStartDate", new Timestamp(occurrence.getTime()));
@@ -952,12 +951,11 @@
try {
parameters.put("eventDateTime", eventDateTime);
processEventReminder(ctx, reminder, parameters);
- long repeatInterval = reminder.get("repeatInterval")
== null ? 0 : reminder.getLong("repeatInterval").longValue();
- if ((repeatCount != 0 && currentCount + 1 >=
repeatCount) || repeatInterval == 0) {
+ TimeDuration duration =
reminder.getDuration("repeatInterval");
+ if ((repeatCount != 0 && currentCount + 1 >=
repeatCount) || duration.isZero()) {
reminder.remove();
} else {
cal.setTime(now);
- TimeDuration duration =
TimeDuration.fromLong(repeatInterval);
duration.addToCalendar(cal);
reminderDateTime = cal.getTime();
reminder.set("currentCount",
Long.valueOf(currentCount + 1));
Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ObjectType.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ObjectType.java?rev=832574&r1=832573&r2=832574&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ObjectType.java
(original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/ObjectType.java Tue Nov
3 21:58:00 2009
@@ -658,6 +658,19 @@
} else if (("Map".equals(type) || "java.util.Map".equals(type)) &&
(str.startsWith("{") && str.endsWith("}"))) {
return StringUtil.toMap(str);
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ if (!str.contains(":")) {
+ // Encoded duration
+ try {
+ NumberFormat nf =
NumberFormat.getNumberInstance(locale);
+ nf.setMaximumFractionDigits(0);
+ Number number = nf.parse(str);
+ return TimeDuration.fromNumber(number);
+ } catch (ParseException e) {
+ throw new GeneralException("Could not convert " + str
+ " to " + type + ": ", e);
+ }
+ }
+ return TimeDuration.parseDuration(str);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -686,6 +699,8 @@
Set<Double> tempSet = FastSet.newInstance();
tempSet.add(dbl);
return tempSet;
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ return TimeDuration.fromNumber(dbl);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -714,6 +729,8 @@
Set<Float> tempSet = FastSet.newInstance();
tempSet.add(flt);
return tempSet;
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ return TimeDuration.fromNumber(flt);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -746,6 +763,8 @@
return new Date(lng.longValue());
} else if ("Timestamp".equals(type) ||
"java.sql.Timestamp".equals(type)) {
return new java.sql.Timestamp(lng.longValue());
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ return TimeDuration.fromNumber(lng);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -773,6 +792,8 @@
Set<Integer> tempSet = FastSet.newInstance();
tempSet.add(intgr);
return tempSet;
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ return TimeDuration.fromNumber(intgr);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -800,6 +821,8 @@
Set<BigDecimal> tempSet = FastSet.newInstance();
tempSet.add(bigDec);
return tempSet;
+ } else if ("TimeDuration".equals(type) ||
"org.ofbiz.base.util.TimeDuration".equals(type)) {
+ return TimeDuration.fromNumber(bigDec);
} else {
throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
}
@@ -1000,6 +1023,31 @@
} else {
return simpleTypeConvert(nodeValue, type, format, timeZone,
locale, noTypeFail);
}
+ } else if (obj instanceof TimeDuration) {
+ TimeDuration duration = (TimeDuration) obj;
+ if ("String".equals(type) || "java.lang.String".equals(type)) {
+ return obj.toString();
+ }
+ long durationLong = TimeDuration.toLong(duration);
+ if ("BigDecimal".equals(type) ||
"java.math.BigDecimal".equals(type)) {
+ return BigDecimal.valueOf(durationLong);
+ } else if ("Double".equals(type) ||
"java.lang.Double".equals(type)) {
+ return Double.valueOf(durationLong);
+ } else if ("Float".equals(type) || "java.lang.Float".equals(type))
{
+ return Float.valueOf(durationLong);
+ } else if ("Long".equals(type) || "java.lang.Long".equals(type)) {
+ return Long.valueOf(durationLong);
+ } else if ("List".equals(type) || "java.util.List".equals(type)) {
+ List<TimeDuration> tempList = FastList.newInstance();
+ tempList.add(duration);
+ return tempList;
+ } else if ("Set".equals(type) || "java.util.Set".equals(type)) {
+ Set<TimeDuration> tempSet = FastSet.newInstance();
+ tempSet.add(duration);
+ return tempSet;
+ } else {
+ throw new GeneralException("Conversion from " + fromType + "
to " + type + " not currently supported");
+ }
} else {
// we can pretty much always do a conversion to a String, so do
that here
if ("String".equals(type) || "java.lang.String".equals(type)) {
Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java?rev=832574&r1=832573&r2=832574&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java
(original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java Tue
Nov 3 21:58:00 2009
@@ -21,9 +21,9 @@
import java.io.Serializable;
import com.ibm.icu.util.Calendar;
-/** A representation of a period of time. */
+/** An immutable representation of a period of time. */
@SuppressWarnings("serial")
-public class TimeDuration implements Serializable {
+public class TimeDuration implements Serializable, Comparable<TimeDuration> {
/** A <code>TimeDuration</code> instance that represents a zero time
duration. */
public static final TimeDuration ZeroTimeDuration = new NullDuration();
@@ -34,6 +34,7 @@
protected int days = 0;
protected int months = 0;
protected int years = 0;
+ protected boolean isNegative = false;
protected TimeDuration() {}
/**
@@ -81,11 +82,42 @@
return false;
}
+ /** Returns a <code>String</code> formatted as
+ * years:months:days:hours:minutes:seconds:millseconds.
+ */
@Override
public String toString() {
return this.years + ":" + this.months + ":" + this.days + ":" +
this.hours + ":" + this.minutes + ":" + this.seconds + ":" + this.millis;
}
+ public int compareTo(TimeDuration arg0) {
+ if (this == arg0) {
+ return 0;
+ }
+ Long thisLong = toLong(this);
+ Long thatLong = toLong(arg0);
+ return thisLong.compareTo(thatLong);
+ }
+
+ /** Returns <code>true</code> if this duration is negative.
+ *
+ * @return <code>true</code> if this duration is negative
+ */
+ public boolean isNegative() {
+ return this.isNegative;
+ }
+
+ /** Returns <code>true</code> if this duration is zero.
+ *
+ * @return <code>true</code> if this duration is zero
+ */
+ public boolean isZero() {
+ return this == ZeroTimeDuration || (this.millis == 0 && this.seconds
== 0 &&
+ this.minutes == 0 && this.hours == 0 && this.days == 0 &&
+ this.months == 0 && this.years == 0);
+
+ }
+
/** Returns the milliseconds in this time duration. */
public int millis() {
return this.millis;
@@ -217,6 +249,7 @@
this.days = Math.min(this.days, -this.days);
this.months = Math.min(this.months, -this.months);
this.years = Math.min(this.years, -this.years);
+ this.isNegative = true;
}
/** Returns a <code>TimeDuration</code> instance derived from a
<code>long</code>
@@ -230,10 +263,10 @@
* @return A <code>TimeDuration</code> instance
*/
public static TimeDuration fromLong(long millis) {
- TimeDuration duration = new TimeDuration();
if (millis == 0) {
- return duration;
+ return ZeroTimeDuration;
}
+ TimeDuration duration = new TimeDuration();
boolean isNegative = false;
if (millis < 0) {
isNegative = true;
@@ -264,12 +297,50 @@
return duration;
}
+ /** Returns a <code>TimeDuration</code> instance derived from a
<code>Number</code>
+ * instance. If <code>number</code> is <code>null</code>,
+ * returns a zero <code>TimeDuration</code>. <p>The years and months
portions of the
+ * returned object are based on a Gregorian calendar. <b>Note:</b> this
+ * method should not be used to calculate elapsed time - use the elapsed
+ * time constructor instead.</p>
+ *
+ * @param number A <code>Number</code> instance, can be <code>null</code>
+ * @return A <code>TimeDuration</code> instance
+ */
+ public static TimeDuration fromNumber(Number number) {
+ return number == null ? ZeroTimeDuration :
fromLong(number.longValue());
+ }
+
+ public static TimeDuration parseDuration(String duration) {
+ if (UtilValidate.isEmpty(duration)) {
+ return ZeroTimeDuration;
+ }
+ boolean isZero = true;
+ int[] intArray = {0, 0, 0, 0, 0, 0, 0};
+ int i = intArray.length - 1;
+ String[] strArray = duration.split(":");
+ for (int s = strArray.length - 1; s >= 0; s--) {
+ if (UtilValidate.isNotEmpty(strArray[s])) {
+ intArray[i] = Integer.parseInt(strArray[s].trim());
+ if (intArray[i] != 0) {
+ isZero = false;
+ }
+ }
+ i--;
+ }
+ if (isZero) {
+ return ZeroTimeDuration;
+ }
+ return new TimeDuration(intArray[0], intArray[1], intArray[2],
+ intArray[3], intArray[4], intArray[5], intArray[6]);
+ }
+
/** Returns a <code>long</code> value derived from a
<code>TimeDuration</code>
* instance. This method is intended to be used in tandem with the
* <code>fromLong</code> method.
*
* @param duration
- * @return the number number of milliseconds in the duration
+ * @return the duration encoded as a <code>long</code> value
*/
public static long toLong(TimeDuration duration) {
return
@@ -288,5 +359,9 @@
public Calendar addToCalendar(Calendar cal) {
return cal;
}
+ @Override
+ public boolean isZero() {
+ return true;
+ }
}
}
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java?rev=832574&r1=832573&r2=832574&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java
(original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java Tue
Nov 3 21:58:00 2009
@@ -41,7 +41,9 @@
import org.ofbiz.base.crypto.HashCrypt;
import org.ofbiz.base.util.Base64;
import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.TimeDuration;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilProperties;
@@ -407,6 +409,11 @@
}
} else if (value != null && !(value instanceof NULL)) {
// make sure the type matches the field Java type
+ if (value instanceof TimeDuration) {
+ try {
+ value = ObjectType.simpleTypeConvert(value,
type.getJavaType(), null, null);
+ } catch (GeneralException e) {}
+ }
if (!ObjectType.instanceOf(value, type.getJavaType())) {
String errMsg = "In entity field [" + this.getEntityName()
+ "." + name + "] set the value passed in [" + value.getClass().getName() + "]
is not compatible with the Java type of the field [" + type.getJavaType() + "]";
// eventually we should do this, but for now we'll do a
"soft" failure: throw new IllegalArgumentException(errMsg);
@@ -580,6 +587,30 @@
}
}
+ /** Returns the specified field as a <code>TimeDuration</code> instance.
+ * The field's Java data type can be either <code>String</code> or
+ * <code>Number</code>. Invalid Java data types will throw
+ * <code>IllegalArgumentException</code>.
+ *
+ * @param name The name of the desired field
+ * @return A <code>TimeDuration</code> instance or <code>null</code>
+ */
+ public TimeDuration getDuration(String name) {
+ Object obj = get(name);
+ if (obj == null) {
+ return null;
+ }
+ try {
+ Number number = (Number) obj;
+ return TimeDuration.fromNumber(number);
+ } catch (Exception e) {}
+ try {
+ String duration = (String) obj;
+ return TimeDuration.parseDuration(duration);
+ } catch (Exception e) {}
+ throw new IllegalArgumentException("getDuration could not map the
object '" + obj.toString() + "' to TimeDuration type, incompatible object type:
" + obj.getClass().getName());
+ }
+
public String getString(String name) {
// might be nice to add some ClassCastException handling... and auto
conversion? hmmm...
Object object = get(name);