001package co.codewizards.cloudstore.local.persistence; 002 003import java.io.File; 004import java.util.HashSet; 005import java.util.Set; 006 007import javax.jdo.annotations.Discriminator; 008import javax.jdo.annotations.DiscriminatorStrategy; 009import javax.jdo.annotations.Index; 010import javax.jdo.annotations.Indices; 011import javax.jdo.annotations.Inheritance; 012import javax.jdo.annotations.InheritanceStrategy; 013import javax.jdo.annotations.NullValue; 014import javax.jdo.annotations.PersistenceCapable; 015import javax.jdo.annotations.Persistent; 016import javax.jdo.annotations.Queries; 017import javax.jdo.annotations.Query; 018 019@PersistenceCapable 020@Inheritance(strategy=InheritanceStrategy.SUPERCLASS_TABLE) 021@Discriminator(strategy=DiscriminatorStrategy.VALUE_MAP, value="NormalFile") 022@Indices({ 023 @Index(name="NormalFile_sha1_length", members={"sha1", "length"}) 024}) 025@Queries({ 026 @Query(name="getNormalFiles_sha1_length", value="SELECT WHERE this.sha1 == :sha1 && this.length == :length") 027}) 028public class NormalFile extends RepoFile { 029 030 private long length; 031 032 @Persistent(nullValue=NullValue.EXCEPTION) 033 private String sha1; 034 035 private boolean inProgress; 036 037 @Persistent(mappedBy="normalFile", dependentElement="true") 038 private Set<FileChunk> fileChunks; 039 040 /** 041 * Gets the file size in bytes. 042 * <p> 043 * It reflects the {@link File#length() File.length} property. 044 * @return the file size in bytes. 045 */ 046 public long getLength() { 047 return length; 048 } 049 public void setLength(long size) { 050 this.length = size; 051 } 052 /** 053 * Gets the <a href="http://en.wikipedia.org/wiki/SHA-1">SHA-1</a> of the file. 054 * @return the <a href="http://en.wikipedia.org/wiki/SHA-1">SHA-1</a> of the file. 055 */ 056 public String getSha1() { 057 return sha1; 058 } 059 public void setSha1(String sha) { 060 this.sha1 = sha; 061 } 062 063 /** 064 * Is this file in progress of being synced? 065 * <p> 066 * If yes, it is ignored in change-sets in order to prevent inconsistent data to propagate further. 067 * <p> 068 * TODO We should later implement a mechanism that parks all modifications locally (not in the DB, but in the 069 * meta-directory) before applying them to the file in one transaction. 070 * @return <code>true</code>, if it is currently in progress of being synced; <code>false</code> otherwise. 071 */ 072 public boolean isInProgress() { 073 return inProgress; 074 } 075 public void setInProgress(boolean inProgress) { 076 this.inProgress = inProgress; 077 } 078 079 public Set<FileChunk> getFileChunks() { 080 // TODO (1) This should be a SortedSet (a TreeSet), but for whatever reason, this does not work anymore 081 // and causes ClassCastExceptions :-( 082 // TODO (2) this should return a decorator which automatically calls FileChunk.makeReadOnly() when 083 // enlisting a new instance! 084 if (fileChunks == null) 085 fileChunks = new HashSet<>(); 086 087 return fileChunks; 088 } 089}