entryAttrs.put(SVNProperty.WORKING_SIZE, "0");
} else {
try {
entryAttrs.put(SVNProperty.WORKING_SIZE, Long.toString(file.length()));
} catch (SecurityException se) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Error getting file size on ''{0}''", file);
SVNErrorManager.error(err, se, SVNLogType.WC);
}
}
}
}
boolean force = false;
if (attributes.containsName(SVNLog.FORCE_ATTR)) {
String forceAttr = attributes.getStringValue(SVNLog.FORCE_ATTR);
force = SVNProperty.booleanValue(forceAttr);
}
try {
adminArea.modifyEntry(fileName, entryAttrs, false, force);
} catch (SVNException svne) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Error modifying entry for ''{0}''", fileName);
SVNErrorManager.error(err, svne, SVNLogType.WC);
}
setEntriesChanged(true);
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.MODIFY_WC_PROPERTY.equals(name)) {
try {
SVNVersionedProperties wcprops = adminArea.getWCProperties(fileName);
if (wcprops != null) {
String propName = attributes.getStringValue(SVNLog.PROPERTY_NAME_ATTR);
SVNPropertyValue propValue = attributes.getSVNPropertyValue(SVNLog.PROPERTY_VALUE_ATTR);
wcprops.setPropertyValue(propName, propValue);
setWCPropertiesChanged(true);
}
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.DELETE_LOCK.equals(name)) {
try {
SVNEntry entry = adminArea.getEntry(fileName, true);
if (entry != null) {
entry.setLockToken(null);
entry.setLockOwner(null);
entry.setLockCreationDate(null);
entry.setLockComment(null);
setEntriesChanged(true);
}
} catch (SVNException svne) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Error removing lock from entry for ''{0}''", fileName);
error = new SVNException(err, svne);
}
} else if (SVNLog.DELETE_CHANGELIST.equals(name)) {
try {
Map entryAttrs = new SVNHashMap();
entryAttrs.put(SVNProperty.CHANGELIST, null);
adminArea.modifyEntry(fileName, entryAttrs, false, false);
setEntriesChanged(true);
} catch (SVNException svne) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code,
"Error removing changelist from entry ''{0}''", fileName);
error = new SVNException(err, svne);
}
} else if (SVNLog.DELETE.equals(name)) {
File file = adminArea.getFile(fileName);
SVNFileUtil.deleteFile(file);
} else if (SVNLog.READONLY.equals(name)) {
File file = adminArea.getFile(fileName);
SVNFileUtil.setReadonly(file, true);
} else if (SVNLog.MOVE.equals(name)) {
File src = adminArea.getFile(fileName);
File dst = adminArea.getFile(attributes.getStringValue(SVNLog.DEST_ATTR));
try {
SVNFileUtil.rename(src, dst);
} catch (SVNException svne) {
error = new SVNException(svne.getErrorMessage().wrap("Can't move source to dest"), svne);
}
} else if (SVNLog.APPEND.equals(name)) {
File src = adminArea.getFile(fileName);
File dst = adminArea.getFile(attributes.getStringValue(SVNLog.DEST_ATTR));
OutputStream os = null;
InputStream is = null;
try {
os = SVNFileUtil.openFileForWriting(dst, true);
is = SVNFileUtil.openFileForReading(src, SVNLogType.WC);
while (true) {
int r = is.read();
if (r < 0) {
break;
}
os.write(r);
}
} catch (IOException e) {
if (src.exists()) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, "Cannot write to ''{0}'': {1}", new Object[] {dst, e.getLocalizedMessage()});
error = new SVNException(err, e);
}
} catch (SVNException svne) {
if (src.exists()) {
error = svne;
}
} finally {
SVNFileUtil.closeFile(os);
SVNFileUtil.closeFile(is);
}
} else if (SVNLog.SET_TIMESTAMP.equals(name)) {
File file = adminArea.getFile(fileName);
String timestamp = attributes.getStringValue(SVNLog.TIMESTAMP_ATTR);
try {
if (timestamp == null) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Missing 'timestamp' attribute in ''{0}''", adminArea.getRoot());
SVNErrorManager.error(err, SVNLogType.WC);
}
Date time = SVNDate.parseDate(timestamp);
//TODO: what about special files (do not set for them).
if (!file.setLastModified(time.getTime())) {
if (!file.canWrite() && file.isFile()) {
SVNFileUtil.setReadonly(file, false);
file.setLastModified(time.getTime());
SVNFileUtil.setReadonly(file, true);
}
}
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.UPGRADE_FORMAT.equals(name)) {
String format = attributes.getStringValue(SVNLog.FORMAT_ATTR);
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
try {
if (format == null) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Invalid 'format' attribute");
SVNErrorManager.error(err, SVNLogType.WC);
}
int number = -1;
try {
number = Integer.parseInt(format);
} catch (NumberFormatException e) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Invalid 'format' attribute");
SVNErrorManager.error(err, e, SVNLogType.WC);
}
if (number == 0) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Invalid 'format' attribute");
SVNErrorManager.error(err, SVNLogType.WC);
}
adminArea.postUpgradeFormat(number);
setEntriesChanged(true);
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.MAYBE_READONLY.equals(name)) {
File file = adminArea.getFile(fileName);
try {
SVNEntry entry = adminArea.getEntry(fileName, false);
if (entry != null) {
adminArea.closeVersionedProperties();
SVNVersionedProperties props = adminArea.getProperties(fileName);
String needsLock = props.getStringPropertyValue(SVNProperty.NEEDS_LOCK);
if (entry.getLockToken() == null && needsLock != null) {
SVNFileUtil.setReadonly(file, true);
}
}
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.MAYBE_EXECUTABLE.equals(name)) {
adminArea.closeVersionedProperties();
SVNVersionedProperties props = adminArea.getProperties(fileName);
boolean executable = SVNFileUtil.isWindows ? false : props.getPropertyValue(SVNProperty.EXECUTABLE) != null;
if (executable) {
SVNFileUtil.setExecutable(adminArea.getFile(fileName), true);
}
} else if (SVNLog.COPY_AND_TRANSLATE.equals(name)) {
String dstName = attributes.getStringValue(SVNLog.DEST_ATTR);
String versionedName = attributes.getStringValue(SVNLog.ATTR2);
if (versionedName == null) {
versionedName = dstName;
}
File src = adminArea.getFile(fileName);
File dst = adminArea.getFile(dstName);
//when performing a merge from a log runner we may have just set
//new properties (log command that copies a new base prop file),
//but probably we've got a non empty props cache which is no more
//valid, so clean it up.
adminArea.closeVersionedProperties();
try {
try {
SVNTranslator.translate(adminArea, versionedName, src, dst, null, true);
} catch (SVNException svne) {
if (src.exists()) {
throw svne;
}
}
// get properties for this entry.
SVNVersionedProperties props = adminArea.getProperties(dstName);
boolean executable = SVNFileUtil.isWindows ? false : props.getPropertyValue(SVNProperty.EXECUTABLE) != null;
if (executable) {
SVNFileUtil.setExecutable(dst, true);
}
SVNEntry entry = adminArea.getEntry(dstName, false);
if (entry != null && entry.getLockToken() == null && props.getPropertyValue(SVNProperty.NEEDS_LOCK) != null) {
SVNFileUtil.setReadonly(dst, true);
}
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.COPY_AND_DETRANSLATE.equals(name)) {
String dstName = attributes.getStringValue(SVNLog.DEST_ATTR);
String versionedName = attributes.getStringValue(SVNLog.ATTR2);
adminArea.closeVersionedProperties();
try {
SVNTranslator.translate(adminArea, versionedName != null ? versionedName : fileName, fileName, dstName, false);
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.COPY.equals(name)) {
File src = adminArea.getFile(fileName);
File dst = adminArea.getFile(attributes.getStringValue(SVNLog.DEST_ATTR));
try {
SVNFileUtil.copy(src, dst, true, false);
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.ADD_TREE_CONFLICT.equals(name)) {
File dirPath = adminArea.getRoot();
String conflictData = attributes.getStringValue(SVNLog.DATA_ATTR);
Map newConflicts = SVNTreeConflictUtil.readTreeConflicts(dirPath, conflictData);
Object[] conflictArray = newConflicts.values().toArray();
SVNTreeConflictDescription newConflict = (SVNTreeConflictDescription) conflictArray[0];
if (!getTreeConflicts().containsKey(newConflict.getPath())) {
getTreeConflicts().put(newConflict.getPath(), newConflict);
setTreeConflictsAdded(true);
}
} else if (SVNLog.MERGE.equals(name)) {
File target = adminArea.getFile(fileName);
try {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
String leftPath = attributes.getStringValue(SVNLog.ATTR1);
if (leftPath == null) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Missing 'left' attribute in ''{0}''", adminArea.getRoot());
SVNErrorManager.error(err, SVNLogType.WC);
}
String rightPath = attributes.getStringValue(SVNLog.ATTR2);
if (rightPath == null) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Missing 'right' attribute in ''{0}''", adminArea.getRoot());
SVNErrorManager.error(err, SVNLogType.WC);
}
String leftLabel = attributes.getStringValue(SVNLog.ATTR3);
leftLabel = leftLabel == null ? ".old" : leftLabel;
String rightLabel = attributes.getStringValue(SVNLog.ATTR4);
rightLabel = rightLabel == null ? ".new" : rightLabel;
String targetLabel = attributes.getStringValue(SVNLog.ATTR5);
targetLabel = targetLabel == null ? ".working" : targetLabel;
//when performing a merge from a log runner we may have just set
//new properties (log command that copies a new base prop file),
//but probably we've got a non empty props cache which is no more
//valid, so clean it up.
adminArea.closeVersionedProperties();
SVNVersionedProperties props = adminArea.getProperties(fileName);
SVNEntry entry = adminArea.getEntry(fileName, true);
SVNStatusType mergeResult = adminArea.mergeText(fileName, adminArea.getFile(leftPath),
adminArea.getFile(rightPath), null, targetLabel, leftLabel, rightLabel, null, false,
null, null);
if (props.getPropertyValue(SVNProperty.EXECUTABLE) != null) {
SVNFileUtil.setExecutable(target, true);
}
if (props.getPropertyValue(SVNProperty.NEEDS_LOCK) != null
&& entry.getLockToken() == null) {
SVNFileUtil.setReadonly(target, true);
}
setEntriesChanged(mergeResult == SVNStatusType.CONFLICTED ||
mergeResult == SVNStatusType.CONFLICTED_UNRESOLVED);
} catch (SVNException svne) {
error = svne;
}
} else if (SVNLog.COMMIT.equals(name)) {
try {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
if (attributes.getStringValue(SVNLog.REVISION_ATTR) == null) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Missing revision attribute for ''{0}''", fileName);
SVNErrorManager.error(err, SVNLogType.WC);
}
SVNEntry entry = adminArea.getEntry(fileName, true);
if (entry == null || (!adminArea.getThisDirName().equals(fileName) && entry.getKind() != SVNNodeKind.FILE)) {
SVNErrorMessage err = SVNErrorMessage.create(code, "Log command for directory ''{0}'' is mislocated", adminArea.getRoot());
SVNErrorManager.error(err, SVNLogType.WC);
}
boolean implicit = attributes.getStringValue("implicit") != null && entry.isCopied();
setEntriesChanged(true);
long revisionNumber = -1;
try {
revisionNumber = Long.parseLong(attributes.getStringValue(SVNLog.REVISION_ATTR));
} catch (NumberFormatException nfe) {
SVNErrorManager.error(SVNErrorMessage.create(SVNErrorCode.WC_BAD_ADM_LOG, nfe), SVNLogType.WC);
}
adminArea.postCommit(fileName, revisionNumber, implicit, code);
} catch (SVNException svne) {
error = svne;
}
} else {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Unrecognized logfile element ''{0}'' in ''{1}''", new Object[]{name, adminArea.getRoot()});
SVNErrorManager.error(err.wrap("In directory ''{0}''", adminArea.getRoot()), SVNLogType.WC);
}
myLogCount = count;
if (error != null) {
SVNErrorCode code = count <= 1 ? SVNErrorCode.WC_BAD_ADM_LOG_START : SVNErrorCode.WC_BAD_ADM_LOG;
SVNErrorMessage err = SVNErrorMessage.create(code, "Error processing command ''{0}'' in ''{1}''", new Object[]{name, adminArea.getRoot()});
SVNErrorManager.error(err, error, SVNLogType.WC);
}
}