/* * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Intalio, Inc. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Intalio, Inc. Exolab is a registered * trademark of Intalio, Inc. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2000 (C) Intalio, Inc. All Rights Reserved. * * $Id$ * Date Author Changes * 12/05/2000 Arnaud Blandin Added the support for NotSupportedOperationException * 11/07/2000 Arnaud Blandin Added a new constructor and setValues method * 11/02/2000 Arnaud Blandin Changed the constructor * 26/10/2000 Arnaud Blandin Created */ package org.exolab.castor.types; import org.exolab.castor.types.TimeDuration; import org.exolab.castor.xml.ValidationException; import java.text.ParseException; import javax.naming.OperationNotSupportedException; /** * The base class for recurring Duration types. * <p> * This base class contains all the time fields (including the time zone ones) * and also the facets period and duration * <p> * The validation of the time fields is done in the set methods and follows <a * href="http://www.iso.ch/markete/8601.pdf">the ISO8601 Date and Time Format</a> * * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a> * @see RecurringDuration * @see Time * @see TimeInstant * @see TimePeriod * @deprecated since Castor 1.0.6 since type derived from this base class are * not in any recommendation. */ public abstract class RecurringDurationBase implements java.io.Serializable { /** the period facet of this recurringDuration. */ private TimeDuration _period = null; /** the duration facet of this recurringDuration. */ private TimeDuration _duration = null; /** the hour field of this recurringDuration. * -1 means that the field has been omitted (cf section 4.5 of ISO 8601) */ private short _hour = 0; /** the minute field of this recurringDuration. * -1 means that the field has been omitted (cf section 4.5 of ISO 8601) */ private short _minute = 0; /** the second field of this recurringDuration. * -1 means that the field has been omitted (cf section 4.5 of ISO 8601) */ private short _second = 0; /** the millsecond field of this recurringDuration. */ private short _millsecond = 0; /** the time zone hour field of this recurringDuration. */ private short _zoneHour = 0; /** the time zone minute field of this recurringDuration. */ private short _zoneMinute = 0; /** true if this recurringDuration is UTC related. */ private boolean _utc = false; /** true if the time zone is negative. */ private boolean _zoneNegative = false; /** true if the recurring duration is negative. */ private boolean _isNegative = false; /** * No-arg constructor. */ protected RecurringDurationBase() { // Nothing to do } /** * Returns a recurringDurationBase with the facets duration and period set. * * @param duration * the TimeDuration representing the duration facet * @param period * the TimeDuration reprensenting the period facet */ protected RecurringDurationBase(TimeDuration duration, TimeDuration period) { try { this.setDuration(duration); this.setPeriodInternal(period); } catch (UnsupportedOperationException e) { String err = "Recurring Duration: " + e; throw new IllegalArgumentException(err); } } /** * returns a recurringDurationBase with the facets duration and period set * up * * @param duration * the String representing the duration facet * @param period * the String reprensenting the period facet * @throws IllegalArgumentException * this exception is thrown when the parameter strings are not * corresponding to valid TimeDuration */ protected RecurringDurationBase(String duration, String period) throws IllegalArgumentException { try { this.setDuration(TimeDuration.parseTimeDuration(duration)); this.setPeriodInternal(TimeDuration.parseTimeDuration(period)); } catch (Exception e) { String err = "In RecurringDurationBase: " + e; throw new IllegalArgumentException(err); } } /** * returns a recurringDurationBase with the facets duration and period set * up but also the fields * * @param duration * the String representing the duration facet * @param period * the String reprensenting the period facet * @param values * an array of shorts which contains the values of the fields * @throws IllegalArgumentException * this exception is thrown when the values array is not of * length 6. * @see #setValues */ protected RecurringDurationBase(String duration, String period, short[] values) throws OperationNotSupportedException { new RecurringDuration(duration, period); if (values.length != 6) { throw new IllegalArgumentException("Wrong numbers of values"); } this.setValues(values); } /** * set the period facet this recurringDuration this method is used to avoid * calling the setPeriod method of subclasses * * @param period * the period to set */ private void setPeriodInternal (TimeDuration period) { _period = period; } /** * set the period facet for this recurringDuration * * @param period * the period to set * @throws OperationNotSupportedException * this exception is thrown when changing the value of the * period facet is not allowed */ public void setPeriod (TimeDuration period) throws UnsupportedOperationException { setPeriodInternal(period); } /** * set the period facet for this recurringDuration * * @param period * the period to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the * period facet is not allowed */ public void setPeriod (String period) throws UnsupportedOperationException { try { setPeriodInternal(TimeDuration.parseTimeDuration(period)); } catch (ParseException e) { String err = "RecurringDuration, setPeriod: " + e; throw new IllegalArgumentException(err); } } /** * set the duration facet for this recurringDuration * * @param duration * the period to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the * duration facet is not allowed */ public void setDuration(TimeDuration duration) throws UnsupportedOperationException { _duration = duration; } /** * set the duration facet for this recurringDuration * * @param duration * the period to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the * duration facet is not allowed */ public void setDuration(String duration) throws UnsupportedOperationException { try { _duration = TimeDuration.parseTimeDuration(duration); } catch (ParseException e) { String err = "RecurringDuration, setDuration: " + e; throw new IllegalArgumentException(err); } } /** * set the hour field for this recurringDuration * * @param hour * the hour to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the hour * field is not allowed */ public void setHour(short hour) throws UnsupportedOperationException { String err = ""; if (hour > 23) { err = "the hour field ("+hour+")must be strictly lower than 24"; throw new IllegalArgumentException(err); } _hour = hour; } /** * set the minute field for this recurringDuration * * @param minute * the minute to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the * minute field is not allowed */ public void setMinute(short minute) throws UnsupportedOperationException { String err = ""; if (minute == -1 && _hour != -1) { err = "minute cannot be omitted if the previous field is not omitted."; throw new IllegalArgumentException(err); } else if (minute > 59) { err = "the minute field ("+minute+") must be lower than 59"; throw new IllegalArgumentException(err); } _minute = minute ; } /** * set the second field for this recurringDuration * * @param second * the second to set * @param millsecond * the millisecond to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the * second field is not allowed */ public void setSecond(short second,short millsecond) throws UnsupportedOperationException { String err = ""; if ( (second == -1) && (_minute != -1)) { err = "second cannot be omitted if the previous field is not omitted."; throw new IllegalArgumentException(err); } else if (second > 60) { err = "the second field ("+second+")must be lower than 60"; throw new IllegalArgumentException(err); } _second = second; _millsecond = millsecond; } /** * set the time zone fields for this recurringDuration * * @param hour * the time zone hour to set * @param minute * the time zone minute to set * @throws UnsupportedOperationException * this exception is thrown when changing the value of the time * zone fields is not allowed */ public void setZone(short hour, short minute) throws UnsupportedOperationException { String err = ""; if (hour > 23) { err = "the zone hour field ("+hour+")must be strictly lower than 24"; throw new IllegalArgumentException(err); } _zoneHour = hour; if (minute > 59) { err = "the minute field ("+minute+")must be lower than 59"; throw new IllegalArgumentException(err); } _zoneMinute = minute; } /** * set all the fields by reading the values in an array * * @param values * an array of shorts with the values the array is supposed to be * of length 6 and ordered like that: * <ul> * <li>hour</li> * <li>minute</li> * <li>second</li> * <li>millisecond</li> * <li>zoneHour</li> * <li>zoneMinute</li> * </ul> * @throws UnsupportedOperationException * this exception is thrown when changing the value of a time * related field is not allowed */ public void setValues(short[] values) throws UnsupportedOperationException { this.setHour(values[0]); this.setMinute(values[1]); this.setSecond(values[2], values[3]); this.setZone(values[4], values[5]); } /** * set the negative field to true */ public void setNegative() { _isNegative = true; } /** * set the time zone negative field to true * * @throws UnsupportedOperationException * this exception is thrown when changing the time zone fields * is not allowed */ public void setZoneNegative() throws UnsupportedOperationException { _zoneNegative = true; } /** * set the UTC field to true */ public void setUTC() { _utc = true; } //Get methods public TimeDuration getPeriod() { return _period; } public TimeDuration getDuration() { return _duration; } public short getHour() { return _hour; } public short getMinute() { return _minute; } public short getSeconds() { return _second; } public short getMilli() { return _millsecond; } public short getZoneHour() { return _zoneHour; } public short getZoneMinute() { return _zoneMinute; } /** * returns an array of short with all the fields which describe a * RecurringDurationBase * * @return an array of short with all the fields which describe a * RecurringDurationBase */ public short[] getValues() { short[] result = new short[6]; result[0] = this.getHour(); result[1] = this.getMinute(); result[2] = this.getSeconds(); result[3] = this.getMilli(); result[4] = this.getZoneHour(); result[5] = this.getZoneMinute(); return result; } //getValues /** * return true if this recurring Duration type is UTC i.e if there is no time zone. * * @return true if this recurringDuration type is UTC else false. */ public boolean isUTC() { _utc = _zoneHour == 0 && _zoneMinute == 0; return _utc; } public boolean isNegative() { return _isNegative; } public boolean isZoneNegative() { return _zoneNegative; } /** * {@inheritDoc} * Override the java.lang.equals method * @see #equal */ public boolean equals(Object object) { if (object instanceof RecurringDurationBase) { try { return equal( (RecurringDurationBase) object); } catch (ValidationException e) { e.printStackTrace(); return false; } } return false; } /** * Returns true if the present instance of Recurring Duration Base is equal * to the parameter. * <p> * The equals relation is the following : * <tt>rd1 equals rd2 iff each field of rd1 is equal to the corresponding field of rd2 </tt> * * @param reccD * the recurring duration to compare with the present instance * @return true if the present instance is equal to the parameter false if * not */ public boolean equal(RecurringDurationBase reccD) throws ValidationException { boolean result = false; if (!(this.getPeriod().equals(reccD.getPeriod())) || !(this.getDuration().equals(reccD.getDuration()))) { String err = "Recurring Duration which have different values " + "for the duration and period can not be compared"; throw new ValidationException(err); } result = (this.getHour() == reccD.getHour()); result = result && (this.getMinute() == reccD.getMinute()); result = result && (this.getSeconds() == reccD.getSeconds()); result = result && (this.getMilli() == reccD.getMilli()); result = result && (this.isNegative() == this.isNegative()); if (!reccD.isUTC()) { result = result && (!this.isUTC()); result = result && (this.getZoneHour() == reccD.getZoneHour()); result = result && (this.getZoneMinute() == reccD.getZoneMinute()); } return result; }//equals /** * Returns true if the present instance of RecurringDurationBase is greater * than the parameter * <p> * Note : the order relation follows the W3C XML Schema draft i.e * <tt>rd1 < rd2 iff rd2-rd1>0</tt> * * @param reccD * the recurring duration base to compare with the present * instance * @return true if the present instance is the greatest, false if not */ public boolean isGreater(RecurringDurationBase reccD) throws ValidationException { if (!(this.getPeriod().equals(reccD.getPeriod())) || !(this.getDuration().equals(reccD.getDuration()))) { String err = "Recurring Duration which have different values " + "for the duration and period can not be compared"; throw new ValidationException(err); } boolean result = false; short[] val_this = this.getValues(); short[] val_reccD = reccD.getValues(); for (int i = 0; result != true || i < val_this.length; i++) { result = val_this[i] > val_reccD[i]; if (val_this[i] < val_reccD[i]) { return false; } } return result; } //isGreater }//-- RecurringDurationBase