package org.openslx.imagemaster.serverconnection; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.crcchecker.CrcFile; import org.openslx.imagemaster.crcchecker.ImageFile; import org.openslx.imagemaster.db.DbImage; /** * Helper class for ImageProcessor and ConnectionHandler to save some infos about the images in the * process list. */ public class UploadingImage { public static final Logger log = Logger.getLogger( UploadingImage.class ); /** * The status list of the blocks. * x = 0 block is missing * x = 200 block arrived and is valid * x > 0 block is invalid and was transmitted x times (needs request) * x < 0 block is invalid and was transmitted x times (needs check) */ private final int[] blockStatus; /** * Remember last position in blockStatus array that was returned, so we don't always * iterate from the beginning. */ private int lastStatusPos = 0; public static final int VALID = 200; public static final int MISSING = 0; private DbImage dbImage = null; // the DB representation of this image /** * Class for accessing the file (read blocks from it) */ private ImageFile imageFile = null; private CrcFile crcFile = null; protected UploadingImage( String uuid ) { this.dbImage = DbImage.getImageByUuid( uuid ); if ( this.dbImage == null ) throw new RuntimeException( "Unknown image " + uuid + " on UploadingImage creation" ); this.blockStatus = this.dbImage.blockStatus; } protected void setValid( int index ) { synchronized ( blockStatus ) { blockStatus[index] = VALID; } } protected void updateDb() { List missingBlocks = new ArrayList<>(); synchronized ( blockStatus ) { for ( int block = 0; block < blockStatus.length; block++ ) { if ( blockStatus[block] != VALID ) { missingBlocks.add( block ); } } } dbImage.updateMissingBlocks( missingBlocks ); } protected void setMissing( int index ) { synchronized ( blockStatus ) { blockStatus[index] = MISSING; } } protected void setNeedsRequest( int index ) { synchronized ( blockStatus ) { blockStatus[index] = Math.abs( blockStatus[index] ); // switch to positive value if needed } } protected void setNeedsCheck( int index ) { synchronized ( blockStatus ) { if ( crcFile == null ) { blockStatus[index] = VALID; } else { blockStatus[index] = -Math.abs( blockStatus[index] ); // switch to negative value if needed } } } protected void increaseTransmittedTimes( int index ) { synchronized ( blockStatus ) { if ( blockStatus[index] == VALID ) return; blockStatus[index] += ( blockStatus[index] <= MISSING ) ? -1 : 1; // increase in both directions } } protected int getTimesTransmitted( int index ) { synchronized ( blockStatus ) { return Math.abs( blockStatus[index] ); } } protected boolean needsRequest( int index ) { synchronized ( blockStatus ) { return ( ( blockStatus[index] >= MISSING ) && ( blockStatus[index] != VALID ) ); } } protected boolean needsCheck( int index ) { synchronized ( blockStatus ) { return ( blockStatus[index] < MISSING ); } } protected int getNumberOfBlocks() { return blockStatus.length; } protected int getNextMissingBlock() { synchronized ( blockStatus ) { for ( int i = 0; i < blockStatus.length; i++ ) { int index = ( i + lastStatusPos ) % blockStatus.length; if ( blockStatus[index] == MISSING ) return lastStatusPos = index; } for ( int index = 0; index < blockStatus.length; index++ ) { if ( blockStatus[index] > MISSING && blockStatus[index] < VALID ) return lastStatusPos = index; } for ( int index = 0; index < blockStatus.length; index++ ) { if ( blockStatus[index] < MISSING ) return lastStatusPos = index; } } return -1; } /* protected long getTimestamp() { return this.timestamp; } */ protected ImageFile getImageFile() { if ( imageFile == null ) { imageFile = new ImageFile( dbImage.getAbsolutePath(), Globals.blockSize ); } return imageFile; } protected CrcFile getCrcFile() { if ( crcFile == null ) { try { crcFile = new CrcFile( dbImage.getAbsolutePath() + ".crc" ); } catch ( IOException e ) { // Not found... return null } } return crcFile; } protected void setCrcFile( CrcFile crcFile ) { if ( crcFile == null ) return; if ( getCrcFile() == null && crcFile.isValid() ) { this.crcFile = crcFile; try { crcFile.writeCrcFile( dbImage.getAbsolutePath() + ".crc" ); } catch ( IOException e ) { log.error( "Could not write crc list to file", e ); } } } public int getAmountOfBlocksNeedingRequest() { if ( blockStatus == null ) return 0; int result = 0; for ( int i = 0; i < blockStatus.length; i++ ) { if ( needsRequest( i ) ) result++; } return result; } public boolean allBlocksValid() { if ( blockStatus == null ) return false; synchronized ( blockStatus ) { for ( int i : blockStatus ) { if ( i != 200 ) return false; } } return true; } @Override public String toString() { return "UUID: " + dbImage.uuid + ", filename " + dbImage.imagePath + "\nmissing blocks " + getAmountOfBlocksNeedingRequest() + ", number of blocks " + getNumberOfBlocks(); } public String getAbsolutePath() { return dbImage.getAbsolutePath(); } public long getFileSize() { return dbImage.fileSize; } public String getUuid() { return dbImage.uuid; } public void updateMissingBlocks( List missingBlocks ) { dbImage.updateMissingBlocks( missingBlocks ); } }