📄 abstractid3v2frame.java
字号:
/*
* MusicTag Copyright (C)2003,2004
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not,
* you can get a copy from http://www.opensource.org/licenses/lgpl-license.php or write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.hadeslee.audiotag.tag.id3;
import com.hadeslee.audiotag.audio.mp3.MP3File;
import com.hadeslee.audiotag.tag.InvalidFrameException;
import com.hadeslee.audiotag.tag.InvalidTagException;
import com.hadeslee.audiotag.tag.TagField;
import com.hadeslee.audiotag.tag.TagOptionSingleton;
import com.hadeslee.audiotag.tag.id3.framebody.AbstractID3v2FrameBody;
import com.hadeslee.audiotag.tag.id3.framebody.FrameBodyUnsupported;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
/**
* This abstract class is each frame header inside a ID3v2 tag.
*
* @author : Paul Taylor
* @author : Eric Farng
* @version $Id: AbstractID3v2Frame.java,v 1.24 2007/11/26 14:20:28 paultaylor Exp $
*/
public abstract class AbstractID3v2Frame
extends AbstractTagFrame implements TagField
{
protected static final String TYPE_FRAME = "frame";
protected static final String TYPE_FRAME_SIZE = "frameSize";
protected static final String UNSUPPORTED_ID = "Unsupported";
//Frame identifier
protected String identifier = "";
//Frame Size
protected int frameSize;
//The purpose of this is to provide the filename that should be used when writing debug messages
//when problems occur reading or writing to file, otherwise it is difficult to track down the error
//when processing many files
private String loggingFilename = "";
/**
* Create an empty frame
*/
protected AbstractID3v2Frame()
{
;
}
/**
* This holds the Status flags (not supported in v2.20
*/
StatusFlags statusFlags = null;
/**
* This holds the Encoding flags (not supported in v2.20)
*/
EncodingFlags encodingFlags = null;
/**
* Create a frame based on another frame
*/
public AbstractID3v2Frame(AbstractID3v2Frame frame)
{
super(frame);
}
/**
* Create a frame based on a body
*/
public AbstractID3v2Frame(AbstractID3v2FrameBody body)
{
this.frameBody = body;
this.frameBody.setHeader(this);
}
/**
* Create a new frame with empty body based on identifier
*
*/
//TODO the identifier checks should be done in the relevent subclasses
public AbstractID3v2Frame(String identifier)
{
logger.info("Creating empty frame of type" + identifier);
this.identifier = identifier;
// Use reflection to map id to frame body, which makes things much easier
// to keep things up to date.
try
{
Class c = Class.forName("com.hadeslee.audiotag.tag.id3.framebody.FrameBody" + identifier);
frameBody = (AbstractID3v2FrameBody) c.newInstance();
}
catch (ClassNotFoundException cnfe)
{
logger.severe(cnfe.getMessage());
frameBody = new FrameBodyUnsupported(identifier);
}
//Instantiate Interface/Abstract should not happen
catch (InstantiationException ie)
{
logger.log(Level.SEVERE,"InstantiationException:" + identifier,ie);
throw new RuntimeException(ie);
}
//Private Constructor shouild not happen
catch (IllegalAccessException iae)
{
logger.log(Level.SEVERE,"IllegalAccessException:" + identifier,iae);
throw new RuntimeException(iae);
}
frameBody.setHeader(this);
if(this instanceof ID3v24Frame)
{
frameBody.setTextEncoding(TagOptionSingleton.getInstance().getId3v24DefaultTextEncoding());
}
else if(this instanceof ID3v23Frame)
{
frameBody.setTextEncoding(TagOptionSingleton.getInstance().getId3v23DefaultTextEncoding());
}
logger.info("Created empty frame of type" + identifier);
}
/**
* Retrieve the logging filename to be used in debugging
*
* @return logging filename to be used in debugging
*/
protected String getLoggingFilename()
{
return loggingFilename;
}
/**
* Set logging filename when construct tag for read from file
*
* @param loggingFilename
*/
protected void setLoggingFilename(String loggingFilename)
{
this.loggingFilename = loggingFilename;
}
/**
* Return the frame identifier, this only identifiies the frame it does not provide a unique
* key, when using frames such as TXXX which are used by many fields *
*
* @return the frame identifier (Tag Field Interface)
*/
//TODO, this is confusing only returns the frameId, which does not neccessarily uniquely
//identify the frame
public String getId()
{
return getIdentifier();
}
/**
* Return the frame identifier
*
* @return the frame identifier
*/
public String getIdentifier()
{
return identifier;
}
//TODO:needs implementing but not sure if this method is required at all
public void copyContent(TagField field)
{
}
/**
* Read the frame body from the specified file via the buffer
*
* @param identifier the frame identifier
* @param byteBuffer to read the frabe body from
* @return a newly created FrameBody
* @throws InvalidFrameException unable to construct a framebody from the data
*
*/
protected AbstractID3v2FrameBody readBody(String identifier, ByteBuffer byteBuffer, int frameSize)
throws InvalidFrameException
{
//Use reflection to map id to frame body, which makes things much easier
//to keep things up to date,although slight performance hit.
logger.finest("Creating framebody:start");
AbstractID3v2FrameBody frameBody;
try
{
Class c = Class.forName("com.hadeslee.audiotag.tag.id3.framebody.FrameBody" + identifier);
Class[] constructorParameterTypes =
{((Class) Class.forName("java.nio.ByteBuffer")), Integer.TYPE
};
Object[] constructorParameterValues =
{byteBuffer, frameSize
};
Constructor construct = c.getConstructor(constructorParameterTypes);
frameBody = (AbstractID3v2FrameBody) (construct.newInstance(constructorParameterValues));
}
//No class defined for this frame type,use FrameUnsupported
catch (ClassNotFoundException cex)
{
logger.info(getLoggingFilename()+":"+"Identifier not recognised:" + identifier + " using FrameBodyUnsupported");
try
{
frameBody = new FrameBodyUnsupported(byteBuffer, frameSize);
}
//Should only throw InvalidFrameException but unfortunately legacy hierachy forces
//read method to declare it can throw InvalidtagException
catch(InvalidFrameException ife)
{
throw ife;
}
catch(InvalidTagException te)
{
throw new InvalidFrameException(te.getMessage());
}
}
//An error has occurred during frame instantiation, if underlying cause is an unchecked exception or error
//propagate it up otherwise mark this frame as invalid
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -