001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.calendar;
023:
024: import java.io.Serializable;
025: import java.util.HashMap;
026: import java.util.Map;
027: import java.util.Properties;
028:
029: import org.jbpm.JbpmException;
030:
031: /**
032: * interpretes textual descriptions of a duration.
033: * <p>Syntax: <quantity> [business] <unit> <br />
034: * Where
035: * <ul>
036: * <li><quantity> is a piece of text that is parsable
037: * with <code>Double.parseDouble(quantity)</code>.
038: * </li>
039: * <li><unit> is one of {second, seconds, minute, minutes,
040: * hour, hours, day, days, week, weeks, month, months, year, years}.
041: * </li>
042: * <li>And adding the optional indication <code>business</code> means that
043: * only business hours should be taken into account for this duration.
044: * </li>
045: * </ul>
046: * </p>
047: */
048: public class Duration implements Serializable {
049:
050: private static final long serialVersionUID = 1L;
051:
052: static final long SECOND = 1000;
053: static final long MINUTE = 60 * SECOND;
054: static final long HOUR = 60 * MINUTE;
055: static final long DAY = 24 * HOUR;
056: static final long WEEK = 7 * DAY;
057: static final long MONTH = 30 * DAY;
058: static final long YEAR = 365 * DAY;
059:
060: static long BUSINESS_DAY = -1;
061: static long BUSINESS_WEEK = -1;
062: static long BUSINESS_MONTH = -1;
063: static long BUSINESS_YEAR = -1;
064:
065: static {
066: Properties businessCalendarProperties = BusinessCalendar
067: .getBusinessCalendarProperties();
068: String businessDayText = businessCalendarProperties
069: .getProperty("business.day.expressed.in.hours");
070: String businessWeekText = businessCalendarProperties
071: .getProperty("business.week.expressed.in.hours");
072: String businessMonthText = businessCalendarProperties
073: .getProperty("business.month.expressed.in.business.days");
074: String businessYearText = businessCalendarProperties
075: .getProperty("business.year.expressed.in.business.days");
076:
077: BUSINESS_DAY = (long) (Double.parseDouble(businessDayText) * HOUR);
078: BUSINESS_WEEK = (long) (Double.parseDouble(businessWeekText) * HOUR);
079: BUSINESS_MONTH = (long) (Double.parseDouble(businessMonthText) * BUSINESS_DAY);
080: BUSINESS_YEAR = (long) (Double.parseDouble(businessYearText) * BUSINESS_DAY);
081: }
082:
083: static Map units = null;
084: static {
085: units = new HashMap();
086: units.put("second", new Long(SECOND));
087: units.put("seconds", new Long(SECOND));
088: units.put("business second", new Long(SECOND));
089: units.put("business seconds", new Long(SECOND));
090: units.put("minute", new Long(MINUTE));
091: units.put("minutes", new Long(MINUTE));
092: units.put("business minute", new Long(MINUTE));
093: units.put("business minutes", new Long(MINUTE));
094: units.put("hour", new Long(HOUR));
095: units.put("hours", new Long(HOUR));
096: units.put("business hour", new Long(HOUR));
097: units.put("business hours", new Long(HOUR));
098: units.put("day", new Long(DAY));
099: units.put("days", new Long(DAY));
100: units.put("business day", new Long(BUSINESS_DAY));
101: units.put("business days", new Long(BUSINESS_DAY));
102: units.put("week", new Long(WEEK));
103: units.put("weeks", new Long(WEEK));
104: units.put("business week", new Long(BUSINESS_WEEK));
105: units.put("business weeks", new Long(BUSINESS_WEEK));
106: units.put("month", new Long(MONTH));
107: units.put("months", new Long(MONTH));
108: units.put("business month", new Long(BUSINESS_MONTH));
109: units.put("business months", new Long(BUSINESS_MONTH));
110: units.put("year", new Long(YEAR));
111: units.put("years", new Long(YEAR));
112: units.put("business year", new Long(BUSINESS_YEAR));
113: units.put("business years", new Long(BUSINESS_YEAR));
114: }
115:
116: long milliseconds = 0;
117: boolean isBusinessTime = false;
118:
119: Duration() {
120: }
121:
122: public Duration(long milliseconds) {
123: this .milliseconds = milliseconds;
124: }
125:
126: public Duration(Duration duration) {
127: this .milliseconds = duration.milliseconds;
128: this .isBusinessTime = duration.isBusinessTime;
129: }
130:
131: /**
132: * creates a duration from a textual description.
133: * syntax: {number} space {unit}
134: * where number is parsable to a java.lang.Number and
135: * unit is one of
136: * <ul>
137: * <li>second</li>
138: * <li>seconds</li>
139: * <li>minute</li>
140: * <li>minutes</li>
141: * <li>hour</li>
142: * <li>hours</li>
143: * <li>day</li>
144: * <li>days</li>
145: * <li>week</li>
146: * <li>weeks</li>
147: * <li>month (30 days)</li>
148: * <li>months (30 days)</li>
149: * <li>year (355 days)</li>
150: * <li>years (355 days)</li>
151: * </ul>
152: */
153: public Duration(String duration) {
154: if (duration == null)
155: throw new JbpmException("duration is null");
156: int separatorIndex = duration.indexOf(' ');
157: if (separatorIndex == -1)
158: throw new IllegalArgumentException(
159: "improper format of duration '" + duration + "'");
160: String quantityText = duration.substring(0, separatorIndex)
161: .trim().toLowerCase();
162: String unitText = duration.substring(separatorIndex + 1).trim()
163: .toLowerCase();
164: if (unitText.startsWith("business")) {
165: isBusinessTime = true;
166: }
167: double amount = Double.parseDouble(quantityText);
168: Long unit = (Long) units.get(unitText);
169: if (unit == null)
170: throw new IllegalArgumentException(
171: "improper format of duration '" + duration + "'");
172: this .milliseconds = (long) (amount * unit.longValue());
173: }
174: }
|