package com.limegroup.gnutella.archive;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.limegroup.gnutella.licenses.License;
import com.limegroup.gnutella.licenses.LicenseFactory;
import com.limegroup.gnutella.util.CommonUtils;
import com.limegroup.gnutella.xml.LimeXMLDocument;
import com.limegroup.gnutella.xml.LimeXMLNames;
import com.limegroup.gnutella.xml.LimeXMLUtils;
import com.limegroup.gnutella.FileDesc;
import com.limegroup.gnutella.FileDetails;
class File {
/*
* From http://www.archive.org/help/contrib-advanced.php:
*
* The format name is very important to choose accurately. The list of
* acceptable format names is: WAVE, 64Kbps MP3, 128Kbps MP3, 256Kbps MP3,
* VBR MP3, 96Kbps MP3, 160Kbps MP3, 192Kbps MP3, Ogg Vorbis, Shorten, Flac,
* 24bit Flac, 64Kbps M3U, VBR M3U, Single Page Original JPEG Tar, Single
* Page Processed JPEG Tar, Single Page Original JPEG ZIP, Single Page
* Processed JPEG ZIP, Single Page Original TIFF ZIP, Single Page Processed
* TIFF ZIP, Checksums, MPEG2, MPEG1, 64Kb MPEG4, 256Kb MPEG4, MPEG4, 56Kb
* QuickTime, 64Kb QuickTime, 256Kb QuickTime, QuickTime, Motion JPEG, DivX,
* IV50, Windows Media, Cinepack, Flash, Real Media, Item Image, Collection
* Header, Animated GIF, Animated GIF Images, Thumbnail, JPEG, Single Page
* Original JPEG, Single Page Processed JPEG, Single Page Original TIFF,
* Single Page Processed TIFF, Multi Page Original TIFF, Multi Page
* Processed TIFF, PDF, DjVuTXT, DjVuXML, Flippy Index, DjVu, Single Page
* Processed JPEG Tar, Single Page Original JPEG Tar, Flippy ZIP, Text,
* Single Book Page Text, TGZiped Text Files, Book Cover, DAT, ARC,
* Metadata, Files Metadata, Item Metadata, Book Metadata. This list is
* dynamically generated so check back later for newly acceptable formats.
*/
private static final HashMap _mp3Formats = new HashMap();
static {
/*
* Weird. looks like if you can only submit constant bit rate MP3s with
* these bitrates
*/
final int[] bitRates = { 64, 96, 128, 160, 192, 256 };
for (int i = 0; i < bitRates.length; i++) {
final Integer bitRate = new Integer(bitRates[i]);
_mp3Formats.put(bitRate, bitRate.toString() + "Kbps MP3");
}
}
private static final String MP3_VBR = "VBR MP3";
private static final String OGG_VORBIS = "Ogg Vorbis";
private final FileDesc _fd;
private String _format;
private String _runtime;
private String _licenseUrl;
private String _licenseDeclaration;
private Element _element;
private final String _remoteFileName; // normalized
/*
* @throws UnsupportedFormatException
*/
File(FileDesc fd) {
_fd = fd;
final LimeXMLDocument xmlDoc = _fd.getXMLDocument();
final String fileName = _fd.getFileName();
_remoteFileName = Archives.normalizeName( fileName );
// set the format
if (LimeXMLUtils.isMP3File(fileName)) {
// check the bitrate
try {
final String bitRateStr = xmlDoc.getValue(LimeXMLNames.AUDIO_BITRATE);
if ( bitRateStr != null ) {
final Integer bitRate = Integer.valueOf( bitRateStr );
if (_mp3Formats.get( bitRate ) != null ) {
_format = (String) _mp3Formats.get( bitRate );
}
}
} catch (NumberFormatException e) {
}
if (_format == null ) {
// I guess we'll just assume it's a VBR then
_format = MP3_VBR;
}
} else if (LimeXMLUtils.isOGGFile(fileName)) {
_format = OGG_VORBIS;
} else {
// Houston, we have a problem
throw new UnsupportedFormatException();
}
// set the runtime
try {
final String secondsStr = xmlDoc.getValue(LimeXMLNames.AUDIO_SECONDS);
if ( secondsStr != null ) {
final int seconds = Integer.parseInt(secondsStr);
_runtime = CommonUtils.seconds2time( seconds );
}
} catch (NumberFormatException e) {
}
// set the licenseUrl and licenseDeclaration
if ( xmlDoc.isLicenseAvailable() ) {
final License license = xmlDoc.getLicense();
if ( license.getLicenseName() == LicenseFactory.CC_NAME ) {
_licenseUrl = license.getLicenseDeed(null).toString();
_licenseDeclaration = xmlDoc.getLicenseString();
}
}
}
String getLicenseUrl() {
return _licenseUrl;
}
String getLicenseDeclaration() {
return _licenseDeclaration;
}
String getLocalFileName() {
return _fd.getFileName();
}
String getRemoteFileName() {
return _remoteFileName;
}
FileDetails getFileDetails() {
return _fd;
}
long getFileSize() {
return _fd.getFileSize();
}
java.io.File getIOFile() {
return _fd.getFile();
}
/**
*
* @param document
* root document for generating the element
* @return
*/
Element getElement( Document document ) {
/*
* Sample XML representation:
*
* <file name="MyHomeMovie.mpeg" source="original">
* <runtime>2:30</runtime>
* <format>MPEG2</format>
* </file>
*/
final String FILE_ELEMENT = "file";
final String NAME_ATTR = "name";
final String SOURCE_ATTR = "source";
final String SOURCE_ATTR_DEFAULT_VALUE = "original";
final String RUNTIME_ELEMENT = "runtime";
final String FORMAT_ELEMENT = "format";
final String LICENSE_ELEMENT = "license";
if ( _element == null ) {
final Element fileElement = document.createElement(FILE_ELEMENT);
fileElement.setAttribute( NAME_ATTR, getRemoteFileName());
fileElement.setAttribute( SOURCE_ATTR, SOURCE_ATTR_DEFAULT_VALUE );
if ( _runtime != null ) {
final Element runtimeElement = document.createElement(RUNTIME_ELEMENT);
runtimeElement.appendChild( document.createTextNode( _runtime ));
fileElement.appendChild( runtimeElement );
}
// _format should not be null (otherwise we would have thrown
// an UnsupportedFormatException upon construction)
final Element formatElement = document.createElement(FORMAT_ELEMENT);
formatElement.appendChild( document.createTextNode( _format ));
fileElement.appendChild( formatElement );
// defacto standard due to ccPublisher. each <file> has
// a child <license> element with its text set to be
// the license declaration
final String licenseDeclaration = getLicenseDeclaration();
if ( licenseDeclaration != null ) {
final Element licenseElement = document.createElement( LICENSE_ELEMENT );
licenseElement.appendChild( document.createTextNode( licenseDeclaration ));
fileElement.appendChild( licenseElement );
}
// we all good now
_element = fileElement;
}
return _element;
}
}