View Javadoc

1   package com.melloware.jukes.file.tag;
2   
3   import java.io.File;
4   import java.util.Map;
5   
6   import org.apache.commons.lang.StringUtils;
7   import org.apache.commons.logging.Log;
8   import org.apache.commons.logging.LogFactory;
9   import org.jaudiotagger.audio.AudioFile;
10  import org.jaudiotagger.audio.AudioFileIO;
11  import org.jaudiotagger.audio.exceptions.CannotReadException;
12  import org.jaudiotagger.audio.exceptions.CannotWriteException;
13  import org.jaudiotagger.tag.FieldDataInvalidException;
14  import org.jaudiotagger.tag.TagFieldKey;
15  
16  import com.jgoodies.uif.application.Application;
17  import com.jgoodies.uif.util.ResourceUtils;
18  import com.melloware.jukes.exception.MusicTagException;
19  import com.melloware.jukes.gui.view.MainFrame;
20  import com.melloware.jukes.util.MessageUtil;
21  
22  /** AZ ?? import com.melloware.jukes.gui.view.MainFrame; **/
23  
24  
25  /**
26   * MusicTag class used for editing OGG, FLAC, SPEEX, and APE file tags. The Ogg
27   * Vorbiscomment system is used as described at
28   * xiph.org/vorbis/doc/v-comment.html
29   * <p>
30   * The Entagged (http://entagged.sourceforge.net/) library is used to read these
31   * types of Tags.
32   * <p>
33   * Copyright (c) 2006 Melloware, Inc. <http://www.melloware.com>
34   * @author Emil A. Lefkof III <info@melloware.com>
35   * @version 4.0
36   * AZ - some modifications 2009
37   */
38  public final class AudioFileTag extends MusicTag {
39  
40     private static final Log LOG = LogFactory.getLog(AudioFileTag.class);
41     private AudioFile audioFile;
42  
43  
44     /**
45      * Constructor that accepts a file.
46      * <p>
47      * @param aFile the file to open
48      * @throws MusicTagException if any error occurs loading tag
49      */
50     public AudioFileTag(File aFile) throws MusicTagException {
51        super(aFile);
52          try {
53           // create the audio file object
54           this.audioFile = AudioFileIO.read(aFile);
55           // initialize all tags
56           initializeTags();
57        } catch (CannotReadException ex) {
58           LOG.error(ex.getMessage(), ex);
59           throw new MusicTagException("CannotReadException opening Music File Tag." + aFile.getAbsolutePath() + "\n\n"
60                    + ex.getMessage());
61        } catch (Exception ex) {
62           LOG.error(ex.getMessage(), ex);
63           throw new MusicTagException("Unexpected exception opening Music File Tag." + aFile.getAbsolutePath() + "\n\n"
64                    + ex.getMessage());
65        }
66  
67     }
68  
69     /*
70      * (non-Javadoc)
71      * @see com.melloware.jukes.file.tag.MusicTag#getArtist()
72      */
73     public String getArtist() {
74  		
75  	  String Artist = "";
76    		
77        if (StringUtils.isBlank(this.artist)) {
78           /** AZ **/ 
79      	  if ( audioFile.getTag().getFirstField(settings.getAlbumArtistTag()) != null){
80      		  Artist = audioFile.getTag().getFirstField(settings.getAlbumArtistTag()).toString().trim();
81      	  }
82      	  if (Artist == "") {
83      	  if ( audioFile.getTag().getFirst(TagFieldKey.ALBUM_ARTIST) != null){
84      		  Artist = audioFile.getTag().getFirst(TagFieldKey.ALBUM_ARTIST).toString().trim();
85      	  }
86      	  }
87      	  if (Artist == "") {
88      	  this.artist = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstArtist(), NO_TAG).trim();
89      	  }
90      	  else {
91      	 this.artist = Artist;  
92      	  }
93        }
94        return this.artist;
95     }
96  
97     /*
98      * (non-Javadoc)
99      * @see com.melloware.jukes.file.tag.MusicTag#getBitRate()
100     */
101    public Long getBitRate() {
102       if (this.bitRate == null) {
103          this.bitRate = Long.valueOf(audioFile.getAudioHeader().getBitRateAsNumber());
104       }
105 
106       return this.bitRate;
107    }
108 
109    /*
110     * (non-Javadoc)
111     * @see com.melloware.jukes.file.tag.MusicTag#getComment()
112     */
113    public String getComment() {
114       if (StringUtils.isBlank(this.comment)) {
115          this.comment = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstComment(), "").trim();
116       }
117       return this.comment;
118    }
119 
120    /*
121     * (non-Javadoc)
122     * @see com.melloware.jukes.file.tag.MusicTag#getCopyrighted()
123     */
124    public String getCopyrighted() {
125       return "No";
126    }
127 
128    /*
129     * (non-Javadoc)
130     * @see com.melloware.jukes.file.tag.MusicTag#getDisc()
131     */
132    public String getDisc() {
133    /** AZ **/		
134    	 if (StringUtils.isBlank(this.disc)) {
135    	 String CD_Number = "";	 
136      this.disc = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstAlbum(), NO_TAG).trim();
137      if (settings.isUseCDNumber()) {
138        if ((audioFile.getTag().getFirst(TagFieldKey.DISC_NO) != null) & (audioFile.getTag().getFirst(TagFieldKey.DISC_NO).length() != 0)) {
139        CD_Number = " - CD " + audioFile.getTag().getFirst(TagFieldKey.DISC_NO).toString().trim();
140        if (audioFile.getTag().getFirstField("TOTALDISCS") != null) {
141            CD_Number = CD_Number + "/" + audioFile.getTag().getFirstField("TOTALDISCS").toString().trim();
142        }   
143        this.disc = this.disc + CD_Number;	
144        }
145        }
146    	 }
147      return this.disc;
148    }
149 
150    /*
151     * (non-Javadoc)
152     * @see com.melloware.jukes.file.tag.MusicTag#getEmphasis()
153     */
154    public String getEmphasis() {
155       return "None";
156    }
157 
158    /*
159     * (non-Javadoc)
160     * @see com.melloware.jukes.file.tag.MusicTag#getEncodedBy()
161     */
162    public String getEncodedBy() {
163       if (StringUtils.isBlank(this.encodedBy)) {
164          this.encodedBy = System.getProperty("application.name");
165       }
166       return this.encodedBy;
167    }
168 
169    /*
170     * (non-Javadoc)
171     * @see com.melloware.jukes.file.tag.MusicTag#getFrequency()
172     */
173    public String getFrequency() {
174       return Integer.toString(audioFile.getAudioHeader().getSampleRateAsNumber());
175 
176    }
177 
178    /*
179     * (non-Javadoc)
180     * @see com.melloware.jukes.file.tag.MusicTag#getGenre()
181     */
182    public String getGenre() {
183       if (StringUtils.isBlank(this.genre)) {
184          this.genre = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstGenre(), "Other").trim();
185       }
186       return this.genre;
187    }
188 
189    /*
190     * (non-Javadoc)
191     * @see com.melloware.jukes.file.tag.MusicTag#getHeader()
192     */
193    public Map getHeader() {
194       return header;
195    }
196 
197    /*
198     * (non-Javadoc)
199     * @see com.melloware.jukes.file.tag.MusicTag#getLayer()
200     */
201    public String getLayer() {
202       return audioFile.getAudioHeader().getEncodingType();
203    }
204 
205    /*
206     * (non-Javadoc)
207     * @see com.melloware.jukes.file.tag.MusicTag#getMode()
208     */
209    public String getMode() {
210       return audioFile.getAudioHeader().getEncodingType();
211    }
212 
213    /*
214     * (non-Javadoc)
215     * @see com.melloware.jukes.file.tag.MusicTag#getTitle()
216     */
217    public String getTitle() {
218       if (StringUtils.isBlank(this.title)) {
219 
220          String temp = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstTitle(), NO_TAG).trim();
221 
222          // if this is the max length for a tag, or it begins with "Track"
223          // try and grab by filename it may be longer
224          if ((temp.length() == 30) || (temp.equals(NO_TAG)) || (temp.startsWith("Track"))) {
225             temp = extractTitleFromFilename();
226             LOG.debug("Filename extracted");
227          }
228 
229          // return v2 tag else if empty return the v1 tag
230          this.title = StringUtils.defaultIfEmpty(temp, NO_TAG).trim();
231       }
232       return this.title;
233    }
234 
235    /*
236     * (non-Javadoc)
237     * @see com.melloware.jukes.file.tag.MusicTag#getTrack()
238     */
239    public String getTrack() {
240       if (StringUtils.isBlank(this.track)) {
241          int trackNum = 0;
242          String tracknumber = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstTrack(), "X").trim();
243          if (StringUtils.isNumeric(tracknumber)) {
244             trackNum = Integer.parseInt(tracknumber);
245          }
246 
247          // return v2 tag else if empty return the v1 tag
248          this.track = StringUtils.leftPad(String.valueOf(trackNum), 2, "0").trim();
249 
250       }
251       return this.track;
252    }
253 
254    /*
255     * (non-Javadoc)
256     * @see com.melloware.jukes.file.tag.MusicTag#getTrackLength()
257     */
258    public long getTrackLength() {
259       if (this.trackLength > 1) {
260          return this.trackLength;
261       }
262       this.trackLength = audioFile.getAudioHeader().getTrackLength();
263       return this.trackLength;
264    }
265 
266    /*
267     * (non-Javadoc)
268     * @see com.melloware.jukes.file.tag.MusicTag#getVersion()
269     */
270    public String getVersion() {
271       return audioFile.getAudioHeader().getEncodingType();
272    }
273 
274    /*
275     * (non-Javadoc)
276     * @see com.melloware.jukes.file.tag.MusicTag#getYear()
277     */
278    public String getYear() {
279       if (StringUtils.isBlank(this.year)) {
280          this.year = StringUtils.defaultIfEmpty(audioFile.getTag().getFirstYear(), CURRENT_YEAR).trim();
281       }
282       return this.year;
283    }
284 
285    /*
286     * (non-Javadoc)
287     * @see com.melloware.jukes.file.tag.MusicTag#setArtist(java.lang.String)
288     */
289    public void setArtist(String aArtist) {
290       this.artist = StringUtils.defaultIfEmpty(aArtist, NO_TAG).trim();
291       try {
292          audioFile.getTag().setArtist(this.artist);
293       } catch (FieldDataInvalidException ex) {
294          LOG.error("FieldDataInvalidException", ex);
295    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
296 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
297       }
298 
299    }
300 
301    /*
302     * (non-Javadoc)
303     * @see com.melloware.jukes.file.tag.MusicTag#setComment(java.lang.String)
304     */
305    public void setComment(String aComment) {
306       this.comment = StringUtils.defaultIfEmpty(aComment, "").trim();
307       try {
308          audioFile.getTag().setComment(this.comment);
309       } catch (FieldDataInvalidException ex) {
310          LOG.error("FieldDataInvalidException", ex);
311    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
312 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
313       }
314    }
315 
316    /*
317     * (non-Javadoc)
318     * @see com.melloware.jukes.file.tag.MusicTag#setDisc(java.lang.String)
319     */
320    public void setDisc(String aDisc) {
321       this.disc = StringUtils.defaultIfEmpty(aDisc, NO_TAG).trim();
322       try {
323          audioFile.getTag().setAlbum(this.disc);
324       } catch (FieldDataInvalidException ex) {
325          LOG.error("FieldDataInvalidException", ex);
326    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
327 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
328       }
329 
330    }
331 
332    /*
333     * (non-Javadoc)
334     * @see com.melloware.jukes.file.tag.MusicTag#setEncodedBy(java.lang.String)
335     */
336    public void setEncodedBy(String aEncodedBy) {
337       this.encodedBy = StringUtils.defaultIfEmpty(aEncodedBy, System.getProperty("application.name")).trim();
338    }
339 
340    /*
341     * (non-Javadoc)
342     * @see com.melloware.jukes.file.tag.MusicTag#setGenre(java.lang.String)
343     */
344    public void setGenre(String aGenre) {
345       this.genre = StringUtils.defaultIfEmpty(aGenre, NO_TAG).trim();
346       try {
347          audioFile.getTag().setGenre(this.genre);
348       } catch (FieldDataInvalidException ex) {
349          LOG.error("FieldDataInvalidException", ex);
350    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
351 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
352       }
353 
354    }
355 
356    /*
357     * (non-Javadoc)
358     * @see com.melloware.jukes.file.tag.MusicTag#setTitle(java.lang.String)
359     */
360    public void setTitle(String aTitle) {
361       this.title = StringUtils.defaultIfEmpty(aTitle, NO_TAG).trim();
362 
363       try {
364          audioFile.getTag().setTitle(this.title);
365       } catch (FieldDataInvalidException ex) {
366          LOG.error("FieldDataInvalidException", ex);
367    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
368 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
369       }
370    }
371 
372    /*
373     * (non-Javadoc)
374     * @see com.melloware.jukes.file.tag.MusicTag#setTrack(java.lang.String)
375     */
376    public void setTrack(String aTrack) {
377       setTrack(aTrack, 2);
378    }
379 
380    /**
381     * Sets the track.
382     * <p>
383     * @param aTrack The track to set.
384     * @param aPadding the number of 0's to pad this track with
385     */
386    public void setTrack(final String aTrack, final int aPadding) {
387       final String current = StringUtils.defaultIfEmpty(aTrack, "0").trim();
388       this.track = StringUtils.leftPad(current, aPadding, "0").trim();
389       try {
390          audioFile.getTag().setTrack(this.track);
391       } catch (FieldDataInvalidException ex) {
392          LOG.error("FieldDataInvalidException", ex);
393    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
394 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
395       }
396    }
397 
398    /*
399     * (non-Javadoc)
400     * @see com.melloware.jukes.file.tag.MusicTag#setTrackLength(long)
401     */
402    public void setTrackLength(long aTrackLength) {
403       this.trackLength = aTrackLength;
404    }
405 
406    /*
407     * (non-Javadoc)
408     * @see com.melloware.jukes.file.tag.MusicTag#setYear(java.lang.String)
409     */
410    public void setYear(String aYear) {
411       this.year = StringUtils.defaultIfEmpty(aYear, CURRENT_YEAR).trim();
412       try {
413          audioFile.getTag().setYear(this.year);
414       } catch (FieldDataInvalidException ex) {
415          LOG.error("FieldDataInvalidException", ex);
416    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
417 	     MessageUtil.showError(mainFrame, "FieldDataInvalidException"); //AZ
418       }
419    }
420 
421    /*
422     * (non-Javadoc)
423     * @see com.melloware.jukes.file.tag.MusicTag#isVBR()
424     */
425    public boolean isVBR() {
426       return audioFile.getAudioHeader().isVariableBitRate();
427    }
428 
429    /*
430     * (non-Javadoc)
431     * @see com.melloware.jukes.file.tag.MusicTag#removeTags()
432     */
433    public void removeTags() throws MusicTagException {
434       if (audioFile != null) {
435          try {
436             AudioFileIO.delete(audioFile);
437          } catch (Exception e) {
438             throw new MusicTagException("Error removing AudioFile tag: " + e.getMessage(), e);
439          }
440          initializeTags();
441       }
442    }
443 
444    /**
445     * Renames this Music file based on a format from prefs. The format is in
446     * aFormat and can have values %n for track number, %t for title, %a for
447     * artist, and %d for disc. Replaces any invalid characters (\\, /, :, , *, ?, ", <, >,
448     * or |) with underscores _ to prevent any errors on file systems. Examples:
449     * %n -%t = 01 - Track.mp3 %a - %d - %n - %t = Artist - Album - 01 -
450     * Track.mp3
451     * <p>
452     * @param aFormat the string format like %n -%t to rename 01 - Track.mp3
453     * @return true if renamed, false if failure
454     */
455    public boolean renameFile(String aFormat) {
456       boolean result = false;
457       try {
458          final String newFileName = createFilenameFromFormat(aFormat);
459          final File newFile = new File(newFileName);
460          // close the audioFile
461          audioFile = null;
462 
463          result = this.file.renameTo(newFile);
464          if (result) {
465             this.file = newFile;
466             this.audioFile = AudioFileIO.read(newFile);
467             initializeTags();
468          }
469       } catch (Exception ex) {
470     	 final String errorMessage = ResourceUtils.getString("messages.ErrorRenamingFile");
471          LOG.error(errorMessage, ex);
472    	     final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
473 	     MessageUtil.showError(mainFrame, errorMessage); //AZ
474       }
475       return result;
476    }
477 
478    /*
479     * (non-Javadoc)
480     * @see com.melloware.jukes.file.tag.MusicTag#save()
481     */
482    public void save() throws MusicTagException {
483       if (audioFile != null) {
484          try {
485             audioFile.commit();
486          } catch (CannotWriteException ex) {
487             throw new MusicTagException("Error saving AudioFile tag: " + ex.getMessage());
488          }
489 
490       }
491 
492    }
493 
494    /**
495     * Initialize the tags for this audio file.
496     */
497    private void initializeTags() {
498       // initialize private variables from tags
499       this.getDisc();
500       this.getArtist();
501       this.getComment();
502       this.getGenre();
503       this.getTitle();
504       this.getTrack();
505       this.getYear();
506       this.getTrackLength();
507       this.getEncodedBy();
508    }
509 
510 }