KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > core > mapping > IMergeContext


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.core.mapping;
12
13 import org.eclipse.core.resources.*;
14 import org.eclipse.core.runtime.*;
15 import org.eclipse.core.runtime.jobs.IJobManager;
16 import org.eclipse.core.runtime.jobs.ISchedulingRule;
17 import org.eclipse.team.core.diff.*;
18 import org.eclipse.team.core.mapping.provider.MergeContext;
19
20 /**
21  * Provides the context for an <code>IResourceMappingMerger</code> or a model
22  * specific synchronization view that supports merging.
23  * * <p>
24  * <a name="async">The diff tree associated with this context may be updated asynchronously in response
25  * to calls to any method of this context (e.g. merge and markAsMerged methods) that may result in changes
26  * in the synchronization state of resources. It may also get updated as a result
27  * of changes triggered from other sources. Hence, the callback from the diff tree
28  * to report changes may occur in the same thread as the method call or
29  * asynchronously in a separate thread, regardless of who triggered the refresh.
30  * Clients of this method (and any other asynchronous method on this context) may
31  * determine if all changes have been collected using {@link IJobManager#find(Object)}
32  * using this context as the <code>family</code> argument in order to determine
33  * if there are any jobs running that are populating the diff tree. Clients may also
34  * call {@link IJobManager#join(Object, IProgressMonitor)} if they wish to wait until
35  * all background handlers related to this context are finished.
36  * </p>
37  * <p>
38  * This interface is not intended to be implemented by clients. Clients should
39  * instead subclass {@link MergeContext}.
40  *
41  * @see IResourceMappingMerger
42  * @see MergeContext
43  * @since 3.2
44  */

45 public interface IMergeContext extends ISynchronizationContext {
46
47     /**
48      * Return the type of merge that will be performed when using this
49      * context (either {@link ISynchronizationContext#TWO_WAY} or
50      * {@link ISynchronizationContext#THREE_WAY}). In most cases,
51      * this type which match that returned by {@link ISynchronizationContext#getType()}.
52      * However, for some THREE_WAY synchronizations, the merge type may
53      * be TWO_WAY which indicates that clients of the context should
54      * ignore local changes when performing merges. This capability is
55      * provided to support replace operations that support three-way
56      * preview but ignore local changes when replacing.
57      * @return the type of merge that will be performed when using this
58      * context.
59      */

60     public int getMergeType();
61     
62     /**
63      * Method that allows the model merger to signal that the file associated
64      * with the given diff node has been completely merged. Model mergers can
65      * call this method if they have transfered all changes from a remote file
66      * to a local file and wish to signal that the merge is done. This will
67      * allow repository providers to update the synchronization state of the
68      * file to reflect that the file is up-to-date with the repository.
69      * <p>
70      * For two-way merging, this method can be used to reject any change. For
71      * three-way merging, this method should only be used when remote content in
72      * being merged with local content (i.e. the file exists both locally and
73      * remotely) with the exception that it can also be used to keep local
74      * changes to a file that has been deleted. See the
75      * {@link #merge(IDiff[], boolean, IProgressMonitor) } method for more
76      * details. For other cases in which either the local file or remote file
77      * does not exist, one of the <code>merge</code> methods should be used.
78      * This is done to accommodate repositories that have special handling for
79      * file additions, removals and moves. Invoking this method with a diff node
80      * associated with a folder will have no effect.
81      * <p>
82      * The <code>inSyncHint</code> allows a client to indicate to the context
83      * that the model persisted in the file is in-sync. If the hint is
84      * <code>true</code>, the context should compare the local and remote
85      * file at the content level and make the local file in-sync with the remote
86      * if the contents are the same.
87      * </p>
88      *
89      * @param node the diff node whose file has been merged
90      * @param inSyncHint a hint to the context that the model persisted in the
91      * file is in-sync.
92      * @param monitor a progress monitor
93      * @throws CoreException if errors occur
94      */

95     public void markAsMerged(IDiff node, boolean inSyncHint,
96             IProgressMonitor monitor) throws CoreException;
97
98     /**
99      * Mark the files associated with the given diff nodes as being merged.
100      * This method is equivalent to calling {@link #markAsMerged(IDiff, boolean, IProgressMonitor) }
101      * for each diff but gives the context the opportunity to optimize the
102      * operation for multiple files.
103      * <p>
104      * This method will batch change notification by using the
105      * {@link #run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) }
106      * method. The rule for he method will be obtained using
107      * {@link #getMergeRule(IDiff)} and the flags will be
108      * <code>IResource.NONE</code> meaning that intermittent change events may
109      * occur. Clients may wrap the call in an outer run that either uses a
110      * broader scheduling rule or the <code>IWorkspace.AVOID_UPDATES</code>
111      * flag.
112      *
113      * @param nodes the nodes to be marked as merged
114      * @param inSyncHint a hint to the context that the model persisted in the
115      * file is in-sync.
116      * @param monitor a progress monitor
117      * @throws CoreException if errors occur
118      */

119     public void markAsMerged(IDiff[] nodes, boolean inSyncHint,
120             IProgressMonitor monitor) throws CoreException;
121     
122     /**
123      * Method that can be called by the model merger to attempt a file-system
124      * level merge. This is useful for cases where the model merger does not
125      * need to do any special processing to perform the merge. By default, this
126      * method attempts to use an appropriate {@link IStorageMerger} to merge the
127      * files covered by the provided traversals. If a storage merger cannot be
128      * found, the text merger is used. If this behavior is not desired,
129      * sub-classes of {@link MergeContext} may override this method.
130      * <p>
131      * This method does a best-effort attempt to merge of the file associated
132      * with the given diff. A file that could not be merged will be indicated in
133      * the returned status. If the status returned has the code
134      * <code>MergeStatus.CONFLICTS</code>, the list of failed files can be
135      * obtained by calling the <code>MergeStatus#getConflictingFiles()</code>
136      * method.
137      * <p>
138      * It is not expected that clients of this API will associate special
139      * meaning with the existence of a folder other than the fact that it
140      * contains files. The sync delta tree should still include folder changes
141      * so that clients that have a one-to-one correspondence between their model
142      * objects and folders can decorate these elements appropriately. However,
143      * clients of this API will only be expected to perform operations on file
144      * deltas and will expect folders to be created as needed to contain the
145      * files (i.e. implementations of this method should ignore any folder
146      * deltas in the provided deltas). Clients will also expect local folders
147      * that have incoming folder deletions to be removed once all the folder's
148      * children have been removed using merge.
149      * <p>
150      * There are two special cases where merge is meaningful for folders. First,
151      * a merge on a local added empty folder with force set should delete the
152      * folder. However, the folder should not be deleted if it has any local
153      * children unless merge is called for those resources first and they end up
154      * being deleted as a result. Second, a merge on an incoming folder addition
155      * should create the empty folder locally.
156      * <p>
157      * It is not expected that clients of this API will be capable of dealing
158      * with namespace conflicts. Implementors should ensure that any namespace
159      * conflicts are dealt with before the merger is invoked.
160      * <p>
161      * The deltas provided to this method should be those obtained from the tree ({@link ISynchronizationContext#getDiffTree()})
162      * of this context. Any resource changes triggered by this merge will be
163      * reported through the resource delta mechanism and the change notification
164      * mechanisms of the delta tree associated with this context.
165      * <p>
166      * For two-way merging, as indicated by either the
167      * {@link ISynchronizationContext#getType()} or {@link #getMergeType()}
168      * methods, clients can either accept changes using the
169      * {@link #merge(IDiff[], boolean, IProgressMonitor) } method or reject them
170      * using {@link #markAsMerged(IDiff, boolean, IProgressMonitor) }.
171      * Three-way changes are a bit more complicated. The following list
172      * summarizes how particular remote file changes can be handled. The delta
173      * kind and flags mentioned in the descriptions are obtained the remote
174      * change (see {@link IThreeWayDiff#getRemoteChange()}), whereas conflicts
175      * are indicated by the three-way delta itself.
176      * <ul>
177      *
178      * <li> When the delta kind is {@link IDiff#ADD} and the delta is also a
179      * move (i.e. the {@link ITwoWayDiff#MOVE_FROM} is set). The merge can
180      * either use the {@link #merge(IDiff[], boolean, IProgressMonitor) } method
181      * to accept the rename or perform an
182      * {@link IFile#move(IPath, boolean, boolean, IProgressMonitor) } where the
183      * source file is obtained using {@link ITwoWayDiff#getFromPath()} and the
184      * destination is the path of the delta ({@link IDiff#getPath()}). This
185      * later approach is helpful in the case where the local file and remote
186      * file both contain content changes (i.e. the file can be moved by the
187      * model and then the contents can be merged by the model). </li>
188      *
189      * <li> When the delta kind is {@link IDiff#REMOVE} and the delta is also a
190      * move (i.e. the {@link ITwoWayDiff#MOVE_TO} is set). The merge can either
191      * use the {@link #merge(IDiff[], boolean, IProgressMonitor) } method to
192      * accept the rename or perform an
193      * {@link IFile#move(IPath, boolean, boolean, IProgressMonitor) } where the
194      * source file is obtained using {@link IDiff#getPath()} and the destination
195      * is obtained from {@link ITwoWayDiff#getToPath()}. This later approach is
196      * helpful in the case where the local file and remote file both contain
197      * content changes (i.e. the file can be moved by the model and then the
198      * contents can be merged by the model). </li>
199      *
200      * <li> When the delta kind is {@link IDiff#ADD} and it is not part of a
201      * move, the merger must use the
202      * {@link #merge(IDiff[], boolean, IProgressMonitor) } method to accept this
203      * change. If there is a conflicting addition, the force flag can be set to
204      * override the local change. If the model wishes to keep the local changes,
205      * they can overwrite the file after merging it. Models should consult the
206      * flags to see if the remote change is a rename ({@link ITwoWayDiff#MOVE_FROM}).
207      * </li>
208      *
209      * <li>When the delta kind is {@link IDiff#REMOVE} and it is not part of a
210      * move, the merger can use the
211      * {@link #merge(IDiff[], boolean, IProgressMonitor) } method but could also
212      * perform the delete manually using any of the {@link IFile} delete
213      * methods. In the case where there are local changes to the file being
214      * deleted, the model may either choose to merge using the force flag (thus
215      * removing the file and the local changes) or call
216      * {@link #markAsMerged(IDiff, boolean, IProgressMonitor) } on the file
217      * which will convert the incoming deletion to an outgoing addition.</li>
218      *
219      * <li>When the delta kind is {@link IDiff#CHANGE} and there is no
220      * conflict, the model is advised to use the
221      * {@link #merge(IDiff[], boolean, IProgressMonitor) } method to merge these
222      * changes as this is the most efficient means to do so. However, the model
223      * can choose to perform the merge themselves and then invoke
224      * {@link #markAsMerged(IDiff, boolean, IProgressMonitor) } with the
225      * <code>inSyncHint</code> set to <code>true</code> but this will be
226      * less efficient. </li>
227      *
228      * <li>When the delta kind is {@link IDiff#CHANGE} and there is a conflict,
229      * the model can use the {@link #merge(IDiff[], boolean, IProgressMonitor) }
230      * method to merge these changes. If the force flag is not set, an
231      * auto-merge is attempted using an appropriate {@link IStorageMerger}. If
232      * the force flag is set, the local changes are discarded. The model can
233      * choose to attempt the merge themselves and, if it is successful, invoke
234      * {@link #markAsMerged(IDiff, boolean, IProgressMonitor) } with the
235      * <code>inSyncHint</code> set to <code>false</code> which will make the
236      * file an outgoing change. </li>
237      * </ul>
238      *
239      * TODO: need to talk about ITwoWayDelta CONTENT and REPLACED
240      *
241      * @see IDiffTree#addDiffChangeListener(IDiffChangeListener)
242      * @see org.eclipse.core.resources.IWorkspace#addResourceChangeListener(IResourceChangeListener)
243      *
244      * @param diff
245      * the difference to be merged
246      * @param ignoreLocalChanges
247      * ignore any local changes when performing the merge.
248      * @param monitor
249      * a progress monitor
250      * @return a status indicating success or failure. A code of
251      * <code>MergeStatus.CONFLICTS</code> indicates that the file
252      * contain non-mergable conflicts and must be merged manually.
253      * @throws CoreException
254      * if an error occurs
255      */

256     public IStatus merge(IDiff diff, boolean ignoreLocalChanges, IProgressMonitor monitor)
257             throws CoreException;
258
259     /**
260      * Attempt to merge any files associated with the given diffs. This method
261      * is equivalent to calling
262      * {@link #merge(IDiff, boolean, IProgressMonitor) } for each diff
263      * individually but gives the context a chance to perform a more optimal
264      * merge involving multiple resources.
265      * <p>
266      * This method will batch change notification by using the
267      * {@link #run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor) }
268      * method. The rule for he method will be obtained using
269      * {@link #getMergeRule(IDiff) } and the flags will be
270      * <code>IResource.NONE</code> meaning that intermittent change events may
271      * occur. Clients may wrap the call in an outer run that either uses a
272      * broader scheduling rule or the <code>IWorkspace.AVOID_UPDATES</code>
273      * flag.
274      *
275      * @param diffs the differences to be merged
276      * @param ignoreLocalChanges ignore any local changes when performing the merge.
277      * @param monitor a progress monitor
278      * @return a status indicating success or failure. A code of
279      * <code>MergeStatus.CONFLICTS</code> indicates that the file
280      * contain non-mergable conflicts and must be merged manually.
281      * @throws CoreException if an error occurs
282      */

283     public IStatus merge(IDiff[] diffs, boolean ignoreLocalChanges,
284             IProgressMonitor monitor) throws CoreException;
285
286     /**
287      * Reject the change associated with the given diff. For a two-way
288      * merge, this should just remove the change from the set of changes in
289      * the diff tree. For a three-way merge, this should throw away the
290      * remote change and keep any local changes. So, for instance, if
291      * the diff is an incoming change or a conflict, the result of rejecting the
292      * change should be an outgoing change that will make the remote state
293      * match the local state.
294      * @param diff the diff
295      * @param monitor a progress monitor
296      * @throws CoreException
297      */

298     public void reject(IDiff diff, IProgressMonitor monitor) throws CoreException;
299     
300     /**
301      * Reject the changes associated with the given diffs. This method is
302      * equivalent to calling {@link #reject(IDiff, IProgressMonitor)} for
303      * each diff.
304      * @param diffs the diffs
305      * @param monitor a progress monitor
306      * @throws CoreException
307      */

308     public void reject(IDiff[] diffs, IProgressMonitor monitor) throws CoreException;
309     
310     /**
311      * Runs the given action as an atomic workspace operation. It has the same
312      * semantics as
313      * {@link IWorkspace#run(IWorkspaceRunnable, ISchedulingRule, int, IProgressMonitor)}
314      * with the added behavior that any synchronization state updates are
315      * batched or deferred until the end of the operation (depending on the
316      * {@link IWorkspace#AVOID_UPDATE } flag.
317      *
318      * @param runnable a workspace runnable
319      * @param rule a scheduling rule to be obtained while the runnable is run
320      * @param flags flags indicating when updates occur (either
321      * <code>IResource.NONE</code> or
322      * <code>IWorkspace.AVOID_UPDATE</code>.
323      * @param monitor a progress monitor
324      * @throws CoreException if an error occurs
325      */

326     public void run(IWorkspaceRunnable runnable, ISchedulingRule rule,
327             int flags, IProgressMonitor monitor) throws CoreException;
328
329     /**
330      * Return the scheduling rule that is required to merge (or reject) the resource
331      * associated with the given diff. If a resource being merged is a folder or
332      * project, the returned rule will be sufficient to merge any files
333      * contained in the folder or project. The returned rule also applies to
334      * {@link #markAsMerged(IDiff, boolean, IProgressMonitor) }
335      * and {@link #reject(IDiff, IProgressMonitor)}.
336      *
337      * @param diff the diff to be merged
338      * @return the scheduling rule that is required to merge the resource of the
339      * given diff
340      */

341     public ISchedulingRule getMergeRule(IDiff diff);
342
343     /**
344      * Return the scheduling rule that is required to merge (or reject) the resources
345      * associated with the given diffs. If a resource being merged is a folder
346      * or project, the returned rule will be sufficient to merge any files
347      * contained in the folder or project. The returned rule also applies to
348      * {@link #markAsMerged(IDiff[], boolean, IProgressMonitor) }
349      * and {@link #reject(IDiff[], IProgressMonitor)}.
350      *
351      * @param diffs the diffs being merged
352      * @return the scheduling rule that is required to merge the resources of
353      * the given diffs
354      */

355     public ISchedulingRule getMergeRule(IDiff[] diffs);
356
357 }
358
Popular Tags