001package co.codewizards.cloudstore.local.persistence; 002 003import static co.codewizards.cloudstore.core.util.HashUtil.*; 004import static co.codewizards.cloudstore.core.util.Util.*; 005import static java.util.Objects.*; 006 007import java.net.URL; 008import java.util.UUID; 009 010import javax.jdo.annotations.Column; 011import javax.jdo.annotations.Discriminator; 012import javax.jdo.annotations.DiscriminatorStrategy; 013import javax.jdo.annotations.Index; 014import javax.jdo.annotations.Inheritance; 015import javax.jdo.annotations.InheritanceStrategy; 016import javax.jdo.annotations.NullValue; 017import javax.jdo.annotations.PersistenceCapable; 018import javax.jdo.annotations.Persistent; 019import javax.jdo.annotations.Queries; 020import javax.jdo.annotations.Query; 021 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024 025import co.codewizards.cloudstore.core.util.UrlUtil; 026 027@PersistenceCapable 028@Inheritance(strategy=InheritanceStrategy.SUPERCLASS_TABLE) 029@Discriminator(strategy=DiscriminatorStrategy.VALUE_MAP, value="RemoteRepository") 030//@Index(name="RemoteRepository_remoteRoot", members="remoteRoot") // Indexing a CLOB with Derby throws an exception :-( [should be a warning, IMHO for portability reasons] 031@Index(name="RemoteRepository_remoteRootSha1", members="remoteRootSha1") 032@Queries({ 033 @Query(name="getRemoteRepository_repositoryId", value="SELECT UNIQUE WHERE this.repositoryId == :repositoryId"), 034 @Query(name="getRemoteRepository_remoteRootSha1", value="SELECT UNIQUE WHERE this.remoteRootSha1 == :remoteRootSha1") 035}) 036public class RemoteRepository extends Repository implements AutoTrackLocalRevision { 037 private static final Logger logger = LoggerFactory.getLogger(RemoteRepository.class); 038 039 @Column(jdbcType="CLOB") 040 private URL remoteRoot; 041 042 private String remoteRootSha1; 043 044 private long localRevision; 045 046 @Persistent(nullValue=NullValue.EXCEPTION) 047 private String localPathPrefix; 048 049 public RemoteRepository() { } 050 051 public RemoteRepository(final UUID repositoryId) { 052 super(repositoryId); 053 } 054 055 public URL getRemoteRoot() { 056 return remoteRoot; 057 } 058 059 public void setRemoteRoot(URL remoteRoot) { 060 if (equal(this.getRemoteRoot(), remoteRoot)) 061 return; 062 063 remoteRoot = UrlUtil.canonicalizeURL(remoteRoot); 064 this.remoteRoot = remoteRoot; 065 this.remoteRootSha1 = remoteRoot == null ? null : sha1(remoteRoot.toExternalForm()); 066 } 067 068 public String getRemoteRootSha1() { 069 return remoteRootSha1; 070 } 071 072 @Override 073 public long getLocalRevision() { 074 return localRevision; 075 } 076 @Override 077 public void setLocalRevision(final long localRevision) { 078 if (! equal(this.localRevision, localRevision)) { 079 if (logger.isDebugEnabled()) 080 logger.debug("setLocalRevision: repositoryId={} old={} new={}", getRepositoryId(), this.localRevision, localRevision); 081 082 this.localRevision = localRevision; 083 } 084 } 085 086 public String getLocalPathPrefix() { 087 return localPathPrefix; 088 } 089 public void setLocalPathPrefix(final String localPathPrefix) { 090 requireNonNull(localPathPrefix, "localPathPrefix"); 091 092 if (!localPathPrefix.isEmpty() && !localPathPrefix.startsWith("/")) 093 throw new IllegalArgumentException("localPathPrefix must start with '/' but does not: " + localPathPrefix); 094 095 if (! equal(this.localPathPrefix, localPathPrefix)) 096 this.localPathPrefix = localPathPrefix; 097 } 098}