Coverage Report - org.jaudiotagger.tag.id3.ID3v1Tag
 
Classes in this File Line Coverage Branch Coverage Complexity
ID3v1Tag
71%
224/312
58%
90/155
3.25
ID3v1Tag$1
100%
1/1
N/A
3.25
 
 1  
 /**
 2  
  *  @author : Paul Taylor
 3  
  *  @author : Eric Farng
 4  
  *
 5  
  *  Version @version:$Id: ID3v1Tag.java 836 2009-11-12 15:44:07Z paultaylor $
 6  
  *
 7  
  *  MusicTag Copyright (C)2003,2004
 8  
  *
 9  
  *  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
 10  
  *  General Public  License as published by the Free Software Foundation; either version 2.1 of the License,
 11  
  *  or (at your option) any later version.
 12  
  *
 13  
  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 14  
  *  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 15  
  *  See the GNU Lesser General Public License for more details.
 16  
  *
 17  
  *  You should have received a copy of the GNU Lesser General Public License along with this library; if not,
 18  
  *  you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
 19  
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20  
  *
 21  
  * Description:
 22  
  *
 23  
  */
 24  
 package org.jaudiotagger.tag.id3;
 25  
 
 26  
 import org.jaudiotagger.audio.generic.Utils;
 27  
 import org.jaudiotagger.audio.mp3.MP3File;
 28  
 import org.jaudiotagger.logging.ErrorMessage;
 29  
 import org.jaudiotagger.tag.*;
 30  
 import org.jaudiotagger.tag.datatype.Artwork;
 31  
 import org.jaudiotagger.tag.reference.GenreTypes;
 32  
 
 33  
 import java.io.IOException;
 34  
 import java.io.RandomAccessFile;
 35  
 import java.nio.ByteBuffer;
 36  
 import java.nio.channels.FileChannel;
 37  
 import java.util.*;
 38  
 import java.util.regex.Matcher;
 39  
 
 40  
 /**
 41  
  * Represents an ID3v1 tag.
 42  
  *
 43  
  * @author : Eric Farng
 44  
  * @author : Paul Taylor
 45  
  */
 46  
 public class ID3v1Tag extends AbstractID3v1Tag implements Tag
 47  
 {
 48  4
     static EnumMap<FieldKey, ID3v1FieldKey> tagFieldToID3v1Field = new EnumMap<FieldKey, ID3v1FieldKey>(FieldKey.class);
 49  
 
 50  
     static
 51  
     {
 52  4
         tagFieldToID3v1Field.put(FieldKey.ARTIST, ID3v1FieldKey.ARTIST);
 53  4
         tagFieldToID3v1Field.put(FieldKey.ALBUM, ID3v1FieldKey.ALBUM);
 54  4
         tagFieldToID3v1Field.put(FieldKey.TITLE, ID3v1FieldKey.TITLE);
 55  4
         tagFieldToID3v1Field.put(FieldKey.TRACK, ID3v1FieldKey.TRACK);
 56  4
         tagFieldToID3v1Field.put(FieldKey.YEAR, ID3v1FieldKey.YEAR);
 57  4
         tagFieldToID3v1Field.put(FieldKey.GENRE, ID3v1FieldKey.GENRE);
 58  4
         tagFieldToID3v1Field.put(FieldKey.COMMENT, ID3v1FieldKey.COMMENT);
 59  4
     }
 60  
 
 61  
     //For writing output
 62  
     protected static final String TYPE_COMMENT = "comment";
 63  
 
 64  
 
 65  
     protected static final int FIELD_COMMENT_LENGTH = 30;
 66  
     protected static final int FIELD_COMMENT_POS = 97;
 67  
     protected static final int BYTE_TO_UNSIGNED = 0xff;
 68  
 
 69  
     protected static final int GENRE_UNDEFINED = 0xff;
 70  
 
 71  
     /**
 72  
      *
 73  
      */
 74  5112
     protected String album = "";
 75  
 
 76  
     /**
 77  
      *
 78  
      */
 79  5112
     protected String artist = "";
 80  
 
 81  
     /**
 82  
      *
 83  
      */
 84  5112
     protected String comment = "";
 85  
 
 86  
     /**
 87  
      *
 88  
      */
 89  5112
     protected String title = "";
 90  
 
 91  
     /**
 92  
      *
 93  
      */
 94  5112
     protected String year = "";
 95  
 
 96  
     /**
 97  
      *
 98  
      */
 99  5112
     protected byte genre = (byte) -1;
 100  
 
 101  
 
 102  
     private static final byte RELEASE = 1;
 103  
     private static final byte MAJOR_VERSION = 0;
 104  
     private static final byte REVISION = 0;
 105  
 
 106  
     /**
 107  
      * Retrieve the Release
 108  
      */
 109  
     public byte getRelease()
 110  
     {
 111  16
         return RELEASE;
 112  
     }
 113  
 
 114  
     /**
 115  
      * Retrieve the Major Version
 116  
      */
 117  
     public byte getMajorVersion()
 118  
     {
 119  16
         return MAJOR_VERSION;
 120  
     }
 121  
 
 122  
     /**
 123  
      * Retrieve the Revision
 124  
      */
 125  
     public byte getRevision()
 126  
     {
 127  16
         return REVISION;
 128  
     }
 129  
 
 130  
     /**
 131  
      * Creates a new ID3v1 datatype.
 132  
      */
 133  
     public ID3v1Tag()
 134  3088
     {
 135  
 
 136  3088
     }
 137  
 
 138  
     public ID3v1Tag(ID3v1Tag copyObject)
 139  
     {
 140  0
         super(copyObject);
 141  
 
 142  0
         this.album = copyObject.album;
 143  0
         this.artist = copyObject.artist;
 144  0
         this.comment = copyObject.comment;
 145  0
         this.title = copyObject.title;
 146  0
         this.year = copyObject.year;
 147  0
         this.genre = copyObject.genre;
 148  0
     }
 149  
 
 150  
     public ID3v1Tag(AbstractTag mp3tag)
 151  12
     {
 152  
 
 153  12
         if (mp3tag != null)
 154  
         {
 155  
             ID3v11Tag convertedTag;
 156  12
             if (mp3tag instanceof ID3v1Tag)
 157  
             {
 158  0
                 throw new UnsupportedOperationException("Copy Constructor not called. Please type cast the argument");
 159  
             }
 160  12
             if (mp3tag instanceof ID3v11Tag)
 161  
             {
 162  0
                 convertedTag = (ID3v11Tag) mp3tag;
 163  
             }
 164  
             else
 165  
             {
 166  12
                 convertedTag = new ID3v11Tag(mp3tag);
 167  
             }
 168  12
             this.album = convertedTag.album;
 169  12
             this.artist = convertedTag.artist;
 170  12
             this.comment = convertedTag.comment;
 171  12
             this.title = convertedTag.title;
 172  12
             this.year = convertedTag.year;
 173  12
             this.genre = convertedTag.genre;
 174  
         }
 175  12
     }
 176  
 
 177  
     /**
 178  
      * Creates a new ID3v1 datatype.
 179  
      *
 180  
      * @param file
 181  
      * @param loggingFilename
 182  
      * @throws TagNotFoundException
 183  
      * @throws IOException
 184  
      */
 185  
     public ID3v1Tag(RandomAccessFile file, String loggingFilename) throws TagNotFoundException, IOException
 186  2012
     {
 187  2012
         setLoggingFilename(loggingFilename);
 188  
         FileChannel fc;
 189  
         ByteBuffer byteBuffer;
 190  
 
 191  2012
         fc = file.getChannel();
 192  2012
         fc.position(file.length() - TAG_LENGTH);
 193  2012
         byteBuffer = ByteBuffer.allocate(TAG_LENGTH);
 194  2012
         fc.read(byteBuffer);
 195  2012
         byteBuffer.flip();
 196  2012
         read(byteBuffer);
 197  282
     }
 198  
 
 199  
     /**
 200  
      * Creates a new ID3v1 datatype.
 201  
      *
 202  
      * @param file
 203  
      * @throws TagNotFoundException
 204  
      * @throws IOException
 205  
      * @deprecated use {@link #ID3v1Tag(RandomAccessFile,String)} instead
 206  
      */
 207  
     public ID3v1Tag(RandomAccessFile file) throws TagNotFoundException, IOException
 208  
     {
 209  0
         this(file, "");
 210  0
     }
 211  
 
 212  
     public void addField(TagField field)
 213  
     {
 214  
         //TODO
 215  0
     }
 216  
 
 217  
     public List<TagField> get(String id)
 218  
     {
 219  
 
 220  8
         if (FieldKey.ARTIST.name().equals(id))
 221  
         {
 222  8
             return getArtist();
 223  
         }
 224  0
         else if (FieldKey.ALBUM.name().equals(id))
 225  
         {
 226  0
             return getAlbum();
 227  
         }
 228  0
         else if (FieldKey.TITLE.name().equals(id))
 229  
         {
 230  0
             return getTitle();
 231  
         }
 232  0
         else if (FieldKey.GENRE.name().equals(id))
 233  
         {
 234  0
             return getGenre();
 235  
         }
 236  0
         else if (FieldKey.YEAR.name().equals(id))
 237  
         {
 238  0
             return getYear();
 239  
         }
 240  0
         else if (FieldKey.COMMENT.name().equals(id))
 241  
         {
 242  0
             return getComment();
 243  
         }
 244  0
         return new ArrayList<TagField>();
 245  
     }
 246  
 
 247  
     public int getFieldCount()
 248  
     {
 249  0
         return 6;
 250  
     }
 251  
 
 252  
     protected List<TagField> returnFieldToList(ID3v1TagField field)
 253  
     {
 254  192
         List<TagField> fields = new ArrayList<TagField>();
 255  192
         fields.add(field);
 256  192
         return fields;
 257  
     }
 258  
 
 259  
     /**
 260  
      * Set Album
 261  
      *
 262  
      * @param album
 263  
      */
 264  
     public void setAlbum(String album)
 265  
     {
 266  64
         if (album == null)
 267  
         {
 268  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 269  
         }
 270  64
         this.album = ID3Tags.truncate(album, FIELD_ALBUM_LENGTH);
 271  64
     }
 272  
 
 273  
     /**
 274  
      * Get Album
 275  
      *
 276  
      * @return album
 277  
      */
 278  
     private String getFirstAlbum()
 279  
     {
 280  112
         return album;
 281  
     }
 282  
 
 283  
     /**
 284  
      * @return album within list or empty if does not exist
 285  
      */
 286  
     public List<TagField> getAlbum()
 287  
     {
 288  28
         if (getFirstAlbum().length() > 0)
 289  
         {
 290  28
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.ALBUM.name(), getFirstAlbum());
 291  28
             return returnFieldToList(field);
 292  
         }
 293  
         else
 294  
         {
 295  0
             return new ArrayList<TagField>();
 296  
         }
 297  
     }
 298  
 
 299  
 
 300  
 
 301  
 
 302  
     /**
 303  
      * Set Artist
 304  
      *
 305  
      * @param artist
 306  
      */
 307  
     public void setArtist(String artist)
 308  
     {
 309  64
         if (artist == null)
 310  
         {
 311  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 312  
         }
 313  64
         this.artist = ID3Tags.truncate(artist, FIELD_ARTIST_LENGTH);
 314  64
     }
 315  
 
 316  
     /**
 317  
      * Get Artist
 318  
      *
 319  
      * @return artist
 320  
      */
 321  
     private String getFirstArtist()
 322  
     {
 323  185
         return artist;
 324  
     }
 325  
 
 326  
     /**
 327  
      * @return Artist within list or empty if does not exist
 328  
      */
 329  
     public List<TagField> getArtist()
 330  
     {
 331  36
         if (getFirstArtist().length() > 0)
 332  
         {
 333  36
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.ARTIST.name(), getFirstArtist());
 334  36
             return returnFieldToList(field);
 335  
         }
 336  
         else
 337  
         {
 338  0
             return new ArrayList<TagField>();
 339  
         }
 340  
     }
 341  
 
 342  
     /**
 343  
      * Set Comment
 344  
      *
 345  
      * @param comment
 346  
      * @throws IllegalArgumentException if comment null
 347  
      */
 348  
     public void setComment(String comment)
 349  
     {
 350  28
         if (comment == null)
 351  
         {
 352  4
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 353  
         }
 354  24
         this.comment = ID3Tags.truncate(comment, FIELD_COMMENT_LENGTH);
 355  24
     }
 356  
 
 357  
     /**
 358  
      * @return comment within list or empty if does not exist
 359  
      */
 360  
     public List<TagField> getComment()
 361  
     {
 362  28
         if (getFirstComment().length() > 0)
 363  
         {
 364  28
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.COMMENT.name(), getFirstComment());
 365  28
             return returnFieldToList(field);
 366  
         }
 367  
         else
 368  
         {
 369  0
             return new ArrayList<TagField>();
 370  
         }
 371  
     }
 372  
 
 373  
     /**
 374  
      * Get Comment
 375  
      *
 376  
      * @return comment
 377  
      */
 378  
     public String getFirstComment()
 379  
     {
 380  44
         return comment;
 381  
     }
 382  
 
 383  
     /**
 384  
      * Sets the genreID,
 385  
      * <p/>
 386  
      * <p>ID3v1 only supports genres defined in a predefined list
 387  
      * so if unable to find value in list set 255, which seems to be the value
 388  
      * winamp uses for undefined.
 389  
      *
 390  
      * @param genreVal
 391  
      */
 392  
     public void setGenre(String genreVal)
 393  
     {
 394  52
         if (genreVal == null)
 395  
         {
 396  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 397  
         }
 398  52
         Integer genreID = GenreTypes.getInstanceOf().getIdForValue(genreVal);
 399  52
         if (genreID != null)
 400  
         {
 401  44
             this.genre = genreID.byteValue();
 402  
         }
 403  
         else
 404  
         {
 405  8
             this.genre = (byte) GENRE_UNDEFINED;
 406  
         }
 407  52
     }
 408  
 
 409  
     /**
 410  
      * Get Genre
 411  
      *
 412  
      * @return genre or empty string if not valid
 413  
      */
 414  
     public String getFirstGenre()
 415  
     {
 416  112
         Integer genreId = genre & BYTE_TO_UNSIGNED;
 417  112
         String genreValue = GenreTypes.getInstanceOf().getValueForId(genreId);
 418  112
         if (genreValue == null)
 419  
         {
 420  16
             return "";
 421  
         }
 422  
         else
 423  
         {
 424  96
             return genreValue;
 425  
         }
 426  
     }
 427  
 
 428  
     /**
 429  
      * Get Genre field
 430  
      * <p/>
 431  
      * <p>Only a single genre is available in ID3v1
 432  
      *
 433  
      * @return
 434  
      */
 435  
     public List<TagField> getGenre()
 436  
     {
 437  28
         if (getFirst(FieldKey.GENRE).length() > 0)
 438  
         {
 439  28
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.GENRE.name(), getFirst(FieldKey.GENRE));
 440  28
             return returnFieldToList(field);
 441  
         }
 442  
         else
 443  
         {
 444  0
             return new ArrayList<TagField>();
 445  
         }
 446  
     }
 447  
 
 448  
     /**
 449  
      * Set Title
 450  
      *
 451  
      * @param title
 452  
      */
 453  
     public void setTitle(String title)
 454  
     {
 455  64
         if (title == null)
 456  
         {
 457  0
             throw new IllegalArgumentException(ErrorMessage.GENERAL_INVALID_NULL_ARGUMENT.getMsg());
 458  
         }
 459  64
         this.title = ID3Tags.truncate(title, FIELD_TITLE_LENGTH);
 460  64
     }
 461  
 
 462  
     /**
 463  
      * Get title
 464  
      *
 465  
      * @return Title
 466  
      */
 467  
     public String getFirstTitle()
 468  
     {
 469  133
         return title;
 470  
     }
 471  
 
 472  
     /**
 473  
      * Get title field
 474  
      * <p/>
 475  
      * <p>Only a single title is available in ID3v1
 476  
      *
 477  
      * @return
 478  
      */
 479  
     public List<TagField> getTitle()
 480  
     {
 481  28
         if (getFirst(FieldKey.TITLE).length() > 0)
 482  
         {
 483  28
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.TITLE.name(), getFirst(FieldKey.TITLE));
 484  28
             return returnFieldToList(field);
 485  
         }
 486  
         else
 487  
         {
 488  0
             return new ArrayList<TagField>();
 489  
         }
 490  
     }
 491  
 
 492  
     /**
 493  
      * Set year
 494  
      *
 495  
      * @param year
 496  
      */
 497  
     public void setYear(String year)
 498  
     {
 499  48
         this.year = ID3Tags.truncate(year, FIELD_YEAR_LENGTH);
 500  48
     }
 501  
 
 502  
     /**
 503  
      * Get year
 504  
      *
 505  
      * @return year
 506  
      */
 507  
     public String getFirstYear()
 508  
     {
 509  108
         return year;
 510  
     }
 511  
 
 512  
     /**
 513  
      * Get year field
 514  
      * <p/>
 515  
      * <p>Only a single year is available in ID3v1
 516  
      *
 517  
      * @return
 518  
      */
 519  
     public List<TagField> getYear()
 520  
     {
 521  28
         if (getFirst(FieldKey.YEAR).length() > 0)
 522  
         {
 523  28
             ID3v1TagField field = new ID3v1TagField(ID3v1FieldKey.YEAR.name(), getFirst(FieldKey.YEAR));
 524  28
             return returnFieldToList(field);
 525  
         }
 526  
         else
 527  
         {
 528  0
             return new ArrayList<TagField>();
 529  
         }
 530  
     }
 531  
 
 532  
     public String getFirstTrack()
 533  
     {
 534  0
         throw new UnsupportedOperationException("ID3v10 cannot store track numbers");
 535  
     }
 536  
 
 537  
     public List<TagField> getTrack()
 538  
     {
 539  0
         throw new UnsupportedOperationException("ID3v10 cannot store track numbers");
 540  
     }
 541  
 
 542  
     public TagField getFirstField(String id)
 543  
     {
 544  48
         List<TagField> results = null;
 545  
 
 546  48
         if (FieldKey.ARTIST.name().equals(id))
 547  
         {
 548  8
             results = getArtist();
 549  
         }
 550  40
         else if (FieldKey.ALBUM.name().equals(id))
 551  
         {
 552  8
             results = getAlbum();
 553  
         }
 554  32
         else if (FieldKey.TITLE.name().equals(id))
 555  
         {
 556  8
             results = getTitle();
 557  
         }
 558  24
         else if (FieldKey.GENRE.name().equals(id))
 559  
         {
 560  8
             results = getGenre();
 561  
         }
 562  16
         else if (FieldKey.YEAR.name().equals(id))
 563  
         {
 564  8
             results = getYear();
 565  
         }
 566  8
         else if (FieldKey.COMMENT.name().equals(id))
 567  
         {
 568  8
             results = getComment();
 569  
         }
 570  
 
 571  48
         if (results != null)
 572  
         {
 573  48
             if (results.size() > 0)
 574  
             {
 575  48
                 return results.get(0);
 576  
             }
 577  
         }
 578  0
         return null;
 579  
     }
 580  
 
 581  
     public Iterator<TagField> getFields()
 582  
     {
 583  0
         throw new UnsupportedOperationException("TODO:Not done yet");
 584  
     }
 585  
 
 586  
     public boolean hasCommonFields()
 587  
     {
 588  
         //TODO
 589  0
         return true;
 590  
     }
 591  
 
 592  
     public boolean hasField(String id)
 593  
     {
 594  
         //TODO
 595  0
         throw new UnsupportedOperationException("TODO:Not done yet");
 596  
     }
 597  
 
 598  
     public boolean isEmpty()
 599  
     {
 600  20
         return !(getFirst(FieldKey.TITLE).length() > 0 || getFirstArtist().length() > 0 || getFirstAlbum().length() > 0 || getFirst(FieldKey.GENRE).length() > 0 || getFirst(FieldKey.YEAR).length() > 0 || getFirstComment().length() > 0);
 601  
     }
 602  
 
 603  
 
 604  
     public void setField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 605  
     {
 606  68
         TagField tagfield = createField(genericKey,value);
 607  68
         setField(tagfield);
 608  68
     }
 609  
 
 610  
     public void addField(FieldKey genericKey, String value) throws KeyNotFoundException, FieldDataInvalidException
 611  
     {
 612  4
         setField(genericKey,value);
 613  4
     }
 614  
 
 615  
     public void setField(TagField field)
 616  
     {
 617  136
         FieldKey genericKey = FieldKey.valueOf(field.getId());
 618  136
         switch (genericKey)
 619  
         {
 620  
             case ARTIST:
 621  28
                 setArtist(field.toString());
 622  28
                 break;
 623  
 
 624  
             case ALBUM:
 625  28
                 setAlbum(field.toString());
 626  28
                 break;
 627  
 
 628  
             case TITLE:
 629  24
                 setTitle(field.toString());
 630  24
                 break;
 631  
 
 632  
             case GENRE:
 633  16
                 setGenre(field.toString());
 634  16
                 break;
 635  
 
 636  
             case YEAR:
 637  12
                 setYear(field.toString());
 638  12
                 break;
 639  
 
 640  
             case COMMENT:
 641  28
                 setComment(field.toString());
 642  
                 break;
 643  
         }
 644  128
     }
 645  
 
 646  
     /**
 647  
      * @param encoding
 648  
      * @return
 649  
      */
 650  
     public boolean setEncoding(String encoding)
 651  
     {
 652  0
         return true;
 653  
     }
 654  
 
 655  
     /**
 656  
      * Create Tag Field using generic key
 657  
      */
 658  
     public TagField createField(FieldKey genericKey, String value)
 659  
     {
 660  76
         return new ID3v1TagField(tagFieldToID3v1Field.get(genericKey).name(), value);
 661  
     }
 662  
 
 663  
     public String getEncoding()
 664  
     {
 665  0
         return "ISO-8859-1";
 666  
     }
 667  
 
 668  
     public TagField getFirstField(FieldKey genericKey)
 669  
     {
 670  0
         List<TagField> l = getFields(genericKey);
 671  0
         return (l.size() != 0) ? l.get(0) : null;
 672  
     }
 673  
 
 674  
     /**
 675  
      * Returns a {@linkplain List list} of {@link TagField} objects whose &quot;{@linkplain TagField#getId() id}&quot;
 676  
      * is the specified one.<br>
 677  
      *
 678  
      * @param genericKey The generic field key
 679  
      * @return A list of {@link TagField} objects with the given &quot;id&quot;.
 680  
      */
 681  
     public List<TagField> getFields(FieldKey genericKey)
 682  
     {
 683  52
         switch (genericKey)
 684  
         {
 685  
             case ARTIST:
 686  8
                 return getArtist();
 687  
 
 688  
             case ALBUM:
 689  8
                 return getAlbum();
 690  
 
 691  
             case TITLE:
 692  8
                 return getTitle();
 693  
 
 694  
             case GENRE:
 695  8
                 return getGenre();
 696  
 
 697  
             case YEAR:
 698  8
                 return getYear();
 699  
 
 700  
             case COMMENT:
 701  12
                 return getComment();
 702  
 
 703  
             default:
 704  0
                 return new ArrayList<TagField>();
 705  
         }
 706  
     }
 707  
 
 708  
 
 709  
     /**
 710  
      * Retrieve the first value that exists for this key id
 711  
      *
 712  
      * @param genericKey
 713  
      * @return
 714  
      */
 715  
     public String getFirst(String genericKey)
 716  
     {
 717  0
         FieldKey matchingKey = FieldKey.valueOf(genericKey);
 718  0
         if (matchingKey != null)
 719  
         {
 720  0
             return getFirst(matchingKey);
 721  
         }
 722  
         else
 723  
         {
 724  0
             return "";
 725  
         }
 726  
     }
 727  
 
 728  
 
 729  
     /**
 730  
      * Retrieve the first value that exists for this generic key
 731  
      *
 732  
      * @param genericKey
 733  
      * @return
 734  
      */
 735  
     public String getFirst(FieldKey genericKey)
 736  
     {
 737  542
         switch (genericKey)
 738  
         {
 739  
             case ARTIST:
 740  97
                 return getFirstArtist();
 741  
 
 742  
             case ALBUM:
 743  40
                 return getFirstAlbum();
 744  
 
 745  
             case TITLE:
 746  133
                 return getFirstTitle();
 747  
 
 748  
             case GENRE:
 749  112
                 return getFirstGenre();
 750  
 
 751  
             case YEAR:
 752  108
                 return getFirstYear();
 753  
 
 754  
             case TRACK:
 755  48
                 return getFirstTrack();
 756  
 
 757  
             case COMMENT:
 758  4
                 return getFirstComment();
 759  
 
 760  
             default:
 761  0
                 return "";
 762  
         }
 763  
     }
 764  
 
 765  
     /**
 766  
      * Delete any instance of tag fields with this key
 767  
      *
 768  
      * @param genericKey
 769  
      */
 770  
     public void deleteField(FieldKey genericKey)
 771  
     {
 772  52
         switch (genericKey)
 773  
         {
 774  
             case ARTIST:
 775  8
                 setArtist("");
 776  8
                 break;
 777  
 
 778  
             case ALBUM:
 779  8
                 setAlbum("");
 780  8
                 break;
 781  
 
 782  
             case TITLE:
 783  12
                 setTitle("");
 784  12
                 break;
 785  
 
 786  
             case GENRE:
 787  8
                 setGenre("");
 788  8
                 break;
 789  
 
 790  
             case YEAR:
 791  8
                 setYear("");
 792  8
                 break;
 793  
 
 794  
             case COMMENT:
 795  8
                 setComment("");
 796  
                 break;
 797  
         }
 798  52
     }
 799  
 
 800  
     /**
 801  
      * @param obj
 802  
      * @return true if this and obj are equivalent
 803  
      */
 804  
     public boolean equals(Object obj)
 805  
     {
 806  0
         if (!(obj instanceof ID3v1Tag))
 807  
         {
 808  0
             return false;
 809  
         }
 810  0
         ID3v1Tag object = (ID3v1Tag) obj;
 811  0
         if (!this.album.equals(object.album))
 812  
         {
 813  0
             return false;
 814  
         }
 815  0
         if (!this.artist.equals(object.artist))
 816  
         {
 817  0
             return false;
 818  
         }
 819  0
         if (!this.comment.equals(object.comment))
 820  
         {
 821  0
             return false;
 822  
         }
 823  0
         if (this.genre != object.genre)
 824  
         {
 825  0
             return false;
 826  
         }
 827  0
         if (!this.title.equals(object.title))
 828  
         {
 829  0
             return false;
 830  
         }
 831  0
         return this.year.equals(object.year) && super.equals(obj);
 832  
     }
 833  
 
 834  
     /**
 835  
      * @return an iterator to iterate through the fields of the tag
 836  
      */
 837  
     public Iterator iterator()
 838  
     {
 839  0
         return new ID3v1Iterator(this);
 840  
     }
 841  
 
 842  
 
 843  
     /**
 844  
      * @param byteBuffer
 845  
      * @throws TagNotFoundException
 846  
      */
 847  
     public void read(ByteBuffer byteBuffer) throws TagNotFoundException
 848  
     {
 849  2012
         if (!seek(byteBuffer))
 850  
         {
 851  1730
             throw new TagNotFoundException(getLoggingFilename() + ":" + "ID3v1 tag not found");
 852  
         }
 853  282
         logger.finer(getLoggingFilename() + ":" + "Reading v1 tag");
 854  
         //Do single file read of data to cut down on file reads
 855  282
         byte[] dataBuffer = new byte[TAG_LENGTH];
 856  282
         byteBuffer.position(0);
 857  282
         byteBuffer.get(dataBuffer, 0, TAG_LENGTH);
 858  282
         title = Utils.getString(dataBuffer, FIELD_TITLE_POS, FIELD_TITLE_LENGTH, "ISO-8859-1").trim();
 859  282
         Matcher m = AbstractID3v1Tag.endofStringPattern.matcher(title);
 860  282
         if (m.find())
 861  
         {
 862  0
             title = title.substring(0, m.start());
 863  
         }
 864  282
         artist = Utils.getString(dataBuffer, FIELD_ARTIST_POS, FIELD_ARTIST_LENGTH, "ISO-8859-1").trim();
 865  282
         m = AbstractID3v1Tag.endofStringPattern.matcher(artist);
 866  282
         if (m.find())
 867  
         {
 868  0
             artist = artist.substring(0, m.start());
 869  
         }
 870  282
         album = Utils.getString(dataBuffer, FIELD_ALBUM_POS, FIELD_ALBUM_LENGTH, "ISO-8859-1").trim();
 871  282
         m = AbstractID3v1Tag.endofStringPattern.matcher(album);
 872  282
         logger.finest(getLoggingFilename() + ":" + "Orig Album is:" + comment + ":");
 873  282
         if (m.find())
 874  
         {
 875  0
             album = album.substring(0, m.start());
 876  0
             logger.finest(getLoggingFilename() + ":" + "Album is:" + album + ":");
 877  
         }
 878  282
         year = Utils.getString(dataBuffer, FIELD_YEAR_POS, FIELD_YEAR_LENGTH, "ISO-8859-1").trim();
 879  282
         m = AbstractID3v1Tag.endofStringPattern.matcher(year);
 880  282
         if (m.find())
 881  
         {
 882  0
             year = year.substring(0, m.start());
 883  
         }
 884  282
         comment = Utils.getString(dataBuffer, FIELD_COMMENT_POS, FIELD_COMMENT_LENGTH, "ISO-8859-1").trim();
 885  282
         m = AbstractID3v1Tag.endofStringPattern.matcher(comment);
 886  282
         logger.finest(getLoggingFilename() + ":" + "Orig Comment is:" + comment + ":");
 887  282
         if (m.find())
 888  
         {
 889  0
             comment = comment.substring(0, m.start());
 890  0
             logger.finest(getLoggingFilename() + ":" + "Comment is:" + comment + ":");
 891  
         }
 892  282
         genre = dataBuffer[FIELD_GENRE_POS];
 893  
 
 894  282
     }
 895  
 
 896  
     /**
 897  
      * Does a tag of this version exist within the byteBuffer
 898  
      *
 899  
      * @return whether tag exists within the byteBuffer
 900  
      */
 901  
     public boolean seek(ByteBuffer byteBuffer)
 902  
     {
 903  3217
         byte[] buffer = new byte[FIELD_TAGID_LENGTH];
 904  
         // read the TAG value
 905  3217
         byteBuffer.get(buffer, 0, FIELD_TAGID_LENGTH);
 906  3217
         return (Arrays.equals(buffer, TAG_ID));
 907  
     }
 908  
 
 909  
     /**
 910  
      * Write this tag to the file, replacing any tag previously existing
 911  
      *
 912  
      * @param file
 913  
      * @throws IOException
 914  
      */
 915  
     public void write(RandomAccessFile file) throws IOException
 916  
     {
 917  242
         logger.info("Saving ID3v1 tag to file");
 918  242
         byte[] buffer = new byte[TAG_LENGTH];
 919  
         int i;
 920  
         String str;
 921  242
         delete(file);
 922  242
         file.seek(file.length());
 923  
         //Copy the TAGID into new buffer
 924  242
         System.arraycopy(TAG_ID, FIELD_TAGID_POS, buffer, FIELD_TAGID_POS, TAG_ID.length);
 925  242
         int offset = FIELD_TITLE_POS;
 926  242
         if (TagOptionSingleton.getInstance().isId3v1SaveTitle())
 927  
         {
 928  242
             str = ID3Tags.truncate(title, FIELD_TITLE_LENGTH);
 929  396
             for (i = 0; i < str.length(); i++)
 930  
             {
 931  154
                 buffer[i + offset] = (byte) str.charAt(i);
 932  
             }
 933  
         }
 934  242
         offset = FIELD_ARTIST_POS;
 935  242
         if (TagOptionSingleton.getInstance().isId3v1SaveArtist())
 936  
         {
 937  242
             str = ID3Tags.truncate(artist, FIELD_ARTIST_LENGTH);
 938  2154
             for (i = 0; i < str.length(); i++)
 939  
             {
 940  1912
                 buffer[i + offset] = (byte) str.charAt(i);
 941  
             }
 942  
         }
 943  242
         offset = FIELD_ALBUM_POS;
 944  242
         if (TagOptionSingleton.getInstance().isId3v1SaveAlbum())
 945  
         {
 946  242
             str = ID3Tags.truncate(album, FIELD_ALBUM_LENGTH);
 947  1896
             for (i = 0; i < str.length(); i++)
 948  
             {
 949  1654
                 buffer[i + offset] = (byte) str.charAt(i);
 950  
             }
 951  
         }
 952  242
         offset = FIELD_YEAR_POS;
 953  242
         if (TagOptionSingleton.getInstance().isId3v1SaveYear())
 954  
         {
 955  242
             str = ID3Tags.truncate(year, AbstractID3v1Tag.FIELD_YEAR_LENGTH);
 956  314
             for (i = 0; i < str.length(); i++)
 957  
             {
 958  72
                 buffer[i + offset] = (byte) str.charAt(i);
 959  
             }
 960  
         }
 961  242
         offset = FIELD_COMMENT_POS;
 962  242
         if (TagOptionSingleton.getInstance().isId3v1SaveComment())
 963  
         {
 964  242
             str = ID3Tags.truncate(comment, FIELD_COMMENT_LENGTH);
 965  298
             for (i = 0; i < str.length(); i++)
 966  
             {
 967  56
                 buffer[i + offset] = (byte) str.charAt(i);
 968  
             }
 969  
         }
 970  242
         offset = FIELD_GENRE_POS;
 971  242
         if (TagOptionSingleton.getInstance().isId3v1SaveGenre())
 972  
         {
 973  242
             buffer[offset] = genre;
 974  
         }
 975  242
         file.write(buffer);
 976  242
         logger.info("Saved ID3v1 tag to file");
 977  242
     }
 978  
 
 979  
     /**
 980  
      * Create strcutured representation of this item.
 981  
      */
 982  
     public void createStructure()
 983  
     {
 984  0
         MP3File.getStructureFormatter().openHeadingElement(TYPE_TAG, getIdentifier());
 985  
         //Header
 986  0
         MP3File.getStructureFormatter().addElement(TYPE_TITLE, this.title);
 987  0
         MP3File.getStructureFormatter().addElement(TYPE_ARTIST, this.artist);
 988  0
         MP3File.getStructureFormatter().addElement(TYPE_ALBUM, this.album);
 989  0
         MP3File.getStructureFormatter().addElement(TYPE_YEAR, this.year);
 990  0
         MP3File.getStructureFormatter().addElement(TYPE_COMMENT, this.comment);
 991  0
         MP3File.getStructureFormatter().addElement(TYPE_GENRE, this.genre);
 992  0
         MP3File.getStructureFormatter().closeHeadingElement(TYPE_TAG);
 993  0
     }
 994  
 
 995  
     public List<Artwork> getArtworkList()
 996  
     {
 997  0
        return Collections.emptyList();
 998  
     }
 999  
 
 1000  
     public Artwork getFirstArtwork()
 1001  
     {           
 1002  0
         return null;
 1003  
     }
 1004  
 
 1005  
     public TagField createField(Artwork artwork) throws FieldDataInvalidException
 1006  
     {
 1007  0
         throw new UnsupportedOperationException(ErrorMessage.GENERIC_NOT_SUPPORTED.getMsg());
 1008  
     }
 1009  
 
 1010  
     public void setField(Artwork artwork) throws FieldDataInvalidException
 1011  
     {
 1012  0
         throw new UnsupportedOperationException(ErrorMessage.GENERIC_NOT_SUPPORTED.getMsg());
 1013  
     }
 1014  
 
 1015  
     public void addField(Artwork artwork) throws FieldDataInvalidException
 1016  
     {
 1017  0
         throw new UnsupportedOperationException(ErrorMessage.GENERIC_NOT_SUPPORTED.getMsg());
 1018  
     }
 1019  
     /**
 1020  
      * Delete all instance of artwork Field
 1021  
      *
 1022  
      * @throws KeyNotFoundException
 1023  
      */
 1024  
     public void deleteArtworkField() throws KeyNotFoundException
 1025  
     {
 1026  0
         throw new UnsupportedOperationException(ErrorMessage.GENERIC_NOT_SUPPORTED.getMsg());
 1027  
     }
 1028  
 }