/* * Syncany, www.syncany.org * Copyright (C) 2011-2015 Philipp C. Heckel <philipp.heckel@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.syncany.database; import java.io.File; import java.util.Date; import org.syncany.database.FileContent.FileChecksum; import org.syncany.database.PartialFileHistory.FileHistoryId; /** * A file version represents a version of a file at a certain time and captures * all of a file's properties. * * <p>A {@link PartialFileHistory} typically consists of multiple <tt>FileVersion</tt>s, * each of which is the incarnation of the same file, but with either changed properties, * or changed content. * * <p>The <tt>FileVersion</tt>'s checksum attribute implicitly links to a {@link FileContent}, * which represents the content of a file. Multiple file versions can link to the same file content. * * @see PartialFileHistory * @author Philipp C. Heckel <philipp.heckel@gmail.com> */ public class FileVersion implements Cloneable { // Optional private FileHistoryId fileHistoryId; // Mandatory private Long version; // TODO [low] This can be an Integer. No need for a long! private String path; private FileType type; private FileStatus status; private Long size; private Date lastModified; // Mandatory (if type is symlink) private String linkTarget; // Optional private FileChecksum checksum; private Date updated; private String posixPermissions; private String dosAttributes; public FileVersion() { // Fressen. } public FileHistoryId getFileHistoryId() { return fileHistoryId; } public void setFileHistoryId(FileHistoryId fileHistoryId) { this.fileHistoryId = fileHistoryId; } public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version; } public FileType getType() { return type; } public void setType(FileType type) { this.type = type; } public Date getLastModified() { return lastModified; } public void setLastModified(Date lastModified) { this.lastModified = lastModified; } public Date getUpdated() { return updated; } public void setUpdated(Date updated) { this.updated = updated; } public FileStatus getStatus() { return status; } public void setStatus(FileStatus status) { this.status = status; } public String getPath() { return path; } public String getName() { return new File(path).getName(); } public void setPath(String path) { this.path = path; } public FileChecksum getChecksum() { return checksum; } public void setChecksum(FileChecksum checksum) { this.checksum = checksum; } public Long getSize() { // TODO [low] Redundant field 'size', this field should not exist. Instead the content's size should be used. This was introduced as a convenience field. return size; } public void setSize(Long size) { this.size = size; } public String getLinkTarget() { return linkTarget; } public void setLinkTarget(String linkTarget) { this.linkTarget = linkTarget; } public String getPosixPermissions() { return posixPermissions; } public void setPosixPermissions(String posixPermissions) { this.posixPermissions = posixPermissions; } public String getDosAttributes() { return dosAttributes; } public void setDosAttributes(String dosAttributes) { this.dosAttributes = dosAttributes; } @Override public String toString() { return "FileVersion [version=" + version + ", path=" + path + ", type=" + type + ", status=" + status + ", size=" + size + ", lastModified=" + lastModified + ", linkTarget=" + linkTarget + ", checksum=" + checksum + ", updated=" + updated + ", posixPermissions=" + posixPermissions + ", dosAttributes=" + dosAttributes + "]"; } @Override public FileVersion clone() { try { FileVersion clone = (FileVersion) super.clone(); clone.setChecksum(getChecksum()); clone.setLastModified(getLastModified()); clone.setUpdated(getUpdated()); clone.setPath(getPath()); clone.setType(getType()); clone.setVersion(getVersion()); clone.setSize(getSize()); clone.setDosAttributes(getDosAttributes()); clone.setPosixPermissions(getPosixPermissions()); clone.setLinkTarget(getLinkTarget()); clone.setStatus(getStatus()); return clone; } catch (Exception ex) { throw new RuntimeException(ex); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((checksum == null) ? 0 : checksum.hashCode()); result = prime * result + ((dosAttributes == null) ? 0 : dosAttributes.hashCode()); result = prime * result + ((lastModified == null) ? 0 : lastModified.hashCode()); result = prime * result + ((linkTarget == null) ? 0 : linkTarget.hashCode()); result = prime * result + ((path == null) ? 0 : path.hashCode()); result = prime * result + ((posixPermissions == null) ? 0 : posixPermissions.hashCode()); result = prime * result + ((size == null) ? 0 : size.hashCode()); result = prime * result + ((status == null) ? 0 : status.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((updated == null) ? 0 : updated.hashCode()); result = prime * result + ((version == null) ? 0 : version.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof FileVersion)) { return false; } FileVersion other = (FileVersion) obj; if (checksum == null) { if (other.checksum != null) { return false; } } else if (!checksum.equals(other.checksum)) { return false; } if (dosAttributes == null) { if (other.dosAttributes != null) { return false; } } else if (!dosAttributes.equals(other.dosAttributes)) { return false; } if (lastModified == null) { if (other.lastModified != null) { return false; } } else if (!lastModified.equals(other.lastModified)) { return false; } if (linkTarget == null) { if (other.linkTarget != null) { return false; } } else if (!linkTarget.equals(other.linkTarget)) { return false; } if (path == null) { if (other.path != null) { return false; } } else if (!path.equals(other.path)) { return false; } if (posixPermissions == null) { if (other.posixPermissions != null) { return false; } } else if (!posixPermissions.equals(other.posixPermissions)) { return false; } if (size == null) { if (other.size != null) { return false; } } else if (!size.equals(other.size)) { return false; } if (status != other.status) { return false; } if (type != other.type) { return false; } if (updated == null) { if (other.updated != null) { return false; } } else if (!updated.equals(other.updated)) { return false; } if (version == null) { if (other.version != null) { return false; } } else if (!version.equals(other.version)) { return false; } return true; } public enum FileStatus { NEW("NEW"), CHANGED("CHANGED"), RENAMED("RENAMED"), DELETED("DELETED"); private String name; private FileStatus(String name) { this.name = name; } public boolean equalsName(String otherName) { return (otherName == null) ? false : name.equals(otherName); } @Override public String toString() { return name; } } /** * A {@link FileVersion} can be of either one of the types in this enum. * Types are treated differently during the index and synchronization process. */ public enum FileType { FILE("FILE"), FOLDER("FOLDER"), SYMLINK("SYMLINK"); private String name; private FileType(String name) { this.name = name; } public boolean equalsName(String otherName) { return (otherName == null) ? false : name.equals(otherName); } @Override public String toString() { return name; } } }