001/*
002 *  Copyright 2001-2005 Stephen Colebourne
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.joda.time.field;
017
018import org.joda.time.Chronology;
019import org.joda.time.DateTimeField;
020
021/**
022 * Wraps another field such that a certain value is added back into
023 * the sequence of numbers.
024 * <p>
025 * This reverses the effect of SkipDateTimeField. This isn't very
026 * elegant.
027 * <p>
028 * SkipUndoDateTimeField is thread-safe and immutable.
029 *
030 * @author Brian S O'Neill
031 * @author Stephen Colebourne
032 * @since 1.0
033 */
034public final class SkipUndoDateTimeField extends DelegatedDateTimeField {
035
036    /** Serialization version. */
037    private static final long serialVersionUID = -5875876968979L;
038
039    /** The chronology to wrap. */
040    private final Chronology iChronology;
041    /** The value to skip. */
042    private final int iSkip;
043    /** The calculated minimum value. */
044    private transient int iMinValue;
045
046    /**
047     * Constructor that reinserts zero.
048     * 
049     * @param chronology  the chronoogy to use
050     * @param field  the field to skip zero on
051     */
052    public SkipUndoDateTimeField(Chronology chronology, DateTimeField field) {
053        this(chronology, field, 0);
054    }
055
056    /**
057     * Constructor.
058     * 
059     * @param chronology  the chronoogy to use
060     * @param field  the field to skip zero on
061     * @param skip  the value to skip
062     */
063    public SkipUndoDateTimeField(Chronology chronology, DateTimeField field, int skip) {
064        super(field);
065        iChronology = chronology;
066        int min = super.getMinimumValue();
067        if (min < skip) {
068            iMinValue = min + 1;
069        } else if (min == skip + 1) {
070            iMinValue = skip;
071        } else {
072            iMinValue = min;
073        }
074        iSkip = skip;
075    }
076
077    //-----------------------------------------------------------------------
078    public int get(long millis) {
079        int value = super.get(millis);
080        if (value < iSkip) {
081            value++;
082        }
083        return value;
084    }
085
086    public long set(long millis, int value) {
087        FieldUtils.verifyValueBounds(this, value, iMinValue, getMaximumValue());
088        if (value <= iSkip) {
089            value--;
090        }
091        return super.set(millis, value);
092    }
093
094    public int getMinimumValue() {
095        return iMinValue;
096    }
097
098    private Object readResolve() {
099        return getType().getField(iChronology);
100    }
101
102}