Coverage Report - org.jaudiotagger.tag.asf.AsfTag
 
Classes in this File Line Coverage Branch Coverage Complexity
AsfTag
87%
146/167
63%
30/47
2.114
AsfTag$1
100%
1/1
N/A
2.114
AsfTag$AsfFieldIterator
77%
7/9
50%
2/4
2.114
 
 1  
 package org.jaudiotagger.tag.asf;
 2  
 
 3  
 import org.jaudiotagger.audio.asf.data.AsfHeader;
 4  
 import org.jaudiotagger.tag.asf.AsfTagField;
 5  
 import org.jaudiotagger.tag.asf.AsfTagTextField;
 6  
 import org.jaudiotagger.tag.asf.AsfTagCoverField;
 7  
 import org.jaudiotagger.audio.generic.AbstractTag;
 8  
 import org.jaudiotagger.logging.ErrorMessage;
 9  
 import org.jaudiotagger.tag.*;
 10  
 import org.jaudiotagger.tag.asf.AsfFieldKey;
 11  
 import org.jaudiotagger.tag.datatype.Artwork;
 12  
 import org.jaudiotagger.tag.reference.PictureTypes;
 13  
 
 14  
 import java.io.UnsupportedEncodingException;
 15  
 import java.util.*;
 16  
 
 17  
 /**
 18  
  * Tag implementation for ASF.<br>
 19  
  * 
 20  
  * @author Christian Laireiter
 21  
  */
 22  689
 public final class AsfTag extends AbstractTag {
 23  
     /**
 24  
      * This iterator is used to iterator an {@link Iterator} with
 25  
      * {@link TagField} objects and returns them by casting to
 26  
      * {@link AsfTagField}.<br>
 27  
      * 
 28  
      * @author Christian Laireiter
 29  
      */
 30  2540
     private static class AsfFieldIterator implements Iterator<AsfTagField> {
 31  
 
 32  
         /**
 33  
          * source iterator.
 34  
          */
 35  
         private final Iterator<TagField> fieldIterator;
 36  
 
 37  
         /**
 38  
          * Creates an isntance.
 39  
          * 
 40  
          * @param iterator
 41  
          *            iterator to read from.
 42  
          */
 43  153
         public AsfFieldIterator(final Iterator<TagField> iterator) {
 44  153
             assert iterator != null;
 45  153
             this.fieldIterator = iterator;
 46  153
         }
 47  
 
 48  
         /**
 49  
          * {@inheritDoc}
 50  
          */
 51  
         public boolean hasNext() {
 52  2689
             return this.fieldIterator.hasNext();
 53  
         }
 54  
 
 55  
         /**
 56  
          * {@inheritDoc}
 57  
          */
 58  
         public AsfTagField next() {
 59  2536
             return (AsfTagField) this.fieldIterator.next();
 60  
         }
 61  
 
 62  
         /**
 63  
          * {@inheritDoc}
 64  
          */
 65  
         public void remove() {
 66  0
             this.fieldIterator.remove();
 67  0
         }
 68  
     }
 69  
 
 70  
     /**
 71  
      * Stores a list of field keys, which identify common fields.<br>
 72  
      */
 73  
     public final static Set<AsfFieldKey> COMMON_FIELDS;
 74  
 
 75  
     /**
 76  
      * This map contains the mapping from {@link org.jaudiotagger.tag.FieldKey} to
 77  
      * {@link AsfFieldKey}.
 78  
      */
 79  
     private static final EnumMap<FieldKey, AsfFieldKey> TAGFIELD_TO_ASFFIELD;
 80  
 
 81  
     // Mapping from generic key to asf key
 82  
     static {
 83  4
         TAGFIELD_TO_ASFFIELD = new EnumMap<FieldKey, AsfFieldKey>(
 84  
                 FieldKey.class);
 85  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ARTIST, AsfFieldKey.AUTHOR);
 86  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ALBUM, AsfFieldKey.ALBUM);
 87  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.TITLE, AsfFieldKey.TITLE);
 88  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.TRACK, AsfFieldKey.TRACK);
 89  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.YEAR, AsfFieldKey.YEAR);
 90  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.GENRE, AsfFieldKey.GENRE);
 91  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.COMMENT, AsfFieldKey.DESCRIPTION);
 92  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ALBUM_ARTIST,
 93  
                 AsfFieldKey.ALBUM_ARTIST);
 94  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.COMPOSER, AsfFieldKey.COMPOSER);
 95  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.GROUPING, AsfFieldKey.GROUPING);
 96  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.DISC_NO, AsfFieldKey.DISC_NO);
 97  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.BPM, AsfFieldKey.BPM);
 98  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ENCODER, AsfFieldKey.ENCODER);
 99  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_ARTISTID,
 100  
                 AsfFieldKey.MUSICBRAINZ_ARTISTID);
 101  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_RELEASEID,
 102  
                 AsfFieldKey.MUSICBRAINZ_RELEASEID);
 103  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_RELEASEARTISTID,
 104  
                 AsfFieldKey.MUSICBRAINZ_RELEASEARTISTID);
 105  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_TRACK_ID,
 106  
                 AsfFieldKey.MUSICBRAINZ_TRACK_ID);
 107  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_DISC_ID,
 108  
                 AsfFieldKey.MUSICBRAINZ_DISC_ID);
 109  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICIP_ID, AsfFieldKey.MUSICIP_ID);
 110  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.AMAZON_ID, AsfFieldKey.AMAZON_ID);
 111  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_RELEASE_STATUS,
 112  
                 AsfFieldKey.MUSICBRAINZ_RELEASE_STATUS);
 113  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_RELEASE_TYPE,
 114  
                 AsfFieldKey.MUSICBRAINZ_RELEASE_TYPE);
 115  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MUSICBRAINZ_RELEASE_COUNTRY,
 116  
                 AsfFieldKey.MUSICBRAINZ_RELEASE_COUNTRY);
 117  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.LYRICS, AsfFieldKey.LYRICS);
 118  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.IS_COMPILATION,
 119  
                 AsfFieldKey.IS_COMPILATION);
 120  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ARTIST_SORT, AsfFieldKey.ARTIST_SORT);
 121  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ALBUM_ARTIST_SORT,
 122  
                 AsfFieldKey.ALBUM_ARTIST_SORT);
 123  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ALBUM_SORT, AsfFieldKey.ALBUM_SORT);
 124  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.TITLE_SORT, AsfFieldKey.TITLE_SORT);
 125  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.COMPOSER_SORT,
 126  
                 AsfFieldKey.COMPOSER_SORT);
 127  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.COVER_ART, AsfFieldKey.COVER_ART);
 128  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.ISRC, AsfFieldKey.ISRC);
 129  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.CATALOG_NO, AsfFieldKey.CATALOG_NO);
 130  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.BARCODE, AsfFieldKey.BARCODE);
 131  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.RECORD_LABEL,
 132  
                 AsfFieldKey.RECORD_LABEL);
 133  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.LYRICIST, AsfFieldKey.LYRICIST);
 134  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.CONDUCTOR, AsfFieldKey.CONDUCTOR);
 135  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.REMIXER, AsfFieldKey.REMIXER);
 136  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MOOD, AsfFieldKey.MOOD);
 137  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.MEDIA, AsfFieldKey.MEDIA);
 138  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_OFFICIAL_RELEASE_SITE,
 139  
                 AsfFieldKey.URL_OFFICIAL_RELEASE_SITE);
 140  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_DISCOGS_RELEASE_SITE,
 141  
                 AsfFieldKey.URL_DISCOGS_RELEASE_SITE);
 142  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_WIKIPEDIA_RELEASE_SITE,
 143  
                 AsfFieldKey.URL_WIKIPEDIA_RELEASE_SITE);
 144  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_OFFICIAL_ARTIST_SITE,
 145  
                 AsfFieldKey.URL_OFFICIAL_ARTIST_SITE);
 146  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_DISCOGS_ARTIST_SITE,
 147  
                 AsfFieldKey.URL_DISCOGS_ARTIST_SITE);
 148  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_WIKIPEDIA_ARTIST_SITE,
 149  
                 AsfFieldKey.URL_WIKIPEDIA_ARTIST_SITE);
 150  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.LANGUAGE, AsfFieldKey.LANGUAGE);
 151  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.KEY, AsfFieldKey.INITIAL_KEY);
 152  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.URL_LYRICS_SITE, AsfFieldKey.URL_LYRICS_SITE);
 153  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.TRACK_TOTAL, AsfFieldKey.TRACK_TOTAL);
 154  4
         TAGFIELD_TO_ASFFIELD.put(FieldKey.DISC_TOTAL, AsfFieldKey.DISC_TOTAL);
 155  
     }
 156  
 
 157  
     static {
 158  4
         COMMON_FIELDS = new HashSet<AsfFieldKey>();
 159  4
         COMMON_FIELDS.add(AsfFieldKey.ALBUM);
 160  4
         COMMON_FIELDS.add(AsfFieldKey.AUTHOR);
 161  4
         COMMON_FIELDS.add(AsfFieldKey.DESCRIPTION);
 162  4
         COMMON_FIELDS.add(AsfFieldKey.GENRE);
 163  4
         COMMON_FIELDS.add(AsfFieldKey.TITLE);
 164  4
         COMMON_FIELDS.add(AsfFieldKey.TRACK);
 165  4
         COMMON_FIELDS.add(AsfFieldKey.YEAR);
 166  4
     }
 167  
 
 168  
     /**
 169  
      * @see #isCopyingFields()
 170  
      */
 171  
     private final boolean copyFields;
 172  
 
 173  
     /**
 174  
      * Creates an empty instance.
 175  
      */
 176  
     public AsfTag() {
 177  20
         this(false);
 178  20
     }
 179  
 
 180  
     /**
 181  
      * Creates an instance and sets the field conversion property.<br>
 182  
      * 
 183  
      * @param copy
 184  
      *            look at {@link #isCopyingFields()}.
 185  
      */
 186  
     public AsfTag(final boolean copy) {
 187  443
         super();
 188  443
         this.copyFields = copy;
 189  443
     }
 190  
 
 191  
     /**
 192  
      * Creates an instance and copies the fields of the source into the own
 193  
      * structure.<br>
 194  
      * 
 195  
      * @param source
 196  
      *            source to read tag fields from.
 197  
      * @param copy
 198  
      *            look at {@link #isCopyingFields()}.
 199  
      * @throws UnsupportedEncodingException
 200  
      *             {@link TagField#getRawContent()} which may be called
 201  
      */
 202  
     public AsfTag(final Tag source, final boolean copy)
 203  
             throws UnsupportedEncodingException {
 204  133
         this(copy);
 205  133
         copyFrom(source);
 206  133
     }
 207  
 
 208  
     /**
 209  
      * {@inheritDoc}
 210  
      */
 211  
     @Override
 212  
     // TODO introduce copy idea to all formats
 213  
     public void addField(final TagField field) {
 214  5765
         if (isValidField(field)) {
 215  5516
             if (AsfFieldKey.isMultiValued(field.getId())) {
 216  2880
                 super.addField(copyFrom(field));
 217  
             } else {
 218  2636
                 super.setField(copyFrom(field));
 219  
             }
 220  
         }
 221  5765
     }
 222  
 
 223  
     /**
 224  
      * Creates a field for copyright and adds it.<br>
 225  
      * 
 226  
      * @param copyRight
 227  
      *            copyright content
 228  
      */
 229  
     public void addCopyright(final String copyRight) {
 230  8
         addField(createCopyrightField(copyRight));
 231  8
     }
 232  
 
 233  
     /**
 234  
      * Creates a field for rating and adds it.<br>
 235  
      * 
 236  
      * @param rating
 237  
      *            rating.
 238  
      */
 239  
     public void addRating(final String rating) {
 240  8
         addField(createRatingField(rating));
 241  8
     }
 242  
 
 243  
     /**
 244  
      * This method copies tag fields from the source.<br>
 245  
      * 
 246  
      * @param source
 247  
      *            source to read tag fields from.
 248  
      */
 249  
     private void copyFrom(final Tag source) {
 250  133
         final Iterator<TagField> fieldIterator = source.getFields();
 251  
         // iterate over all fields
 252  2485
         while (fieldIterator.hasNext()) {
 253  2352
             final TagField copy = copyFrom(fieldIterator.next());
 254  2352
             if (copy != null) {
 255  2352
                 super.addField(copy);
 256  
             }
 257  2352
         }
 258  133
     }
 259  
 
 260  
     /**
 261  
      * If {@link #isCopyingFields()} is <code>true</code>, Creates a copy of
 262  
      * <code>source</code>, if its not empty-<br>
 263  
      * However, plain {@link TagField} objects can only be transformed into
 264  
      * binary fields using their {@link TagField#getRawContent()} method.<br>
 265  
      * 
 266  
      * @param source
 267  
      *            source field to copy.
 268  
      * @return A copy, which is as close to the source as possible, or
 269  
      *         <code>null</code> if the field is empty (empty byte[] or blank
 270  
      *         string}.
 271  
      */
 272  
     private TagField copyFrom(final TagField source) {
 273  
         TagField result;
 274  8401
         if (isCopyingFields()) {
 275  8393
             if (source instanceof AsfTagField) {
 276  
                 try {
 277  8393
                     result = (TagField) ((AsfTagField) source).clone();
 278  0
                 } catch (CloneNotSupportedException e) {
 279  0
                     result = new AsfTagField(((AsfTagField) source)
 280  
                             .getDescriptor());
 281  8393
                 }
 282  0
             } else if (source instanceof TagTextField) {
 283  0
                 final String content = ((TagTextField) source).getContent();
 284  0
                 result = new AsfTagTextField(source.getId(), content);
 285  0
             } else {
 286  0
                 throw new RuntimeException("Unknown Asf Tag Field class:" // NOPMD
 287  
                         // by
 288  
                         // Christian
 289  
                         // Laireiter
 290  
                         // on
 291  
                         // 5/9/09
 292  
                         // 5:44
 293  
                         // PM
 294  
                         + source.getClass());
 295  
             }
 296  
         } else {
 297  8
             result = source;
 298  
         }
 299  8401
         return result;
 300  
     }
 301  
 
 302  
 
 303  
 
 304  
     /**
 305  
      * Creates an {@link AsfTagCoverField} from given artwork
 306  
      * 
 307  
      * @param artwork
 308  
      *            artwork to create a ASF field from.
 309  
      * 
 310  
      * @return ASF field capable of storing artwork.
 311  
      */
 312  
     public AsfTagCoverField createField(final Artwork artwork) {
 313  8
         return new AsfTagCoverField(artwork.getBinaryData(), artwork
 314  
                 .getPictureType(), artwork.getDescription(), artwork
 315  
                 .getMimeType());
 316  
     }
 317  
 
 318  
     /**
 319  
      * Create artwork field
 320  
      * 
 321  
      * @param data
 322  
      *            raw image data
 323  
      * @return creates a default ASF picture field with default
 324  
      *         {@linkplain PictureTypes#DEFAULT_ID picture type}.
 325  
      */
 326  
     public AsfTagCoverField createArtworkField(final byte[] data) {
 327  4
         return new AsfTagCoverField(data, PictureTypes.DEFAULT_ID, null, null);
 328  
     }
 329  
 
 330  
     /**
 331  
      * Creates a field for storing the copyright.<br>
 332  
      * 
 333  
      * @param content
 334  
      *            Copyright value.
 335  
      * @return {@link AsfTagTextField}
 336  
      */
 337  
     public AsfTagTextField createCopyrightField(final String content) {
 338  20
         return new AsfTagTextField(AsfFieldKey.COPYRIGHT, content);
 339  
     }
 340  
 
 341  
     /**
 342  
      * Creates a field for storing the copyright.<br>
 343  
      * 
 344  
      * @param content
 345  
      *            Rating value.
 346  
      * @return {@link AsfTagTextField}
 347  
      */
 348  
     public AsfTagTextField createRatingField(final String content) {
 349  20
         return new AsfTagTextField(AsfFieldKey.RATING, content);
 350  
     }
 351  
 
 352  
     /**
 353  
      * Create tag text field using ASF key
 354  
      * <p/>
 355  
      * Uses the correct subclass for the key.<br>
 356  
      * 
 357  
      * @param asfFieldKey
 358  
      *            field key to create field for.
 359  
      * @param value
 360  
      *            string value for the created field.
 361  
      * @return text field with given content.
 362  
      */
 363  
     public AsfTagTextField createField(final AsfFieldKey asfFieldKey,
 364  
             final String value) {
 365  777
         if (value == null) {
 366  0
             throw new IllegalArgumentException(
 367  
                     ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 368  
         }
 369  777
         if (asfFieldKey == null) {
 370  0
             throw new IllegalArgumentException(
 371  
                     ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 372  
         }
 373  777
         switch (asfFieldKey) {
 374  
         case COVER_ART:
 375  4
             throw new UnsupportedOperationException(
 376  
                     "Cover Art cannot be created using this method");
 377  
         case BANNER_IMAGE:
 378  0
             throw new UnsupportedOperationException(
 379  
                     "Banner Image cannot be created using this method");
 380  
         default:
 381  773
             return new AsfTagTextField(asfFieldKey.getFieldName(), value);
 382  
         }
 383  
     }
 384  
 
 385  
     /**
 386  
      * {@inheritDoc}
 387  
      */
 388  
     @Override
 389  
     public AsfTagTextField createField(final FieldKey genericKey,
 390  
             final String value) throws KeyNotFoundException,
 391  
             FieldDataInvalidException {
 392  745
         if (value == null) {
 393  0
             throw new IllegalArgumentException(
 394  
                     ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 395  
         }
 396  745
         if (genericKey == null) {
 397  0
             throw new IllegalArgumentException(
 398  
                     ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 399  
         }
 400  745
         final AsfFieldKey asfFieldKey = TAGFIELD_TO_ASFFIELD.get(genericKey);
 401  745
         if (asfFieldKey == null) {
 402  0
             throw new KeyNotFoundException("No ASF fieldkey for "
 403  
                     + genericKey.toString());
 404  
         }
 405  745
         return createField(asfFieldKey, value);
 406  
     }
 407  
 
 408  
     /**
 409  
      * Removes all fields which are stored to the provided field key.
 410  
      * 
 411  
      * @param fieldKey
 412  
      *            fields to remove.
 413  
      */
 414  
     public void deleteField(final AsfFieldKey fieldKey) {
 415  20
         super.deleteField(fieldKey.getFieldName());
 416  20
     }
 417  
 
 418  
     /**
 419  
      * {@inheritDoc}
 420  
      */
 421  
     @Override
 422  
     public void deleteField(final FieldKey fieldKey)
 423  
             throws KeyNotFoundException {
 424  4
         if (fieldKey == null) {
 425  0
             throw new KeyNotFoundException();
 426  
         }
 427  4
         super.deleteField(TAGFIELD_TO_ASFFIELD.get(fieldKey).getFieldName());
 428  4
     }
 429  
 
 430  
     /**
 431  
      * {@inheritDoc}
 432  
      */
 433  
     @Override
 434  
     public List<TagField> getFields(final FieldKey fieldKey)
 435  
             throws KeyNotFoundException {
 436  1092
         if (fieldKey == null) {
 437  0
             throw new KeyNotFoundException();
 438  
         }
 439  1092
         return super.get(TAGFIELD_TO_ASFFIELD.get(fieldKey).getFieldName());
 440  
     }
 441  
 
 442  
     /**
 443  
      * @return
 444  
      */
 445  
     public List<Artwork> getArtworkList() {
 446  32
         final List<TagField> coverartList = getFields(FieldKey.COVER_ART);
 447  32
         final List<Artwork> artworkList = new ArrayList<Artwork>(coverartList
 448  
                 .size());
 449  
 
 450  32
         for (final TagField next : coverartList) {
 451  24
             final AsfTagCoverField coverArt = (AsfTagCoverField) next;
 452  24
             final Artwork artwork = new Artwork();
 453  24
             artwork.setBinaryData(coverArt.getRawImageData());
 454  24
             artwork.setMimeType(coverArt.getMimeType());
 455  24
             artwork.setDescription(coverArt.getDescription());
 456  24
             artwork.setPictureType(coverArt.getPictureType());
 457  24
             artworkList.add(artwork);
 458  24
         }
 459  32
         return artworkList;
 460  
     }
 461  
 
 462  
     /**
 463  
      * This method iterates through all stored fields.<br>
 464  
      * This method can only be used if this class has been created with field
 465  
      * conversion turned on.
 466  
      * 
 467  
      * @return Iterator for iterating through ASF fields.
 468  
      */
 469  
     public Iterator<AsfTagField> getAsfFields() {
 470  153
         if (!isCopyingFields()) {
 471  0
             throw new IllegalStateException(
 472  
                     "Since the field conversion is not enabled, this method cannot be executed");
 473  
         }
 474  153
         return new AsfFieldIterator(getFields());
 475  
     }
 476  
 
 477  
     /**
 478  
      * Returns a list of stored copyrights.
 479  
      * 
 480  
      * @return list of stored copyrights.
 481  
      */
 482  
     public List<TagField> getCopyright() {
 483  8
         return get(AsfFieldKey.COPYRIGHT.getFieldName());
 484  
     }
 485  
 
 486  
     /**
 487  
      * {@inheritDoc}
 488  
      */
 489  
     @Override
 490  
     public String getFirst(final FieldKey genericKey)
 491  
             throws KeyNotFoundException {
 492  701
         if (genericKey == null) {
 493  0
             throw new KeyNotFoundException();
 494  
         }
 495  701
         return super.getFirst(TAGFIELD_TO_ASFFIELD.get(genericKey).getFieldName());
 496  
     }
 497  
 
 498  
     /**
 499  
      * Returns the Copyright.
 500  
      * 
 501  
      * @return the Copyright.
 502  
      */
 503  
     public String getFirstCopyright() {
 504  16
         return getFirst(AsfFieldKey.COPYRIGHT.getFieldName());
 505  
     }
 506  
 
 507  
     /**
 508  
      * {@inheritDoc}
 509  
      */
 510  
     @Override
 511  
     public AsfTagField getFirstField(final FieldKey genericKey)
 512  
             throws KeyNotFoundException {
 513  4
         if (genericKey == null) {
 514  0
             throw new KeyNotFoundException();
 515  
         }
 516  4
         return (AsfTagField) super.getFirstField(TAGFIELD_TO_ASFFIELD.get(
 517  
                 genericKey).getFieldName());
 518  
     }
 519  
 
 520  
     /**
 521  
      * Returns the Rating.
 522  
      * 
 523  
      * @return the Rating.
 524  
      */
 525  
     public String getFirstRating() {
 526  16
         return getFirst(AsfFieldKey.RATING.getFieldName());
 527  
     }
 528  
 
 529  
     /**
 530  
      * Returns a list of stored ratings.
 531  
      * 
 532  
      * @return list of stored ratings.
 533  
      */
 534  
     public List<TagField> getRating() {
 535  8
         return get(AsfFieldKey.RATING.getFieldName());
 536  
     }
 537  
 
 538  
     /**
 539  
      * {@inheritDoc}
 540  
      */
 541  
     @Override
 542  
     protected boolean isAllowedEncoding(final String enc) {
 543  0
         return AsfHeader.ASF_CHARSET.name().equals(enc);
 544  
     }
 545  
 
 546  
     /**
 547  
      * If <code>true</code>, the {@link #copyFrom(TagField)} method creates a
 548  
      * new {@link AsfTagField} instance and copies the content from the source.<br>
 549  
      * This method is utilized by {@link #addField(TagField)} and
 550  
      * {@link #setField(TagField)}.<br>
 551  
      * So if <code>true</code> it is ensured that the {@link AsfTag} instance
 552  
      * has its own copies of fields, which cannot be modified after assignment
 553  
      * (which could pass some checks), and it just stores {@link AsfTagField}
 554  
      * objects.<br>
 555  
      * Only then {@link #getAsfFields()} can work. otherwise
 556  
      * {@link IllegalStateException} is thrown.
 557  
      * 
 558  
      * @return state of field conversion.
 559  
      */
 560  
     public boolean isCopyingFields() {
 561  8554
         return this.copyFields;
 562  
     }
 563  
 
 564  
     /**
 565  
      * Check field is valid and can be added to this tag
 566  
      * 
 567  
      * @param field
 568  
      *            field to add
 569  
      * @return <code>true</code> if field may be added.
 570  
      */
 571  
     // TODO introduce this concept to all formats
 572  
     private boolean isValidField(final TagField field) {
 573  6306
         if (field == null) {
 574  0
             return false;
 575  
         }
 576  
 
 577  6306
         if (!(field instanceof AsfTagField)) {
 578  0
             return false;
 579  
         }
 580  
 
 581  6306
         return !field.isEmpty();
 582  
     }
 583  
 
 584  
     /**
 585  
      * {@inheritDoc}
 586  
      */
 587  
     @Override
 588  
     // TODO introduce copy idea to all formats
 589  
     public void setField(final TagField field) {
 590  541
         if (isValidField(field)) {
 591  
             // Copy only occurs if flag setField
 592  533
             super.setField(copyFrom(field));
 593  
         }
 594  541
     }
 595  
 
 596  
     /**
 597  
      * Sets the copyright.<br>
 598  
      * 
 599  
      * @param Copyright
 600  
      *            the copyright to set.
 601  
      */
 602  
     public void setCopyright(final String Copyright) {
 603  12
         setField(createCopyrightField(Copyright));
 604  12
     }
 605  
 
 606  
     /**
 607  
      * Sets the Rating.<br>
 608  
      * 
 609  
      * @param rating
 610  
      *            the rating to set.
 611  
      */
 612  
     public void setRating(final String rating) {
 613  12
         setField(createRatingField(rating));
 614  12
     }
 615  
 }