package org.cmc.music.myid3.id3v2;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.cmc.music.common.ID3FrameType;
import org.cmc.music.common.ID3ReadException;
import org.cmc.music.common.ID3WriteException;
import org.cmc.music.metadata.IMusicMetadata;
import org.cmc.music.metadata.ImageData;
import org.cmc.music.metadata.MusicMetadata;
import org.cmc.music.metadata.MusicMetadataConstants;
import org.cmc.music.metadata.UnknownUserTextValue;
import org.cmc.music.myid3.MyID3Listener;
public abstract class ID3v2FrameTranslation implements MusicMetadataConstants
{
/*
* Responsible for translating N metadata keys to N id3v2 frames.
*
* One key may map to more than one frame; more than one key may map to one
* frame.
*/
private static abstract class Translator
{
/*
* Translate (if found), a set of 0-N related keys from the metadata,
* adding frames to the vector.
*
* Remove translated keys from the metadata.
*/
public abstract void translateMetadataToFrames(IMusicMetadata metadata,
Vector frames, IFrameFactory frameFactory) throws IOException;
/*
* Translate a set of 1-N related frames to 1-N metadata keys.
*
* Remove translated frames from the vector.
*/
public abstract void translateFramesToMetadata(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, Vector frames)
throws ID3ReadException;
protected final MyID3v2FrameText findAndRemoveUniqueTextFrame(
MyID3Listener listener, boolean strict, Vector frames,
ID3FrameType frameType) throws ID3ReadException
{
List translated = new ArrayList();
for (int i = 0; i < frames.size(); i++)
{
MyID3v2Frame frame = (MyID3v2Frame) frames.get(i);
if (frameType.matches(frame.frameID))
{
if (translated.size() > 0)
{
if (strict)
throw new ID3ReadException(
"Unexpected duplicate frame: "
+ frame.frameID);
else if (listener != null)
listener.log("Unexpected duplicate frame",
frame.frameID);
}
MyID3v2FrameText textFrame = (MyID3v2FrameText) frame;
translated.add(frame);
}
}
frames.removeAll(translated);
if (translated.size() > 0)
return (MyID3v2FrameText) translated.get(0);
return null;
}
protected final List findAndRemoveFrames(MyID3Listener listener,
boolean strict, Vector frames, ID3FrameType frameType)
throws ID3ReadException
{
List translated = new ArrayList();
for (int i = 0; i < frames.size(); i++)
{
MyID3v2Frame frame = (MyID3v2Frame) frames.get(i);
if (frameType.matches(frame.frameID))
translated.add(frame);
}
frames.removeAll(translated);
return translated;
}
}
/*
* Maps a String value from a single text frame to a single metadata key.
*
* Frame should only appear once in tag.
*/
private static abstract class SimpleTranslator extends Translator
{
protected abstract void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
throws ID3ReadException;
protected abstract String getAndClearMetadataValue(IMusicMetadata values);
protected abstract ID3FrameType getFrameType();
public final void translateMetadataToFrames(IMusicMetadata metadata,
Vector frames, IFrameFactory frameFactory) throws IOException
{
String value = getAndClearMetadataValue(metadata);
if (value == null)
return;
ID3v2OutputFrame frame = frameFactory.createTextFrame(
getFrameType(), value);
frames.add(frame);
}
public final void translateFramesToMetadata(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
MyID3v2FrameText textFrame = findAndRemoveUniqueTextFrame(listener,
strict, frames, getFrameType());
if (null != textFrame)
setMetadataValue(listener, strict, metadata, textFrame.value);
}
}
private static final Translator TRANSLATORS[] = {
new Translator() {
public void translateMetadataToFrames(IMusicMetadata metadata,
Vector frames, IFrameFactory frameFactory) throws IOException
{
List pictures = metadata.getPictures();
for (int i = 0; i < pictures.size(); i++)
{
ImageData picture = (ImageData) pictures.get(i);
ID3v2OutputFrame frame = frameFactory
.createPictureFrame(picture);
frames.add(frame);
}
metadata.clearPictures();
}
public void translateFramesToMetadata(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
List found = findAndRemoveFrames(listener, strict, frames,
ID3FrameType.PICTURE);
for (int i = 0; i < found.size(); i++)
{
MyID3v2FrameImage frame = (MyID3v2FrameImage) found.get(i);
ImageData imageData = frame.getImageData();
metadata.addPicture(imageData);
}
}
}, //
new Translator() {
public void translateMetadataToFrames(IMusicMetadata metadata,
Vector frames, IFrameFactory frameFactory) throws IOException
{
List comments = metadata.getComments();
for (int i = 0; i < comments.size(); i++)
{
String comment = (String) comments.get(i);
ID3v2OutputFrame frame = frameFactory
.createCommentFrame(comment);
frames.add(frame);
}
metadata.clearComments();
}
public void translateFramesToMetadata(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
List found = findAndRemoveFrames(listener, strict, frames,
ID3FrameType.COMMENT);
for (int i = 0; i < found.size(); i++)
{
MyID3v2FrameText textFrame = (MyID3v2FrameText) found.get(i);
metadata.addComment(textFrame.value);
}
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener, boolean strict,
IMusicMetadata values, String value)
{
values.setComposer(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getComposer();
values.clearComposer();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.COMPOSER;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener, boolean strict,
IMusicMetadata values, String value)
{
values.setAlbum(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getAlbum();
values.clearAlbum();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.ALBUM;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener, boolean strict,
IMusicMetadata values, String value)
{
values.setArtist(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getArtist();
values.clearArtist();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.ARTIST;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener, boolean strict,
IMusicMetadata values, String value)
{
values.setSongTitle(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getSongTitle();
values.clearSongTitle();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.TITLE;
}
}, //
// new SimpleTranslator() {
// protected void setMetadataValue(MyID3Listener listener, boolean
// strict, IMusicMetadata values,
// String value)
// {
// values.setEngineer(value);
// }
//
// protected String getAndClearMetadataValue(IMusicMetadata values)
// {
// String result = values.getEngineer();
// values.clearEngineer();
// return result;
// }
//
// protected ID3FrameType getFrameType()
// {
// return ID3FrameType.ENGINEER;
// }
// }, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setPublisher(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getPublisher();
values.clearPublisher();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.PUBLISHER;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setConductor(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getConductor();
values.clearConductor();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.CONDUCTOR;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setBand(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getBand();
values.clearBand();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.BAND;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setMixArtist(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getMixArtist();
values.clearMixArtist();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.MIX_ARTIST;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setLyricist(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getLyricist();
values.clearLyricist();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.LYRICIST;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setEncodedBy(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getEncodedBy();
values.clearEncodedBy();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.ENCODED_BY;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setEncoderSettings(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getEncoderSettings();
values.clearEncoderSettings();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.ENCODER_SETTINGS;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setMediaType(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getMediaType();
values.clearMediaType();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.MEDIA_TYPE;
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
{
values.setFileType(value);
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
String result = values.getFileType();
values.clearFileType();
return result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.FILE_TYPE;
}
}, //
new Translator() {
public final void translateMetadataToFrames(
IMusicMetadata metadata, Vector frames,
IFrameFactory frameFactory) throws IOException
{
String genreString = "";
if (null != metadata.getGenreName())
genreString = metadata.getGenreName();
if (null != metadata.getGenreID())
genreString = "(" + metadata.getGenreID() + ")"
+ genreString;
metadata.clearGenre();
if (genreString.length() > 0)
{
ID3v2OutputFrame frame = frameFactory.createTextFrame(
ID3FrameType.CONTENTTYPE, genreString);
frames.add(frame);
}
}
public final void translateFramesToMetadata(
MyID3Listener listener, boolean strict,
IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
MyID3v2FrameText textFrame = findAndRemoveUniqueTextFrame(
listener, strict, frames, ID3FrameType.CONTENTTYPE);
if (null == textFrame)
return;
// TODO: actually, TCON are of form
// (1)(2)refinement...
// should catch or at least warn of refinements, multiples
// values
String value = textFrame.value;
// try
// {
if (value == null || value.trim().length() < 1)
return;
value = value.trim();
Number genreID = null;
String genreName = null;
String genreIdParenRegex = "^\\((\\d+)\\)";
Pattern genreIdParenPattern = Pattern
.compile(genreIdParenRegex);
while (true)
{
Matcher m = genreIdParenPattern.matcher(value);
if (!m.find())
break;
// discard genre ids after first
if (null == genreID)
{
try
{
String genreIDString = m.group(1);
genreID = Integer.valueOf(genreIDString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid genre value: " + value);
else if (null != listener)
listener.log("Invalid genre value", value);
}
}
value = value.substring(m.group(0).length());
}
String genreIdOnlyRegex = "^\\d+$";
Pattern genreIdOnlyPattern = Pattern
.compile(genreIdOnlyRegex);
Matcher m = genreIdOnlyPattern.matcher(value);
if (m.find())
{
try
{
String genreIDString = m.group(0);
genreID = Integer.valueOf(genreIDString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid genre value: " + value);
else if (null != listener)
listener.log("Invalid genre value", value);
}
value = "";
}
// RE genreIdRegExp = new RE("^\\((\\d+)\\)");
//
// // Debug.debug("id_only", id_only);
// while (genreIdRegExp.match(value))
// {
// // discard genre ids after first
// if (null == genreID)
// {
// genreID = genreIdRegExp.group(1);
// }
//
// value = value.substring(genreIdRegExp.group(0)
// .length());
// }
// boolean id_only = new RE("^\\(\\d+\\)").match(value);
//
// Number genreID = null;
// String genreName = null;
//
// // Debug.debug("id_only", id_only);
// if (id_only)
// {
// int index = value.indexOf(')');
// String number = value.substring(1, index);
// // Debug.debug("number", number);
//
// number = number.trim();
// if (isNumber(number))
// {
// genreID = new Integer(number);
// if (genreID.intValue() != 0)
// genreName = ID3v1Genre
// .getNameForID(genreID);
//
// value = value.substring(index + 1);
// }
// } else
// {
// boolean numeric_only = new RE("^\\d+$")
// .match(value);
// // Debug.debug("numeric_only", numeric_only);
// if (numeric_only)
// {
// genreID = new Integer(value);
// if (genreID.intValue() != 0)
// genreName = ID3v1Genre
// .getNameForID(genreID);
//
// value = "";
// // Debug.debug("id", id);
// }
// }
if (value.length() > 0)
genreName = value;
if (null != genreName && genreID != null)
metadata.setGenre(genreName, genreID);
else if (null != genreName)
metadata.setGenreName(genreName);
else if (null != genreID)
metadata.setGenreID(genreID);
// } catch (NumberFormatException e)
// {
// Debug.debug(e);
// }
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
throws ID3ReadException
{
try
{
Number year = Integer.valueOf(value);
values.setYear(year);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException("Invalid year value: "
+ value);
else if (null != listener)
listener.log("Invalid year value", value);
}
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
Number result = values.getYear();
values.clearYear();
return result == null ? null : "" + result;
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.YEAR;
}
}, //
new Translator() {
public final void translateMetadataToFrames(
IMusicMetadata metadata, Vector frames,
IFrameFactory frameFactory) throws IOException
{
Object trackCount = metadata.getTrackCount();
Object trackNumber = metadata.getTrackNumberDescription();
if (trackCount != null || trackNumber != null)
{
String value = "";
if (trackNumber != null)
value += trackNumber.toString();
if (trackCount != null)
{
value += "/";
value += trackCount.toString();
}
frames.add(frameFactory.createTextFrame(
ID3FrameType.TRACKNUM, value));
}
metadata.clearTrackCount();
metadata.clearTrackNumber();
}
public final void translateFramesToMetadata(
MyID3Listener listener, boolean strict,
IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
MyID3v2FrameText textFrame = findAndRemoveUniqueTextFrame(
listener, strict, frames, ID3FrameType.TRACKNUM);
if (null == textFrame)
return;
String value = textFrame.value;
if (value == null || value.trim().length() < 1)
return;
value = value.trim();
String trackNumberDescription = null;
Number trackCount = null;
String justTrackCountRegex = "^/(\\d+)$";
Pattern justTrackCountPattern = Pattern
.compile(justTrackCountRegex);
Matcher justTrackCountPatternMatcher = justTrackCountPattern
.matcher(value);
String trackNumberAndCountRegex = "^(\\w+)/(\\d+)$";
Pattern trackNumberAndCountPattern = Pattern
.compile(trackNumberAndCountRegex);
Matcher trackNumberAndCountPatternMatcher = trackNumberAndCountPattern
.matcher(value);
if (justTrackCountPatternMatcher.find())
{
try
{
String trackCountString = justTrackCountPatternMatcher
.group(1);
trackCount = Integer.valueOf(trackCountString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid track number value: " + value);
else if (null != listener)
listener.log("Invalid track number value",
value);
}
} else if (trackNumberAndCountPatternMatcher.find())
{
try
{
trackNumberDescription = trackNumberAndCountPatternMatcher
.group(1);
String trackCountString = trackNumberAndCountPatternMatcher
.group(2);
trackCount = Integer.valueOf(trackCountString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid track number value: " + value);
else if (null != listener)
listener.log("Invalid track number value",
value);
}
} else
trackNumberDescription = value;
metadata.setTrackCount(trackCount);
metadata.setTrackNumberDescription(trackNumberDescription);
}
}, //
new Translator() {
public final void translateMetadataToFrames(
IMusicMetadata metadata, Vector frames,
IFrameFactory frameFactory) throws IOException
{
Number partOfSetIndex = metadata.getPartOfSetIndex();
Number partOfSetCount = metadata.getPartOfSetCount();
if (partOfSetIndex != null || partOfSetCount != null)
{
String value = "";
if (partOfSetIndex != null)
value += partOfSetIndex.toString();
if (partOfSetCount != null)
{
value += "/";
value += partOfSetCount.toString();
}
frames.add(frameFactory.createTextFrame(
ID3FrameType.PARTINSET, value));
}
metadata.clearPartOfSetIndex();
metadata.clearPartOfSetCount();
}
public final void translateFramesToMetadata(
MyID3Listener listener, boolean strict,
IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
MyID3v2FrameText textFrame = findAndRemoveUniqueTextFrame(
listener, strict, frames, ID3FrameType.PARTINSET);
if (null == textFrame)
return;
String value = textFrame.value;
if (value == null || value.trim().length() < 1)
return;
value = value.trim();
Number partOfSetIndex = null;
Number partOfSetCount = null;
String justPartOfSetIndexRegex = "^(\\d+)/?$";
Pattern justPartOfSetIndexPattern = Pattern
.compile(justPartOfSetIndexRegex);
Matcher justPartOfSetIndexPatternMatcher = justPartOfSetIndexPattern
.matcher(value);
String partOfSetIndexAndCountRegex = "^(\\d*)/(\\d+)$";
Pattern partOfSetIndexAndCountPattern = Pattern
.compile(partOfSetIndexAndCountRegex);
Matcher partOfSetIndexAndCountPatternMatcher = partOfSetIndexAndCountPattern
.matcher(value);
if (justPartOfSetIndexPatternMatcher.find())
{
try
{
String partOfSetIndexString = justPartOfSetIndexPatternMatcher
.group(1);
partOfSetIndex = Integer
.valueOf(partOfSetIndexString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid part of set value: " + value);
else if (null != listener)
listener
.log("Invalid part of set value", value);
}
} else if (partOfSetIndexAndCountPatternMatcher.find())
{
try
{
String partOfSetIndexString = partOfSetIndexAndCountPatternMatcher
.group(1);
partOfSetIndex = Integer
.valueOf(partOfSetIndexString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid part of set value: " + value);
else if (null != listener)
listener
.log("Invalid part of set value", value);
}
try
{
String partOfSetCountString = partOfSetIndexAndCountPatternMatcher
.group(2);
partOfSetCount = Integer
.valueOf(partOfSetCountString);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid part of set value: " + value);
else if (null != listener)
listener
.log("Invalid part of set value", value);
}
} else
{
if (strict)
throw new ID3ReadException(
"Invalid part of set value: " + value);
else if (null != listener)
listener.log("Invalid part of set value", value);
}
metadata.setPartOfSetIndex(partOfSetIndex);
metadata.setPartOfSetCount(partOfSetCount);
}
}, //
new SimpleTranslator() {
protected void setMetadataValue(MyID3Listener listener,
boolean strict, IMusicMetadata values, String value)
throws ID3ReadException
{
try
{
Long year = Long.valueOf(value);
// ms to seconds
year = new Long(year.longValue() / 1000);
values.setDurationSeconds(year);
} catch (NumberFormatException e)
{
if (strict)
throw new ID3ReadException(
"Invalid duration value: " + value);
else if (null != listener)
listener.log("Invalid duration value", value);
}
}
protected String getAndClearMetadataValue(IMusicMetadata values)
{
Number result = values.getDurationSeconds();
values.clearDurationSeconds();
return result == null ? null : ""
+ (result.longValue() * 1000);
}
protected ID3FrameType getFrameType()
{
return ID3FrameType.SONGLEN;
}
}, //
new Translator() {
public void translateMetadataToFrames(IMusicMetadata metadata,
Vector frames, IFrameFactory frameFactory)
throws IOException
{
String engineer = metadata.getEngineer();
if (null != engineer)
frames.add(frameFactory.createUserTextFrame("engineer",
engineer));
metadata.clearEngineer();
List unknownUserTextValues = metadata
.getUnknownUserTextValues();
for (int i = 0; i < unknownUserTextValues.size(); i++)
{
UnknownUserTextValue value = (UnknownUserTextValue) unknownUserTextValues
.get(i);
ID3v2OutputFrame frame = frameFactory
.createUserTextFrame(value.key, value.value);
frames.add(frame);
}
metadata.clearUnknownUserTextValues();
}
public void translateFramesToMetadata(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, Vector frames)
throws ID3ReadException
{
List found = findAndRemoveFrames(listener, strict, frames,
ID3FrameType.USERTEXT);
for (int i = 0; i < found.size(); i++)
{
MyID3v2FrameText textFrame = (MyID3v2FrameText) found
.get(i);
if (textFrame.value.equals("engineer"))
metadata.setEngineer(textFrame.value2);
else
metadata
.addUnknownUserTextValue(new UnknownUserTextValue(
textFrame.value, textFrame.value2));
}
}
}, //
};
// private static final Map KEY_TO_FRAME_TYPE_MAP = new HashMap();
// private static final Vector IGNORED_FRAME_TYPES = new Vector();
// static
// {
// for (int i = 0; i < TRANSLATORS.length; i++)
// {
// Translator handler = TRANSLATORS[i];
//
// Object key = handler.getMetadataKey();
// if (key != null)
// KEY_TO_FRAME_TYPE_MAP.put(key, handler.getFrameType());
// else
// IGNORED_FRAME_TYPES.add(handler.getFrameType());
// }
// }
// private static final Vector IGNORED_METADATA_KEYS = new Vector();
// static
// {
// IGNORED_METADATA_KEYS.add(KEY_COMPILATION);
// IGNORED_METADATA_KEYS.add(KEY_SOUNDTRACK);
// IGNORED_METADATA_KEYS.add(KEY_ACAPELLA);
// IGNORED_METADATA_KEYS.add(KEY_PRODUCER);
// }
//
// public static final boolean isIgnoredMetadataKey(String key)
// {
// return IGNORED_METADATA_KEYS.contains(key);
// }
//
// public static final ID3FrameType getID3FrameType(Object key)
// {
// if (key.equals(KEY_PICTURES))
// return ID3FrameType.PICTURE;
//
// return (ID3FrameType) KEY_TO_FRAME_TYPE_MAP.get(key);
// }
//
// public static final boolean isIgnoredID3FrameType(ID3FrameType
// frame_type)
// {
// return IGNORED_FRAME_TYPES.contains(frame_type);
// }
public static final MusicMetadata translateFramesToMetadata(
MyID3Listener listener, boolean strict, Vector frames)
throws ID3ReadException
{
// if (frames == null)
// return null;
//
MusicMetadata result = new MusicMetadata("id3v2");
for (int i = 0; i < TRANSLATORS.length; i++)
{
Translator translator = TRANSLATORS[i];
translator.translateFramesToMetadata(listener, strict, result,
frames);
}
for (int i = 0; i < frames.size(); i++)
{
MyID3v2Frame frame = (MyID3v2Frame) frames.get(i);
if (strict)
throw new ID3ReadException("Could not translate frame: "
+ frame.frameID);
else if (null != listener)
listener.log("Could not translate frame", frame.frameID);
}
return result;
}
public static final List translateMetadataToFrames(MyID3Listener listener,
boolean strict, IMusicMetadata metadata, IFrameFactory frameFactory)
throws ID3WriteException, IOException
{
Vector frames = new Vector();
// make a local copy; we're going to clear keys as we translate them.
metadata = new MusicMetadata(metadata);
for (int i = 0; i < TRANSLATORS.length; i++)
{
Translator translator = TRANSLATORS[i];
translator
.translateMetadataToFrames(metadata, frames, frameFactory);
}
Map untranslated = metadata.getRawValues();
List untranslatedKeys = new ArrayList(untranslated.keySet());
for (int i = 0; i < untranslatedKeys.size(); i++)
{
String key = (String) untranslatedKeys.get(i);
if (strict)
throw new ID3WriteException(
"Could not translate metadata key: " + key);
else if (null != listener)
listener.log("Could not translate metadata key", key);
}
return frames;
}
}