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; } }