Coverage Report - org.jaudiotagger.tag.asf.AsfFieldKey
 
Classes in this File Line Coverage Branch Coverage Complexity
AsfFieldKey
98%
97/98
70%
14/20
1.4
 
 1  
 package org.jaudiotagger.tag.asf;
 2  
 
 3  
 import org.jaudiotagger.audio.asf.data.ContainerType;
 4  
 import org.jaudiotagger.audio.asf.data.ContentBranding;
 5  
 import org.jaudiotagger.audio.asf.data.ContentDescription;
 6  
 
 7  
 import java.util.HashMap;
 8  
 import java.util.Map;
 9  
 
 10  
 /**
 11  
  * Field keys which need to be mapped for ASF files, or only specified for ASF.
 12  
  *
 13  
  * TODO These attributes and their v23 mapping that havent been added to enum yet
 14  
  *
 15  
  * WMA      ID3v1   ID3v22  ID3v2324
 16  
  *
 17  
  * CopyrightURL                   WCP         WCOP
 18  
  * Duration                   TLE         TLEN
 19  
  * FileSize                             TSIZ
 20  
  * WM/AudioFileURL                   WAF         WOAF
 21  
  * WM/AudioSourceURL                   WAS         WOAS
 22  
  * WM/Binary                   GEO         GEOB
 23  
  * WM/EncodingSettings                   TSS         TSSE
 24  
  * WM/EncodingTime                             TDEN
 25  
  * WM/MCDI                             MCDI
 26  
  * WM/ModifiedBy                             TPE4
 27  
  * WM/OriginalAlbumTitle                   TOT         TOAL
 28  
  * WM/OriginalArtist                   TOA         TOPE
 29  
  * WM/OriginalFilename                   TOF         TOFN
 30  
  * WM/OriginalLyricist                   TOL         TOLY
 31  
  * WM/OriginalReleaseYear                   TOR         TORY
 32  
  * WM/PlaylistDelay                             TDLY
 33  
  * WM/RadioStationName                   TRN         TRSN
 34  
  * WM/RadioStationOwner                   TRO         TRSO
 35  
  * WM/SetSubTitle                             TSST
 36  
  * WM/Text                   TXX         TXXX
 37  
  * WM/UniqueFileIdentifier                   UFI         UFID
 38  
  * WM/UserWebURL                   WXX         WXXX
 39  
  *
 40  
  * @author Christian Laireiter
 41  
  */
 42  20
 public enum AsfFieldKey
 43  
 {
 44  
     /*
 45  
      * Keys are arbitrary because these fields don't have 'keys' internally because they are stored in preset contents descriptor
 46  
      */
 47  
     
 48  
     // Content Description Object keys
 49  4
     AUTHOR(ContentDescription.KEY_AUTHOR, false, ContainerType.CONTENT_DESCRIPTION),
 50  4
     TITLE(ContentDescription.KEY_TITLE, false, ContainerType.CONTENT_DESCRIPTION),
 51  4
     RATING(ContentDescription.KEY_RATING, false, ContainerType.CONTENT_DESCRIPTION),
 52  4
     COPYRIGHT(ContentDescription.KEY_COPYRIGHT, false, ContainerType.CONTENT_DESCRIPTION),
 53  4
     DESCRIPTION(ContentDescription.KEY_DESCRIPTION, false, ContainerType.CONTENT_DESCRIPTION),
 54  
     
 55  
     // Content Branding Object keys
 56  4
     BANNER_IMAGE(ContentBranding.KEY_BANNER_IMAGE,false, ContainerType.CONTENT_BRANDING),
 57  4
     BANNER_IMAGE_TYPE(ContentBranding.KEY_BANNER_TYPE,false, ContainerType.CONTENT_BRANDING),
 58  4
     BANNER_IMAGE_URL(ContentBranding.KEY_BANNER_URL, false, ContainerType.CONTENT_BRANDING),
 59  4
     COPYRIGHT_URL(ContentBranding.KEY_COPYRIGHT_URL, false, ContainerType.CONTENT_BRANDING),
 60  
     
 61  
     /*
 62  
      * keys are important because this is how values will be looked up by other applications
 63  
      */
 64  4
     ALBUM("WM/AlbumTitle", false),
 65  4
     ALBUM_ARTIST("WM/AlbumArtist", true),
 66  4
     ALBUM_ARTIST_SORT("WM/AlbumArtistSortOrder", false),
 67  4
     ALBUM_SORT("WM/AlbumSortOrder", false),
 68  4
     AMAZON_ID("ASIN", false),
 69  4
     ARTIST_SORT("WM/ArtistSortOrder", false),           
 70  4
     BARCODE("WM/Barcode", false),
 71  4
     BPM("WM/BeatsPerMinute", false),
 72  4
     CATALOG_NO("WM/CatalogNo", false),
 73  4
     CATEGORY("WM/Category", true),      
 74  4
     COMPOSER("WM/Composer", true),
 75  4
     COMPOSER_SORT("WM/ComposerSort", false),
 76  4
     CONDUCTOR("WM/Conductor", true),
 77  4
     COVER_ART("WM/Picture", true),
 78  4
     COVER_ART_URL("WM/AlbumCoverURL", true),
 79  4
     DIRECTOR("WM/Director", true),
 80  4
     DISC_NO("WM/PartOfSet", false),
 81  4
     DISC_TOTAL("WM/DiscTotal", false),
 82  4
     ENCODER("WM/ToolName", false),
 83  4
     ENCODED_BY("WM/EncodedBy", false),
 84  4
     GENRE("WM/Genre", true),
 85  4
     GENRE_ID("WM/GenreID", true),
 86  4
     GROUPING("WM/ContentGroupDescription", false),
 87  4
     INITIAL_KEY("WM/InitialKey", false),
 88  4
     IS_COMPILATION("WM/IsCompilation", false),
 89  4
     ISRC("WM/ISRC", false),
 90  4
     ISVBR("IsVBR", true),
 91  4
     LANGUAGE("WM/Language", true),
 92  4
     LYRICIST("WM/Writer", true),
 93  4
     LYRICS("WM/Lyrics", false),
 94  4
     LYRICS_SYNCHRONISED("WM/Lyrics_Synchronised", true),
 95  4
     MEDIA("WM/Media", false),
 96  4
     MOOD("WM/Mood", true),
 97  4
     MUSICBRAINZ_ARTISTID("MusicBrainz/Artist Id", false),
 98  4
     MUSICBRAINZ_DISC_ID("MusicBrainz/Disc Id", false),
 99  4
     MUSICBRAINZ_RELEASE_COUNTRY("MusicBrainz/Album Release Country", false),
 100  4
     MUSICBRAINZ_RELEASE_STATUS("MusicBrainz/Album Status", false),
 101  4
     MUSICBRAINZ_RELEASE_TYPE("MusicBrainz/Album Type", false),
 102  4
     MUSICBRAINZ_RELEASEARTISTID("MusicBrainz/Album Artist Id", false),
 103  4
     MUSICBRAINZ_RELEASEID("MusicBrainz/Album Id", false),
 104  4
     MUSICBRAINZ_TRACK_ID("MusicBrainz/Track Id", false),
 105  4
     MUSICIP_ID("MusicIP/PUID", false),
 106  4
     PRODUCER("WM/Producer", false),
 107  4
     RECORD_LABEL("WM/Publisher", false),
 108  4
     REMIXER("WM/ModifiedBy", false),
 109  4
     SUBTITLE("WM/SubTitle", false),
 110  4
     TITLE_SORT("WM/TitleSortOrder", false),
 111  4
     TRACK("WM/TrackNumber", false),
 112  4
     TRACK_TOTAL("WM/TrackTotal", false),
 113  4
     URL_DISCOGS_ARTIST_SITE("WM/DiscogsArtistUrl", false),
 114  4
     URL_DISCOGS_RELEASE_SITE("WM/DiscogsReleaseUrl", false),
 115  4
     URL_OFFICIAL_ARTIST_SITE("WM/AuthorURL", false),
 116  4
     URL_OFFICIAL_RELEASE_SITE("WM/OfficialReleaseUrl", false),
 117  4
     URL_PROMOTIONAL_SITE("WM/PromotionURL", true),
 118  4
     URL_WIKIPEDIA_ARTIST_SITE("WM/WikipediaArtistUrl", false),
 119  4
     URL_WIKIPEDIA_RELEASE_SITE("WM/WikipediaReleaseUrl", false),
 120  4
     URL_LYRICS_SITE("WM/LyricsUrl", false),
 121  
 
 122  4
     YEAR("WM/Year", false),
 123  
     
 124  
     // Special field for all unknown field names, which will getFields maximum support
 125  4
     CUSTOM ("___CUSTOM___", true);
 126  
 
 127  
     /**
 128  
      * Stores the {@link AsfFieldKey#fieldName} to the field key.
 129  
      */
 130  
     private final static Map<String, AsfFieldKey> FIELD_ID_MAP;
 131  
 
 132  
     static
 133  
     {
 134  4
         FIELD_ID_MAP = new HashMap<String, AsfFieldKey>(AsfFieldKey.values().length);
 135  276
         for (AsfFieldKey curr : AsfFieldKey.values())
 136  
         {
 137  272
             if (curr != CUSTOM) {
 138  268
                 assert !FIELD_ID_MAP.containsKey(curr.getFieldName()) : "duplicate field entry: "+curr.getFieldName();
 139  268
                 FIELD_ID_MAP.put(curr.getFieldName(), curr);
 140  
             }
 141  
         }
 142  4
     }
 143  
 
 144  
 
 145  
     /**
 146  
      * Searches for an ASF field key which represents the given id string.<br>
 147  
      *
 148  
      * @param fieldName the field name used for this key
 149  
      * @return the Enum that represents this field
 150  
      */
 151  
     public static AsfFieldKey getAsfFieldKey(final String fieldName)
 152  
     {
 153  21596
         AsfFieldKey result = FIELD_ID_MAP.get(fieldName);
 154  21596
         if (result == null) {
 155  6529
             result = CUSTOM;
 156  
         }
 157  21596
         return result;
 158  
     }
 159  
 
 160  
     /**
 161  
      * Tests whether the field is enabled for multiple values.<br>
 162  
      *
 163  
      * @param fieldName field id to test.
 164  
      * @return <code>true</code> if ASF implementation supports multiple values for the field.
 165  
      */
 166  
     public static boolean isMultiValued(final String fieldName)
 167  
     {
 168  5520
         final AsfFieldKey fieldKey = getAsfFieldKey(fieldName);
 169  5520
         return fieldKey != null && fieldKey.isMultiValued();
 170  
     }
 171  
 
 172  
 
 173  
     /**
 174  
      * If set, the field has a standard id assigned.
 175  
      */
 176  
     private final String fieldName;
 177  
 
 178  
     /**
 179  
      * If <code>true</code>, the field will be stored repeatedly if occurs so in tags.
 180  
      */
 181  
     private final boolean multiValued;
 182  
 
 183  
     /**
 184  
      * The lowest possible container type, such a field can be stored into.<br>
 185  
      * Low means, container with least capabilities.
 186  
      */
 187  
     private final ContainerType lowestContainer;
 188  
     
 189  
     /**
 190  
      * The highest possible container type, such a field can be stored into.<br>
 191  
      * High means, most capabilities, for example string length exceeds that of
 192  
      * the extended content description, it will be stored one level up (metadata library).
 193  
      */
 194  
     private final ContainerType highestContainer;
 195  
     
 196  
     /**
 197  
      * Creates an instance<br>
 198  
      * Lowest/Highest will be {@link ContainerType#EXTENDED_CONTENT} /
 199  
      * {@link ContainerType#METADATA_LIBRARY_OBJECT}
 200  
      * 
 201  
      * @param asfFieldName
 202  
      *            standard field identifier.
 203  
      * @param multiValue
 204  
      *            <code>true</code> if the this ASF field can have multiple
 205  
      *            values.
 206  
      */
 207  
     private AsfFieldKey(final String asfFieldName, final boolean multiValue) {
 208  236
         this(asfFieldName, multiValue, ContainerType.EXTENDED_CONTENT,
 209  
                 ContainerType.METADATA_LIBRARY_OBJECT);
 210  236
     }
 211  
     
 212  
     /**
 213  
      * Creates an instance.<br>
 214  
      * 
 215  
      * @param asfFieldName
 216  
      *              standard field identifier.
 217  
      * @param multiValue           
 218  
      *              <code>true</code> if the this ASF field can have multiple
 219  
      *              values.
 220  
      * @param restrictedTo
 221  
      *              fields must be stored in this container.
 222  
      */
 223  
     private AsfFieldKey(final String asfFieldName, final boolean multiValue,
 224  
             final ContainerType restrictedTo) {
 225  36
         this(asfFieldName, multiValue, restrictedTo, restrictedTo);
 226  36
     }
 227  
 
 228  
     /**
 229  
      * Creates an instance.<br>
 230  
      * 
 231  
      * @param asfFieldName
 232  
      *              standard field identifier.
 233  
      * @param multiValue           
 234  
      *              <code>true</code> if the this ASF field can have multiple
 235  
      *              values.
 236  
      * @param lowest
 237  
      *              fields must be stored at least in this container.
 238  
      * @param highest
 239  
      *              fields aren't allowed to be stored in better containers than
 240  
      *              this.
 241  
      */
 242  
     private AsfFieldKey(final String asfFieldName, final boolean multiValue,
 243  272
             final ContainerType lowest, final ContainerType highest) {
 244  272
         this.fieldName = asfFieldName;
 245  272
         assert !multiValue || highest.isMultiValued() : "Definition error";
 246  272
         this.multiValued = multiValue && highest.isMultiValued();
 247  272
         this.lowestContainer = lowest;
 248  272
         this.highestContainer = highest;
 249  272
         assert ContainerType.areInCorrectOrder(lowest, highest);
 250  272
     }
 251  
 
 252  
 
 253  
     /**
 254  
      * Returns the standard field id.
 255  
      *
 256  
      * @return the standard field id. (may be <code>null</code>)
 257  
      */
 258  
     public String getFieldName()
 259  
     {
 260  3646
         return this.fieldName;
 261  
     }
 262  
 
 263  
     /**
 264  
      * @return the highestContainer
 265  
      */
 266  
     public ContainerType getHighestContainer() {
 267  8110
         return this.highestContainer;
 268  
     }
 269  
     
 270  
     /**
 271  
      * @return the lowestContainer
 272  
      */
 273  
     public ContainerType getLowestContainer() {
 274  0
         return this.lowestContainer;
 275  
     }
 276  
     
 277  
     /**
 278  
      * Returns <code>true</code> if this field can store multiple values.
 279  
      *
 280  
      * @return <code>true</code> if multiple values are supported for this field.
 281  
      */
 282  
     public boolean isMultiValued()
 283  
     {
 284  5520
         return this.multiValued;
 285  
     }
 286  
     
 287  
     /**
 288  
      * {@inheritDoc}
 289  
      */
 290  
     @Override
 291  
     public String toString()
 292  
     {
 293  4
         return getFieldName();
 294  
     }
 295  
 }