All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.farng.mp3.filename.FilenameToken Maven / Gradle / Ivy

Go to download

This library reads song information, such as song title, artist, and album, from an MP3 file. It supports ID3v1, ID3v1.1, Lyrics3v1, Lyrics3v2, ID3v2.2, ID3v2.3, and ID3v2.4 tags. MP3 Frame Headers can also be read. There is a FilenameTag, a ID3v2.4 tag that is intelligently derived from the file name. It contains tag synchronization utilities, multiple save options, and easy tag conversion methods.

The newest version!
package org.farng.mp3.filename;

import org.farng.mp3.AbstractMP3Tag;
import org.farng.mp3.TagOptionSingleton;
import org.farng.mp3.id3.AbstractFrameBodyTextInformation;
import org.farng.mp3.id3.AbstractFrameBodyUrlLink;
import org.farng.mp3.id3.AbstractID3v2Frame;
import org.farng.mp3.id3.AbstractID3v2FrameBody;
import org.farng.mp3.id3.FrameBodyCOMM;
import org.farng.mp3.id3.ID3v2_4;
import org.farng.mp3.id3.ID3v2_4Frame;

import java.util.Iterator;

/**
 * This composite subclass is the leaf of the tree. It contains the actual strings found in the filename.
 *
 * @author Eric Farng
 * @version $Revision: 1.7 $
 */
public class FilenameToken extends AbstractFilenameComposite {

    /**
     * what information this object represents.
     */
    private Class id3v2FrameBodyClass = null;
    /**
     * token that this object represents
     */
    private String token = null;

    /**
     * Creates a new FilenameToken object.
     */
    public FilenameToken() {
        super();
    }

    /**
     * Creates a new FilenameToken object.
     */
    public FilenameToken(final FilenameToken copyObject) {
        super(copyObject);
        try {
            id3v2FrameBodyClass = id3v2FrameBodyClass.newInstance().getClass();
        } catch (IllegalAccessException ex) {
            throw new NullPointerException("IllegalAccessException: No access to run constructor to create copy " +
                                           ex.getMessage());
        } catch (InstantiationException ex) {
            throw new NullPointerException("InstantiationException: Unable to instantiate constructor to copy " +
                                           ex.getMessage());
        }
        token = copyObject.token;
    }

    public void setFrame(final AbstractID3v2Frame frame) {
        if (id3v2FrameBodyClass != null && id3v2FrameBodyClass.equals(frame.getBody().getClass())) {
            //todo add support for more tag matches. only doing text
            //      information and URL links right now because i'm lazy
            if (AbstractFrameBodyTextInformation.class.isInstance(frame.getBody())) {
                token = ((AbstractFrameBodyTextInformation) frame.getBody()).getText();
            } else if (AbstractFrameBodyUrlLink.class.isInstance(frame.getBody())) {
                token = ((AbstractFrameBodyUrlLink) frame.getBody()).getUrlLink();
            }
        }
    }

    /**
     * Sets the ID3v2 frame body that this token represents
     *
     * @param id3v2FrameBodyClass the ID3v2 frame body that this token represents
     */
    public void setId3v2FrameBodyClass(final Class id3v2FrameBodyClass) {
        this.id3v2FrameBodyClass = id3v2FrameBodyClass;
    }

    /**
     * Returns the ID3v2 frame body that this token represents
     *
     * @return the ID3v2 frame body that this token represents
     */
    public Class getId3v2FrameBodyClass() {
        return id3v2FrameBodyClass;
    }

    /**
     * Sets the token that this class contains
     *
     * @param token the token that this class contains
     */
    public void setToken(final String token) {
        this.token = token.trim();
    }

    /**
     * Return the token that this class contains
     *
     * @return the token that this class contains
     */
    public String getToken() {
        return token;
    }

    /**
     * Reconstruct the filename that is represented by this composite.
     *
     * @return the filename that is represented by this composite.
     */
    public String composeFilename() {
        return token;
    }

    public ID3v2_4 createId3Tag() {
        final ID3v2_4 newTag = new ID3v2_4();
        if (id3v2FrameBodyClass != null) {
            try {
                final AbstractID3v2FrameBody body = (AbstractID3v2FrameBody) id3v2FrameBodyClass.newInstance();

                //todo need to add support for more frame bodies here
                if (body instanceof AbstractFrameBodyTextInformation) {
                    ((AbstractFrameBodyTextInformation) body).setText(token);
                    ((AbstractFrameBodyTextInformation) body).setTextEncoding((byte) 0);
                } else if (body instanceof AbstractFrameBodyUrlLink) {
                    ((AbstractFrameBodyUrlLink) body).setUrlLink(token);
                } else if (body instanceof FrameBodyCOMM) {
                    ((FrameBodyCOMM) body).setText(token);
                    ((FrameBodyCOMM) body).setDescription("");
                    ((FrameBodyCOMM) body).setLanguage(TagOptionSingleton.getInstance().getLanguage());
                    ((FrameBodyCOMM) body).setTextEncoding(TagOptionSingleton.getInstance().getTextEncoding());
                }
                final ID3v2_4Frame frame = new ID3v2_4Frame();
                frame.setBody(body);
                newTag.setFrame(frame);
            } catch (IllegalAccessException ex) {
                // catch and dont' create the frame
            } catch (InstantiationException ex) {
                // catch and dont' create the frame
            }
        }
        return newTag;
    }

    /**
     * Returns an iterator through each FilenameToken in this composite in the correct order for the file
     * name.
     *
     * @return an iterator through each FilenameToken in this composite
     */
    public Iterator iterator() {
        return new FilenameTokenIterator(this);
    }

    /**
     * Match all elements of this composite against the keywords for this class type found in
     * TagOptionSingleton. If the FilenameToken matches the keyword, the token's class is
     * set.
     *
     * @param matchId3v2FrameBodyClass Class of keywords to match against.
     */
    public void matchAgainstKeyword(final Class matchId3v2FrameBodyClass) {
        if (AbstractID3v2FrameBody.class.isAssignableFrom(matchId3v2FrameBodyClass)) {
            if (TagOptionSingleton.getInstance().isCompositeMatchOverwrite() || id3v2FrameBodyClass == null) {
                final Iterator iterator = TagOptionSingleton.getInstance()
                        .getKeywordListIterator(matchId3v2FrameBodyClass);
                final String lowerCaseToken = token.toLowerCase();
                while (iterator.hasNext()) {
                    final String matchString = ((String) iterator.next()).toLowerCase();
                    if (matchString.equals(lowerCaseToken) ||
                        matchString.indexOf(lowerCaseToken) >= 0 ||
                        lowerCaseToken.indexOf(matchString) >= 0) {
                        setId3v2FrameBodyClass(matchId3v2FrameBodyClass);
                        break;
                    }
                }
            }
        }
    }

    /**
     * Match all elements of this composite against the given tag. If any element of matchTag matches any
     * element of this tag's composite, then this tag's composite leaf node's class is set.
     *
     * @param matchTag Tag to match against
     */
    public void matchAgainstTag(final AbstractMP3Tag matchTag) {
        if (TagOptionSingleton.getInstance().isCompositeMatchOverwrite() || id3v2FrameBodyClass == null) {
            final ID3v2_4 tag;
            if (matchTag instanceof ID3v2_4) {
                tag = (ID3v2_4) matchTag;
            } else {
                tag = new ID3v2_4(matchTag);
            }
            final Iterator iterator = tag.iterator();
            AbstractID3v2Frame frame;
            AbstractID3v2FrameBody body;
            String matchString = null;
            final String lowerCaseToken = token.toLowerCase();
            while (iterator.hasNext()) {
                frame = (ID3v2_4Frame) iterator.next();
                body = (AbstractID3v2FrameBody) frame.getBody();
                //todo add support for more tag matches. only doing text
                //      information and URL links right now because i'm lazy
                if (body instanceof AbstractFrameBodyTextInformation) {
                    matchString = ((AbstractFrameBodyTextInformation) body).getText();
                    if (matchString != null) {
                        matchString = matchString.toLowerCase();
                    }
                } else if (body instanceof AbstractFrameBodyUrlLink) {
                    matchString = ((AbstractFrameBodyUrlLink) body).getUrlLink();
                    if (matchString != null) {
                        matchString = matchString.toLowerCase();
                    }
                } else if (body instanceof FrameBodyCOMM) {
                    matchString = ((FrameBodyCOMM) body).getText();
                }
                if (lowerCaseToken.equals(matchString) ||
                    matchString != null &&
                    (matchString.indexOf(lowerCaseToken) >= 0 || lowerCaseToken.indexOf(matchString) >= 0)) {
                    setId3v2FrameBodyClass(body.getClass());
                    break;
                }
            }
        }
    }

    /**
     * Returns a string containing debug information about this class
     *
     * @return a string containing debug information about this class
     */
    public String toString() {
        return id3v2FrameBodyClass + ": " + token;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy