Skip to main content
summaryrefslogtreecommitdiffstats
blob: 7dd8544b611e86caddde7473114ab54260d14df4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package org.eclipse.team.internal.ccvs.core.client;

/*
 * (c) Copyright IBM Corp. 2000, 2002.
 * All Rights Reserved.
 */

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFile;
import org.eclipse.team.internal.ccvs.core.resources.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.resources.ICVSResourceVisitor;
import org.eclipse.team.internal.ccvs.core.syncinfo.*;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.Assert;

/**
 * An ICVSResourceVisitor that is superclass to all ICVSResourceVisitor's used
 * by Command and it's subclasses.
 * Provides helper methods to send files and folders with modifications
 * to the server.
 */
abstract class AbstractStructureVisitor implements ICVSResourceVisitor {
	protected Session session;
	
	// The last folder that has already been sent to the server during this visit
	private ICVSFolder lastFolderSend;

	// Subclasses can use to show visitor progress
	protected IProgressMonitor monitor;

	public AbstractStructureVisitor(Session session, IProgressMonitor monitor) {
		this.session = session;
		this.monitor = monitor;
	}

	protected boolean isOrphanedSubtree(ICVSFolder mFolder) {
		return mFolder.isCVSFolder() && ! mFolder.isManaged() && ! mFolder.equals(session.getLocalRoot()) && mFolder.getParent().isCVSFolder();
	}
	
	/**
	 * Send the folder relative to the root to the server. Send all 
	 * appropiate modifier like Sticki, Questionable, Static-directory.
	 * <br>
	 * If this folder was send last, it is not resend again (there is 
	 * no advantage of doing so).
	 */
	protected void sendFolder(ICVSFolder mFolder, boolean constructFolder, boolean sendQuestionable) throws CVSException {

		String local;
		String remote;
		CVSEntryLineTag tag;

		// Do not send the same folder twice
		if (mFolder.equals(lastFolderSend)) {
			return;
		}

		local = mFolder.getRelativePath(session.getLocalRoot());

		if (constructFolder && mFolder.exists()) {
			session.sendConstructedDirectory(local);
			lastFolderSend = mFolder;
			return;
		}
		
		boolean isQuestionable = !mFolder.isCVSFolder() || isOrphanedSubtree(mFolder);

		// XXX The logic of when to send what looks wrong!
		if (sendQuestionable && isQuestionable) {
			// This implies, that the mFolder exists. If we have not send the parent-folder of this 
			// folder we have to send the parent-folder to have this questionable below this parent-folder.
			Assert.isTrue(mFolder.getParent().isCVSFolder());
			sendFolder(mFolder.getParent(), constructFolder, sendQuestionable);
			session.sendQuestionable(mFolder);
			return;
		}

		remote = mFolder.getRemoteLocation(session.getLocalRoot());

		if (remote == null) {
			return;
		}

		session.sendDirectory(local, remote);

		FolderSyncInfo info = mFolder.getFolderSyncInfo();
		if (info != null) {

			if (info.getIsStatic()) {
				session.sendStaticDirectory();
			}

			tag = info.getTag();

			if (tag != null && tag.getType() != tag.HEAD) {
				session.sendSticky(tag.toEntryLineFormat(false));
			}
		}

		// Remember, that we send this folder
		lastFolderSend = mFolder;
	}

	/*
	 * Send the information about the file to the server.
	 * 
	 * If the file is modified, its contents are sent as well.
	 */
	protected void sendFile(ICVSFile mFile, boolean sendQuestionable, String mode) throws CVSException {

		// Send the file's entry line to the server
		if (mFile.isManaged()) {
			session.sendEntry(mFile.getSyncInfo().getEntryLine(false, mFile.getTimeStamp()));
		} else {
			// If the file is not managed, send a questionable to the server if the file exists locally
			// A unmanaged, locally non-existant file results from the explicit use of the file name as a command argument
			if (sendQuestionable) {
				if (mFile.exists()) {
					session.sendQuestionable(mFile);
				}
				return;
			}
		}
		
		// If the file exists, send the appropriate indication to the server
		if (mFile.exists()) {
			if (mFile.isModified()) {
				boolean binary = mode != null && mode.indexOf(ResourceSyncInfo.BINARY_TAG) != -1;
				session.sendModified(mFile, binary, monitor);
			} else {
				session.sendUnchanged(mFile);
			}
		}
	}
}

Back to the top