Coverage Report - org.jaudiotagger.tag.flac.FlacTag
 
Classes in this File Line Coverage Branch Coverage Complexity
FlacTag
69%
81/116
57%
30/52
2.265
 
 1  
 package org.jaudiotagger.tag.flac;
 2  
 
 3  
 import org.jaudiotagger.audio.flac.metadatablock.MetadataBlockDataPicture;
 4  
 import org.jaudiotagger.audio.generic.Utils;
 5  
 import org.jaudiotagger.tag.*;
 6  
 import org.jaudiotagger.tag.datatype.Artwork;
 7  
 import org.jaudiotagger.tag.id3.valuepair.ImageFormats;
 8  
 import org.jaudiotagger.tag.id3.valuepair.TextEncoding;
 9  
 import org.jaudiotagger.tag.reference.PictureTypes;
 10  
 import org.jaudiotagger.tag.vorbiscomment.VorbisCommentTag;
 11  
 import org.jaudiotagger.tag.vorbiscomment.VorbisCommentFieldKey;
 12  
 import org.jaudiotagger.tag.vorbiscomment.VorbisCommentTagField;
 13  
 import org.jaudiotagger.logging.ErrorMessage;
 14  
 
 15  
 import javax.imageio.ImageIO;
 16  
 import java.awt.image.BufferedImage;
 17  
 import java.io.ByteArrayOutputStream;
 18  
 import java.io.DataOutputStream;
 19  
 import java.io.IOException;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 
 24  
 /**
 25  
  * Flac uses Vorbis Comment for most of its metadata and a Flac Picture Block for images
 26  
  * <p/>
 27  
  * <p/>
 28  
  * This class enscapulates the items into a single tag
 29  
  */
 30  
 public class FlacTag implements Tag
 31  
 {
 32  94
     private VorbisCommentTag tag = null;
 33  94
     private List<MetadataBlockDataPicture> images = new ArrayList<MetadataBlockDataPicture>();
 34  
 
 35  
     public FlacTag(VorbisCommentTag tag, List<MetadataBlockDataPicture> images)
 36  94
     {
 37  94
         this.tag = tag;
 38  94
         this.images = images;
 39  94
     }
 40  
 
 41  
     /**
 42  
      * @return images
 43  
      */
 44  
     public List<MetadataBlockDataPicture> getImages()
 45  
     {
 46  231
         return images;
 47  
     }
 48  
 
 49  
     /**
 50  
      * @return the vorbis tag (this is what handles text metadata)
 51  
      */
 52  
     public VorbisCommentTag getVorbisCommentTag()
 53  
     {
 54  222
         return tag;
 55  
     }
 56  
 
 57  
     public void addField(TagField field) throws FieldDataInvalidException
 58  
     {
 59  37
         if (field instanceof MetadataBlockDataPicture)
 60  
         {
 61  4
             images.add((MetadataBlockDataPicture) field);
 62  
         }
 63  
         else
 64  
         {
 65  33
             tag.addField(field);
 66  
         }
 67  37
     }
 68  
 
 69  
     public List<TagField> get(String id)
 70  
     {
 71  16
         if (id.equals(FieldKey.COVER_ART.name()))
 72  
         {
 73  12
             List<TagField> castImages = new ArrayList<TagField>();
 74  12
             for (MetadataBlockDataPicture image : images)
 75  
             {
 76  20
                 castImages.add(image);
 77  
             }
 78  12
             return castImages;
 79  
         }
 80  
         else
 81  
         {
 82  4
             return tag.get(id);
 83  
         }
 84  
     }
 85  
 
 86  
 
 87  
     public boolean hasCommonFields()
 88  
     {
 89  0
         return tag.hasCommonFields();
 90  
     }
 91  
 
 92  
    public boolean hasField(String id)
 93  
     {
 94  0
         if (id.equals(FieldKey.COVER_ART.name()))
 95  
         {
 96  0
             return images.size() > 0;
 97  
         }
 98  
         else
 99  
         {
 100  0
             return tag.hasField(id);
 101  
         }
 102  
     }
 103  
 
 104  
     /**
 105  
      * Determines whether the tag has no fields specified.<br>
 106  
      * <p/>
 107  
      * <p>If there are no images we return empty if either there is no VorbisTag or if there is a
 108  
      * VorbisTag but it is empty
 109  
      *
 110  
      * @return <code>true</code> if tag contains no field.
 111  
      */
 112  
     public boolean isEmpty()
 113  
     {
 114  42
         return (tag == null || tag.isEmpty()) && images.size() == 0;
 115  
     }
 116  
 
 117  
     public void setField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 118  
     {
 119  6
         TagField tagfield = createField(genericKey,value);
 120  6
         setField(tagfield);
 121  6
     }
 122  
 
 123  
     public void addField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 124  
     {
 125  29
         TagField tagfield = createField(genericKey,value);
 126  29
         addField(tagfield);
 127  29
     }
 128  
 
 129  
     /**
 130  
      * Create and set field with name of vorbisCommentkey
 131  
      *
 132  
      * @param vorbisCommentKey
 133  
      * @param value
 134  
      * @throws KeyNotFoundException
 135  
      * @throws FieldDataInvalidException
 136  
      */
 137  
     public void setField(String vorbisCommentKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 138  
     {
 139  4
         TagField tagfield = createField(vorbisCommentKey,value);
 140  4
         setField(tagfield);
 141  4
     }
 142  
 
 143  
     /**
 144  
      * Create and add field with name of vorbisCommentkey
 145  
      * @param vorbisCommentKey
 146  
      * @param value
 147  
      * @throws KeyNotFoundException
 148  
      * @throws FieldDataInvalidException
 149  
      */
 150  
     public void addField(String vorbisCommentKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 151  
     {
 152  0
         TagField tagfield = createField(vorbisCommentKey,value);
 153  0
         addField(tagfield);
 154  0
     }
 155  
 
 156  
     /**
 157  
      * @param field
 158  
      * @throws FieldDataInvalidException
 159  
      */
 160  
     public void setField(TagField field) throws FieldDataInvalidException
 161  
     {
 162  68
         if (field instanceof MetadataBlockDataPicture)
 163  
         {
 164  9
             if (images.size() == 0)
 165  
             {
 166  5
                 images.add(0, (MetadataBlockDataPicture) field);
 167  
             }
 168  
             else
 169  
             {
 170  4
                 images.set(0, (MetadataBlockDataPicture) field);
 171  
             }
 172  
         }
 173  
         else
 174  
         {
 175  59
             tag.setField(field);
 176  
         }
 177  68
     }
 178  
 
 179  
     public TagField createField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 180  
     {
 181  92
         if (genericKey.equals(FieldKey.COVER_ART))
 182  
         {
 183  4
             throw new UnsupportedOperationException(ErrorMessage.ARTWORK_CANNOT_BE_CREATED_WITH_THIS_METHOD.getMsg());
 184  
         }
 185  
         else
 186  
         {
 187  88
             return tag.createField(genericKey, value);
 188  
         }
 189  
     }
 190  
 
 191  
     /**
 192  
      * Create Tag Field using ogg key
 193  
      *
 194  
      * @param vorbisCommentFieldKey
 195  
      * @param value
 196  
      * @return
 197  
      * @throws org.jaudiotagger.tag.KeyNotFoundException
 198  
      * @throws org.jaudiotagger.tag.FieldDataInvalidException
 199  
      */
 200  
     public TagField createField(VorbisCommentFieldKey vorbisCommentFieldKey, String value) throws KeyNotFoundException,FieldDataInvalidException
 201  
     {
 202  0
         if (vorbisCommentFieldKey.equals(VorbisCommentFieldKey.COVERART))
 203  
         {
 204  0
             throw new UnsupportedOperationException(ErrorMessage.ARTWORK_CANNOT_BE_CREATED_WITH_THIS_METHOD.getMsg());
 205  
         }
 206  0
         return tag.createField(vorbisCommentFieldKey,value);
 207  
     }
 208  
 
 209  
     /**
 210  
      * Create Tag Field using ogg key
 211  
      * <p/>
 212  
      * This method is provided to allow you to create key of any value because VorbisComment allows
 213  
      * arbitary keys.
 214  
      *
 215  
      * @param vorbisCommentFieldKey
 216  
      * @param value
 217  
      * @return
 218  
      */
 219  
     public TagField createField(String vorbisCommentFieldKey, String value)
 220  
     {
 221  4
         if (vorbisCommentFieldKey.equals(VorbisCommentFieldKey.COVERART.getFieldName()))
 222  
         {
 223  0
             throw new UnsupportedOperationException(ErrorMessage.ARTWORK_CANNOT_BE_CREATED_WITH_THIS_METHOD.getMsg());
 224  
         }
 225  4
         return tag.createField(vorbisCommentFieldKey,value);
 226  
     }
 227  
 
 228  
     public String getFirst(String id)
 229  
     {
 230  4
         if (id.equals(FieldKey.COVER_ART.name()))
 231  
         {
 232  0
             throw new UnsupportedOperationException(ErrorMessage.ARTWORK_CANNOT_BE_CREATED_WITH_THIS_METHOD.getMsg());
 233  
         }
 234  
         else
 235  
         {
 236  4
             return tag.getFirst(id);
 237  
         }
 238  
     }
 239  
 
 240  
     public String getFirst(FieldKey id) throws KeyNotFoundException
 241  
     {
 242  160
         if (id.equals(FieldKey.COVER_ART))
 243  
         {
 244  0
             throw new UnsupportedOperationException(ErrorMessage.ARTWORK_CANNOT_BE_RETRIEVED_WITH_THIS_METHOD.getMsg());
 245  
         }
 246  
         else
 247  
         {
 248  160
             return tag.getFirst(id);
 249  
         }
 250  
 
 251  
     }
 252  
 
 253  
     public TagField getFirstField(String id)
 254  
     {
 255  0
         if (id.equals(FieldKey.COVER_ART.name()))
 256  
         {
 257  0
             if (images.size() > 0)
 258  
             {
 259  0
                 return images.get(0);
 260  
             }
 261  
             else
 262  
             {
 263  0
                 return null;
 264  
             }
 265  
         }
 266  
         else
 267  
         {
 268  0
             return tag.getFirstField(id);
 269  
         }
 270  
     }
 271  
 
 272  
     public TagField getFirstField(FieldKey genericKey) throws KeyNotFoundException
 273  
     {
 274  0
         if (genericKey == null)
 275  
         {
 276  0
             throw new KeyNotFoundException();
 277  
         }
 278  
 
 279  0
         if(genericKey == FieldKey.COVER_ART )
 280  
         {
 281  0
             return getFirstField(FieldKey.COVER_ART.name());
 282  
         }
 283  
         else
 284  
         {
 285  0
             return tag.getFirstField(genericKey);            
 286  
         }
 287  
     }
 288  
 
 289  
     /**
 290  
      * Delete any instance of tag fields with this key
 291  
      *
 292  
      * @param fieldKey
 293  
      */
 294  
     public void deleteField(FieldKey fieldKey) throws KeyNotFoundException
 295  
     {
 296  4
         if (fieldKey.equals(FieldKey.COVER_ART))
 297  
         {
 298  4
             images.clear();
 299  
         }
 300  
         else
 301  
         {
 302  0
             tag.deleteField(fieldKey);
 303  
         }
 304  4
     }
 305  
 
 306  
     //TODO addField images to iterator
 307  
     public Iterator<TagField> getFields()
 308  
     {
 309  0
         return tag.getFields();
 310  
     }
 311  
 
 312  
     public int getFieldCount()
 313  
     {
 314  0
         return tag.getFieldCount() + images.size();
 315  
     }
 316  
 
 317  
     public boolean setEncoding(String enc) throws FieldDataInvalidException
 318  
     {
 319  0
         return tag.setEncoding(enc);
 320  
     }
 321  
 
 322  
     public List<TagField> getFields(FieldKey id) throws KeyNotFoundException
 323  
     {
 324  36
         if (id.equals(FieldKey.COVER_ART))
 325  
         {
 326  4
             List<TagField> castImages = new ArrayList<TagField>();
 327  4
             for (MetadataBlockDataPicture image : images)
 328  
             {
 329  8
                 castImages.add(image);
 330  
             }
 331  4
             return castImages;
 332  
         }
 333  
         else
 334  
         {
 335  32
             return tag.getFields(id);
 336  
         }
 337  
      }
 338  
 
 339  
     public TagField createArtworkField(byte[] imageData, int pictureType, String mimeType, String description, int width, int height, int colourDepth, int indexedColouredCount) throws FieldDataInvalidException
 340  
     {
 341  5
         return new MetadataBlockDataPicture(imageData, pictureType, mimeType, description, width, height, colourDepth, indexedColouredCount);
 342  
     }
 343  
 
 344  
     /**
 345  
      * Create Artwork when  have the bufferedimage
 346  
      *
 347  
      * @param bi
 348  
      * @param pictureType
 349  
      * @param mimeType
 350  
      * @param description
 351  
      * @param colourDepth
 352  
      * @param indexedColouredCount
 353  
      * @return
 354  
      * @throws FieldDataInvalidException
 355  
      */
 356  
     public TagField createArtworkField(BufferedImage bi, int pictureType, String mimeType, String description, int colourDepth, int indexedColouredCount) throws FieldDataInvalidException
 357  
     {
 358  
         //Convert to byte array
 359  
         try
 360  
         {
 361  4
             final ByteArrayOutputStream output = new ByteArrayOutputStream();
 362  4
             ImageIO.write(bi, ImageFormats.getFormatForMimeType(mimeType), new DataOutputStream(output));
 363  
 
 364  
             //Add to image list
 365  4
             return new MetadataBlockDataPicture(output.toByteArray(), pictureType, mimeType, description, bi.getWidth(), bi.getHeight(), colourDepth, indexedColouredCount);
 366  
         }
 367  0
         catch (IOException ioe)
 368  
         {
 369  0
             throw new FieldDataInvalidException("Unable to convert image to bytearray, check mimetype parameter");
 370  
         }
 371  
     }
 372  
 
 373  
     /**
 374  
      * Create Link to Image File, not recommended because if either flac or image file is moved link
 375  
      * will be broken.
 376  
      * @param url
 377  
      * @return
 378  
      */
 379  
     public TagField createLinkedArtworkField(String url)
 380  
     {
 381  
         //Add to image list
 382  4
         return new MetadataBlockDataPicture(Utils.getDefaultBytes(url, TextEncoding.CHARSET_ISO_8859_1), PictureTypes.DEFAULT_ID, MetadataBlockDataPicture.IMAGE_IS_URL, "", 0, 0, 0, 0);
 383  
     }
 384  
 
 385  
      /**
 386  
      * Create artwork field
 387  
      *
 388  
      * @return
 389  
      */
 390  
     public TagField createField(Artwork artwork) throws FieldDataInvalidException
 391  
     {
 392  4
         if(artwork.isLinked())
 393  
         {
 394  0
              return new MetadataBlockDataPicture(
 395  
                     Utils.getDefaultBytes(artwork.getImageUrl(), TextEncoding.CHARSET_ISO_8859_1),
 396  
                     artwork.getPictureType(),
 397  
                     MetadataBlockDataPicture.IMAGE_IS_URL,
 398  
                     "",
 399  
                     0,
 400  
                     0,
 401  
                     0,
 402  
                     0);
 403  
         }
 404  
         else
 405  
         {
 406  
             BufferedImage image;
 407  
             try
 408  
             {
 409  4
                 image = artwork.getImage();
 410  
             }
 411  0
             catch(IOException ioe)
 412  
             {
 413  0
                 throw new FieldDataInvalidException("Unable to createField bufferd image from the image");
 414  4
             }
 415  
 
 416  4
             return new MetadataBlockDataPicture(artwork.getBinaryData(),
 417  
                     artwork.getPictureType(),
 418  
                     artwork.getMimeType(),
 419  
                     artwork.getDescription(),
 420  
                     image.getWidth(),
 421  
                     image.getHeight(),
 422  
                     0,
 423  
                     0);
 424  
         }
 425  
     }
 426  
 
 427  
     public void setField(Artwork artwork) throws FieldDataInvalidException
 428  
     {
 429  4
         this.setField(createField(artwork));
 430  4
     }
 431  
 
 432  
     public void addField(Artwork artwork) throws FieldDataInvalidException
 433  
     {
 434  0
         this.addField(createField(artwork));
 435  0
     }
 436  
 
 437  
     public List<Artwork> getArtworkList()
 438  
     {         
 439  32
         List<Artwork>  artworkList  = new ArrayList<Artwork>(images.size());
 440  
 
 441  32
         for(MetadataBlockDataPicture coverArt:images)
 442  
         {
 443  48
             Artwork artwork = new Artwork();
 444  48
             artwork.setMimeType(coverArt.getMimeType());
 445  48
             artwork.setDescription(coverArt.getDescription());
 446  48
             artwork.setPictureType(coverArt.getPictureType());
 447  48
             if(coverArt.isImageUrl())
 448  
             {
 449  24
                 artwork.setLinked(coverArt.isImageUrl());
 450  24
                 artwork.setImageUrl(coverArt.getImageUrl());
 451  
             }
 452  
             else
 453  
             {
 454  24
                 artwork.setBinaryData(coverArt.getImageData());
 455  
             }
 456  48
             artworkList.add(artwork);
 457  48
         }
 458  32
         return artworkList;
 459  
     }
 460  
 
 461  
     public Artwork getFirstArtwork()
 462  
     {
 463  8
         List<Artwork> artwork = getArtworkList();
 464  8
         if(artwork.size()>0)
 465  
         {
 466  8
             return artwork.get(0);
 467  
         }
 468  0
         return null;
 469  
     }
 470  
 
 471  
     /**
 472  
      * Delete all instance of artwork Field
 473  
      *
 474  
      * @throws KeyNotFoundException
 475  
      */
 476  
     public void deleteArtworkField() throws KeyNotFoundException
 477  
     {
 478  4
         this.deleteField(FieldKey.COVER_ART);
 479  4
     }
 480  
 }