package bluej.groupwork.svn;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javafx.application.Platform;
import org.tigris.subversion.javahl.ClientException;
import org.tigris.subversion.javahl.ConflictDescriptor;
import org.tigris.subversion.javahl.ConflictResult;
import org.tigris.subversion.javahl.Depth;
import org.tigris.subversion.javahl.NodeKind;
import org.tigris.subversion.javahl.Notify2;
import org.tigris.subversion.javahl.NotifyAction;
import org.tigris.subversion.javahl.NotifyInformation;
import org.tigris.subversion.javahl.NotifyStatus;
import org.tigris.subversion.javahl.PropertyData;
import org.tigris.subversion.javahl.Revision;
import org.tigris.subversion.javahl.SVNClientInterface;
import org.tigris.subversion.javahl.Status;
import org.tigris.subversion.javahl.StatusCallback;
import org.tigris.subversion.javahl.SubversionException;

import bluej.groupwork.TeamworkCommandAborted;
import bluej.groupwork.TeamworkCommandError;
import bluej.groupwork.TeamworkCommandResult;
import bluej.groupwork.UpdateListener;
import bluej.groupwork.UpdateResults;
import bluej.utility.Debug;
import threadchecker.OnThread;
import threadchecker.Tag;


| Subversion command to update to a particular revision. | | @author Davin McCall | public class SvnUpdateToCommand extends SvnCommand implements UpdateResults{ private long version; private Set<File> files; private Set<File> forceFiles; private UpdateListener listener; private List<File> conflicts = new ArrayList<File>(); private Set<File> binaryConflicts = new HashSet<File>(); public SvnUpdateToCommand(SvnRepository repository, UpdateListener listener, long version, Set<File> files, Set<File> forceFiles) { super(repository); this.version = version; this.files = files; this.forceFiles = forceFiles; this.listener = listener; } @OnThread(Tag.Worker) protected TeamworkCommandResult doCommand() { SVNClientInterface client = getClient(); final List<File> addedList = new ArrayList<File>(); final List<File> updatedList = new ArrayList<File>(); final List<File> removedList = new ArrayList<File>(); final List<File> removedDirs = new ArrayList<File>(); try { String [] paths = new String[forceFiles.size() + files.size()]; int j = 0; for (Iterator<File> i = forceFiles.iterator(); i.hasNext(); ) { File file = i.next(); paths[j++] = file.getAbsolutePath(); file.delete(); } for (Iterator<File> i = files.iterator(); i.hasNext(); ) { File file = i.next(); paths[j++] = file.getAbsolutePath(); } client.notification2(new Notify2() { public void onNotify(NotifyInformation ninfo) { if (ninfo.getKind() == NodeKind.file || ninfo.getKind() == NodeKind.none) { int action = ninfo.getAction(); if (ninfo.getPath() != null) { File file = new File(ninfo.getPath()); if (action == NotifyAction.update_add || action == NotifyAction.restore) { addedList.add(file); } else if (action == NotifyAction.update_update) { updatedList.add(file); if (ninfo.getContentState() == NotifyStatus.conflicted) { conflicts.add(file); } } else if (action == NotifyAction.update_delete) { removedList.add(file); } else if (action == NotifyAction.tree_conflict) { binaryConflicts.add(file); } } } else if (ninfo.getKind() == NodeKind.dir) { int action = ninfo.getAction(); if (action == NotifyAction.update_delete) { removedDirs.add(new File(ninfo.getPath())); } } } }); client.update(paths, Revision.getInstance(version), Depth.immediates, false, false, false); } catch (ClientException ce) { if (isCancelled()) { return new TeamworkCommandAborted(); } else { return new TeamworkCommandError(ce.getMessage(), ce.getLocalizedMessage()); } } finally { client.notification2(null); Platform.runLater(() -> { Iterator<File> i; for (i = addedList.iterator(); i.hasNext(); ) { listener.fileModified(i.next()); } for (i = updatedList.iterator(); i.hasNext(); ) { listener.fileModified(i.next()); } for (i = removedList.iterator(); i.hasNext(); ) { listener.fileRemoved(i.next()); } for (i = removedDirs.iterator(); i.hasNext(); ) { listener.dirRemoved(i.next()); } }); if (! conflicts.isEmpty()) { Iterator<File> i; for (i = conflicts.iterator(); i.hasNext(); ) { File file = (File) i.next(); try { PropertyData pdata = client.propertyGet( file.getAbsolutePath(), "svn:mime-type", Revision.getInstance(version)); if (pdata != null && "application/octet-stream".equals(pdata.getValue())) { i.remove(); binaryConflicts.add(file); } else { client.resolve(file.getAbsolutePath(), 0, ConflictResult.chooseMerged); } } catch (SubversionException se) { Debug.message("Subversion client exception when resolving conflicts: " + se.getLocalizedMessage()); Debug.message(" (on file: " + file + ")"); } } } if (! conflicts.isEmpty() || ! binaryConflicts.isEmpty()) { Platform.runLater(() -> listener.handleConflicts(this)); } } return new TeamworkCommandResult(); } @Override public boolean mergeCommitNeeded() { return false; } @Override public Set getBinaryConflicts() { return binaryConflicts; } @Override public List getConflicts() { return conflicts; } @Override public void overrideFiles(final Set<File> files) { final SVNClientInterface client = getRepository().getClient(); StatusCallback scb = new StatusCallback() { public void doStatus(Status status) { File file = new File(status.getPath()); try { ConflictDescriptor cd = status.getConflictDescriptor(); if (cd != null) { int action = cd.getAction(); int kind = cd.getKind(); int reason = cd.getReason(); if (kind != ConflictDescriptor.Kind.text) { return; } if (action == ConflictDescriptor.Action.delete && reason == ConflictDescriptor.Reason.edited) { client.resolve(file.getAbsolutePath(), 0, ConflictResult.chooseMerged); boolean keepLocal = ! files.contains(file); String [] paths = new String[] { file.getPath() }; client.remove(paths, "", true, keepLocal, Collections.emptyMap()); if (!keepLocal) { Platform.runLater(() -> listener.fileRemoved(file)); } return; } else if (action == ConflictDescriptor.Action.edit && reason == ConflictDescriptor.Reason.deleted) { client.resolve(file.getAbsolutePath(), 0, ConflictResult.chooseTheirsFull); } } String conflictOld = status.getConflictOld(); if (conflictOld != null) { File oldRev = new File(file.getParent(), status.getConflictOld()); oldRev.delete(); } if (files.contains(file)) { client.resolve(file.getAbsolutePath(), 0, ConflictResult.chooseTheirsFull); } else { client.resolve(file.getAbsolutePath(), 0, ConflictResult.chooseMineFull); } } catch (SubversionException sve) { Debug.message("Subversion library exception trying to resolve binary conflict: " + sve.getLocalizedMessage()); Debug.message(" (on file: " + file + ")"); } } }; for (Iterator<File> i = binaryConflicts.iterator(); i.hasNext(); ) { File file = i.next(); try { client.status(file.getAbsolutePath(), Depth.empty, false, true, true, true, new String[0], scb); } catch (ClientException ce) { Debug.message("Subversion library exception trying to resolve binary conflict: " + ce.getLocalizedMessage()); Debug.message(" (on file: " + file + ")"); } } } }
top, use, map, class SvnUpdateToCommand

.   SvnUpdateToCommand
.   doCommand
.   onNotify
.   mergeCommitNeeded
.   getBinaryConflicts
.   getConflicts
.   overrideFiles
.   doStatus




391 neLoCode + 2 LoComm