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 */
016 package org.joda.time.field;
017
018 import java.io.Serializable;
019 import java.util.HashMap;
020 import org.joda.time.DurationField;
021 import org.joda.time.DurationFieldType;
022
023 /**
024 * A placeholder implementation to use when a duration field is not supported.
025 * <p>
026 * UnsupportedDurationField is thread-safe and immutable.
027 *
028 * @author Brian S O'Neill
029 * @since 1.0
030 */
031 public final class UnsupportedDurationField extends DurationField implements Serializable {
032
033 /** Serialization lock. */
034 private static final long serialVersionUID = -6390301302770925357L;
035
036 /** The cache of unsupported duration field instances */
037 private static HashMap cCache;
038
039 /**
040 * Gets an instance of UnsupportedDurationField for a specific named field.
041 * The returned instance is cached.
042 *
043 * @param type the type to obtain
044 * @return the instance
045 */
046 public static synchronized UnsupportedDurationField getInstance(DurationFieldType type) {
047 UnsupportedDurationField field;
048 if (cCache == null) {
049 cCache = new HashMap(7);
050 field = null;
051 } else {
052 field = (UnsupportedDurationField) cCache.get(type);
053 }
054 if (field == null) {
055 field = new UnsupportedDurationField(type);
056 cCache.put(type, field);
057 }
058 return field;
059 }
060
061 /** The name of the field */
062 private final DurationFieldType iType;
063
064 /**
065 * Constructor.
066 *
067 * @param type the type to use
068 */
069 private UnsupportedDurationField(DurationFieldType type) {
070 iType = type;
071 }
072
073 //-----------------------------------------------------------------------
074 // Design note: Simple Accessors return a suitable value, but methods
075 // intended to perform calculations throw an UnsupportedOperationException.
076
077 public final DurationFieldType getType() {
078 return iType;
079 }
080
081 public String getName() {
082 return iType.getName();
083 }
084
085 /**
086 * This field is not supported.
087 *
088 * @return false always
089 */
090 public boolean isSupported() {
091 return false;
092 }
093
094 /**
095 * This field is precise.
096 *
097 * @return true always
098 */
099 public boolean isPrecise() {
100 return true;
101 }
102
103 /**
104 * Always throws UnsupportedOperationException
105 *
106 * @throws UnsupportedOperationException
107 */
108 public int getValue(long duration) {
109 throw unsupported();
110 }
111
112 /**
113 * Always throws UnsupportedOperationException
114 *
115 * @throws UnsupportedOperationException
116 */
117 public long getValueAsLong(long duration) {
118 throw unsupported();
119 }
120
121 /**
122 * Always throws UnsupportedOperationException
123 *
124 * @throws UnsupportedOperationException
125 */
126 public int getValue(long duration, long instant) {
127 throw unsupported();
128 }
129
130 /**
131 * Always throws UnsupportedOperationException
132 *
133 * @throws UnsupportedOperationException
134 */
135 public long getValueAsLong(long duration, long instant) {
136 throw unsupported();
137 }
138
139 /**
140 * Always throws UnsupportedOperationException
141 *
142 * @throws UnsupportedOperationException
143 */
144 public long getMillis(int value) {
145 throw unsupported();
146 }
147
148 /**
149 * Always throws UnsupportedOperationException
150 *
151 * @throws UnsupportedOperationException
152 */
153 public long getMillis(long value) {
154 throw unsupported();
155 }
156
157 /**
158 * Always throws UnsupportedOperationException
159 *
160 * @throws UnsupportedOperationException
161 */
162 public long getMillis(int value, long instant) {
163 throw unsupported();
164 }
165
166 /**
167 * Always throws UnsupportedOperationException
168 *
169 * @throws UnsupportedOperationException
170 */
171 public long getMillis(long value, long instant) {
172 throw unsupported();
173 }
174
175 /**
176 * Always throws UnsupportedOperationException
177 *
178 * @throws UnsupportedOperationException
179 */
180 public long add(long instant, int value) {
181 throw unsupported();
182 }
183
184 /**
185 * Always throws UnsupportedOperationException
186 *
187 * @throws UnsupportedOperationException
188 */
189 public long add(long instant, long value) {
190 throw unsupported();
191 }
192
193 /**
194 * Always throws UnsupportedOperationException
195 *
196 * @throws UnsupportedOperationException
197 */
198 public int getDifference(long minuendInstant, long subtrahendInstant) {
199 throw unsupported();
200 }
201
202 /**
203 * Always throws UnsupportedOperationException
204 *
205 * @throws UnsupportedOperationException
206 */
207 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) {
208 throw unsupported();
209 }
210
211 /**
212 * Always returns zero.
213 *
214 * @return zero always
215 */
216 public long getUnitMillis() {
217 return 0;
218 }
219
220 /**
221 * Always returns zero, indicating that sort order is not relevent.
222 *
223 * @return zero always
224 */
225 public int compareTo(Object durationField) {
226 return 0;
227 }
228
229 //------------------------------------------------------------------------
230 /**
231 * Compares this duration field to another.
232 *
233 * @param obj the object to compare to
234 * @return true if equal
235 */
236 public boolean equals(Object obj) {
237 if (this == obj) {
238 return true;
239 } else if (obj instanceof UnsupportedDurationField) {
240 UnsupportedDurationField other = (UnsupportedDurationField) obj;
241 if (other.getName() == null) {
242 return (getName() == null);
243 }
244 return (other.getName().equals(getName()));
245 }
246 return false;
247 }
248
249 /**
250 * Gets a suitable hashcode.
251 *
252 * @return the hashcode
253 */
254 public int hashCode() {
255 return getName().hashCode();
256 }
257
258 /**
259 * Get a suitable debug string.
260 *
261 * @return debug string
262 */
263 public String toString() {
264 return "UnsupportedDurationField[" + getName() + ']';
265 }
266
267 /**
268 * Ensure proper singleton serialization
269 */
270 private Object readResolve() {
271 return getInstance(iType);
272 }
273
274 private UnsupportedOperationException unsupported() {
275 return new UnsupportedOperationException(iType + " field is unsupported");
276 }
277
278 }