File metaFile = new File(metaFilePath);
if (file.exists()) {
isUpdating = true;
if (isCollection != file.isDirectory()) {
throw new SynchronizationException(
MessageCode.COLLECTION_AND_RESOURCE_SAME_NAME,
new String[]{"file name: " + filePath});
}
if (metaFile.exists()) {
// we need to check the last updated times of the current resource
// and the updating resource
// get the meta file OMElement
OMElement metaFileElement = Utils.getOMElementFromMetaFile(metaFilePath);
OMElement metaFileVersionElement =
metaFileElement.getFirstChildWithName(new QName("version"));
if (metaFileVersionElement == null) {
throw new SynchronizationException(MessageCode.UNSUPPORTED_DUMP_FORMAT,
new String[]{"missing element: version",
"meta file path: " + metaFilePath});
}
OMElement updatingVersionElement = root.getFirstChildWithName(new QName("version"));
if (updatingVersionElement == null) {
throw new SynchronizationException(MessageCode.CHECKOUT_OLD_VERSION,
new String[]{"missing element: version", "path: " + path});
}
String metaFileVersionStr = metaFileVersionElement.getText();
String updatingVersionStr = updatingVersionElement.getText();
if (isCollection) {
if (metaFileVersionStr.equals(updatingVersionStr)) {
// so there is no server updates for the collection
Utils.createMetaFile(metaFilePath, root);
collectionIsNotUpdated = true;
}
} else {
// here we not just check server side updates, but also check local changes using md5s
byte[] currentFileContent = Utils.getBytesFromFile(file);
String metaFileMD5 = metaFileElement.getAttributeValue(new QName("md5"));
String currentMD5 = Utils.getMD5(currentFileContent);
if (metaFileMD5 != null && metaFileMD5.equals(currentMD5)) {
// there is no modifications happens to the current file locally,
if (metaFileVersionStr.equals(updatingVersionStr)) {
// the file in the server is not updated, so just keep the current file locally.
// so we are only storing the meta information in the meta file.
Utils.createMetaFile(metaFilePath, root);
return;
} else {
// there is a server update to the file, so lets allow it to update the local one
// local one is not updated, so it will be overwritten by the server one
}
} else if (metaFileVersionStr.equals(updatingVersionStr)) {
// there is no server side changes, but there are client side changes,
// just don't update the content, but let the meta file get updated.
Utils.createMetaFile(metaFilePath, root);
return;
} else {
// this is the following scenario
// (!metaFileMD5.equals(currentMD5) &&
// !metaFileVersionStr.equals(updatingVersionStr))
if (updatingMD5 != null && !updatingMD5.equals(currentMD5)) {
isConflicting = true;
root.addAttribute("md5", "", null);
}
}
}
} else if (!isCollection) {
// if there is no meta file exists, that mean there is a conflict
// a new resource is created both locally and in server
isConflicting = true;
}
if (isConflicting && !isSilentUpdate) {
// should rename the current file as file.mine
String mineFileName = filePath + SynchronizationConstants.MINE_FILE_POSTFIX;
File mineFile = new File(mineFileName);
Utils.copy(file, mineFile);
// updating the current file as versionedFileName
String versionedFileName = filePath + SynchronizationConstants.SERVER_FILE_POSTFIX;
file = new File(versionedFileName);
// set the conflicting flag
root.addAttribute("conflicting", "true", null);
}
} else if (isSilentUpdate) {
// if no files exists locally, the silent update will return
return;
} else if (metaFile.exists()) {
// now the meta file is there but the direct file is deleted, so we will
// ask whether he want to get the up. Default behaviour is not to take the update from
// the server. This is because the working copy is up-to-date.
if (callback == null || callback.getConfirmation(new Message(
MessageCode.KEEP_DELETED_FILE,
new String[]{filePath}),
SynchronizationConstants.DELETE_CONFIRMATION_CONTEXT)) {
return;
}
}
if (!isUpdating) {
try {
// Create file if it does not exist
if (isCollection) {
boolean ignore = file.mkdir(); // ignores the return value purposely
} else {
boolean ignore = file.createNewFile(); // ignores the return value purposely
}
} catch (IOException e) {
throw new SynchronizationException(MessageCode.FILE_CREATION_FAILED, e,
new String[]{"file name: " + filePath});
}
}
if (!isCollection) {
try {
boolean writeToFile = true;
if (file.exists()) {
byte[] currentContentBytes = Utils.getBytesFromFile(file);
if (currentContentBytes != null && contentBytes != null) {
String currentContentMd5 = Utils.getMD5(currentContentBytes);
String writingContentMd5 = Utils.getMD5(contentBytes);
if (writingContentMd5 != null &&
writingContentMd5.equals(currentContentMd5)) {
writeToFile = false;
}
}
}
if (writeToFile) {
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(contentBytes);
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (IOException e) {
throw new SynchronizationException(MessageCode.PROBLEM_IN_CREATING_CONTENT,
e,
new String[]{"file name: " + filePath});
}
} else {
// creating the meta directory
String metaDirectoryName =
filePath + File.separator + SynchronizationConstants.META_DIRECTORY;
File metaDirectory = new File(metaDirectoryName);
if (!metaDirectory.exists() && !metaDirectory.mkdir()) {
throw new SynchronizationException(MessageCode.ERROR_CREATING_META_FILE,
new String[]{"file: " + metaDirectoryName});
}
}
boolean iterateChildren = true;