* @throws SVNException
* @since 1.1.1
*/
public void doLoad(File repositoryRoot, InputStream dumpStream, boolean usePreCommitHook, boolean usePostCommitHook, SVNUUIDAction uuidAction, String parentDir) throws SVNException {
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
ISVNLoadHandler handler = getLoadHandler(repositoryRoot, usePreCommitHook, usePostCommitHook, uuidAction, parentDir, decoder);
String line = null;
int version = -1;
StringBuffer buffer = new StringBuffer();
try {
line = SVNFileUtil.readLineFromStream(dumpStream, buffer, decoder);
if (line == null) {
SVNAdminHelper.generateIncompleteDataError();
}
//parse format
if (!line.startsWith(SVNAdminHelper.DUMPFILE_MAGIC_HEADER + ":")) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header");
SVNErrorManager.error(err);
}
try {
line = line.substring(SVNAdminHelper.DUMPFILE_MAGIC_HEADER.length() + 1);
line = line.trim();
version = Integer.parseInt(line);
if (version > SVNAdminHelper.DUMPFILE_FORMAT_VERSION) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Unsupported dumpfile version: {0,number,integer}", new Integer(version));
SVNErrorManager.error(err);
}
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header");
SVNErrorManager.error(err, nfe);
}
while (true) {
checkCancelled();
boolean foundNode = false;
//skip empty lines
buffer.setLength(0);
line = SVNFileUtil.readLineFromStream(dumpStream, buffer, decoder);
if (line == null) {
if (buffer.length() > 0) {
SVNAdminHelper.generateIncompleteDataError();
} else {
break;
}
}
if (line.length() == 0 || Character.isWhitespace(line.charAt(0))) {
continue;
}
Map headers = readHeaderBlock(dumpStream, line, decoder);
if (headers.containsKey(SVNAdminHelper.DUMPFILE_REVISION_NUMBER)) {
handler.closeRevision();
handler.openRevision(headers);
} else if (headers.containsKey(SVNAdminHelper.DUMPFILE_NODE_PATH)) {
handler.openNode(headers);
foundNode = true;
} else if (headers.containsKey(SVNAdminHelper.DUMPFILE_UUID)) {
String uuid = (String) headers.get(SVNAdminHelper.DUMPFILE_UUID);
handler.parseUUID(uuid);
} else if (headers.containsKey(SVNAdminHelper.DUMPFILE_MAGIC_HEADER)) {
try {
version = Integer.parseInt((String) headers.get(SVNAdminHelper.DUMPFILE_MAGIC_HEADER));
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header");
SVNErrorManager.error(err, nfe);
}
} else {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Unrecognized record type in stream");
SVNErrorManager.error(err);
}
String contentLength = (String) headers.get(SVNAdminHelper.DUMPFILE_CONTENT_LENGTH);
String propContentLength = (String) headers.get(SVNAdminHelper.DUMPFILE_PROP_CONTENT_LENGTH);
String textContentLength = (String) headers.get(SVNAdminHelper.DUMPFILE_TEXT_CONTENT_LENGTH);
boolean isOldVersion = version == 1 && contentLength != null && propContentLength == null && textContentLength == null;
int actualPropLength = 0;
if (propContentLength != null || isOldVersion) {
String delta = (String) headers.get(SVNAdminHelper.DUMPFILE_PROP_DELTA);
boolean isDelta = delta != null && "true".equals(delta);
if (foundNode && !isDelta) {
handler.removeNodeProperties();
}
int length = 0;
try {
length = Integer.parseInt(propContentLength != null ? propContentLength : contentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse property block length header");
SVNErrorManager.error(err, nfe);
}
actualPropLength += handler.parsePropertyBlock(dumpStream, length, foundNode);
}
if (textContentLength != null) {
String delta = (String) headers.get(SVNAdminHelper.DUMPFILE_TEXT_DELTA);
boolean isDelta = delta != null && "true".equals(delta);
int length = 0;
try {
length = Integer.parseInt(textContentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse text block length header");
SVNErrorManager.error(err, nfe);
}
handler.parseTextBlock(dumpStream, length, isDelta);
} else if (isOldVersion) {
int length = 0;
try {
length = Integer.parseInt(contentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse content length header");
SVNErrorManager.error(err, nfe);
}
length -= actualPropLength;
if (length > 0 || SVNNodeKind.parseKind((String)headers.get(SVNAdminHelper.DUMPFILE_NODE_KIND)) == SVNNodeKind.FILE) {
handler.parseTextBlock(dumpStream, length, false);
}
}
if (contentLength != null && !isOldVersion) {
int remaining = 0;
try {
remaining = Integer.parseInt(contentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse content length header");
SVNErrorManager.error(err, nfe);
}
int propertyContentLength = 0;
if (propContentLength != null) {
try {
propertyContentLength = Integer.parseInt(propContentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse property block length header");
SVNErrorManager.error(err, nfe);
}
}
remaining -= propertyContentLength;
int txtContentLength = 0;
if (textContentLength != null) {
try {
txtContentLength = Integer.parseInt(textContentLength);
} catch (NumberFormatException nfe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Malformed dumpfile header: can't parse text block length header");
SVNErrorManager.error(err, nfe);
}
}
remaining -= txtContentLength;
if (remaining < 0) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.STREAM_MALFORMED_DATA, "Sum of subblock sizes larger than total block content length");
SVNErrorManager.error(err);
}
byte buf[] = new byte[SVNAdminHelper.STREAM_CHUNK_SIZE];
while (remaining > 0) {
int numToRead = remaining >= SVNAdminHelper.STREAM_CHUNK_SIZE ? SVNAdminHelper.STREAM_CHUNK_SIZE : remaining;
int numRead = dumpStream.read(buf, 0, numToRead);
remaining -= numRead;
if (numRead != numToRead) {
SVNAdminHelper.generateIncompleteDataError();
}
}
}
if (foundNode) {
handler.closeNode();
foundNode = false;
}
}
handler.closeRevision();
} catch (IOException ioe) {
SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
SVNErrorManager.error(err, ioe);
}