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