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