001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
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 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.api.model;
020
021/**
022 * Value holding a base {@link Long} value and a delta.
023 * <p>
024 * This is used when the actual intent of the value is to be an incremental update to an existing value.
025 *
026 * @since 6.0
027 */
028public class DeltaLong extends Delta {
029
030    private static final long serialVersionUID = 1L;
031
032    private final Long base;
033
034    private final long delta;
035
036    /**
037     * A {@link DeltaLong} with the given base and delta.
038     */
039    public DeltaLong(Long base, long delta) {
040        this.base = base;
041        this.delta = delta;
042    }
043
044    /**
045     * A {@link DeltaLong} with the given base and delta.
046     *
047     * @deprecated since 8.3, use {@link #DeltaLong(Long, long)} instead.
048     */
049    @Deprecated
050    public DeltaLong(long base, long delta) {
051        this.base = Long.valueOf(base);
052        this.delta = delta;
053    }
054
055    /**
056     * Returns a {@link DeltaLong} from the given base number and delta.
057     * <p>
058     * The base number may be a {@link Long} (which may be null), or a {@link DeltaLong}. If it is a {@link DeltaLong}
059     * then the returned value will keep its base and just add deltas.
060     *
061     * @param base the base number
062     * @param delta the delta
063     * @return a {@link DeltaLong}
064     */
065    public static DeltaLong valueOf(Number base, long delta) {
066        if (base == null || base instanceof Long) {
067            return new DeltaLong((Long) base, delta);
068        } else if (base instanceof DeltaLong) {
069            DeltaLong dl = (DeltaLong) base;
070            if (delta == 0) {
071                return dl;
072            } else {
073                return new DeltaLong(dl.base, dl.delta + delta);
074            }
075        } else {
076            throw new IllegalArgumentException(base.getClass().getName());
077        }
078    }
079
080    /**
081     * Returns a {@link DeltaLong} from the given base number and delta.
082     * <p>
083     * The base number may be a {@link Long} (which may be null), or a {@link DeltaLong}. If it is a {@link DeltaLong}
084     * then the returned value will keep its base and just add deltas.
085     *
086     * @param base the base number
087     * @param delta the delta
088     * @return a {@link DeltaLong}
089     * @deprecated since 8.3, use {@link #valueOf(Number, long)} instead.
090     */
091    @Deprecated
092    public static DeltaLong deltaOrLong(Number base, long delta) {
093        return valueOf(base, delta);
094    }
095
096    @Override
097    public Delta add(Delta other) {
098        if (!(other instanceof DeltaLong)) {
099            throw new IllegalArgumentException("Cannot add " + getClass().getSimpleName() + " and "
100                    + other.getClass().getSimpleName());
101        }
102        return new DeltaLong(base, delta + ((DeltaLong) other).delta);
103    }
104
105    @Override
106    public Number add(Number other) {
107        if (!(other instanceof Long)) {
108            throw new IllegalArgumentException("Cannot add " + getClass().getSimpleName() + " and "
109                    + other.getClass().getSimpleName());
110        }
111        return Long.valueOf(((Long) other).longValue() + delta);
112    }
113
114    @Override
115    public Long getBase() {
116        return base;
117    }
118
119    // @Override
120    public long getDelta() {
121        return delta;
122    }
123
124    @Override
125    public Long getDeltaValue() {
126        return Long.valueOf(delta);
127    }
128
129    @Override
130    public Long getFullValue() {
131        return Long.valueOf(longValue());
132    }
133
134    @Override
135    public long longValue() {
136        return base == null ? delta : base.longValue() + delta;
137    }
138
139    @Override
140    public int intValue() {
141        return (int) longValue();
142    }
143
144    @Override
145    public float floatValue() {
146        return longValue();
147    }
148
149    @Override
150    public double doubleValue() {
151        return longValue();
152    }
153
154    @Override
155    public String toString() {
156        return Long.toString(longValue());
157    }
158
159    @Override
160    public boolean equals(Object obj) {
161        if (obj instanceof DeltaLong) {
162            DeltaLong dl = (DeltaLong) obj;
163            if (delta != dl.delta) {
164                return false;
165            }
166            return base == null ? dl.base == null : base.equals(dl.base);
167        }
168        return false;
169    }
170
171    @Override
172    public int hashCode() {
173        int result = 31;
174        if (base != null) {
175            long b = base.longValue();
176            result += (int) (b ^ (b >>> 32));
177        }
178        return 31 * result + (int) (delta ^ (delta >>> 32));
179    }
180
181}