Coverage Report - org.jaudiotagger.tag.vorbiscomment.VorbisCommentTag
 
Classes in this File Line Coverage Branch Coverage Complexity
VorbisCommentTag
85%
120/141
61%
21/34
1.963
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2003-2005 Rapha�l Slinckx <raphael@slinckx.net>
 4  
  * 
 5  
  * This library is free software; you can redistribute it and/or
 6  
  * modify it under the terms of the GNU Lesser General Public
 7  
  * License as published by the Free Software Foundation; either
 8  
  * version 2.1 of the License, or (at your option) any later version.
 9  
  *  
 10  
  * This library is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
  * Lesser General Public License for more details.
 14  
  * 
 15  
  * You should have received a copy of the GNU Lesser General Public
 16  
  * License along with this library; if not, write to the Free Software
 17  
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18  
  */
 19  
 package org.jaudiotagger.tag.vorbiscomment;
 20  
 
 21  
 import org.jaudiotagger.audio.generic.AbstractTag;
 22  
 import org.jaudiotagger.audio.ogg.util.VorbisHeader;
 23  
 import org.jaudiotagger.logging.ErrorMessage;
 24  
 import org.jaudiotagger.tag.FieldDataInvalidException;
 25  
 import org.jaudiotagger.tag.FieldKey;
 26  
 import org.jaudiotagger.tag.KeyNotFoundException;
 27  
 import org.jaudiotagger.tag.TagField;
 28  
 import org.jaudiotagger.tag.datatype.Artwork;
 29  
 import static org.jaudiotagger.tag.vorbiscomment.VorbisCommentFieldKey.ALBUM;
 30  
 import static org.jaudiotagger.tag.vorbiscomment.VorbisCommentFieldKey.VENDOR;
 31  
 import org.jaudiotagger.tag.vorbiscomment.util.Base64Coder;
 32  
 
 33  
 import java.util.ArrayList;
 34  
 import java.util.EnumMap;
 35  
 import java.util.List;
 36  
 
 37  
 /**
 38  
  * This is the logical representation of  Vorbis Comment Data
 39  
  */
 40  
 public class VorbisCommentTag extends AbstractTag
 41  
 {
 42  4
     private static EnumMap<FieldKey, VorbisCommentFieldKey> tagFieldToOggField = new EnumMap<FieldKey, VorbisCommentFieldKey>(FieldKey.class);
 43  
 
 44  
     static
 45  
     {
 46  4
         tagFieldToOggField.put(FieldKey.ARTIST, VorbisCommentFieldKey.ARTIST);
 47  4
         tagFieldToOggField.put(FieldKey.ALBUM, VorbisCommentFieldKey.ALBUM);
 48  4
         tagFieldToOggField.put(FieldKey.TITLE, VorbisCommentFieldKey.TITLE);
 49  4
         tagFieldToOggField.put(FieldKey.TRACK, VorbisCommentFieldKey.TRACKNUMBER);
 50  4
         tagFieldToOggField.put(FieldKey.YEAR, VorbisCommentFieldKey.DATE);
 51  4
         tagFieldToOggField.put(FieldKey.GENRE, VorbisCommentFieldKey.GENRE);
 52  4
         tagFieldToOggField.put(FieldKey.COMMENT, VorbisCommentFieldKey.COMMENT);
 53  4
         tagFieldToOggField.put(FieldKey.ALBUM_ARTIST, VorbisCommentFieldKey.ALBUMARTIST);
 54  4
         tagFieldToOggField.put(FieldKey.COMPOSER, VorbisCommentFieldKey.COMPOSER);
 55  4
         tagFieldToOggField.put(FieldKey.GROUPING, VorbisCommentFieldKey.GROUPING);
 56  4
         tagFieldToOggField.put(FieldKey.DISC_NO, VorbisCommentFieldKey.DISCNUMBER);
 57  4
         tagFieldToOggField.put(FieldKey.BPM, VorbisCommentFieldKey.BPM);
 58  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_ARTISTID, VorbisCommentFieldKey.MUSICBRAINZ_ARTISTID);
 59  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_RELEASEID, VorbisCommentFieldKey.MUSICBRAINZ_ALBUMID);
 60  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_RELEASEARTISTID, VorbisCommentFieldKey.MUSICBRAINZ_ALBUMARTISTID);
 61  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_TRACK_ID, VorbisCommentFieldKey.MUSICBRAINZ_TRACKID);
 62  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_DISC_ID, VorbisCommentFieldKey.MUSICBRAINZ_DISCID);
 63  4
         tagFieldToOggField.put(FieldKey.MUSICIP_ID, VorbisCommentFieldKey.MUSICIP_PUID);
 64  4
         tagFieldToOggField.put(FieldKey.AMAZON_ID, VorbisCommentFieldKey.ASIN);
 65  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_RELEASE_STATUS, VorbisCommentFieldKey.MUSICBRAINZ_ALBUMSTATUS);
 66  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_RELEASE_TYPE, VorbisCommentFieldKey.MUSICBRAINZ_ALBUMTYPE);
 67  4
         tagFieldToOggField.put(FieldKey.MUSICBRAINZ_RELEASE_COUNTRY, VorbisCommentFieldKey.RELEASECOUNTRY);
 68  4
         tagFieldToOggField.put(FieldKey.LYRICS, VorbisCommentFieldKey.LYRICS);
 69  4
         tagFieldToOggField.put(FieldKey.IS_COMPILATION, VorbisCommentFieldKey.COMPILATION);
 70  4
         tagFieldToOggField.put(FieldKey.ARTIST_SORT, VorbisCommentFieldKey.ARTISTSORT);
 71  4
         tagFieldToOggField.put(FieldKey.ALBUM_ARTIST_SORT, VorbisCommentFieldKey.ALBUMARTISTSORT);
 72  4
         tagFieldToOggField.put(FieldKey.ALBUM_SORT, VorbisCommentFieldKey.ALBUMSORT);
 73  4
         tagFieldToOggField.put(FieldKey.TITLE_SORT, VorbisCommentFieldKey.TITLESORT);
 74  4
         tagFieldToOggField.put(FieldKey.COMPOSER_SORT, VorbisCommentFieldKey.COMPOSERSORT);
 75  4
         tagFieldToOggField.put(FieldKey.ENCODER, VorbisCommentFieldKey.VENDOR);     //Known as vendor in VorbisComment
 76  4
         tagFieldToOggField.put(FieldKey.ISRC, VorbisCommentFieldKey.ISRC);
 77  4
         tagFieldToOggField.put(FieldKey.BARCODE, VorbisCommentFieldKey.BARCODE);
 78  4
         tagFieldToOggField.put(FieldKey.CATALOG_NO, VorbisCommentFieldKey.CATALOGNUMBER);
 79  4
         tagFieldToOggField.put(FieldKey.RECORD_LABEL, VorbisCommentFieldKey.LABEL);
 80  4
         tagFieldToOggField.put(FieldKey.LYRICIST, VorbisCommentFieldKey.LYRICIST);
 81  4
         tagFieldToOggField.put(FieldKey.CONDUCTOR, VorbisCommentFieldKey.CONDUCTOR);
 82  4
         tagFieldToOggField.put(FieldKey.REMIXER, VorbisCommentFieldKey.REMIXER);
 83  4
         tagFieldToOggField.put(FieldKey.MOOD, VorbisCommentFieldKey.MOOD);
 84  4
         tagFieldToOggField.put(FieldKey.MEDIA, VorbisCommentFieldKey.MEDIA);
 85  4
         tagFieldToOggField.put(FieldKey.URL_DISCOGS_ARTIST_SITE, VorbisCommentFieldKey.URL_DISCOGS_ARTIST_SITE);
 86  4
         tagFieldToOggField.put(FieldKey.URL_DISCOGS_RELEASE_SITE, VorbisCommentFieldKey.URL_DISCOGS_RELEASE_SITE);
 87  4
         tagFieldToOggField.put(FieldKey.URL_OFFICIAL_ARTIST_SITE, VorbisCommentFieldKey.URL_OFFICIAL_ARTIST_SITE);
 88  4
         tagFieldToOggField.put(FieldKey.URL_OFFICIAL_RELEASE_SITE, VorbisCommentFieldKey.URL_OFFICIAL_RELEASE_SITE);
 89  4
         tagFieldToOggField.put(FieldKey.URL_WIKIPEDIA_ARTIST_SITE, VorbisCommentFieldKey.URL_WIKIPEDIA_ARTIST_SITE);
 90  4
         tagFieldToOggField.put(FieldKey.URL_WIKIPEDIA_RELEASE_SITE, VorbisCommentFieldKey.URL_WIKIPEDIA_RELEASE_SITE);
 91  4
         tagFieldToOggField.put(FieldKey.LANGUAGE, VorbisCommentFieldKey.LANGUAGE);
 92  4
         tagFieldToOggField.put(FieldKey.KEY, VorbisCommentFieldKey.KEY);
 93  4
         tagFieldToOggField.put(FieldKey.URL_LYRICS_SITE, VorbisCommentFieldKey.URL_LYRICS_SITE);
 94  4
         tagFieldToOggField.put(FieldKey.TRACK_TOTAL, VorbisCommentFieldKey.TRACKTOTAL);
 95  4
         tagFieldToOggField.put(FieldKey.DISC_TOTAL, VorbisCommentFieldKey.DISCTOTAL);
 96  
 
 97  4
     }
 98  
 
 99  
     //This is the vendor string that will be written if no other is supplied. Should be the name of the software
 100  
     //that actually encoded the file in the first place.
 101  
     public static final String DEFAULT_VENDOR = "jaudiotagger";
 102  
 
 103  
     /**
 104  
      * Only used within Package, hidden because it doesnt set Vendor
 105  
      * which should be done when created by end user
 106  
      */
 107  
     VorbisCommentTag()
 108  282
     {
 109  
 
 110  282
     }
 111  
 
 112  
     /**
 113  
      * Use to construct a new tag properly initialized
 114  
      *
 115  
      * @return
 116  
      */
 117  
     public static VorbisCommentTag createNewTag()
 118  
     {
 119  24
         VorbisCommentTag tag = new VorbisCommentTag();
 120  24
         tag.setVendor(DEFAULT_VENDOR);
 121  24
         return tag;
 122  
     }
 123  
 
 124  
     /**
 125  
      * @return the vendor, generically known as the encoder
 126  
      */
 127  
     public String getVendor()
 128  
     {
 129  437
         return getFirst(VENDOR.getFieldName());
 130  
     }
 131  
 
 132  
     /**
 133  
      * Set the vendor, known as the encoder  generally
 134  
      * <p/>
 135  
      * We dont want this to be blank, when written to file this field is written to a different location
 136  
      * to all other fields but user of library can just reat it as another field
 137  
      *
 138  
      * @param vendor
 139  
      */
 140  
     public void setVendor(String vendor)
 141  
     {
 142  286
         if (vendor == null)
 143  
         {
 144  0
             vendor = DEFAULT_VENDOR;
 145  
         }
 146  286
         super.setField(new VorbisCommentTagField(VENDOR.getFieldName(), vendor));
 147  286
     }
 148  
 
 149  
     protected boolean isAllowedEncoding(String enc)
 150  
     {
 151  0
         return enc.equals(VorbisHeader.CHARSET_UTF_8);
 152  
     }
 153  
 
 154  
     public String toString()
 155  
     {
 156  3
         return "OGG " + super.toString();
 157  
     }
 158  
 
 159  
     /**
 160  
      * Create Tag Field using generic key
 161  
      */
 162  
     @Override
 163  
     public TagField createField(FieldKey genericKey, String value) throws KeyNotFoundException,FieldDataInvalidException
 164  
     {
 165  264
         if (genericKey == null)
 166  
         {
 167  0
             throw new KeyNotFoundException();
 168  
         }
 169  264
         return createField(tagFieldToOggField.get(genericKey), value);
 170  
     }
 171  
 
 172  
     /**
 173  
      * Create Tag Field using ogg key
 174  
      *
 175  
      * @param vorbisCommentFieldKey
 176  
      * @param value
 177  
      * @return
 178  
      * @throws org.jaudiotagger.tag.KeyNotFoundException
 179  
      * @throws org.jaudiotagger.tag.FieldDataInvalidException
 180  
      */
 181  
     public TagField createField(VorbisCommentFieldKey vorbisCommentFieldKey, String value) throws KeyNotFoundException,FieldDataInvalidException
 182  
     {
 183  322
         if (value == null)
 184  
         {
 185  4
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 186  
         }
 187  318
         if (vorbisCommentFieldKey == null)
 188  
         {
 189  4
             throw new KeyNotFoundException();
 190  
         }
 191  
 
 192  314
         return new VorbisCommentTagField(vorbisCommentFieldKey.getFieldName(), value);
 193  
     }
 194  
 
 195  
     /**
 196  
      * Create Tag Field using ogg key
 197  
      * <p/>
 198  
      * This method is provided to allow you to create key of any value because VorbisComment allows
 199  
      * arbitary keys.
 200  
      *
 201  
      * @param vorbisCommentFieldKey
 202  
      * @param value
 203  
      * @return
 204  
      */
 205  
     public TagField createField(String vorbisCommentFieldKey, String value)
 206  
     {
 207  8
         if (value == null)
 208  
         {
 209  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 210  
         }
 211  8
         return new VorbisCommentTagField(vorbisCommentFieldKey, value);
 212  
     }
 213  
 
 214  
     /**
 215  
      * Maps the generic key to the ogg key and return the list of values for this field
 216  
      *
 217  
      * @param genericKey
 218  
      */
 219  
     @Override
 220  
     public List<TagField> getFields(FieldKey genericKey) throws KeyNotFoundException
 221  
     {
 222  36
         VorbisCommentFieldKey vorbisCommentFieldKey = tagFieldToOggField.get(genericKey);
 223  36
         if (vorbisCommentFieldKey == null)
 224  
         {
 225  0
             throw new KeyNotFoundException();
 226  
         }
 227  36
         return super.get(vorbisCommentFieldKey.getFieldName());
 228  
     }
 229  
 
 230  
     /**
 231  
      * Retrieve the first value that exists for this vorbis comment key
 232  
      *
 233  
      * @param vorbisCommentKey
 234  
      * @return
 235  
      * @throws org.jaudiotagger.tag.KeyNotFoundException
 236  
      */
 237  
     public List<TagField> get(VorbisCommentFieldKey vorbisCommentKey) throws KeyNotFoundException
 238  
     {
 239  35
         if (vorbisCommentKey == null)
 240  
         {
 241  0
             throw new KeyNotFoundException();
 242  
         }
 243  35
         return super.get(vorbisCommentKey.getFieldName());
 244  
     }
 245  
 
 246  
     /**
 247  
      * Retrieve the first value that exists for this generic key
 248  
      *
 249  
      * @param genericKey
 250  
      * @return
 251  
      */
 252  
     public String getFirst(FieldKey genericKey) throws KeyNotFoundException
 253  
     {
 254  318
         VorbisCommentFieldKey vorbisCommentFieldKey = tagFieldToOggField.get(genericKey);
 255  318
         if (vorbisCommentFieldKey == null)
 256  
         {
 257  0
             throw new KeyNotFoundException();
 258  
         }
 259  318
         return super.getFirst(vorbisCommentFieldKey.getFieldName());
 260  
     }
 261  
 
 262  
     /**
 263  
      * Retrieve the first value that exists for this vorbis comment key
 264  
      *
 265  
      * @param vorbisCommentKey
 266  
      * @return
 267  
      * @throws org.jaudiotagger.tag.KeyNotFoundException
 268  
      */
 269  
     public String getFirst(VorbisCommentFieldKey vorbisCommentKey) throws KeyNotFoundException
 270  
     {
 271  304
         if (vorbisCommentKey == null)
 272  
         {
 273  0
             throw new KeyNotFoundException();
 274  
         }
 275  304
         return super.getFirst(vorbisCommentKey.getFieldName());
 276  
     }
 277  
 
 278  
     /**
 279  
      * Delete fields with this generic key
 280  
      *
 281  
      * @param genericKey
 282  
      */
 283  
     public void deleteField(FieldKey genericKey) throws KeyNotFoundException
 284  
     {
 285  0
         if (genericKey == null)
 286  
         {
 287  0
             throw new KeyNotFoundException();
 288  
         }
 289  0
         VorbisCommentFieldKey vorbisCommentFieldKey = tagFieldToOggField.get(genericKey);
 290  0
         deleteField(vorbisCommentFieldKey);
 291  0
     }
 292  
 
 293  
     /**
 294  
      * Delete fields with this vorbisCommentFieldKey
 295  
      *
 296  
      * @param vorbisCommentFieldKey
 297  
      * @throws org.jaudiotagger.tag.KeyNotFoundException
 298  
      */
 299  
     public void deleteField(VorbisCommentFieldKey vorbisCommentFieldKey) throws KeyNotFoundException
 300  
     {
 301  27
         if (vorbisCommentFieldKey == null)
 302  
         {
 303  0
             throw new KeyNotFoundException();
 304  
         }
 305  27
         super.deleteField(vorbisCommentFieldKey.getFieldName());
 306  27
     }
 307  
 
 308  
     /**
 309  
      * Create artwork field
 310  
      * <p/>
 311  
      * Actually create two fields , the data field and the mimetype
 312  
      *
 313  
      * @param data     raw image data
 314  
      * @param mimeType mimeType of data
 315  
      *                 <p/>
 316  
      *                 TODO could possibly work out mimetype from data, but unlike mp4 there is nothing to restrict to only png
 317  
      *                 or jpeg images
 318  
      * @return
 319  
      */
 320  
     public void setArtworkField(byte[] data, String mimeType)
 321  
     {
 322  4
         char[] testdata = Base64Coder.encode(data);
 323  4
         String base64image = new String(testdata);
 324  4
         VorbisCommentTagField dataField = new VorbisCommentTagField(VorbisCommentFieldKey.COVERART.getFieldName(), base64image);
 325  4
         VorbisCommentTagField mimeField = new VorbisCommentTagField(VorbisCommentFieldKey.COVERARTMIME.getFieldName(), mimeType);
 326  
 
 327  4
         setField(dataField);
 328  4
         setField(mimeField);
 329  
 
 330  4
     }
 331  
 
 332  
     /**
 333  
      * Retrieve artwork raw data
 334  
      *
 335  
      * @return
 336  
      */
 337  
     public byte[] getArtworkBinaryData()
 338  
     {
 339  92
         String base64data = this.getFirst(VorbisCommentFieldKey.COVERART);
 340  92
         byte[] rawdata = Base64Coder.decode(base64data.toCharArray());
 341  92
         return rawdata;
 342  
     }
 343  
 
 344  
     /**
 345  
      * @return mimetype
 346  
      */
 347  
     public String getArtworkMimeType()
 348  
     {
 349  28
         return this.getFirst(VorbisCommentFieldKey.COVERARTMIME);
 350  
     }
 351  
 
 352  
     /**
 353  
      * Is this tag empty
 354  
      * <p/>
 355  
      * <p>Overridden because check for size of one because there is always a vendor tag unless just
 356  
      * created an empty vorbis tag as part of flac tag in which case size could be zero
 357  
      *
 358  
      * @see org.jaudiotagger.tag.Tag#isEmpty()
 359  
      */
 360  
     public boolean isEmpty()
 361  
     {
 362  131
         return fields.size() <= 1;
 363  
     }
 364  
 
 365  
     /**
 366  
      * Add Field
 367  
      * <p/>
 368  
      * <p>Overidden because there can only be one vendor set
 369  
      *
 370  
      * @param field
 371  
      */
 372  
     public void addField(TagField field)
 373  
     {
 374  1458
         if (field.getId().equals(VorbisCommentFieldKey.VENDOR.getFieldName()))
 375  
         {
 376  4
             super.setField(field);
 377  
         }
 378  
         else
 379  
         {
 380  1454
             super.addField(field);
 381  
         }
 382  1458
     }
 383  
 
 384  
      public TagField getFirstField(FieldKey genericKey) throws KeyNotFoundException
 385  
     {
 386  0
         if (genericKey == null)
 387  
         {
 388  0
             throw new KeyNotFoundException();
 389  
         }
 390  0
         return getFirstField(tagFieldToOggField.get(genericKey).getFieldName());
 391  
     }
 392  
 
 393  
     public List<Artwork> getArtworkList()
 394  
     {
 395  32
         List<Artwork>  artworkList  = new ArrayList<Artwork>(1);
 396  
 
 397  32
         if(getArtworkBinaryData()!=null & getArtworkBinaryData().length>0)
 398  
         {
 399  24
             Artwork artwork=new Artwork();
 400  24
             artwork.setMimeType(getArtworkMimeType());
 401  24
             artwork.setBinaryData(getArtworkBinaryData());
 402  24
             artworkList.add(artwork);
 403  
         }
 404  32
         return artworkList;
 405  
     }
 406  
 
 407  
     /**
 408  
      * Create artwork field
 409  
      *
 410  
      * Not supported because reuire two fields to be created use
 411  
      * @return
 412  
      */
 413  
     public TagField createField(Artwork artwork) throws FieldDataInvalidException
 414  
     {
 415  0
         throw new UnsupportedOperationException("Please use setField instead");
 416  
     }
 417  
 
 418  
     /**
 419  
      * Create artwork field
 420  
      *
 421  
      * Actually sets two fields
 422  
      *
 423  
      * @return
 424  
      */
 425  
     @Override
 426  
     public void setField(Artwork artwork) throws FieldDataInvalidException
 427  
     {
 428  5
         char[] testdata = Base64Coder.encode(artwork.getBinaryData());
 429  5
                   String base64image = new String(testdata);
 430  5
                TagField imageTagField  = createField(VorbisCommentFieldKey.COVERART, base64image);
 431  5
                    TagField imageTypeField = createField(VorbisCommentFieldKey.COVERARTMIME, artwork.getMimeType());
 432  
 
 433  5
         this.setField(imageTagField);
 434  5
         this.setField(imageTypeField);
 435  5
     }
 436  
 
 437  
     /**
 438  
      * Create and set field with name of vorbisCommentkey
 439  
      *
 440  
      * @param vorbisCommentKey
 441  
      * @param value
 442  
      * @throws KeyNotFoundException
 443  
      * @throws FieldDataInvalidException
 444  
      */
 445  
     public void setField(String vorbisCommentKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 446  
     {
 447  4
         TagField tagfield = createField(vorbisCommentKey,value);
 448  4
         setField(tagfield);
 449  4
     }
 450  
 
 451  
     /**
 452  
      * Create and add field with name of vorbisCommentkey
 453  
      * @param vorbisCommentKey
 454  
      * @param value
 455  
      * @throws KeyNotFoundException
 456  
      * @throws FieldDataInvalidException
 457  
      */
 458  
     public void addField(String vorbisCommentKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 459  
     {
 460  0
         TagField tagfield = createField(vorbisCommentKey,value);
 461  0
         addField(tagfield);
 462  0
     }
 463  
 
 464  
      /**
 465  
      * Delete all instance of artwork Field
 466  
      *
 467  
      * @throws KeyNotFoundException
 468  
      */
 469  
     public void deleteArtworkField() throws KeyNotFoundException
 470  
     {
 471  4
         this.deleteField(VorbisCommentFieldKey.COVERART);
 472  4
         this.deleteField(VorbisCommentFieldKey.COVERARTMIME);
 473  4
     }
 474  
 }
 475