use of org.tigris.subversion.svnclientadapter.ISVNLogMessageChangePath in project subclipse by subclipse.
the class Cache method writeLogMessage.
private void writeLogMessage(ISVNLogMessage logMessage, int level, boolean writingTempFile) throws IOException {
RandomAccessFile revRaf = null;
RandomAccessFile logRaf = null;
if (writingTempFile) {
revRaf = revisionsTempRaf;
logRaf = logMessagesTempRaf;
} else {
revRaf = revisionsRaf;
logRaf = logMessagesRaf;
}
long revision = logMessage.getRevision().getNumber();
long fp = logRaf.getFilePointer();
// if (writingTempFile) System.out.println("writing rev "+revision+" at "+fp+"
// "+revisionsTempRaf.getFilePointer());
// else System.out.println("writing rev "+revision+" at "+fp+"
// "+revisionsRaf.getFilePointer());
revRaf.writeLong(fp);
logRaf.writeLong(revision);
logRaf.writeLong(logMessage.getDate().getTime());
logRaf.writeUTF(notNull(logMessage.getAuthor()));
String message = notNull(logMessage.getMessage());
if (message.length() > 64000) {
message = message.substring(0, 64397) + "...";
}
logRaf.writeUTF(message);
ISVNLogMessageChangePath[] changePaths = logMessage.getChangedPaths();
logRaf.writeInt(changePaths.length);
// common starting path in all changed paths
int cc = 0;
if (changePaths.length > 1) {
String a = changePaths[0].getPath();
String b = null;
for (int i = 1; i < changePaths.length; i++) {
b = changePaths[i].getPath();
cc = commonChars(a, b, cc);
a = b;
}
logRaf.writeUTF(a.substring(0, cc));
}
for (int i = 0; i < changePaths.length; i++) {
ISVNLogMessageChangePath changePath = changePaths[i];
logRaf.writeChar(changePath.getAction());
logRaf.writeUTF(changePath.getPath().substring(cc));
long copySrcRevision = 0;
if (changePath.getCopySrcRevision() != null && changePath.getCopySrcPath() != null) {
copySrcRevision = changePath.getCopySrcRevision().getNumber();
logRaf.writeLong(copySrcRevision);
logRaf.writeUTF(changePath.getCopySrcPath());
} else {
logRaf.writeLong(copySrcRevision);
}
}
if (level == 0 && (!logMessage.hasChildren())) {
logRaf.writeInt(0);
// System.out.println("A. Children: 0");
}
}
use of org.tigris.subversion.svnclientadapter.ISVNLogMessageChangePath in project subclipse by subclipse.
the class Cache method createGraph.
public Graph createGraph(String rootPath, long revision, WorkListener listener) {
// System.out.println("create graph");
Graph graph = new Graph(rootPath);
// root path is the first opened branch
graph.addBranch(rootPath);
long seek = getSeek(revision);
RandomAccessFile file = null;
try {
file = new RandomAccessFile(logMessagesFile, "r");
file.seek(seek);
while (file.getFilePointer() < file.length()) {
ISVNLogMessage lm = readNext(file, true);
ISVNLogMessageChangePath[] changedPaths = lm.getChangedPaths();
String[] pa = graph.getPathsAsArray();
Node node = null;
for (int n = 0; n < changedPaths.length; n++) {
ISVNLogMessageChangePath cp = changedPaths[n];
String nodePath = cp.getPath();
String copySrcPath = cp.getCopySrcPath();
for (int i = 0; i < pa.length; i++) {
String branchPath = pa[i];
if (copySrcPath == null) {
if ((cp.getAction() == 'A' && nodePath.equals(branchPath)) || (cp.getAction() == 'D' && isEqualsOrParent(nodePath, branchPath)) || (cp.getAction() == 'M' && nodePath.equals(branchPath))) {
Branch branch = graph.getBranch(branchPath);
if (branch.isEnded()) {
// the branch was ended with a D action
continue;
}
node = toNode(lm, cp);
node.setParent(branch.getLastNode());
branch.addNode(node);
if (node.getAction() == 'D') {
branch.end();
}
}
} else if (copySrcPath != null && isEqualsOrParent(copySrcPath, branchPath)) {
Branch branch = graph.getBranch(branchPath);
Node source = branch.getSource(cp.getCopySrcRevision().getNumber());
if (source == null)
continue;
node = toNode(lm, cp);
node.setSource(source);
String path = nodePath + branchPath.substring(copySrcPath.length());
Branch newBranch = graph.getBranch(path);
if (newBranch == null) {
newBranch = graph.addBranch(path);
}
newBranch.addNode(node);
}
}
}
if (node != null && lm.hasChildren()) {
ISVNLogMessage[] cm = lm.getChildMessages();
for (int i = 0; i < cm.length; i++) {
ISVNLogMessage child = cm[i];
ISVNLogMessageChangePath[] cp = child.getChangedPaths();
for (int j = 0; j < cp.length; j++) {
ISVNLogMessageChangePath changePath = cp[j];
for (int k = 0; k < pa.length; k++) {
String path = pa[k];
if (path.equals(changePath.getPath())) {
Branch branch = graph.getBranch(path);
Node source = branch.getSource(child.getRevision().getNumber());
if (source == null)
continue;
// add connection between "node" and "source"
node.addMergedRevision(source);
}
}
}
}
}
if (listener != null)
listener.worked();
}
} catch (IOException e) {
throw new CacheException("Error while calculating graph", e);
} finally {
closeFile(file);
}
// Tags
List paths = graph.getPaths();
Iterator iter = paths.iterator();
while (iter.hasNext()) {
String path = (String) iter.next();
Branch branch = graph.getBranch(path);
if (branch.getNodes().size() == 1) {
Node firstNode = (Node) branch.getNodes().iterator().next();
if (firstNode.getSource() != null && firstNode.getChildCount() == 0) {
// therefore is a tag
if (firstNode.getSource() != null) {
firstNode.getSource().addTag(firstNode);
}
}
}
}
return graph;
}
use of org.tigris.subversion.svnclientadapter.ISVNLogMessageChangePath in project subclipse by subclipse.
the class LogEntry method getLogEntryChangePaths.
/*
* (non-Javadoc)
* @see org.tigris.subversion.subclipse.core.history.ILogEntry#getLogEntryChangePaths()
*/
public LogEntryChangePath[] getLogEntryChangePaths() {
ISVNLogMessageChangePath[] changePaths = null;
if (SVNProviderPlugin.getPlugin().getSVNClientManager().isFetchChangePathOnDemand()) {
SVNUrl url = resource.getRepository().getRepositoryRoot();
if (url == null)
url = updateRootUrl(resource);
changePaths = getPathsOnDemand(url);
if (changePaths == null) {
// Root URL is probably bad. Run svn info to retrieve the root URL and
// update it in the repository.
SVNUrl url2 = updateRootUrl(resource);
if (!url.toString().equals(url2.toString()))
changePaths = getPathsOnDemand(url);
// one last try using the resource URL
if (changePaths == null)
changePaths = getPathsOnDemand(resource.getUrl());
// Still nothing, just return an empty array
if (changePaths == null)
changePaths = new ISVNLogMessageChangePath[0];
}
} else {
changePaths = logMessage.getChangedPaths();
}
LogEntryChangePath[] logEntryChangePaths = new LogEntryChangePath[changePaths.length];
for (int i = 0; i < changePaths.length; i++) {
logEntryChangePaths[i] = new LogEntryChangePath(this, changePaths[i]);
}
return logEntryChangePaths;
}
use of org.tigris.subversion.svnclientadapter.ISVNLogMessageChangePath in project subclipse by subclipse.
the class Cache method findRootNode.
/**
* This method finds the revision number and path where the file was first created.
*
* @param path The path of the selected file
* @param revision The revision number of the selected file
* @param listener A listener to implement a progress bar for example
* @return a Node object just containing the path and revision properties setted
*/
public Node findRootNode(String path, long revision, WorkListener listener) {
// r means "current revision"
long r = revision;
// pr means "previous revision"
long pr = r;
RandomAccessFile logMessages = null;
try {
/*
* We need to read the logMessagesFiles backwards, from the selected revision
* to the root revision.
* It is done by jumping backwards and reading a
* maximmun of MAX_LOG_MESSAGES number of messages inside an array
* that acts as a buffer.
*/
logMessages = new RandomAccessFile(logMessagesFile, "r");
ISVNLogMessage[] buffer = new ISVNLogMessage[MAX_LOG_MESSAGES];
do {
// We are going to jump to a previous revision.
// Exactly MAX_LOG_MESSAGES revisions before
r -= (MAX_LOG_MESSAGES) - 1;
if (r < 1) {
// Well, we cannot jump to a revision lower than 1
r = 1;
}
// It moves the file pointer to the revision. Here is where it jumps backwards
logMessages.seek(getSeek(r));
// It calculates how many log messages should be read
// this won't be higher than MAX_LOG_MESSAGES
int size = (int) (pr - r + 1);
if (size == 0)
break;
// It reads the log messages to the buffer
readNext(logMessages, buffer, size);
// It iterates over all log messages
for (int k = 0; k < size; k++) {
ISVNLogMessage lm = buffer[k];
// System.out.println("revision: "+lm.getRevision().getNumber());
// It iterates over all changed paths
ISVNLogMessageChangePath[] changedPaths = lm.getChangedPaths();
for (int n = 0; n < changedPaths.length; n++) {
ISVNLogMessageChangePath cp = changedPaths[n];
/*
* It is only interested on 'A' actions.
* If copySrcPath is not null it compares the paths to know
* if the changedPath is equals or parent to the current path.
* For example if it is finding the root node for /branches/a/foo.txt
* "A /branches/a from /trunk"
* In this case /branches/a is parent of /branches/a/foo.txt
* so now we know that /branches/a/foo.txt was copied from /trunk/foo.txt
* If copySrcPath is null and the changed path is equal to the path
* we are looking for then we have found the root node.
*/
if (lm.getRevision().getNumber() <= revision && cp.getAction() == 'A') {
if (cp.getCopySrcPath() != null) {
if (isEqualsOrParent(cp.getPath(), Util.unescape(path))) {
revision = lm.getRevision().getNumber();
path = cp.getCopySrcPath() + Util.unescape(path).substring(cp.getPath().length());
// TODO: here I could seek to 'revision'
// because all other revisions in between will be ignored
}
} else {
if (cp.getPath().equals(Util.unescape(path))) {
revision = lm.getRevision().getNumber();
Node node = new Node();
node.setPath(Util.unescape(path));
node.setRevision(revision);
return node;
}
}
}
}
if (listener != null)
listener.worked();
}
// previous revision is the current revision
pr = r;
} while (true);
} catch (IOException e) {
throw new CacheException("Error while finding root node", e);
} finally {
closeFile(logMessages);
}
Node n = new Node();
n.setPath(Util.unescape(path));
n.setRevision(revision);
return n;
}
use of org.tigris.subversion.svnclientadapter.ISVNLogMessageChangePath in project subclipse by subclipse.
the class GetLogsCommand method getUrls.
/**
* get the urls of the resource for each revision in logMessages It will always be the same url if
* the resource has never been moved
*
* @param logMessages
* @return an array of corresponding resource urls
*/
private SVNUrl[] getUrls(ISVNLogMessage[] logMessages) {
SVNUrl[] urls = new SVNUrl[logMessages.length];
SVNUrl rootRepositoryUrl = remoteResource.getRepository().getRepositoryRoot();
if (rootRepositoryUrl == null) {
// and so that the url was always the same
return fillUrlsWith(urls, remoteResource.getUrl());
}
// we identify the logMessage corresponding to the revision
// of the remote resource
int indexRemote = -1;
for (int i = 0; i < logMessages.length; i++) {
if (logMessages[i].getRevision().equals(remoteResource.getLastChangedRevision())) {
indexRemote = i;
break;
}
}
if (indexRemote > -1) {
urls[indexRemote] = remoteResource.getUrl();
}
// we get the url of more recent revisions
SVNUrl currentUrl = remoteResource.getUrl();
for (int i = indexRemote + 1; i < logMessages.length; i++) {
ISVNLogMessageChangePath[] changePaths = logMessages[i].getChangedPaths();
for (int j = 0; j < changePaths.length; j++) {
SVNUrl urlChangedPath = rootRepositoryUrl.appendPath(changePaths[j].getPath());
if (currentUrl.equals(urlChangedPath)) {
urls[i] = currentUrl;
break;
}
if (changePaths[j].getCopySrcPath() != null) {
SVNUrl urlCopyPath = rootRepositoryUrl.appendPath(changePaths[j].getCopySrcPath());
if (currentUrl.equals(urlCopyPath)) {
currentUrl = rootRepositoryUrl.appendPath(changePaths[j].getPath());
urls[i] = currentUrl;
break;
}
}
}
if (urls[i] == null) {
// something went wrong
return fillUrlsWith(urls, remoteResource.getUrl());
}
}
// we get the url of previous revisions
currentUrl = remoteResource.getUrl();
for (int i = indexRemote - 1; i >= 0; i--) {
ISVNLogMessageChangePath[] changePaths = logMessages[i].getChangedPaths();
for (int j = 0; j < changePaths.length; j++) {
SVNUrl urlChangedPath = rootRepositoryUrl.appendPath(changePaths[j].getPath());
if (currentUrl.equals(urlChangedPath)) {
urls[i] = currentUrl;
if (changePaths[j].getCopySrcPath() != null) {
SVNUrl urlCopyPath = rootRepositoryUrl.appendPath(changePaths[j].getCopySrcPath());
currentUrl = urlCopyPath;
}
break;
}
}
if (urls[i] == null) {
// something went wrong
return fillUrlsWith(urls, remoteResource.getUrl());
}
}
return urls;
}
Aggregations