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}