1 | /* |
2 | * Copyright 2001-2005 Stephen Colebourne |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | package org.joda.time.field; |
17 | |
18 | import java.io.Serializable; |
19 | import java.util.HashMap; |
20 | import org.joda.time.DurationField; |
21 | import org.joda.time.DurationFieldType; |
22 | |
23 | /** |
24 | * A placeholder implementation to use when a duration field is not supported. |
25 | * <p> |
26 | * UnsupportedDurationField is thread-safe and immutable. |
27 | * |
28 | * @author Brian S O'Neill |
29 | * @since 1.0 |
30 | */ |
31 | public final class UnsupportedDurationField extends DurationField implements Serializable { |
32 | |
33 | /** Serialization lock. */ |
34 | private static final long serialVersionUID = -6390301302770925357L; |
35 | |
36 | /** The cache of unsupported duration field instances */ |
37 | private static HashMap cCache; |
38 | |
39 | /** |
40 | * Gets an instance of UnsupportedDurationField for a specific named field. |
41 | * The returned instance is cached. |
42 | * |
43 | * @param type the type to obtain |
44 | * @return the instance |
45 | */ |
46 | public static synchronized UnsupportedDurationField getInstance(DurationFieldType type) { |
47 | UnsupportedDurationField field; |
48 | if (cCache == null) { |
49 | cCache = new HashMap(7); |
50 | field = null; |
51 | } else { |
52 | field = (UnsupportedDurationField) cCache.get(type); |
53 | } |
54 | if (field == null) { |
55 | field = new UnsupportedDurationField(type); |
56 | cCache.put(type, field); |
57 | } |
58 | return field; |
59 | } |
60 | |
61 | /** The name of the field */ |
62 | private final DurationFieldType iType; |
63 | |
64 | /** |
65 | * Constructor. |
66 | * |
67 | * @param type the type to use |
68 | */ |
69 | private UnsupportedDurationField(DurationFieldType type) { |
70 | iType = type; |
71 | } |
72 | |
73 | //----------------------------------------------------------------------- |
74 | // Design note: Simple Accessors return a suitable value, but methods |
75 | // intended to perform calculations throw an UnsupportedOperationException. |
76 | |
77 | public final DurationFieldType getType() { |
78 | return iType; |
79 | } |
80 | |
81 | public String getName() { |
82 | return iType.getName(); |
83 | } |
84 | |
85 | /** |
86 | * This field is not supported. |
87 | * |
88 | * @return false always |
89 | */ |
90 | public boolean isSupported() { |
91 | return false; |
92 | } |
93 | |
94 | /** |
95 | * This field is precise. |
96 | * |
97 | * @return true always |
98 | */ |
99 | 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 | } |