Coverage Report - org.jaudiotagger.tag.TagOptionSingleton
 
Classes in this File Line Coverage Branch Coverage Complexity
TagOptionSingleton
73%
182/247
50%
19/38
1.306
 
 1  
 /**
 2  
  *  @author : Paul Taylor
 3  
  *  @author : Eric Farng
 4  
  *
 5  
  *  Version @version:$Id: TagOptionSingleton.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  
  * Options that are used for every datatype and class in this library.
 23  
  *
 24  
  */
 25  
 package org.jaudiotagger.tag;
 26  
 
 27  
 import org.jaudiotagger.tag.id3.framebody.AbstractID3v2FrameBody;
 28  
 import org.jaudiotagger.tag.id3.framebody.FrameBodyCOMM;
 29  
 import org.jaudiotagger.tag.id3.framebody.FrameBodyTIPL;
 30  
 import org.jaudiotagger.tag.id3.framebody.ID3v24FrameBody;
 31  
 import org.jaudiotagger.tag.id3.valuepair.TextEncoding;
 32  
 import org.jaudiotagger.tag.lyrics3.Lyrics3v2Fields;
 33  
 import org.jaudiotagger.tag.reference.GenreTypes;
 34  
 import org.jaudiotagger.tag.reference.Languages;
 35  
 
 36  
 import java.util.HashMap;
 37  
 import java.util.Iterator;
 38  
 import java.util.LinkedList;
 39  
 
 40  
 public class TagOptionSingleton
 41  
 {
 42  
     /**
 43  
      *
 44  
      */
 45  4
     private static HashMap<String, TagOptionSingleton> tagOptionTable = new HashMap<String, TagOptionSingleton>();
 46  
 
 47  
     /**
 48  
      *
 49  
      */
 50  4
     private static String DEFAULT = "default";
 51  
 
 52  
     /**
 53  
      *
 54  
      */
 55  4
     private static String defaultOptions = DEFAULT;
 56  
 
 57  
     /**
 58  
      *
 59  
      */
 60  4
     private HashMap<Class<? extends ID3v24FrameBody>, LinkedList<String>> keywordMap = new HashMap<Class<? extends ID3v24FrameBody>, LinkedList<String>>();
 61  
 
 62  
     /**
 63  
      * Map of lyric ID's to Boolean objects if we should or should not save the
 64  
      * specific Kyrics3 field. Defaults to true.
 65  
      */
 66  4
     private HashMap<String, Boolean> lyrics3SaveFieldMap = new HashMap<String, Boolean>();
 67  
 
 68  
     /**
 69  
      * parenthesis map stuff
 70  
      */
 71  4
     private HashMap<String, String> parenthesisMap = new HashMap<String, String>();
 72  
 
 73  
     /**
 74  
      * <code>HashMap</code> listing words to be replaced if found
 75  
      */
 76  4
     private HashMap<String, String> replaceWordMap = new HashMap<String, String>();
 77  
 
 78  
 
 79  
     /**
 80  
      * default language for any ID3v2 tags frameswhich require it. This string
 81  
      * is in the [ISO-639-2] ISO/FDIS 639-2 definition
 82  
      */
 83  4
     private String language = "eng";
 84  
 
 85  
 
 86  
     /**
 87  
      *
 88  
      */
 89  4
     private boolean filenameTagSave = false;
 90  
 
 91  
     /**
 92  
      * if we should save any fields of the ID3v1 tag or not. Defaults to true.
 93  
      */
 94  4
     private boolean id3v1Save = true;
 95  
 
 96  
     /**
 97  
      * if we should save the album field of the ID3v1 tag or not. Defaults to
 98  
      * true.
 99  
      */
 100  4
     private boolean id3v1SaveAlbum = true;
 101  
 
 102  
     /**
 103  
      * if we should save the artist field of the ID3v1 tag or not. Defaults to
 104  
      * true.
 105  
      */
 106  4
     private boolean id3v1SaveArtist = true;
 107  
 
 108  
     /**
 109  
      * if we should save the comment field of the ID3v1 tag or not. Defaults to
 110  
      * true.
 111  
      */
 112  4
     private boolean id3v1SaveComment = true;
 113  
 
 114  
     /**
 115  
      * if we should save the genre field of the ID3v1 tag or not. Defaults to
 116  
      * true.
 117  
      */
 118  4
     private boolean id3v1SaveGenre = true;
 119  
 
 120  
     /**
 121  
      * if we should save the title field of the ID3v1 tag or not. Defaults to
 122  
      * true.
 123  
      */
 124  4
     private boolean id3v1SaveTitle = true;
 125  
 
 126  
     /**
 127  
      * if we should save the track field of the ID3v1 tag or not. Defaults to
 128  
      * true.
 129  
      */
 130  4
     private boolean id3v1SaveTrack = true;
 131  
 
 132  
     /**
 133  
      * if we should save the year field of the ID3v1 tag or not. Defaults to
 134  
      * true.
 135  
      */
 136  4
     private boolean id3v1SaveYear = true;
 137  
 
 138  
 
 139  
     /**
 140  
      * When adjusting the ID3v2 padding, if should we copy the current ID3v2
 141  
      * tag to the new MP3 file. Defaults to true.
 142  
      */
 143  4
     private boolean id3v2PaddingCopyTag = true;
 144  
 
 145  
     /**
 146  
      * When adjusting the ID3v2 padding, if we should shorten the length of the
 147  
      * ID3v2 tag padding. Defaults to false.
 148  
      */
 149  4
     private boolean id3v2PaddingWillShorten = false;
 150  
 
 151  
     /**
 152  
      * if we should save any fields of the ID3v2 tag or not. Defaults to true.
 153  
      */
 154  4
     private boolean id3v2Save = true;
 155  
 
 156  
 
 157  
     /**
 158  
      * if we should keep an empty Lyrics3 field while we're reading. This is
 159  
      * different from a string of white space. Defaults to false.
 160  
      */
 161  4
     private boolean lyrics3KeepEmptyFieldIfRead = false;
 162  
 
 163  
     /**
 164  
      * if we should save any fields of the Lyrics3 tag or not. Defaults to
 165  
      * true.
 166  
      */
 167  4
     private boolean lyrics3Save = true;
 168  
 
 169  
     /**
 170  
      * if we should save empty Lyrics3 field or not. Defaults to false.
 171  
      * <p/>
 172  
      * todo I don't think this is implemented yet.
 173  
      */
 174  4
     private boolean lyrics3SaveEmptyField = false;
 175  
 
 176  
     /**
 177  
      *
 178  
      */
 179  4
     private boolean originalSavedAfterAdjustingID3v2Padding = true;
 180  
 
 181  
 
 182  
     /**
 183  
      * default time stamp format for any ID3v2 tag frames which require it.
 184  
      */
 185  4
     private byte timeStampFormat = 2;
 186  
 
 187  
     /**
 188  
      * number of frames to sync when trying to find the start of the MP3 frame
 189  
      * data. The start of the MP3 frame data is the start of the music and is
 190  
      * different from the ID3v2 frame data.
 191  
      */
 192  4
     private int numberMP3SyncFrame = 3;
 193  
 
 194  
     /**
 195  
      * Unsynchronize tags/frames this is rarely required these days and can cause more
 196  
      * problems than it solves
 197  
      */
 198  4
     private boolean unsyncTags = false;
 199  
 
 200  
     /**
 201  
      * iTunes needlessly writes null terminators at the end for TextEncodedStringSizeTerminated values,
 202  
      * if this option is enabled these characters are removed
 203  
      */
 204  4
     private boolean removeTrailingTerminatorOnWrite = true;
 205  
 
 206  
     /**
 207  
      * This is the default text encoding to use for new v23 frames, when unicode is required
 208  
      * UTF16 will always be used because that is the only valid option for v23.
 209  
      */
 210  4
     private byte id3v23DefaultTextEncoding = TextEncoding.ISO_8859_1;
 211  
 
 212  
     /**
 213  
      * This is the default text encoding to use for new v24 frames, it defaults to simple ISO8859
 214  
      * but by changing this value you could always used UTF8 for example whether you needed to or not
 215  
      */
 216  4
     private byte id3v24DefaultTextEncoding = TextEncoding.ISO_8859_1;
 217  
 
 218  
     /**
 219  
      * This is text encoding to use for new v24 frames when unicode is required, it defaults to UTF16 just
 220  
      * because this encoding is understand by all ID3 versions
 221  
      */
 222  4
     private byte id3v24UnicodeTextEncoding = TextEncoding.UTF_16;
 223  
 
 224  
 
 225  
     /**
 226  
      * When writing frames if this is set to true then the frame will be written
 227  
      * using the defaults disregarding the text encoding originally used to create
 228  
      * the frame.
 229  
      */
 230  4
     private boolean resetTextEncodingForExistingFrames = false;
 231  
 
 232  
     /**
 233  
      * Some formats impose maxmimum lengths for fields , if the text provided is longer
 234  
      * than the formats allows it will truncate and write a warning, if this is not set
 235  
      * it will throw an exception
 236  
      */
 237  4
     private boolean truncateTextWithoutErrors = false;
 238  
 
 239  
     /**
 240  
      * Frames such as TRCK and TPOS sometimes pad single didgit numbers to aid sorting
 241  
      */
 242  4
     private boolean padNumbers = false;
 243  
 
 244  
     /**
 245  
      * Creates a new TagOptions datatype. All Options are set to their default
 246  
      * values
 247  
      */
 248  
     private TagOptionSingleton()
 249  4
     {
 250  4
         setToDefault();
 251  4
     }
 252  
 
 253  
 
 254  
     /**
 255  
      * @return
 256  
      */
 257  
     public static TagOptionSingleton getInstance()
 258  
     {
 259  20892
         return getInstance(defaultOptions);
 260  
     }
 261  
 
 262  
     /**
 263  
      * @param instanceKey
 264  
      * @return
 265  
      */
 266  
     public static TagOptionSingleton getInstance(String instanceKey)
 267  
     {
 268  20892
         TagOptionSingleton tagOptions = tagOptionTable.get(instanceKey);
 269  
 
 270  20892
         if (tagOptions == null)
 271  
         {
 272  4
             tagOptions = new TagOptionSingleton();
 273  4
             tagOptionTable.put(instanceKey, tagOptions);
 274  
         }
 275  
 
 276  20892
         return tagOptions;
 277  
     }
 278  
 
 279  
     /**
 280  
      * @param filenameTagSave
 281  
      */
 282  
     public void setFilenameTagSave(boolean filenameTagSave)
 283  
     {
 284  0
         this.filenameTagSave = filenameTagSave;
 285  0
     }
 286  
 
 287  
     /**
 288  
      * @return
 289  
      */
 290  
     public boolean isFilenameTagSave()
 291  
     {
 292  0
         return filenameTagSave;
 293  
     }
 294  
 
 295  
 
 296  
     /**
 297  
      * @param instanceKey
 298  
      */
 299  
     public void setInstanceKey(String instanceKey)
 300  
     {
 301  0
         TagOptionSingleton.defaultOptions = instanceKey;
 302  0
     }
 303  
 
 304  
     /**
 305  
      * @return
 306  
      */
 307  
     public static String getInstanceKey()
 308  
     {
 309  0
         return defaultOptions;
 310  
     }
 311  
 
 312  
 
 313  
     /**
 314  
      * @param id3v1Save
 315  
      */
 316  
     public void setId3v1Save(boolean id3v1Save)
 317  
     {
 318  0
         this.id3v1Save = id3v1Save;
 319  0
     }
 320  
 
 321  
     /**
 322  
      * @return
 323  
      */
 324  
     public boolean isId3v1Save()
 325  
     {
 326  1239
         return id3v1Save;
 327  
     }
 328  
 
 329  
     /**
 330  
      * @param id3v1SaveAlbum
 331  
      */
 332  
     public void setId3v1SaveAlbum(boolean id3v1SaveAlbum)
 333  
     {
 334  0
         this.id3v1SaveAlbum = id3v1SaveAlbum;
 335  0
     }
 336  
 
 337  
     /**
 338  
      * @return
 339  
      */
 340  
     public boolean isId3v1SaveAlbum()
 341  
     {
 342  276
         return id3v1SaveAlbum;
 343  
     }
 344  
 
 345  
     /**
 346  
      * @param id3v1SaveArtist
 347  
      */
 348  
     public void setId3v1SaveArtist(boolean id3v1SaveArtist)
 349  
     {
 350  0
         this.id3v1SaveArtist = id3v1SaveArtist;
 351  0
     }
 352  
 
 353  
     /**
 354  
      * @return
 355  
      */
 356  
     public boolean isId3v1SaveArtist()
 357  
     {
 358  276
         return id3v1SaveArtist;
 359  
     }
 360  
 
 361  
     /**
 362  
      * @param id3v1SaveComment
 363  
      */
 364  
     public void setId3v1SaveComment(boolean id3v1SaveComment)
 365  
     {
 366  0
         this.id3v1SaveComment = id3v1SaveComment;
 367  0
     }
 368  
 
 369  
     /**
 370  
      * @return
 371  
      */
 372  
     public boolean isId3v1SaveComment()
 373  
     {
 374  276
         return id3v1SaveComment;
 375  
     }
 376  
 
 377  
     /**
 378  
      * @param id3v1SaveGenre
 379  
      */
 380  
     public void setId3v1SaveGenre(boolean id3v1SaveGenre)
 381  
     {
 382  0
         this.id3v1SaveGenre = id3v1SaveGenre;
 383  0
     }
 384  
 
 385  
     /**
 386  
      * @return
 387  
      */
 388  
     public boolean isId3v1SaveGenre()
 389  
     {
 390  276
         return id3v1SaveGenre;
 391  
     }
 392  
 
 393  
     /**
 394  
      * @param id3v1SaveTitle
 395  
      */
 396  
     public void setId3v1SaveTitle(boolean id3v1SaveTitle)
 397  
     {
 398  0
         this.id3v1SaveTitle = id3v1SaveTitle;
 399  0
     }
 400  
 
 401  
     /**
 402  
      * @return
 403  
      */
 404  
     public boolean isId3v1SaveTitle()
 405  
     {
 406  276
         return id3v1SaveTitle;
 407  
     }
 408  
 
 409  
     /**
 410  
      * @param id3v1SaveTrack
 411  
      */
 412  
     public void setId3v1SaveTrack(boolean id3v1SaveTrack)
 413  
     {
 414  0
         this.id3v1SaveTrack = id3v1SaveTrack;
 415  0
     }
 416  
 
 417  
     /**
 418  
      * @return
 419  
      */
 420  
     public boolean isId3v1SaveTrack()
 421  
     {
 422  0
         return id3v1SaveTrack;
 423  
     }
 424  
 
 425  
     /**
 426  
      * @param id3v1SaveYear
 427  
      */
 428  
     public void setId3v1SaveYear(boolean id3v1SaveYear)
 429  
     {
 430  0
         this.id3v1SaveYear = id3v1SaveYear;
 431  0
     }
 432  
 
 433  
     /**
 434  
      * @return
 435  
      */
 436  
     public boolean isId3v1SaveYear()
 437  
     {
 438  276
         return id3v1SaveYear;
 439  
     }
 440  
 
 441  
 
 442  
     /**
 443  
      * @param id3v2PaddingCopyTag
 444  
      */
 445  
     public void setId3v2PaddingCopyTag(boolean id3v2PaddingCopyTag)
 446  
     {
 447  0
         this.id3v2PaddingCopyTag = id3v2PaddingCopyTag;
 448  0
     }
 449  
 
 450  
     /**
 451  
      * @return
 452  
      */
 453  
     public boolean isId3v2PaddingCopyTag()
 454  
     {
 455  0
         return id3v2PaddingCopyTag;
 456  
     }
 457  
 
 458  
 
 459  
     /**
 460  
      * @param id3v2PaddingWillShorten
 461  
      */
 462  
     public void setId3v2PaddingWillShorten(boolean id3v2PaddingWillShorten)
 463  
     {
 464  0
         this.id3v2PaddingWillShorten = id3v2PaddingWillShorten;
 465  0
     }
 466  
 
 467  
     /**
 468  
      * @return
 469  
      */
 470  
     public boolean isId3v2PaddingWillShorten()
 471  
     {
 472  0
         return id3v2PaddingWillShorten;
 473  
     }
 474  
 
 475  
     /**
 476  
      * @param id3v2Save
 477  
      */
 478  
     public void setId3v2Save(boolean id3v2Save)
 479  
     {
 480  0
         this.id3v2Save = id3v2Save;
 481  0
     }
 482  
 
 483  
     /**
 484  
      * @return
 485  
      */
 486  
     public boolean isId3v2Save()
 487  
     {
 488  1239
         return id3v2Save;
 489  
     }
 490  
 
 491  
 
 492  
     /**
 493  
      * @return
 494  
      */
 495  
     public Iterator<Class<? extends ID3v24FrameBody>> getKeywordIterator()
 496  
     {
 497  0
         return keywordMap.keySet().iterator();
 498  
     }
 499  
 
 500  
     /**
 501  
      * @param id3v2_4FrameBody
 502  
      * @return
 503  
      */
 504  
     public Iterator<String> getKeywordListIterator(Class<? extends ID3v24FrameBody> id3v2_4FrameBody)
 505  
     {
 506  1909
         return keywordMap.get(id3v2_4FrameBody).iterator();
 507  
     }
 508  
 
 509  
     /**
 510  
      * Sets the default language for any ID3v2 tag frames which require it.
 511  
      * While the value will already exist when reading from a file, this value
 512  
      * will be used when a new ID3v2 Frame is created from scratch.
 513  
      *
 514  
      * @param lang language ID, [ISO-639-2] ISO/FDIS 639-2 definition
 515  
      */
 516  
     public void setLanguage(String lang)
 517  
     {
 518  0
         if (Languages.getInstanceOf().getIdToValueMap().containsKey(lang))
 519  
         {
 520  0
             language = lang;
 521  
         }
 522  0
     }
 523  
 
 524  
     /**
 525  
      * Returns the default language for any ID3v2 tag frames which require it.
 526  
      *
 527  
      * @return language ID, [ISO-639-2] ISO/FDIS 639-2 definition
 528  
      */
 529  
     public String getLanguage()
 530  
     {
 531  0
         return language;
 532  
     }
 533  
 
 534  
     /**
 535  
      * @param lyrics3KeepEmptyFieldIfRead
 536  
      */
 537  
     public void setLyrics3KeepEmptyFieldIfRead(boolean lyrics3KeepEmptyFieldIfRead)
 538  
     {
 539  0
         this.lyrics3KeepEmptyFieldIfRead = lyrics3KeepEmptyFieldIfRead;
 540  0
     }
 541  
 
 542  
     /**
 543  
      * @return
 544  
      */
 545  
     public boolean isLyrics3KeepEmptyFieldIfRead()
 546  
     {
 547  0
         return lyrics3KeepEmptyFieldIfRead;
 548  
     }
 549  
 
 550  
     /**
 551  
      * @param lyrics3Save
 552  
      */
 553  
     public void setLyrics3Save(boolean lyrics3Save)
 554  
     {
 555  0
         this.lyrics3Save = lyrics3Save;
 556  0
     }
 557  
 
 558  
     /**
 559  
      * @return
 560  
      */
 561  
     public boolean isLyrics3Save()
 562  
     {
 563  1239
         return lyrics3Save;
 564  
     }
 565  
 
 566  
     /**
 567  
      * @param lyrics3SaveEmptyField
 568  
      */
 569  
     public void setLyrics3SaveEmptyField(boolean lyrics3SaveEmptyField)
 570  
     {
 571  0
         this.lyrics3SaveEmptyField = lyrics3SaveEmptyField;
 572  0
     }
 573  
 
 574  
     /**
 575  
      * @return
 576  
      */
 577  
     public boolean isLyrics3SaveEmptyField()
 578  
     {
 579  0
         return lyrics3SaveEmptyField;
 580  
     }
 581  
 
 582  
     /**
 583  
      * Sets if we should save the Lyrics3 field. Defaults to true.
 584  
      *
 585  
      * @param id   Lyrics3 id string
 586  
      * @param save true if you want to save this specific Lyrics3 field.
 587  
      */
 588  
     public void setLyrics3SaveField(String id, boolean save)
 589  
     {
 590  0
         this.lyrics3SaveFieldMap.put(id, save);
 591  0
     }
 592  
 
 593  
     /**
 594  
      * Returns true if we should save the Lyrics3 field asked for in the
 595  
      * argument. Defaults to true.
 596  
      *
 597  
      * @param id Lyrics3 id string
 598  
      * @return true if we should save the Lyrics3 field.
 599  
      */
 600  
     public boolean getLyrics3SaveField(String id)
 601  
     {
 602  0
         return lyrics3SaveFieldMap.get(id);
 603  
     }
 604  
 
 605  
     /**
 606  
      * @return
 607  
      */
 608  
     public HashMap<String, Boolean> getLyrics3SaveFieldMap()
 609  
     {
 610  0
         return lyrics3SaveFieldMap;
 611  
     }
 612  
 
 613  
     /**
 614  
      * @param oldWord
 615  
      * @return
 616  
      */
 617  
     public String getNewReplaceWord(String oldWord)
 618  
     {
 619  0
         return replaceWordMap.get(oldWord);
 620  
     }
 621  
 
 622  
     /**
 623  
      * Sets the number of MP3 frames to sync when trying to find the start of
 624  
      * the MP3 frame data. The start of the MP3 frame data is the start of the
 625  
      * music and is different from the ID3v2 frame data. WinAmp 2.8 seems to
 626  
      * sync 3 frames. Default is 5.
 627  
      *
 628  
      * @param numberMP3SyncFrame number of MP3 frames to sync
 629  
      */
 630  
     public void setNumberMP3SyncFrame(int numberMP3SyncFrame)
 631  
     {
 632  0
         this.numberMP3SyncFrame = numberMP3SyncFrame;
 633  0
     }
 634  
 
 635  
     /**
 636  
      * Returns the number of MP3 frames to sync when trying to find the start
 637  
      * of the MP3 frame data. The start of the MP3 frame data is the start of
 638  
      * the music and is different from the ID3v2 frame data. WinAmp 2.8 seems
 639  
      * to sync 3 frames. Default is 5.
 640  
      *
 641  
      * @return number of MP3 frames to sync
 642  
      */
 643  
     public int getNumberMP3SyncFrame()
 644  
     {
 645  0
         return numberMP3SyncFrame;
 646  
     }
 647  
 
 648  
     /**
 649  
      * @return
 650  
      */
 651  
     public Iterator<String> getOldReplaceWordIterator()
 652  
     {
 653  0
         return replaceWordMap.keySet().iterator();
 654  
     }
 655  
 
 656  
     /**
 657  
      * @param open
 658  
      * @return
 659  
      */
 660  
     public boolean isOpenParenthesis(String open)
 661  
     {
 662  0
         return parenthesisMap.containsKey(open);
 663  
     }
 664  
 
 665  
     /**
 666  
      * @return
 667  
      */
 668  
     public Iterator<String> getOpenParenthesisIterator()
 669  
     {
 670  0
         return parenthesisMap.keySet().iterator();
 671  
     }
 672  
 
 673  
     /**
 674  
      * @param originalSavedAfterAdjustingID3v2Padding
 675  
      *
 676  
      */
 677  
     public void setOriginalSavedAfterAdjustingID3v2Padding(boolean originalSavedAfterAdjustingID3v2Padding)
 678  
     {
 679  0
         this.originalSavedAfterAdjustingID3v2Padding = originalSavedAfterAdjustingID3v2Padding;
 680  0
     }
 681  
 
 682  
     /**
 683  
      * @return
 684  
      */
 685  
     public boolean isOriginalSavedAfterAdjustingID3v2Padding()
 686  
     {
 687  0
         return originalSavedAfterAdjustingID3v2Padding;
 688  
     }
 689  
 
 690  
 
 691  
     /**
 692  
      * Sets the default time stamp format for ID3v2 tags which require it.
 693  
      * While the value will already exist when reading from a file, this value
 694  
      * will be used when a new ID3v2 Frame is created from scratch.
 695  
      * <p/>
 696  
      * <p/>
 697  
      * $01  Absolute time, 32 bit sized, using MPEG frames as unit<br>
 698  
      * $02  Absolute time, 32 bit sized, using milliseconds as unit<br>
 699  
      * </p>
 700  
      *
 701  
      * @param tsf the new default time stamp format
 702  
      */
 703  
     public void setTimeStampFormat(byte tsf)
 704  
     {
 705  0
         if ((tsf == 1) || (tsf == 2))
 706  
         {
 707  0
             timeStampFormat = tsf;
 708  
         }
 709  0
     }
 710  
 
 711  
     /**
 712  
      * Returns the default time stamp format for ID3v2 tags which require it.
 713  
      * <p/>
 714  
      * <p/>
 715  
      * $01  Absolute time, 32 bit sized, using MPEG frames as unit<br>
 716  
      * $02  Absolute time, 32 bit sized, using milliseconds as unit<br>
 717  
      * </p>
 718  
      *
 719  
      * @return the default time stamp format
 720  
      */
 721  
     public byte getTimeStampFormat()
 722  
     {
 723  0
         return timeStampFormat;
 724  
     }
 725  
 
 726  
     /**
 727  
      *
 728  
      */
 729  
     public void setToDefault()
 730  
     {
 731  1909
         keywordMap = new HashMap<Class<? extends ID3v24FrameBody>, LinkedList<String>>();
 732  1909
         filenameTagSave = false;
 733  1909
         id3v1Save = true;
 734  1909
         id3v1SaveAlbum = true;
 735  1909
         id3v1SaveArtist = true;
 736  1909
         id3v1SaveComment = true;
 737  1909
         id3v1SaveGenre = true;
 738  1909
         id3v1SaveTitle = true;
 739  1909
         id3v1SaveTrack = true;
 740  1909
         id3v1SaveYear = true;
 741  1909
         id3v2PaddingCopyTag = true;
 742  1909
         id3v2PaddingWillShorten = false;
 743  1909
         id3v2Save = true;
 744  1909
         language = "eng";
 745  1909
         lyrics3KeepEmptyFieldIfRead = false;
 746  1909
         lyrics3Save = true;
 747  1909
         lyrics3SaveEmptyField = false;
 748  1909
         lyrics3SaveFieldMap = new HashMap<String, Boolean>();
 749  1909
         numberMP3SyncFrame = 3;
 750  1909
         parenthesisMap = new HashMap<String, String>();
 751  1909
         replaceWordMap = new HashMap<String, String>();
 752  1909
         timeStampFormat = 2;
 753  1909
         unsyncTags = false;
 754  1909
         removeTrailingTerminatorOnWrite = true;
 755  1909
         id3v23DefaultTextEncoding = TextEncoding.ISO_8859_1;
 756  1909
         id3v24DefaultTextEncoding = TextEncoding.ISO_8859_1;
 757  1909
         id3v24UnicodeTextEncoding = TextEncoding.UTF_16;
 758  1909
         resetTextEncodingForExistingFrames = false;
 759  1909
         truncateTextWithoutErrors = false;
 760  1909
         padNumbers = false;
 761  
 
 762  
         //default all lyrics3 fields to save. id3v1 fields are individual
 763  
         // settings. id3v2 fields are always looked at to save.
 764  1909
         Iterator<String> iterator = Lyrics3v2Fields.getInstanceOf().getIdToValueMap().keySet().iterator();
 765  
         String fieldId;
 766  
 
 767  17181
         while (iterator.hasNext())
 768  
         {
 769  15272
             fieldId = iterator.next();
 770  15272
             lyrics3SaveFieldMap.put(fieldId, true);
 771  
         }
 772  
 
 773  
         try
 774  
         {
 775  1909
             addKeyword(FrameBodyCOMM.class, "ultimix");
 776  1909
             addKeyword(FrameBodyCOMM.class, "dance");
 777  1909
             addKeyword(FrameBodyCOMM.class, "mix");
 778  1909
             addKeyword(FrameBodyCOMM.class, "remix");
 779  1909
             addKeyword(FrameBodyCOMM.class, "rmx");
 780  1909
             addKeyword(FrameBodyCOMM.class, "live");
 781  1909
             addKeyword(FrameBodyCOMM.class, "cover");
 782  1909
             addKeyword(FrameBodyCOMM.class, "soundtrack");
 783  1909
             addKeyword(FrameBodyCOMM.class, "version");
 784  1909
             addKeyword(FrameBodyCOMM.class, "acoustic");
 785  1909
             addKeyword(FrameBodyCOMM.class, "original");
 786  1909
             addKeyword(FrameBodyCOMM.class, "cd");
 787  1909
             addKeyword(FrameBodyCOMM.class, "extended");
 788  1909
             addKeyword(FrameBodyCOMM.class, "vocal");
 789  1909
             addKeyword(FrameBodyCOMM.class, "unplugged");
 790  1909
             addKeyword(FrameBodyCOMM.class, "acapella");
 791  1909
             addKeyword(FrameBodyCOMM.class, "edit");
 792  1909
             addKeyword(FrameBodyCOMM.class, "radio");
 793  1909
             addKeyword(FrameBodyCOMM.class, "original");
 794  1909
             addKeyword(FrameBodyCOMM.class, "album");
 795  1909
             addKeyword(FrameBodyCOMM.class, "studio");
 796  1909
             addKeyword(FrameBodyCOMM.class, "instrumental");
 797  1909
             addKeyword(FrameBodyCOMM.class, "unedited");
 798  1909
             addKeyword(FrameBodyCOMM.class, "karoke");
 799  1909
             addKeyword(FrameBodyCOMM.class, "quality");
 800  1909
             addKeyword(FrameBodyCOMM.class, "uncensored");
 801  1909
             addKeyword(FrameBodyCOMM.class, "clean");
 802  1909
             addKeyword(FrameBodyCOMM.class, "dirty");
 803  
 
 804  1909
             addKeyword(FrameBodyTIPL.class, "f.");
 805  1909
             addKeyword(FrameBodyTIPL.class, "feat");
 806  1909
             addKeyword(FrameBodyTIPL.class, "feat.");
 807  1909
             addKeyword(FrameBodyTIPL.class, "featuring");
 808  1909
             addKeyword(FrameBodyTIPL.class, "ftng");
 809  1909
             addKeyword(FrameBodyTIPL.class, "ftng.");
 810  1909
             addKeyword(FrameBodyTIPL.class, "ft.");
 811  1909
             addKeyword(FrameBodyTIPL.class, "ft");
 812  
 
 813  1909
             iterator = GenreTypes.getInstanceOf().getValueToIdMap().keySet().iterator();
 814  
 
 815  284441
             while (iterator.hasNext())
 816  
             {
 817  282532
                 addKeyword(FrameBodyCOMM.class, iterator.next());
 818  
             }
 819  
         }
 820  0
         catch (TagException ex)
 821  
         {
 822  
             // this shouldn't happen, indicates coding error
 823  0
             throw new RuntimeException(ex);
 824  1909
         }
 825  
 
 826  
 
 827  1909
         addReplaceWord("v.", "vs.");
 828  1909
         addReplaceWord("vs.", "vs.");
 829  1909
         addReplaceWord("versus", "vs.");
 830  1909
         addReplaceWord("f.", "feat.");
 831  1909
         addReplaceWord("feat", "feat.");
 832  1909
         addReplaceWord("featuring", "feat.");
 833  1909
         addReplaceWord("ftng.", "feat.");
 834  1909
         addReplaceWord("ftng", "feat.");
 835  1909
         addReplaceWord("ft.", "feat.");
 836  1909
         addReplaceWord("ft", "feat.");
 837  
 
 838  
 
 839  1909
         iterator = this.getKeywordListIterator(FrameBodyTIPL.class);
 840  
 
 841  
 
 842  1909
         addParenthesis("(", ")");
 843  1909
         addParenthesis("[", "]");
 844  1909
         addParenthesis("{", "}");
 845  1909
         addParenthesis("<", ">");
 846  1909
     }
 847  
 
 848  
 
 849  
     /**
 850  
      * @param id3v2FrameBodyClass
 851  
      * @param keyword
 852  
      * @throws TagException
 853  
      */
 854  
     public void addKeyword(Class<? extends ID3v24FrameBody> id3v2FrameBodyClass, String keyword) throws TagException
 855  
     {
 856  351256
         if (!AbstractID3v2FrameBody.class.isAssignableFrom(id3v2FrameBodyClass))
 857  
         {
 858  0
             throw new TagException("Invalid class type. Must be AbstractId3v2FrameBody " + id3v2FrameBodyClass);
 859  
         }
 860  
 
 861  351256
         if ((keyword != null) && (keyword.length() > 0))
 862  
         {
 863  
             LinkedList<String> keywordList;
 864  
 
 865  351256
             if (!keywordMap.containsKey(id3v2FrameBodyClass))
 866  
             {
 867  3818
                 keywordList = new LinkedList<String>();
 868  3818
                 keywordMap.put(id3v2FrameBodyClass, keywordList);
 869  
             }
 870  
             else
 871  
             {
 872  347438
                 keywordList = keywordMap.get(id3v2FrameBodyClass);
 873  
             }
 874  
 
 875  351256
             keywordList.add(keyword);
 876  
         }
 877  351256
     }
 878  
 
 879  
     /**
 880  
      * @param open
 881  
      * @param close
 882  
      */
 883  
     public void addParenthesis(String open, String close)
 884  
     {
 885  7636
         parenthesisMap.put(open, close);
 886  7636
     }
 887  
 
 888  
     /**
 889  
      * @param oldWord
 890  
      * @param newWord
 891  
      */
 892  
     public void addReplaceWord(String oldWord, String newWord)
 893  
     {
 894  19090
         replaceWordMap.put(oldWord, newWord);
 895  19090
     }
 896  
 
 897  
     /**
 898  
      * @return are tags unsynchronized when written if contain bit pattern that could be mistaken for audio marker
 899  
      */
 900  
     public boolean isUnsyncTags()
 901  
     {
 902  2636
         return unsyncTags;
 903  
     }
 904  
 
 905  
     /**
 906  
      * Unsync tag where neccessary, currently only applies to IDv23
 907  
      *
 908  
      * @param unsyncTags set whether tags are  unsynchronized when written if contain bit pattern that could
 909  
      *                   be mistaken for audio marker
 910  
      */
 911  
     public void setUnsyncTags(boolean unsyncTags)
 912  
     {
 913  61
         this.unsyncTags = unsyncTags;
 914  61
     }
 915  
 
 916  
     /**
 917  
      * Do we remove unneccessary trailing null characters on write
 918  
      *
 919  
      * @return true if we remove unneccessary trailing null characters on write
 920  
      */
 921  
     public boolean isRemoveTrailingTerminatorOnWrite()
 922  
     {
 923  4052
         return removeTrailingTerminatorOnWrite;
 924  
     }
 925  
 
 926  
     /**
 927  
      * Remove unneccessary trailing null characters on write
 928  
      *
 929  
      * @param removeTrailingTerminatorOnWrite
 930  
      *
 931  
      */
 932  
     public void setRemoveTrailingTerminatorOnWrite(boolean removeTrailingTerminatorOnWrite)
 933  
     {
 934  8
         this.removeTrailingTerminatorOnWrite = removeTrailingTerminatorOnWrite;
 935  8
     }
 936  
 
 937  
     /**
 938  
      * Get the default text encoding to use for new v23 frames, when unicode is required
 939  
      * UTF16 will always be used because that is the only valid option for v23/v22
 940  
      *
 941  
      * @return
 942  
      */
 943  
     public byte getId3v23DefaultTextEncoding()
 944  
     {
 945  549
         return id3v23DefaultTextEncoding;
 946  
     }
 947  
 
 948  
     /**
 949  
      * Set the default text encoding to use for new v23 frames, when unicode is required
 950  
      * UTF16 will always be used because that is the only valid option for v23/v22
 951  
      *
 952  
      * @param id3v23DefaultTextEncoding
 953  
      */
 954  
     public void setId3v23DefaultTextEncoding(byte id3v23DefaultTextEncoding)
 955  
     {
 956  24
         if ((id3v23DefaultTextEncoding == TextEncoding.ISO_8859_1) || (id3v23DefaultTextEncoding == TextEncoding.UTF_16))
 957  
         {
 958  24
             this.id3v23DefaultTextEncoding = id3v23DefaultTextEncoding;
 959  
         }
 960  24
     }
 961  
 
 962  
     /**
 963  
      * Get the default text encoding to use for new v24 frames, it defaults to simple ISO8859
 964  
      * but by changing this value you could always used UTF8 for example whether you needed to or not
 965  
      *
 966  
      * @return
 967  
      */
 968  
     public byte getId3v24DefaultTextEncoding()
 969  
     {
 970  853
         return id3v24DefaultTextEncoding;
 971  
     }
 972  
 
 973  
     /**
 974  
      * Set the default text encoding to use for new v24 frames, it defaults to simple ISO8859
 975  
      * but by changing this value you could always used UTF8 for example whether you needed to or not
 976  
      *
 977  
      * @param id3v24DefaultTextEncoding
 978  
      */
 979  
     public void setId3v24DefaultTextEncoding(byte id3v24DefaultTextEncoding)
 980  
     {
 981  4
         if ((id3v24DefaultTextEncoding == TextEncoding.ISO_8859_1) || (id3v24DefaultTextEncoding == TextEncoding.UTF_16) || (id3v24DefaultTextEncoding == TextEncoding.UTF_16BE) || (id3v24DefaultTextEncoding == TextEncoding.UTF_8))
 982  
         {
 983  4
             this.id3v24DefaultTextEncoding = id3v24DefaultTextEncoding;
 984  
         }
 985  
 
 986  4
     }
 987  
 
 988  
     /**
 989  
      * Get the text encoding to use for new v24 frames when unicode is required, it defaults to UTF16 just
 990  
      * because this encoding is understand by all ID3 versions
 991  
      *
 992  
      * @return
 993  
      */
 994  
     public byte getId3v24UnicodeTextEncoding()
 995  
     {
 996  28
         return id3v24UnicodeTextEncoding;
 997  
     }
 998  
 
 999  
     /**
 1000  
      * Set the text encoding to use for new v24 frames when unicode is required, it defaults to UTF16 just
 1001  
      * because this encoding is understand by all ID3 versions
 1002  
      *
 1003  
      * @param id3v24UnicodeTextEncoding
 1004  
      */
 1005  
     public void setId3v24UnicodeTextEncoding(byte id3v24UnicodeTextEncoding)
 1006  
     {
 1007  4
         if ((id3v24UnicodeTextEncoding == TextEncoding.UTF_16) || (id3v24UnicodeTextEncoding == TextEncoding.UTF_16BE) || (id3v24UnicodeTextEncoding == TextEncoding.UTF_8))
 1008  
         {
 1009  4
             this.id3v24UnicodeTextEncoding = id3v24UnicodeTextEncoding;
 1010  
         }
 1011  4
     }
 1012  
 
 1013  
     /**
 1014  
      * When writing frames if this is set to true then the frame will be written
 1015  
      * using the defaults disregarding the text encoding originally used to create
 1016  
      * the frame.
 1017  
      *
 1018  
      * @return
 1019  
      */
 1020  
     public boolean isResetTextEncodingForExistingFrames()
 1021  
     {
 1022  4308
         return resetTextEncodingForExistingFrames;
 1023  
     }
 1024  
 
 1025  
     /**
 1026  
      * When writing frames if this is set to true then the frame will be written
 1027  
      * using the defaults disregarding the text encoding originally used to create
 1028  
      * the frame.
 1029  
      *
 1030  
      * @param resetTextEncodingForExistingFrames
 1031  
      *
 1032  
      */
 1033  
     public void setResetTextEncodingForExistingFrames(boolean resetTextEncodingForExistingFrames)
 1034  
     {
 1035  32
         this.resetTextEncodingForExistingFrames = resetTextEncodingForExistingFrames;
 1036  32
     }
 1037  
 
 1038  
     /**
 1039  
      *
 1040  
      * @return truncate without errors
 1041  
      */
 1042  
     public boolean isTruncateTextWithoutErrors()
 1043  
     {
 1044  48
         return truncateTextWithoutErrors;
 1045  
     }
 1046  
 
 1047  
     /**
 1048  
      * Set truncate without errors
 1049  
      *
 1050  
      * @param truncateTextWithoutErrors
 1051  
      */
 1052  
     public void setTruncateTextWithoutErrors(boolean truncateTextWithoutErrors)
 1053  
     {
 1054  24
         this.truncateTextWithoutErrors = truncateTextWithoutErrors;
 1055  24
     }
 1056  
 
 1057  
     public boolean isPadNumbers()
 1058  
     {
 1059  927
         return padNumbers;
 1060  
     }
 1061  
 
 1062  
     public void setPadNumbers(boolean padNumbers)
 1063  
     {
 1064  56
         this.padNumbers = padNumbers;
 1065  56
     }
 1066  
 }