blob: 8b67cc63e0983d29c8d9595a524a8a5be76e65ad [file] [log] [blame]
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Eclipse">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<title>Eclipse Platform Core RFC 0008 - Resource Moves, Renames, and Deletes</title>
</head>
<body>
<h1>
Resource Moves, Renames, and Deletes</h1>
<i><font size=-1>Last revised 15:00 Thursday February 14, 2002</font></i>
<p>This proposal deals with improving the Eclipse Platform's support for
allowing a Team provider to control the movement of existing resources under its
control. The proposal would give Team providers a (headless) way of doing
this sort of thing.
<h2>
Work Item</h2>
Ref: uncommitted work item from early 2.0 plan.
<blockquote><b>Allow pre-validation of rename/move/delete.</b> VCM providers that need to manage a project's namespace would like advance notification
of impending resource moves, renames, and deletes. (Other clients would
like a similar opportunity to veto inappropriate name changes to their
resources; this is a different concern.) We will add a callback so that
the relevant VCM provider will be able to register for advance notification
with an opportunity to veto. These changes will affect the UI and Core
components.</blockquote>
The title and description for this item is not quite right. The work item
would be better described as:
<blockquote><b>Allow VCM control over rename/move/delete.</b> Team providers
sometimes need tighter control over how project resources are manipulated
in the local file system. For instance, a project directory might be a
specially mounted remote file system located on a Team server, and require
special server communication in order to delete, move, or change the name
of a resource. Or the Team provider may track version history across move/renames.
(Other clients would like a similar opportunity to veto inappropriate name
changes to their resources; this is a different concern.) We will add a
headless callback so that the relevant Team provider will be able to control
moves, renames, and deletes. These changes will affect the Core and Team components.</blockquote>
<h2>
Problem</h2>
Some VCM systems must keep close tabs on the files under their control.
<ul>
<li>Some Team providers use pessimistic locking, and need to be involved early
so that they can determine whether a move/rename is likely to fail because
either the source or target resource is check out by another.</li>
<li>Some Team providers may materialize "managed" files in a project by mounting
or mapping server-side files into the local file system. These client-side
directories can also hold other "unmanaged" files; files newly created
on the client side files are considered "unmanaged" until the user explicitly
places them under management. Under this kind of arrangement, it may be
the case that deleting, renaming, or moving a "managed" file cannot be
accomplished by direct manipulations of the local file system - it instead
requires communication with the Team provider's server to effect such changes.
In other words, the Team provider could only support these operations if
it can intercept and perform all the local file system manipulations itself.</li>
<li>Some Team providers endeavor to maintain a file's version history across
namespace changes. In some cases, it may give a Team provider more options
if it can get advance notice of moves and renames, rather than having to
rely entirely on after-the-fact resource change notifications (in which
moves are recorded).</li>
<li>Some Team provider require additional repository-specific validation.</li>
</ul>
<p>(Note that newly-created files are a separate matter; until they exist
and have been placed under VCM control, changes to their names are not
of interest. This is why create and copy operations are not included
in this discussion.)
<h2>
Background - support available in Eclipse 1.0</h2>
There is no support available in Eclipse 1.0 for any facet of this problem.
<p>The workspace operations for moving resources are as follows:
<ul>
<li>
IResource.move(IPath,boolean,IProgressMonitor)</li>
<ul>
<li>
IFile.move(IPath,boolean,boolean,IProgressMonitor)</li>
<li>
IFolder.move(IPath,boolean,boolean,IProgressMonitor)</li>
</ul>
<li>
IResource.move(IProjectDescription,boolean,boolean,IProgressMonitor)</li>
<li>
IProject.move(IProjectDescription,boolean,IProgressMonitor)</li>
<li>
IWorkspace.move(IResource[],IPath,boolean,IProgressMonitor)</li>
</ul>
The workspace operations for deleting resources are:
<ul>
<li>
IResource.delete(boolean,IProgressMonitor)</li>
<ul>
<li>
IWorkspaceRoot.delete(boolean,boolean,IProgressMonitor)</li>
<li>
IProject.delete(boolean,boolean,IProgressMonitor)</li>
<li>
IFile.delete(boolean,boolean,IProgressMonitor)</li>
<li>
IFolder.delete(boolean,boolean,IProgressMonitor)</li>
</ul>
<li>
IWorkspace.delete(IResource[],boolean,IProgressMonitor)</li>
</ul>
All operations for moving and deleting resources are implemented entirely
by the core resource plug-in; there is currently no mechanisms by which
another party could participate.
<h2>
Design Constraints</h2>
All of the operations for moving and deleting resources are available to
arbitrary clients and are billed as "core" operations; i.e., operations
that run headless. Callers may be holding locks at the time of call, or
making the call in a non-UI thread. Consequently, it would be problematic
if existing uses were to attempt to reacquire locks or pop up dialogs to
interact with the user.
<p>This means that none of the existing operations can ever bring up a
UI - all must run headless. If we add hooks to these operations, the hooks
must run headless.
<p>The alternative is to add a parallel set of operations that would allow
a UI-aware client to pass in a UI context in which to converse with the
user (by employing exactly the same design as the recently-added validate-edit
support). These new API methods could have more stringent contracts that
spell out the conditions which UIs would need. However, this does nothing
for existing plug-ins that manipulate resources with the exisiting API
methods; these would still need to run headless.
<h2>
Proposal</h2>
The move and delete operations have several facets:
<ul>
<li>
manipulating the local file system</li>
<ul>
<li>
capture "before" file states in local history</li>
<li>
move or delete files and folders</li>
</ul>
<li>
manipulating the workspace resource tree</li>
<ul>
<li>
move or delete file and folder resources from in-memory tree, including
markers and resource properties</li>
<li>
generate resource deltas</li>
</ul>
<li>
reporting status back to the client</li>
</ul>
The proposal is that Core would provide a headless hook that would give
the hook overall responsibility for carrying out these operations. The hook
would have control over the local file system facet of the operation, and would
call back into the Core
to capture local file history, update the workspace resource tree, report
progress, and report status back to the user. The hook would also be furnished
with standard building block sub-operations, so that it is possible for a
particular hook implementation to embellish the standard behavior without having to
implement everything from scratch.
<p>This hook would be filled by the Team component, which would delegate
the request to the Team provider for the project that owns the resource.
The Team provider would not be obliged to participate in these operations;
if it decided to pass, the Core would fall back on its own internal implementation
the operation much as it does currently.
<p>Newly-created files and folders are not under version control automatically.
Adding a file or folder to version control is a separate follow-on operation
that each Team provider will give the user. This is why create and copy
operations are not included in this hook.
<h3>
Support in Core Component</h3>
Here is a sketch of how the move and delete resource operations in the
API would be implemented (important details, such as batching, have been
omitted in the interest of brevity):
<p><tt>Resource</tt>
<br><tt>&nbsp;&nbsp; public IStatus move(</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IPath destination,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean force,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean keepHistory,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IProgressMonitor monitor)
throws CoreException {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // do easy precondition checks before calling
hook</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (!this.exists()) throw new CoreException(...);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (findResource(destination) != null) throw
new CoreException(...);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; IResourceTree rto = ...;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; INamespaceControlHook hook = ...;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; boolean done = false;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (hook != null) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done = hook.move(this,
destination, force, keepHistory, monitor, rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (!done) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; internalMove(this, destination,
force, keepHistory, monitor, rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (rto.getStatus().isOK()) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rto.getStatus();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; } else {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new CoreException(rto.getStatus());</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<p><tt>IResource</tt>
<br><tt>&nbsp;&nbsp; public IStatus delete(</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean force,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean keepHistory,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IProgressMonitor monitor)
throws CoreException {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; // do easy precondition checks before calling
hook</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (!this.exists()) throw new CoreException(...);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; IResourceTree rto = ...;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; INamespaceControlHook hook = ...;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; boolean done = false;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (hook != null) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; done = hook.delete(this,
force, keepHistory, monitor, rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (!done) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ops = internalDelete(this,
force, keepHistory, monitor, rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp; if (rto.getStatus().isOK()) {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rto.getStatus();</tt>
<br><tt>&nbsp;&nbsp;&nbsp; } else {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new CoreException(rto.getStatus());</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<p>(The API operations for moving or deleting a project have a slightly
extended contract, but the general flavor of the hook is the same.)
<h4>
Hook Semantics</h4>
The hook is bound by the terms of the API contract of the resource operation,
including:
<ul>
<li>
capturing the "before" state of resources in the local file history (when
keepHistory parameter is specified)</li>
<li>
detecting and failing in cases where the resource tree is out of sync with
the local file system (when force parameter is specified)</li>
<li>
reporting progress</li>
<li>reporting status to caller</li>
</ul>
<h4>
New Core API</h4>
The new core API is provided for the Team component and its Team providers.
Rather than clutter up the main resources API package with this special-purpose
API, we propose adding the new core API in a new <tt>org.eclipse.core.resources.</tt><tt>team</tt>
package. (The question of whether to use a separate API package is clearly
a separable issue. If we do go for a separate package, we should consider
moving the hook interface for validateEdit/validateSave into this package
too.)
<p>The <tt>INamespaceControlHook</tt> interface appears in the new core
extension point, and would be implemented by the Team component, and likely
by each Team provider.<p><tt>package org.eclipse.core.resources.</tt><tt>team</tt>
<br><tt>public interface INamespaceControlHook {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public boolean delete(IResource resource,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean force,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean keepHistory,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
IProgressMonitor monitor,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
IResourceTree rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public boolean move(IResource resource,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
IResource destination,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean force,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
boolean keepHistory,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
IProgressMonitor monitor,</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
IResourceTree rto);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; //... others for project move, project delete</tt>
<br><tt>}</tt>
<p>The <tt>IResourceTree</tt> interface provides the operations that manipulate
the resource tree (move markers, properties, collect result statuses) without
touching the local file system. The sole implementation would be internal
to core, and would be passed as a parameter to the <tt>INamespaceControlHook</tt>
implementation.
<p><tt>package org.eclipse.core.resources.</tt><tt>team</tt>
<br><tt>public interface IResourceTree {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void deletedFile(IResource file, IStatus status);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void deletedFolder(IResource folder, IStatus
status);</tt>
<p><tt>&nbsp;&nbsp;&nbsp; public void movedFile(IResource source, IResource dest,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long
destTimestamp, IStatus status);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void movedFolder(IResource source, IResource
dest, IStatus status);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void movedEmptyFolder(IResource source,
IResource dest, IStatus status);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void moved(IResource source, IResource
dest);</tt>
<p><tt>&nbsp;&nbsp;&nbsp; public void createdFile(IResource file, long timestamp,
IStatus status);</tt>
<br><tt>&nbsp;&nbsp;&nbsp; public void createdFolder(IResource folder, IStatus
status);</tt>
<p><tt>&nbsp;&nbsp;&nbsp; public boolean copyToLocalHistory(IResource
file, boolean stealable);</tt>
<p><tt>&nbsp;&nbsp;&nbsp; // standard building blocks<br>
&nbsp;&nbsp;&nbsp; public void standardDeleteResource(IResource resource,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean force, boolean keepHistory,
IProgressMonitor monitor);<br>
&nbsp;&nbsp;&nbsp; public void standardMoveResource(IResource resource,
IResource dest,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean force, boolean keepHistory,
IProgressMonitor monitor);<br>
&nbsp;&nbsp;&nbsp; ...<br>
</tt>
<br><tt>&nbsp;&nbsp;&nbsp; //... plus others for moving or deleting a project</tt>
<br><tt>}</tt>
<h4>
New Core Extension Point</h4>
The Core resources plug-in would provide a new namespaceControl extension
point intended to be extended by none other than the Team component.
<p><b><i>Identifier:</i></b> <tt>org.eclipse.core.resources.namespaceControl</tt>
<br><b><i>Description:</i></b> For providing an implementation of an <tt>INamespaceControlHook</tt>
to be used in implementing resource moves and deletes. This extension point
tolerates at most one extension.
<p><b><i>Configuration Markup:</i></b>
<p><tt>&nbsp;&nbsp; &lt;!ELEMENT namespaceControl EMPTY></tt>
<br><tt>&nbsp;&nbsp; &lt;!ATTLIST namespaceControl class CDATA #REQUIRED></tt>
<p>class - a fully qualified name of a class which implements <tt>org.eclipse.core.resource.team.INamespaceControlHook.</tt>
<p><b><i>Examples:</i></b>
<br>The following is an example of using the <tt>namespaceControl </tt>extension
point.
<p>(in file <tt>plugin.xml</tt>)
<p><tt>&nbsp;&nbsp; &lt;extension point="org.eclipse.core.resources.namespaceControl"></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;namespaceControl class="org.eclipse.team.internal.VCMNamespaceControlHook"/></tt>
<br><tt>&nbsp;&nbsp; &lt;/extension></tt>
<h4>
API Compatibility</h4>
In summary, the changes affect the Eclipse Platform Core component API
in the following ways:
<ul>
<li>
Adding a new extension point.</li>
<li>
Adding a new API package: <tt>org.eclipse.core.resource.team</tt></li>
<li>
Adding 2 new API interfaces.</li>
</ul>
The changes maintain full API compatibility with existing plug-ins in compliance
with the 1.0 API.
<h4>
Local History</h4>
The hook implementation calls <tt>copyToLocalHistory</tt> when appropriate
to copy the state of a file to the local history before it is changed (or
deleted). Bearing in mind that the purpose of the local history is to preserve
intermediate file states so that the user has some options for recovering
from mistakes, etc., the Team provider should consider whether anything
is at risk before adding states to the local history. For instance, the
state of a file that the user has neither checked out nor modified is likely
not at risk since it exists as a version in the repository; deleting such
a file would not deserve a local history entry.
<h4>
Resource Tree Operations</h4>
The hook may need to access the workspace resource tree as well as the
local file system. Since the hook is in the midst of a workspace operation,
they must not call any of the normal resource API operations that modify
resources. However, they must be able to at least walk the resource tree.
This they should be able to do through the resource API.
<p>In order to modify the resource tree, they call <tt>IResourceTree</tt>
methods. These operations affect the resource tree (immediately). If the hook
passes the timestamp for a file, it is used; if no timestamp is passed, the local file
system is queried for the value.
<h4>
Timestamping</h4>
The Core and the hook must employ the same file timestamp scheme; otherwise,
the core will fail to correctly identify when files in the local file system
change. Currently, the Core uses an internal native mechanism that is more
accurate than java.io.File.lastModified(). We should review whether this
is still needed; if it is, we need to add an API method (to <tt>IResourceTree</tt>)
so that the Team provider can use it.
<h4>
Multiple API Entry Points</h4>
There are several move methods in the API. All single resource moves should
funnel through a single move operation taking a source resource, a target
resource, a force flag, a keepHistory flag, and a progress monitor. IWorkspace.move
moves multiple siblings to a single target folder. These would be passed
through the move pinch point one at a time.
<p>Likewise for delete methods. All single resource delete should funnel
through a single delete operation taking a source resource, a force flag,
a keepHistory flag, and a progress monitor. IWorkspace.delete deletes multiple
independent resources, and would pass them through the delete pinch point
one at a time. Resources scattered across different projects will get routed
automatically to the appropriate project-specific Team provider.
<h4>
Inter-project Moves</h4>
A move operation may move resources from one project into a different project.
The move request will be dispatched to the Team provider of the project
containing the source resource. The Team provider may decide to be clever
if it also manages the destination project; otherwise, it should just use
local file system copy operation to copy the files to the destination,
and then delete the originals when done.
<p>Note that each project in the workspace could have a different Team provider
(or none at all), and each could map the project root directory to a different
drive or OS file system.
<h4>
Projects</h4>
The API operations for moving or deleting a project have a slightly extended
contract, but the general flavor of the hook is the same. The hook is responsible
for the files in the project's root directory in the local file system.
Project properties, markers, and other project metadata are still a Core
responsibility.
<h4>Other Useful Building Blocks</h4>
<p>The IResourceTree API should also include standard implementations of the
operations as additional building blocks. This would make it simpler for a Team
provider to embellish the standard behavior instead of having to reimplement it
from scratch.</p>
<h4>
Example</h4>
Assumptions:
<ul>
<li>Project contains /P/f/a.txt(t1),b.txt(t2).</li>
<li>Resource tree is in perfect sync with local file system.</li>
<li>Operation is move folder /P/f to /P/g force=false, keepHistory=true</li>
<li>All local file system manipulation done &quot;by hand&quot; (i.e.,
avoiding standard building blocks).</li>
</ul>
<p>Sequence of calls:</p>
<p><code>Folder[/P/f].move(dest=Path[/P/g],force=false,keepHistory=true,monitor)
<br>- VCMNSHook.move(source=Folder[/P/f],dest=Folder[/P/g],force,keepHistory,monitor,rto)
<br>-- VCMProvider1.move(source,dest,force,keepHistory,monitor,rto)
<br>--- java.io creates folder /P/g
<br>--- rto.createdFolder(dest, OK)
<br>---- Folder[/P/g] created in resource tree
<br>--- rto.copyToLocalHistory(File[P/f/a.txt],steal=false)
<br>--- check timestamp on /P/f/a.txt is t1
<br>--- java.io rename file /P/f/a.txt to /P/g/a.txt
<br>--- new timestamp of /P/g/a.txt is t1'
<br>--- rto.movedFile(File[/P/f/a.txt], t1, File[/P/g/a.txt], t1', OK)
<br>---- File[/P/g/a.txt] created in resource tree with timestamp t1'
<br>---- markers and properties copied from File[/P/f/a.txt] to File[/P/g/a.txt]
<br>---- File[/P/f/a.txt] deleted from resource tree
<br>---- delta for File[/P/g/a.txt] records moved from File[/P/f/a.txt]
<br>---- delta for File[/P/f/a.txt] records moved to File[/P/g/a.txt]
<br>--- check timestamp on /P/f/b.txt is t2
<br>--- java.io rename file /P/f/b.txt to /P/g/b.txt
<br>--- new timestamp of /P/g/b.txt is t2'
<br>--- rto.movedFile(File[/P/f/b.txt], t2, File[/P/g/b.txt], t2', OK)
<br>---- File[/P/g/b.txt] created in resource tree with timestamp t2'
<br>---- markers and properties copied from File[/P/f/b.txt] to File[/P/g/b.txt]
<br>---- File[/P/f/b.txt] deleted from resource tree
<br>---- delta for File[/P/g/b.txt] records moved from File[/P/f/b.txt]
<br>---- delta for File[/P/f/b.txt] records moved to File[/P/g/b.txt]
<br>--- java.io deletes folder /P/f
<br>--- rto.moved(source,dest)
<br>---- markers and properties copied from Folder[/P/f] to Folder[/P/g]
<br>---- delta for Folder[/P/g] records moved from Folder[/P/f]
<br>---- delta for Folder[/P/f] records moved to Folder[/P/g]
<br>--- return true
<br>-- return true
<br>- return OK</code>
<h3>
Support in Team Component</h3>
<ul>
<li>
Team component contributes implementation to <tt>namespaceControl </tt>extension
point.</li>
<li>
Team component publishes its own API so that Team providers can get involved.</li>
<li>
Team component routes requests to the Team provider for the relevant project.</li>
<li>
Particular Team providers will orchestrate moving or deleting
files in a particular project.</li>
</ul>
<h3>
Support in Other Components</h3>
None required. These hooks are activated whenever a client calls a core
API operation to delete, move, or rename a file or folder.
<br>&nbsp;
</body>
</html>