[4231] | 1 | /*
|
---|
| 2 | * This is public domain software - that is, you can do whatever you want
|
---|
| 3 | * with it, and include it software that is licensed under the GNU or the
|
---|
| 4 | * BSD license, or whatever other licence you choose, including proprietary
|
---|
| 5 | * closed source licenses. I do ask that you leave this header in tact.
|
---|
| 6 | *
|
---|
| 7 | * If you make modifications to this code that you think would benefit the
|
---|
| 8 | * wider community, please send me a copy and I'll post it on my site.
|
---|
| 9 | *
|
---|
| 10 | * If you make use of this code, I'd appreciate hearing about it.
|
---|
| 11 | * drew@drewnoakes.com
|
---|
| 12 | * Latest version of this software kept at
|
---|
| 13 | * http://drewnoakes.com/
|
---|
| 14 | *
|
---|
| 15 | * Created by dnoakes on 25-Nov-2002 20:30:39 using IntelliJ IDEA.
|
---|
| 16 | */
|
---|
| 17 | package com.drew.metadata;
|
---|
| 18 |
|
---|
| 19 | import com.drew.lang.Rational;
|
---|
| 20 |
|
---|
| 21 | import java.io.Serializable;
|
---|
| 22 | import java.lang.reflect.Array;
|
---|
| 23 | import java.text.DateFormat;
|
---|
| 24 | import java.util.ArrayList;
|
---|
| 25 | import java.util.HashMap;
|
---|
| 26 | import java.util.Iterator;
|
---|
| 27 | import java.util.List;
|
---|
| 28 |
|
---|
| 29 | /**
|
---|
| 30 | * Base class for all Metadata directory types with supporting methods for setting and
|
---|
| 31 | * getting tag values.
|
---|
| 32 | */
|
---|
| 33 | public abstract class Directory implements Serializable
|
---|
| 34 | {
|
---|
| 35 | /**
|
---|
| 36 | * Map of values hashed by type identifiers.
|
---|
| 37 | */
|
---|
| 38 | protected final HashMap _tagMap;
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * The descriptor used to interperet tag values.
|
---|
| 42 | */
|
---|
| 43 | protected TagDescriptor _descriptor;
|
---|
| 44 |
|
---|
| 45 | /**
|
---|
| 46 | * A convenient list holding tag values in the order in which they were stored.
|
---|
| 47 | * This is used for creation of an iterator, and for counting the number of
|
---|
| 48 | * defined tags.
|
---|
| 49 | */
|
---|
| 50 | protected final List _definedTagList;
|
---|
| 51 |
|
---|
| 52 | private List _errorList;
|
---|
| 53 |
|
---|
| 54 | // ABSTRACT METHODS
|
---|
| 55 |
|
---|
| 56 | /**
|
---|
| 57 | * Provides the name of the directory, for display purposes. E.g. <code>Exif</code>
|
---|
| 58 | * @return the name of the directory
|
---|
| 59 | */
|
---|
| 60 | public abstract String getName();
|
---|
| 61 |
|
---|
| 62 | /**
|
---|
| 63 | * Provides the map of tag names, hashed by tag type identifier.
|
---|
| 64 | * @return the map of tag names
|
---|
| 65 | */
|
---|
| 66 | protected abstract HashMap getTagNameMap();
|
---|
| 67 |
|
---|
| 68 | // CONSTRUCTORS
|
---|
| 69 |
|
---|
| 70 | /**
|
---|
| 71 | * Creates a new Directory.
|
---|
| 72 | */
|
---|
| 73 | public Directory()
|
---|
| 74 | {
|
---|
| 75 | _tagMap = new HashMap();
|
---|
| 76 | _definedTagList = new ArrayList();
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | // VARIOUS METHODS
|
---|
| 80 |
|
---|
| 81 | /**
|
---|
| 82 | * Indicates whether the specified tag type has been set.
|
---|
| 83 | * @param tagType the tag type to check for
|
---|
| 84 | * @return true if a value exists for the specified tag type, false if not
|
---|
| 85 | */
|
---|
| 86 | public boolean containsTag(int tagType)
|
---|
| 87 | {
|
---|
| 88 | return _tagMap.containsKey(new Integer(tagType));
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | /**
|
---|
| 92 | * Returns an Iterator of Tag instances that have been set in this Directory.
|
---|
| 93 | * @return an Iterator of Tag instances
|
---|
| 94 | */
|
---|
| 95 | public Iterator getTagIterator()
|
---|
| 96 | {
|
---|
| 97 | return _definedTagList.iterator();
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | /**
|
---|
| 101 | * Returns the number of tags set in this Directory.
|
---|
| 102 | * @return the number of tags set in this Directory
|
---|
| 103 | */
|
---|
| 104 | public int getTagCount()
|
---|
| 105 | {
|
---|
| 106 | return _definedTagList.size();
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | /**
|
---|
| 110 | * Sets the descriptor used to interperet tag values.
|
---|
| 111 | * @param descriptor the descriptor used to interperet tag values
|
---|
| 112 | */
|
---|
| 113 | public void setDescriptor(TagDescriptor descriptor)
|
---|
| 114 | {
|
---|
| 115 | if (descriptor==null) {
|
---|
| 116 | throw new NullPointerException("cannot set a null descriptor");
|
---|
| 117 | }
|
---|
| 118 | _descriptor = descriptor;
|
---|
| 119 | }
|
---|
| 120 |
|
---|
| 121 | public void addError(String message)
|
---|
| 122 | {
|
---|
| 123 | if (_errorList==null) {
|
---|
| 124 | _errorList = new ArrayList();
|
---|
| 125 | }
|
---|
| 126 | _errorList.add(message);
|
---|
| 127 | }
|
---|
| 128 |
|
---|
| 129 | public boolean hasErrors()
|
---|
| 130 | {
|
---|
| 131 | return (_errorList!=null && _errorList.size()>0);
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | public Iterator getErrors()
|
---|
| 135 | {
|
---|
| 136 | return _errorList.iterator();
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | public int getErrorCount()
|
---|
| 140 | {
|
---|
| 141 | return _errorList.size();
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | // TAG SETTERS
|
---|
| 145 |
|
---|
| 146 | /**
|
---|
| 147 | * Sets an int value for the specified tag.
|
---|
| 148 | * @param tagType the tag's value as an int
|
---|
| 149 | * @param value the value for the specified tag as an int
|
---|
| 150 | */
|
---|
| 151 | public void setInt(int tagType, int value)
|
---|
| 152 | {
|
---|
| 153 | setObject(tagType, new Integer(value));
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | /**
|
---|
| 157 | * Sets a double value for the specified tag.
|
---|
| 158 | * @param tagType the tag's value as an int
|
---|
| 159 | * @param value the value for the specified tag as a double
|
---|
| 160 | */
|
---|
| 161 | public void setDouble(int tagType, double value)
|
---|
| 162 | {
|
---|
| 163 | setObject(tagType, new Double(value));
|
---|
| 164 | }
|
---|
| 165 |
|
---|
| 166 | /**
|
---|
| 167 | * Sets a float value for the specified tag.
|
---|
| 168 | * @param tagType the tag's value as an int
|
---|
| 169 | * @param value the value for the specified tag as a float
|
---|
| 170 | */
|
---|
| 171 | public void setFloat(int tagType, float value)
|
---|
| 172 | {
|
---|
| 173 | setObject(tagType, new Float(value));
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | /**
|
---|
| 177 | * Sets an int value for the specified tag.
|
---|
| 178 | * @param tagType the tag's value as an int
|
---|
| 179 | * @param value the value for the specified tag as a String
|
---|
| 180 | */
|
---|
| 181 | public void setString(int tagType, String value)
|
---|
| 182 | {
|
---|
| 183 | setObject(tagType, value);
|
---|
| 184 | }
|
---|
| 185 |
|
---|
| 186 | /**
|
---|
| 187 | * Sets an int value for the specified tag.
|
---|
| 188 | * @param tagType the tag's value as an int
|
---|
| 189 | * @param value the value for the specified tag as a boolean
|
---|
| 190 | */
|
---|
| 191 | public void setBoolean(int tagType, boolean value)
|
---|
| 192 | {
|
---|
| 193 | setObject(tagType, new Boolean(value));
|
---|
| 194 | }
|
---|
| 195 |
|
---|
| 196 | /**
|
---|
| 197 | * Sets a long value for the specified tag.
|
---|
| 198 | * @param tagType the tag's value as an int
|
---|
| 199 | * @param value the value for the specified tag as a long
|
---|
| 200 | */
|
---|
| 201 | public void setLong(int tagType, long value)
|
---|
| 202 | {
|
---|
| 203 | setObject(tagType, new Long(value));
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 | /**
|
---|
| 207 | * Sets a java.util.Date value for the specified tag.
|
---|
| 208 | * @param tagType the tag's value as an int
|
---|
| 209 | * @param value the value for the specified tag as a java.util.Date
|
---|
| 210 | */
|
---|
| 211 | public void setDate(int tagType, java.util.Date value)
|
---|
| 212 | {
|
---|
| 213 | setObject(tagType, value);
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | /**
|
---|
| 217 | * Sets a Rational value for the specified tag.
|
---|
| 218 | * @param tagType the tag's value as an int
|
---|
| 219 | * @param rational rational number
|
---|
| 220 | */
|
---|
| 221 | public void setRational(int tagType, Rational rational)
|
---|
| 222 | {
|
---|
| 223 | setObject(tagType, rational);
|
---|
| 224 | }
|
---|
| 225 |
|
---|
| 226 | /**
|
---|
| 227 | * Sets a Rational array for the specified tag.
|
---|
| 228 | * @param tagType the tag identifier
|
---|
| 229 | * @param rationals the Rational array to store
|
---|
| 230 | */
|
---|
| 231 | public void setRationalArray(int tagType, Rational[] rationals)
|
---|
| 232 | {
|
---|
| 233 | setObjectArray(tagType, rationals);
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 | /**
|
---|
| 237 | * Sets an int array for the specified tag.
|
---|
| 238 | * @param tagType the tag identifier
|
---|
| 239 | * @param ints the int array to store
|
---|
| 240 | */
|
---|
| 241 | public void setIntArray(int tagType, int[] ints)
|
---|
| 242 | {
|
---|
| 243 | setObjectArray(tagType, ints);
|
---|
| 244 | }
|
---|
| 245 |
|
---|
| 246 | /**
|
---|
| 247 | * Sets a byte array for the specified tag.
|
---|
| 248 | * @param tagType the tag identifier
|
---|
| 249 | * @param bytes the byte array to store
|
---|
| 250 | */
|
---|
| 251 | public void setByteArray(int tagType, byte[] bytes)
|
---|
| 252 | {
|
---|
| 253 | setObjectArray(tagType, bytes);
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | /**
|
---|
| 257 | * Sets a String array for the specified tag.
|
---|
| 258 | * @param tagType the tag identifier
|
---|
| 259 | * @param strings the String array to store
|
---|
| 260 | */
|
---|
| 261 | public void setStringArray(int tagType, String[] strings)
|
---|
| 262 | {
|
---|
| 263 | setObjectArray(tagType, strings);
|
---|
| 264 | }
|
---|
| 265 |
|
---|
| 266 | /**
|
---|
| 267 | * Private helper method, containing common functionality for all 'add'
|
---|
| 268 | * methods.
|
---|
| 269 | * @param tagType the tag's value as an int
|
---|
| 270 | * @param value the value for the specified tag
|
---|
| 271 | * @throws NullPointerException if value is <code>null</code>
|
---|
| 272 | */
|
---|
| 273 | public void setObject(int tagType, Object value)
|
---|
| 274 | {
|
---|
| 275 | if (value==null) {
|
---|
| 276 | throw new NullPointerException("cannot set a null object");
|
---|
| 277 | }
|
---|
| 278 |
|
---|
| 279 | Integer key = new Integer(tagType);
|
---|
| 280 | if (!_tagMap.containsKey(key)) {
|
---|
| 281 | _definedTagList.add(new Tag(tagType, this));
|
---|
| 282 | }
|
---|
| 283 | _tagMap.put(key, value);
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | /**
|
---|
| 287 | * Private helper method, containing common functionality for all 'add...Array'
|
---|
| 288 | * methods.
|
---|
| 289 | * @param tagType the tag's value as an int
|
---|
| 290 | * @param array the array of values for the specified tag
|
---|
| 291 | */
|
---|
| 292 | public void setObjectArray(int tagType, Object array)
|
---|
| 293 | {
|
---|
| 294 | // for now, we don't do anything special -- this method might be a candidate for removal once the dust settles
|
---|
| 295 | setObject(tagType, array);
|
---|
| 296 | }
|
---|
| 297 |
|
---|
| 298 | // TAG GETTERS
|
---|
| 299 |
|
---|
| 300 | /**
|
---|
| 301 | * Returns the specified tag's value as an int, if possible.
|
---|
| 302 | */
|
---|
| 303 | public int getInt(int tagType) throws MetadataException
|
---|
| 304 | {
|
---|
| 305 | Object o = getObject(tagType);
|
---|
| 306 | if (o==null) {
|
---|
| 307 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 308 | } else if (o instanceof String) {
|
---|
| 309 | try {
|
---|
| 310 | return Integer.parseInt((String)o);
|
---|
| 311 | } catch (NumberFormatException nfe) {
|
---|
| 312 | // convert the char array to an int
|
---|
| 313 | String s = (String)o;
|
---|
| 314 | byte[] bytes = s.getBytes();
|
---|
| 315 | long val = 0;
|
---|
| 316 | for (int i = 0; i < bytes.length; i++) {
|
---|
| 317 | val = val << 8;
|
---|
| 318 | val += bytes[i];
|
---|
| 319 | }
|
---|
| 320 | return (int)val;
|
---|
| 321 | }
|
---|
| 322 | } else if (o instanceof Number) {
|
---|
| 323 | return ((Number)o).intValue();
|
---|
| 324 | } else if (o instanceof Rational[]) {
|
---|
| 325 | Rational[] rationals = (Rational[])o;
|
---|
| 326 | if (rationals.length==1)
|
---|
| 327 | return rationals[0].intValue();
|
---|
| 328 | } else if (o instanceof byte[]) {
|
---|
| 329 | byte[] bytes = (byte[])o;
|
---|
| 330 | if (bytes.length==1)
|
---|
| 331 | return bytes[0];
|
---|
| 332 | } else if (o instanceof int[]) {
|
---|
| 333 | int[] ints = (int[])o;
|
---|
| 334 | if (ints.length==1)
|
---|
| 335 | return ints[0];
|
---|
| 336 | }
|
---|
| 337 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to int. It is of type '" + o.getClass() + "'.");
|
---|
| 338 | }
|
---|
| 339 |
|
---|
| 340 | // TODO get Array methods need to return cloned data, to maintain this directory's integrity
|
---|
| 341 |
|
---|
| 342 | /**
|
---|
| 343 | * Gets the specified tag's value as a String array, if possible. Only supported
|
---|
| 344 | * where the tag is set as String[], String, int[], byte[] or Rational[].
|
---|
| 345 | * @param tagType the tag identifier
|
---|
| 346 | * @return the tag's value as an array of Strings
|
---|
| 347 | * @throws MetadataException if the tag has not been set or cannot be represented
|
---|
| 348 | * as a String[]
|
---|
| 349 | */
|
---|
| 350 | public String[] getStringArray(int tagType) throws MetadataException
|
---|
| 351 | {
|
---|
| 352 | Object o = getObject(tagType);
|
---|
| 353 | if (o==null) {
|
---|
| 354 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 355 | } else if (o instanceof String[]) {
|
---|
| 356 | return (String[])o;
|
---|
| 357 | } else if (o instanceof String) {
|
---|
| 358 | String[] strings = {(String)o};
|
---|
| 359 | return strings;
|
---|
| 360 | } else if (o instanceof int[]) {
|
---|
| 361 | int[] ints = (int[])o;
|
---|
| 362 | String[] strings = new String[ints.length];
|
---|
| 363 | for (int i = 0; i<strings.length; i++) {
|
---|
| 364 | strings[i] = Integer.toString(ints[i]);
|
---|
| 365 | }
|
---|
| 366 | return strings;
|
---|
| 367 | } else if (o instanceof byte[]) {
|
---|
| 368 | byte[] bytes = (byte[])o;
|
---|
| 369 | String[] strings = new String[bytes.length];
|
---|
| 370 | for (int i = 0; i<strings.length; i++) {
|
---|
| 371 | strings[i] = Byte.toString(bytes[i]);
|
---|
| 372 | }
|
---|
| 373 | return strings;
|
---|
| 374 | } else if (o instanceof Rational[]) {
|
---|
| 375 | Rational[] rationals = (Rational[])o;
|
---|
| 376 | String[] strings = new String[rationals.length];
|
---|
| 377 | for (int i = 0; i<strings.length; i++) {
|
---|
| 378 | strings[i] = rationals[i].toSimpleString(false);
|
---|
| 379 | }
|
---|
| 380 | return strings;
|
---|
| 381 | }
|
---|
| 382 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to an String array. It is of type '" + o.getClass() + "'.");
|
---|
| 383 | }
|
---|
| 384 |
|
---|
| 385 | /**
|
---|
| 386 | * Gets the specified tag's value as an int array, if possible. Only supported
|
---|
| 387 | * where the tag is set as String, int[], byte[] or Rational[].
|
---|
| 388 | * @param tagType the tag identifier
|
---|
| 389 | * @return the tag's value as an int array
|
---|
| 390 | * @throws MetadataException if the tag has not been set, or cannot be converted to
|
---|
| 391 | * an int array
|
---|
| 392 | */
|
---|
| 393 | public int[] getIntArray(int tagType) throws MetadataException
|
---|
| 394 | {
|
---|
| 395 | Object o = getObject(tagType);
|
---|
| 396 | if (o==null) {
|
---|
| 397 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 398 | } else if (o instanceof Rational[]) {
|
---|
| 399 | Rational[] rationals = (Rational[])o;
|
---|
| 400 | int[] ints = new int[rationals.length];
|
---|
| 401 | for (int i = 0; i<ints.length; i++) {
|
---|
| 402 | ints[i] = rationals[i].intValue();
|
---|
| 403 | }
|
---|
| 404 | return ints;
|
---|
| 405 | } else if (o instanceof int[]) {
|
---|
| 406 | return (int[])o;
|
---|
| 407 | } else if (o instanceof byte[]) {
|
---|
| 408 | byte[] bytes = (byte[])o;
|
---|
| 409 | int[] ints = new int[bytes.length];
|
---|
| 410 | for (int i = 0; i<bytes.length; i++) {
|
---|
| 411 | byte b = bytes[i];
|
---|
| 412 | ints[i] = b;
|
---|
| 413 | }
|
---|
| 414 | return ints;
|
---|
| 415 | } else if (o instanceof String) {
|
---|
| 416 | String str = (String)o;
|
---|
| 417 | int[] ints = new int[str.length()];
|
---|
| 418 | for (int i = 0; i<str.length(); i++) {
|
---|
| 419 | ints[i] = str.charAt(i);
|
---|
| 420 | }
|
---|
| 421 | return ints;
|
---|
| 422 | }
|
---|
| 423 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to an int array. It is of type '" + o.getClass() + "'.");
|
---|
| 424 | }
|
---|
| 425 |
|
---|
| 426 | /**
|
---|
| 427 | * Gets the specified tag's value as an byte array, if possible. Only supported
|
---|
| 428 | * where the tag is set as String, int[], byte[] or Rational[].
|
---|
| 429 | * @param tagType the tag identifier
|
---|
| 430 | * @return the tag's value as a byte array
|
---|
| 431 | * @throws MetadataException if the tag has not been set, or cannot be converted to
|
---|
| 432 | * a byte array
|
---|
| 433 | */
|
---|
| 434 | public byte[] getByteArray(int tagType) throws MetadataException
|
---|
| 435 | {
|
---|
| 436 | Object o = getObject(tagType);
|
---|
| 437 | if (o==null) {
|
---|
| 438 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 439 | } else if (o instanceof Rational[]) {
|
---|
| 440 | Rational[] rationals = (Rational[])o;
|
---|
| 441 | byte[] bytes = new byte[rationals.length];
|
---|
| 442 | for (int i = 0; i<bytes.length; i++) {
|
---|
| 443 | bytes[i] = rationals[i].byteValue();
|
---|
| 444 | }
|
---|
| 445 | return bytes;
|
---|
| 446 | } else if (o instanceof byte[]) {
|
---|
| 447 | return (byte[])o;
|
---|
| 448 | } else if (o instanceof int[]) {
|
---|
| 449 | int[] ints = (int[])o;
|
---|
| 450 | byte[] bytes = new byte[ints.length];
|
---|
| 451 | for (int i = 0; i<ints.length; i++) {
|
---|
| 452 | bytes[i] = (byte)ints[i];
|
---|
| 453 | }
|
---|
| 454 | return bytes;
|
---|
| 455 | } else if (o instanceof String) {
|
---|
| 456 | String str = (String)o;
|
---|
| 457 | byte[] bytes = new byte[str.length()];
|
---|
| 458 | for (int i = 0; i<str.length(); i++) {
|
---|
| 459 | bytes[i] = (byte)str.charAt(i);
|
---|
| 460 | }
|
---|
| 461 | return bytes;
|
---|
| 462 | }
|
---|
| 463 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a byte array. It is of type '" + o.getClass() + "'.");
|
---|
| 464 | }
|
---|
| 465 |
|
---|
| 466 | /**
|
---|
| 467 | * Returns the specified tag's value as a double, if possible.
|
---|
| 468 | */
|
---|
| 469 | public double getDouble(int tagType) throws MetadataException
|
---|
| 470 | {
|
---|
| 471 | Object o = getObject(tagType);
|
---|
| 472 | if (o==null) {
|
---|
| 473 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 474 | } else if (o instanceof String) {
|
---|
| 475 | try {
|
---|
| 476 | return Double.parseDouble((String)o);
|
---|
| 477 | } catch (NumberFormatException nfe) {
|
---|
| 478 | throw new MetadataException("unable to parse string " + o + " as a double", nfe);
|
---|
| 479 | }
|
---|
| 480 | } else if (o instanceof Number) {
|
---|
| 481 | return ((Number)o).doubleValue();
|
---|
| 482 | }
|
---|
| 483 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a double. It is of type '" + o.getClass() + "'.");
|
---|
| 484 | }
|
---|
| 485 |
|
---|
| 486 | /**
|
---|
| 487 | * Returns the specified tag's value as a float, if possible.
|
---|
| 488 | */
|
---|
| 489 | public float getFloat(int tagType) throws MetadataException
|
---|
| 490 | {
|
---|
| 491 | Object o = getObject(tagType);
|
---|
| 492 | if (o==null) {
|
---|
| 493 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 494 | } else if (o instanceof String) {
|
---|
| 495 | try {
|
---|
| 496 | return Float.parseFloat((String)o);
|
---|
| 497 | } catch (NumberFormatException nfe) {
|
---|
| 498 | throw new MetadataException("unable to parse string " + o + " as a float", nfe);
|
---|
| 499 | }
|
---|
| 500 | } else if (o instanceof Number) {
|
---|
| 501 | return ((Number)o).floatValue();
|
---|
| 502 | }
|
---|
| 503 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a float. It is of type '" + o.getClass() + "'.");
|
---|
| 504 | }
|
---|
| 505 |
|
---|
| 506 | /**
|
---|
| 507 | * Returns the specified tag's value as a long, if possible.
|
---|
| 508 | */
|
---|
| 509 | public long getLong(int tagType) throws MetadataException
|
---|
| 510 | {
|
---|
| 511 | Object o = getObject(tagType);
|
---|
| 512 | if (o==null) {
|
---|
| 513 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 514 | } else if (o instanceof String) {
|
---|
| 515 | try {
|
---|
| 516 | return Long.parseLong((String)o);
|
---|
| 517 | } catch (NumberFormatException nfe) {
|
---|
| 518 | throw new MetadataException("unable to parse string " + o + " as a long", nfe);
|
---|
| 519 | }
|
---|
| 520 | } else if (o instanceof Number) {
|
---|
| 521 | return ((Number)o).longValue();
|
---|
| 522 | }
|
---|
| 523 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a long. It is of type '" + o.getClass() + "'.");
|
---|
| 524 | }
|
---|
| 525 |
|
---|
| 526 | /**
|
---|
| 527 | * Returns the specified tag's value as a boolean, if possible.
|
---|
| 528 | */
|
---|
| 529 | public boolean getBoolean(int tagType) throws MetadataException
|
---|
| 530 | {
|
---|
| 531 | Object o = getObject(tagType);
|
---|
| 532 | if (o==null) {
|
---|
| 533 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 534 | } else if (o instanceof Boolean) {
|
---|
| 535 | return ((Boolean)o).booleanValue();
|
---|
| 536 | } else if (o instanceof String) {
|
---|
| 537 | try {
|
---|
| 538 | return Boolean.getBoolean((String)o);
|
---|
| 539 | } catch (NumberFormatException nfe) {
|
---|
| 540 | throw new MetadataException("unable to parse string " + o + " as a boolean", nfe);
|
---|
| 541 | }
|
---|
| 542 | } else if (o instanceof Number) {
|
---|
| 543 | return (((Number)o).doubleValue()!=0);
|
---|
| 544 | }
|
---|
| 545 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a boolean. It is of type '" + o.getClass() + "'.");
|
---|
| 546 | }
|
---|
| 547 |
|
---|
| 548 | /**
|
---|
| 549 | * Returns the specified tag's value as a java.util.Date, if possible.
|
---|
| 550 | */
|
---|
| 551 | public java.util.Date getDate(int tagType) throws MetadataException
|
---|
| 552 | {
|
---|
| 553 | Object o = getObject(tagType);
|
---|
| 554 | if (o==null) {
|
---|
| 555 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 556 | } else if (o instanceof java.util.Date) {
|
---|
| 557 | return (java.util.Date)o;
|
---|
| 558 | } else if (o instanceof String) {
|
---|
| 559 | // add new dateformat strings to make this method even smarter
|
---|
| 560 | // so far, this seems to cover all known date strings
|
---|
| 561 | // (for example, AM and PM strings are not supported...)
|
---|
| 562 | String datePatterns[] = {
|
---|
| 563 | "yyyy:MM:dd HH:mm:ss",
|
---|
| 564 | "yyyy:MM:dd HH:mm",
|
---|
| 565 | "yyyy-MM-dd HH:mm:ss",
|
---|
| 566 | "yyyy-MM-dd HH:mm"};
|
---|
| 567 | String dateString = (String)o;
|
---|
| 568 | for (int i = 0; i<datePatterns.length; i++) {
|
---|
| 569 | try {
|
---|
| 570 | DateFormat parser = new java.text.SimpleDateFormat(datePatterns[i]);
|
---|
| 571 | return parser.parse(dateString);
|
---|
| 572 | } catch (java.text.ParseException ex) {
|
---|
| 573 | // simply try the next pattern
|
---|
| 574 | }
|
---|
| 575 | }
|
---|
| 576 | }
|
---|
| 577 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a java.util.Date. It is of type '" + o.getClass() + "'.");
|
---|
| 578 | }
|
---|
| 579 |
|
---|
| 580 | /**
|
---|
| 581 | * Returns the specified tag's value as a Rational, if possible.
|
---|
| 582 | */
|
---|
| 583 | public Rational getRational(int tagType) throws MetadataException
|
---|
| 584 | {
|
---|
| 585 | Object o = getObject(tagType);
|
---|
| 586 | if (o==null) {
|
---|
| 587 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 588 | } else if (o instanceof Rational) {
|
---|
| 589 | return (Rational)o;
|
---|
| 590 | }
|
---|
| 591 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a Rational. It is of type '" + o.getClass() + "'.");
|
---|
| 592 | }
|
---|
| 593 |
|
---|
| 594 | public Rational[] getRationalArray(int tagType) throws MetadataException
|
---|
| 595 | {
|
---|
| 596 | Object o = getObject(tagType);
|
---|
| 597 | if (o==null) {
|
---|
| 598 | throw new MetadataException("Tag " + getTagName(tagType) + " has not been set -- check using containsTag() first");
|
---|
| 599 | } else if (o instanceof Rational[]) {
|
---|
| 600 | return (Rational[])o;
|
---|
| 601 | }
|
---|
| 602 | throw new MetadataException("Tag '" + tagType + "' cannot be cast to a Rational array. It is of type '" + o.getClass() + "'.");
|
---|
| 603 | }
|
---|
| 604 |
|
---|
| 605 | /**
|
---|
| 606 | * Returns the specified tag's value as a String. This value is the 'raw' value. A more presentable decoding
|
---|
| 607 | * of this value may be obtained from the corresponding Descriptor.
|
---|
| 608 | * @return the String reprensentation of the tag's value, or
|
---|
| 609 | * <code>null</code> if the tag hasn't been defined.
|
---|
| 610 | */
|
---|
| 611 | public String getString(int tagType)
|
---|
| 612 | {
|
---|
| 613 | Object o = getObject(tagType);
|
---|
| 614 | if (o==null)
|
---|
| 615 | return null;
|
---|
| 616 |
|
---|
| 617 | if (o instanceof Rational)
|
---|
| 618 | return ((Rational)o).toSimpleString(true);
|
---|
| 619 |
|
---|
| 620 | if (o.getClass().isArray())
|
---|
| 621 | {
|
---|
| 622 | // handle arrays of objects and primitives
|
---|
| 623 | int arrayLength = Array.getLength(o);
|
---|
| 624 | // determine if this is an array of objects i.e. [Lcom.drew.blah
|
---|
| 625 | boolean isObjectArray = o.getClass().toString().startsWith("class [L");
|
---|
| 626 | StringBuffer sbuffer = new StringBuffer();
|
---|
| 627 | for (int i = 0; i<arrayLength; i++)
|
---|
| 628 | {
|
---|
| 629 | if (i!=0)
|
---|
| 630 | sbuffer.append(' ');
|
---|
| 631 | if (isObjectArray)
|
---|
| 632 | sbuffer.append(Array.get(o, i).toString());
|
---|
| 633 | else
|
---|
| 634 | sbuffer.append(Array.getInt(o, i));
|
---|
| 635 | }
|
---|
| 636 | return sbuffer.toString();
|
---|
| 637 | }
|
---|
| 638 |
|
---|
| 639 | return o.toString();
|
---|
| 640 | }
|
---|
| 641 |
|
---|
| 642 | /**
|
---|
| 643 | * Returns the object hashed for the particular tag type specified, if available.
|
---|
| 644 | * @param tagType the tag type identifier
|
---|
| 645 | * @return the tag's value as an Object if available, else null
|
---|
| 646 | */
|
---|
| 647 | public Object getObject(int tagType)
|
---|
| 648 | {
|
---|
| 649 | return _tagMap.get(new Integer(tagType));
|
---|
| 650 | }
|
---|
| 651 |
|
---|
| 652 | // OTHER METHODS
|
---|
| 653 |
|
---|
| 654 | /**
|
---|
| 655 | * Returns the name of a specified tag as a String.
|
---|
| 656 | * @param tagType the tag type identifier
|
---|
| 657 | * @return the tag's name as a String
|
---|
| 658 | */
|
---|
| 659 | public String getTagName(int tagType)
|
---|
| 660 | {
|
---|
| 661 | Integer key = new Integer(tagType);
|
---|
| 662 | HashMap nameMap = getTagNameMap();
|
---|
| 663 | if (!nameMap.containsKey(key)) {
|
---|
| 664 | String hex = Integer.toHexString(tagType);
|
---|
| 665 | while (hex.length()<4) {
|
---|
| 666 | hex = "0" + hex;
|
---|
| 667 | }
|
---|
| 668 | return "Unknown tag (0x" + hex + ")";
|
---|
| 669 | }
|
---|
| 670 | return (String)nameMap.get(key);
|
---|
| 671 | }
|
---|
| 672 |
|
---|
| 673 | /**
|
---|
| 674 | * Provides a description of a tag's value using the descriptor set by
|
---|
| 675 | * <code>setDescriptor(Descriptor)</code>.
|
---|
| 676 | * @param tagType the tag type identifier
|
---|
| 677 | * @return the tag value's description as a String
|
---|
| 678 | * @throws MetadataException if a descriptor hasn't been set, or if an error
|
---|
| 679 | * occurs during calculation of the description within the Descriptor
|
---|
| 680 | */
|
---|
| 681 | public String getDescription(int tagType) throws MetadataException
|
---|
| 682 | {
|
---|
| 683 | if (_descriptor==null) {
|
---|
| 684 | throw new MetadataException("a descriptor must be set using setDescriptor(...) before descriptions can be provided");
|
---|
| 685 | }
|
---|
| 686 |
|
---|
| 687 | return _descriptor.getDescription(tagType);
|
---|
| 688 | }
|
---|
| 689 | }
|
---|