package de.unikassel.sdcframework; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import de.unikassel.android.sdcframework.data.independent.BasicSample; import de.unikassel.android.sdcframework.data.independent.BasicSampleCollection; import de.unikassel.android.sdcframework.data.independent.DeviceInformation; import de.unikassel.android.sdcframework.data.independent.FileReferenceSampleData; import de.unikassel.android.sdcframework.data.independent.GlobalSerializer; import de.unikassel.android.sdcframework.data.independent.SampleData; import de.unikassel.android.sdcframework.util.FileUtils; /** * Utility class to read SDC Archive content. <br/> * <br/> * To use it, you need the simple-xml framework library (>= Version 2.5.3) and * the sdcframework_independent library. * * @author Katy Hilgenberg */ public class ArchiveContent { /** * The log helper class */ private final static LogUtil log = new LogUtil( ArchiveContent.class ); /** * The raw SDCF data */ private final SDCFRawData rawData; /** * The file map ( name to location mapping ) */ private final Map< String, String > mapFiles = new HashMap< String, String >(); /** * Constructor */ private ArchiveContent() { rawData = new SDCFRawData(); } /** * Getter for the raw SDCF data * * @return the raw data */ public SDCFRawData getRawData() { return rawData; } /** * Getter for the file map * * @return the file map */ public Map< String, String > getMapFiles() { return mapFiles; } /** * Does create a SDC content instance from the archive content * * @param archive * the archive file * @param audioFilePath * the directory to store the files in * @return the SDC content of the files in the archive */ public static ArchiveContent createFromArchive( File archive, String audioFilePath ) { ArchiveContent content = new ArchiveContent(); ZipInputStream zipStream = null; if ( !audioFilePath.endsWith( File.separator ) ) audioFilePath += File.separatorChar; try { zipStream = new ZipInputStream( new BufferedInputStream( new FileInputStream( archive ) ) ); ZipEntry entry = zipStream.getNextEntry(); while ( entry != null ) { String srcFileName = entry.getName(); if ( srcFileName .equals( BasicSampleCollection.SAMPLE_COLLECTION_FILE ) ) { // deserialize the device information content.getRawData() .setSampleCollection( GlobalSerializer .fromXML( BasicSampleCollection.class, FileUtils .readTextStreamContent( zipStream ) ) ); } else if ( srcFileName .equals( DeviceInformation.DEVICE_INFO_FILE ) ) { // deserialize the samples information content.getRawData() .setDeviceInfo( GlobalSerializer.fromXML( DeviceInformation.class, FileUtils .readTextStreamContent( zipStream ) ) ); } else { // extract files map the storage path String destFileName = audioFilePath + srcFileName; content.getMapFiles().put( srcFileName, destFileName ); OutputStream outStream = new BufferedOutputStream( new FileOutputStream( destFileName ) ); try { byte[] buffer = new byte[1024]; int count = zipStream.read( buffer ); while ( count != -1 ) { outStream.write( buffer, 0, count ); count = zipStream.read( buffer ); } } finally { outStream.close(); } } entry = zipStream.getNextEntry(); } } catch ( Exception e ) { content = null; log.error( "Failed to extract archive content from file \"" + archive + "\"" ); } finally { if ( zipStream != null ) { try { zipStream.close(); } catch ( IOException e ) {} } } if ( content != null ) { // update the related file path to the new location entries in the // file reference sample data for ( BasicSample sample : content.getRawData() .getSampleCollection().getSamples() ) { SampleData data = sample.getData(); if ( data instanceof FileReferenceSampleData ) { FileReferenceSampleData fileRefData = (FileReferenceSampleData) data; String fileName = content.getMapFiles().get( fileRefData.getRelatedData() ); fileRefData.updateRelatedData( fileName ); } } content.getMapFiles().clear(); } return content; } }