/*
* 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.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.syncany.database.ChunkEntry.ChunkChecksum;
/**
* A file content represents the content of a file. It contains a list of
* references to {@link ChunkEntry}s, and identifies a content by its checksum.
*
* <p>A file content is implicitly referenced by one or many {@link FileVersion}s
* through the checksum attribute. A file content always contains the full list of
* chunks it resembles. There are no deltas!
*
* <p>Unlike the chunk list in a {@link MultiChunkEntry}, the order of the chunks
* is very important, because a file can only be reconstructed if the order of
* its chunks are followed.
*
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class FileContent {
private FileChecksum checksum;
private long size;
private List<ChunkChecksum> chunkChecksums;
public FileContent() {
this.chunkChecksums = new ArrayList<ChunkChecksum>();
}
public void addChunk(ChunkChecksum chunk) {
chunkChecksums.add(chunk);
}
public FileChecksum getChecksum() {
return checksum;
}
public void setChecksum(FileChecksum checksum) {
this.checksum = checksum;
}
public long getSize() {
return size;
}
public void setSize(long contentSize) {
size = contentSize;
}
public List<ChunkChecksum> getChunks() {
return Collections.unmodifiableList(chunkChecksums);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((checksum == null) ? 0 : checksum.hashCode());
result = prime * result + ((chunkChecksums == null) ? 0 : chunkChecksums.hashCode());
result = prime * result + (int) (size ^ (size >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof FileContent)) {
return false;
}
FileContent other = (FileContent) obj;
if (checksum == null) {
if (other.checksum != null) {
return false;
}
}
else if (!checksum.equals(other.checksum)) {
return false;
}
if (chunkChecksums == null) {
if (other.chunkChecksums != null) {
return false;
}
}
else if (!chunkChecksums.equals(other.chunkChecksums)) {
return false;
}
if (size != other.size) {
return false;
}
return true;
}
@Override
public String toString() {
return "FileContent [checksum=" + checksum + ", contentSize=" + size + ", chunks=" + chunkChecksums + "]";
}
public static class FileChecksum extends ObjectId {
public FileChecksum(byte[] array) {
super(array);
}
public static FileChecksum parseFileChecksum(String s) {
return new FileChecksum(ObjectId.parseObjectId(s));
}
public static boolean fileChecksumEquals(FileChecksum checksum1, FileChecksum checksum2) {
if (checksum1 != null && checksum2 != null) {
return checksum1.equals(checksum2);
}
else {
return checksum1 == null && checksum2 == null;
}
}
}
}