📄 abstractid3v2tag.java
字号:
}
public int getFieldCount()
{
Iterator it = getFields();
int count = 0;
while(it.hasNext())
{
count ++;
it.next();
}
return count;
}
//TODO is this a special field?
public boolean setEncoding(String enc) throws FieldDataInvalidException
{
throw new UnsupportedOperationException("Not Implemented Yet");
}
/**
* Retrieve the first value that exists for this generic key
*
* @param genericKey
* @return
*/
public String getFirst(TagFieldKey genericKey) throws KeyNotFoundException
{
if (genericKey == null)
{
throw new KeyNotFoundException();
}
return doGetFirst(getFrameAndSubIdFromGenericKey(genericKey));
}
/**
* Create a new TagField
* <p/>
* Only textual data supported at the moment. The genericKey will be mapped
* to the correct implementation key and return a TagField.
*
* @param genericKey is the generic key
* @param value to store
* @return
*/
public TagField createTagField(TagFieldKey genericKey, String value)
throws KeyNotFoundException, FieldDataInvalidException
{
if (genericKey == null)
{
throw new KeyNotFoundException();
}
return doCreateTagField(getFrameAndSubIdFromGenericKey(genericKey),value);
}
/**
* Create Frame for Id3 Key
* <p/>
* Only textual data supported at the moment, should only be used with frames that
* support a simple string argument.
*
* @param formatKey
* @param value
* @return
* @throws KeyNotFoundException
* @throws FieldDataInvalidException
*/
protected TagField doCreateTagField(FrameAndSubId formatKey, String value)
throws KeyNotFoundException, FieldDataInvalidException
{
AbstractID3v2Frame frame = createFrame(formatKey.getFrameId());
if (frame.getBody() instanceof FrameBodyUFID)
{
((FrameBodyUFID) frame.getBody()).setOwner(formatKey.getSubId());
try
{
((FrameBodyUFID) frame.getBody()).setUniqueIdentifier(value.getBytes("ISO-8859-1"));
}
catch (UnsupportedEncodingException uee)
{
//This will never happen because we are using a charset supported on all platforms
//but just in case
throw new RuntimeException("When encoding UFID charset ISO-8859-1 was deemed unsupported");
}
}
else if (frame.getBody() instanceof FrameBodyTXXX)
{
((FrameBodyTXXX) frame.getBody()).setDescription(formatKey.getSubId());
((FrameBodyTXXX) frame.getBody()).setText(value);
}
else if (frame.getBody() instanceof FrameBodyWXXX)
{
((FrameBodyWXXX) frame.getBody()).setDescription(formatKey.getSubId());
((FrameBodyWXXX) frame.getBody()).setUrlLink(value);
}
else if (frame.getBody() instanceof AbstractFrameBodyTextInfo)
{
((AbstractFrameBodyTextInfo) frame.getBody()).setText(value);
}
else if ((frame.getBody() instanceof FrameBodyAPIC )||(frame.getBody() instanceof FrameBodyPIC))
{
throw new UnsupportedOperationException("Please use createArtwork() instead for creating artwork");
}
else
{
throw new FieldDataInvalidException("Field with key of:" + formatKey.getFrameId() + ":does not accept cannot parse data:" + value);
}
return frame;
}
/**
*
* @param formatKey
* @return
* @throws KeyNotFoundException
*/
protected String doGetFirst(FrameAndSubId formatKey) throws KeyNotFoundException
{
//Simple 1 to 1 mapping
if (formatKey.getSubId() == null)
{
return getFirst(formatKey.getFrameId());
}
else
{
//Get list of frames that this uses
List<TagField> list = get(formatKey.getFrameId());
ListIterator<TagField> li = list.listIterator();
while (li.hasNext())
{
AbstractTagFrameBody next = ((AbstractID3v2Frame) li.next()).getBody();
if (next instanceof FrameBodyTXXX)
{
if (((FrameBodyTXXX) next).getDescription().equals(formatKey.getSubId()))
{
return ((FrameBodyTXXX) next).getText();
}
}
else if (next instanceof FrameBodyWXXX)
{
if (((FrameBodyWXXX) next).getDescription().equals(formatKey.getSubId()))
{
return ((FrameBodyWXXX) next).getUrlLink();
}
}
else if (next instanceof FrameBodyUFID)
{
if (!((FrameBodyUFID) next).getUniqueIdentifier().equals(formatKey.getSubId()))
{
return new String(((FrameBodyUFID) next).getUniqueIdentifier());
}
}
else
{
throw new RuntimeException("Need to implement get(TagFieldKey genericKey) for:" + next.getClass());
}
}
return "";
}
}
/**
* Create a link to artwork, this is not recommended because the link may be broken if the mp3 or image
* file is moved
*
* @param url specifies the link, it could be a local file or could be a full url
* @return
*/
public TagField createLinkedArtworkField(String url)
{
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(TagFieldKey.COVER_ART).getFrameId());
if(frame.getBody() instanceof FrameBodyAPIC)
{
FrameBodyAPIC body = (FrameBodyAPIC)frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, Utils.getDefaultBytes(url, TextEncoding.CHARSET_ISO_8859_1));
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_MIME_TYPE, FrameBodyAPIC.IMAGE_IS_URL);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
}
else if(frame.getBody() instanceof FrameBodyPIC)
{
FrameBodyPIC body = (FrameBodyPIC)frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, Utils.getDefaultBytes(url, TextEncoding.CHARSET_ISO_8859_1));
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_IMAGE_FORMAT, FrameBodyAPIC.IMAGE_IS_URL);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
}
return frame;
}
/**
* Create Artwork
*
* @see PictureTypes
*
* @param data
* @param mimeType of the image
*/
public TagField createArtworkField(byte[] data,String mimeType)
{
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(TagFieldKey.COVER_ART).getFrameId());
if(frame.getBody() instanceof FrameBodyAPIC)
{
FrameBodyAPIC body = (FrameBodyAPIC)frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, data);
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_MIME_TYPE, mimeType);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
}
else if(frame.getBody() instanceof FrameBodyPIC)
{
FrameBodyPIC body = (FrameBodyPIC)frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, data);
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_IMAGE_FORMAT, ImageFormats.getFormatForMimeType(mimeType));
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
}
return frame;
}
/**
* Delete fields with this generic key
*
* @param genericKey
*/
public void deleteTagField(TagFieldKey genericKey) throws KeyNotFoundException
{
if (genericKey == null)
{
throw new KeyNotFoundException();
}
FrameAndSubId formatKey = getFrameAndSubIdFromGenericKey(genericKey);
doDeleteTagField(formatKey);
}
/**
* Internal delete method
*
* @param formatKey
* @throws KeyNotFoundException
*/
protected void doDeleteTagField(FrameAndSubId formatKey) throws KeyNotFoundException
{
//Simple 1 to 1 mapping
if (formatKey.getSubId() == null)
{
removeFrame(formatKey.getFrameId());
}
else
{
//Get list of frames that this uses
List<TagField> list = get(formatKey.getFrameId());
ListIterator<TagField> li = list.listIterator();
while (li.hasNext())
{
AbstractTagFrameBody next = ((AbstractID3v2Frame) li.next()).getBody();
if (next instanceof FrameBodyTXXX)
{
if (((FrameBodyTXXX) next).getDescription().equals(formatKey.getSubId()))
{
li.remove();
}
}
else if (next instanceof FrameBodyWXXX)
{
if (((FrameBodyWXXX) next).getDescription().equals(formatKey.getSubId()))
{
li.remove();
}
}
else if (next instanceof FrameBodyUFID)
{
if (((FrameBodyUFID) next).getUniqueIdentifier().equals(formatKey.getSubId()))
{
li.remove();
}
}
else
{
throw new RuntimeException("Need to implement get(TagFieldKey genericKey) for:" + next.getClass());
}
}
}
}
protected abstract FrameAndSubId getFrameAndSubIdFromGenericKey(TagFieldKey genericKey);
/**
* Get field(s) for this key
*
* @param genericKey
* @return
* @throws KeyNotFoundException
*/
public List<TagField> get(TagFieldKey genericKey) throws KeyNotFoundException
{
if (genericKey == null)
{
throw new KeyNotFoundException();
}
FrameAndSubId formatKey = getFrameAndSubIdFromGenericKey(genericKey);
//Get list of frames that this uses, as we are going to remove entries we dont want take a copy
List<TagField> list = get(formatKey.getFrameId());
List<TagField> filteredList = new ArrayList<TagField>();
String subFieldId = formatKey.getSubId();
String frameid = formatKey.getFrameId();
//... do we need to refine the list further i.e we only want TXXX frames that relate to the particular
//key that was passed as a parameter
if (subFieldId != null)
{
for (TagField tagfield : list)
{
AbstractTagFrameBody next = ((AbstractID3v2Frame) tagfield).getBody();
if (next instanceof FrameBodyTXXX)
{
if (((FrameBodyTXXX) next).getDescription().equals(formatKey.getSubId()))
{
filteredList.add(tagfield);
}
}
else if (next instanceof FrameBodyWXXX)
{
if (((FrameBodyWXXX) next).getDescription().equals(formatKey.getSubId()))
{
filteredList.add(tagfield);
}
}
else if (next instanceof FrameBodyUFID)
{
if (((FrameBodyUFID) next).getUniqueIdentifier().equals(formatKey.getSubId()))
{
filteredList.add(tagfield);
}
}
else
{
throw new RuntimeException("Need to implement get(TagFieldKey genericKey) for:" + next.getClass());
}
}
return filteredList;
}
else
{
return list;
}
}
/**
* This class had to be created to minimize the duplicate code in concrete subclasses
* of this class. It is required in some cases when using the Fieldkey enums because enums
* cant be subclassed. We want to use enums instead of regular classes because they are
* much easier for endusers to to use.
*/
class FrameAndSubId
{
private String frameId;
private String subId;
public FrameAndSubId(String frameId, String subId)
{
this.frameId = frameId;
this.subId = subId;
}
public String getFrameId()
{
return frameId;
}
public String getSubId()
{
return subId;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -