001package co.codewizards.cloudstore.local.persistence; 002 003import static co.codewizards.cloudstore.core.util.HashUtil.sha1; 004import static co.codewizards.cloudstore.core.util.Util.assertNotNull; 005 006import javax.jdo.annotations.Column; 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.NEW_TABLE) 021@Discriminator(strategy=DiscriminatorStrategy.VALUE_MAP, value="DeleteModification") 022@Indices({ 023 @Index(name="DeleteModification_pathSha1", members={"pathSha1"}), 024 @Index(name="DeleteModification_sha1_length", members={"sha1", "length"}) 025}) 026//@Unique(name="DeleteModification_pathSha1_localRevision_remoteRepository", members={"pathSha1", "localRevision", "remoteRepository"}) // causes an NPE :-( The NPE is not nice, but it's clear that this cannot work: There are 2 separate tables (InheritanceStrategy.NEW_TABLE). 027@Queries({ 028 @Query(name="getDeleteModificationsForPathAfter_pathSha1_localRevision_remoteRepository", value="SELECT WHERE this.pathSha1 == :pathSha1 && this.localRevision > :localRevision"), 029 @Query(name="getDeleteModifications_sha1_length", value="SELECT WHERE this.sha1 == :sha1 && this.length == :length") 030}) 031public class DeleteModification extends Modification { 032 033 @Persistent(nullValue=NullValue.EXCEPTION, defaultFetchGroup="true") 034 @Column(jdbcType="CLOB") 035 private String path; 036 037 @Persistent(nullValue=NullValue.EXCEPTION) 038 private String pathSha1; 039 040 private long length; 041 042 private String sha1; 043 044 /** 045 * Gets the path of the deleted directory or file. 046 * <p> 047 * This path is always relative to the local repository's root; even if the remote repository uses a 048 * {@link RemoteRepository#getLocalPathPrefix() path-prefix}. Stripping of the path-prefix is 049 * done during DTO generation. 050 * @return the path of the deleted directory or file. Never <code>null</code>. 051 */ 052 public String getPath() { 053 return path; 054 } 055 public void setPath(String path) { 056 assertNotNull("path", path); 057 if (path.isEmpty()) 058 throw new IllegalArgumentException("path is empty! path must start with '/' and thus has a minimum length of 1 char!"); 059 060 if (!path.startsWith("/")) 061 throw new IllegalArgumentException("path does not start with '/'!"); 062 063 this.path = path; 064 this.pathSha1 = sha1(path); 065 } 066 067 public long getLength() { 068 return length; 069 } 070 public void setLength(long length) { 071 this.length = length; 072 } 073 public String getSha1() { 074 return sha1; 075 } 076 public void setSha1(String sha1) { 077 this.sha1 = sha1; 078 } 079 080}