/*
* ====================================================================
* Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://svnkit.com/license.html
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
* ====================================================================
*/
package org.tmatesoft.svn.core.wc;
import java.io.File;
import java.util.Collection;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.wc17.SVNWCContext;
import org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc2.*;
/**
* The <b>SVNStatusClient</b> class provides methods for obtaining information
* on the status of Working Copy items. The functionality of
* <b>SVNStatusClient</b> corresponds to the <code>'svn status'</code> command of the native SVN
* command line client.
*
* <p>
* One of the main advantages of <b>SVNStatusClient</b> lies in that fact that
* for each processed item the status information is collected and put into an
* <b>SVNStatus</b> object. Further there are two ways how this object can be
* passed to a developer (depending on the version of the <b>doStatus()</b>
* method that was invoked):
* <ol>
* <li>the <b>SVNStatus</b> can be passed to a developer's status handler (that
* should implement <b>ISVNStatusHandler</b>) in which the developer retrieves
* status information and decides how to interprete that info;
* <li>another way is that an appropriate <b>doStatus()</b> method just returns
* that <b>SVNStatus</b> object.
* </ol>
* Those methods that match the first variant can be called recursively -
* obtaining status information for all child entries, the second variant just
* the reverse - methods are called non-recursively and allow to get status info
* on a single item.
*
* @version 1.3
* @author TMate Software Ltd.
* @since 1.2
* @see ISVNStatusHandler
* @see SVNStatus
* @see <a target="_top" href="http://svnkit.com/kb/examples/">Examples</a>
*/
public class SVNStatusClient extends SVNBasicClient {
private ISVNStatusFileProvider myFilesProvider;
/**
* Constructs and initializes an <b>SVNStatusClient</b> object with the
* specified run-time configuration and authentication drivers.
*
* <p>
* If <code>options</code> is <span class="javakeyword">null</span>, then
* this <b>SVNStatusClient</b> will be using a default run-time
* configuration driver which takes client-side settings from the default
* SVN's run-time configuration area but is not able to change those
* settings (read more on {@link ISVNOptions} and {@link SVNWCUtil}).
*
* <p>
* If <code>authManager</code> is <span class="javakeyword">null</span>,
* then this <b>SVNStatusClient</b> will be using a default authentication
* and network layers driver (see
* {@link SVNWCUtil#createDefaultAuthenticationManager()}) which uses
* server-side settings and auth storage from the default SVN's run-time
* configuration area (or system properties if that area is not found).
*
* @param authManager
* an authentication and network layers driver
* @param options
* a run-time configuration options driver
*/
public SVNStatusClient(ISVNAuthenticationManager authManager, ISVNOptions options) {
super(authManager, options);
}
/**
* Constructs and initializes an <b>SVNStatusClient</b> object with the
* specified run-time configuration and repository pool object.
*
* <p/>
* If <code>options</code> is <span class="javakeyword">null</span>, then
* this <b>SVNStatusClient</b> will be using a default run-time
* configuration driver which takes client-side settings from the default
* SVN's run-time configuration area but is not able to change those
* settings (read more on {@link ISVNOptions} and {@link SVNWCUtil}).
*
* <p/>
* If <code>repositoryPool</code> is <span class="javakeyword">null</span>,
* then {@link org.tmatesoft.svn.core.io.SVNRepositoryFactory} will be used
* to create {@link SVNRepository repository access objects}.
*
* @param repositoryPool
* a repository pool object
* @param options
* a run-time configuration options driver
*/
public SVNStatusClient(ISVNRepositoryPool repositoryPool, ISVNOptions options) {
super(repositoryPool, options);
}
public SVNStatusClient(SvnOperationFactory of) {
super(of);
}
protected void initDefaults() {
setFilesProvider(null);
}
/**
* Collects status information on Working Copy items and passes it to a
* <code>handler</code>.
*
* @param path
* local item's path
* @param recursive
* relevant only if <code>path</code> denotes a directory: <span
* class="javakeyword">true</span> to obtain status info
* recursively for all child entries, <span
* class="javakeyword">false</span> only for items located
* immediately in the directory itself
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @param reportAll
* <span class="javakeyword">true</span> to collect status
* information on those items that are in a <i>'normal'</i> state
* (unchanged), otherwise <span class="javakeyword">false</span>
* @param includeIgnored
* <span class="javakeyword">true</span> to force the operation
* to collect information on items that were set to be ignored
* (like <i>'--no-ignore'</i> option in the SVN client's <i>'svn
* status'</i> command to disregard default and
* <i>'svn:ignore'</i> property ignores), otherwise <span
* class="javakeyword">false</span>
* @param handler
* a caller's status handler that will be involved in processing
* status information
* @return the revision number the status information was collected against
* @throws SVNException
* @see ISVNStatusHandler
* @deprecated use
* {@link #doStatus(File, SVNRevision, SVNDepth, boolean, boolean, boolean, boolean, ISVNStatusHandler, Collection)}
* instead
*/
public long doStatus(File path, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, ISVNStatusHandler handler) throws SVNException {
return doStatus(path, SVNRevision.HEAD, SVNDepth.fromRecurse(recursive), remote, reportAll, includeIgnored, false, handler, null);
}
/**
* Collects status information on Working Copy items and passes it to a
* <code>handler</code>.
*
* <p>
* Calling this method is equivalent to
*
* <code>doStatus(path, SVNRevision.HEAD, recursive, remote, reportAll, includeIgnored, collectParentExternals, handler)</code>.
*
* @param path
* local item's path
* @param recursive
* relevant only if <code>path</code> denotes a directory: <span
* class="javakeyword">true</span> to obtain status info
* recursively for all child entries, <span
* class="javakeyword">false</span> only for items located
* immediately in the directory itself
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @param reportAll
* <span class="javakeyword">true</span> to collect status
* information on all items including those ones that are in a
* <i>'normal'</i> state (unchanged), otherwise <span
* class="javakeyword">false</span>
* @param includeIgnored
* <span class="javakeyword">true</span> to force the operation
* to collect information on items that were set to be ignored
* (like <i>'--no-ignore'</i> option in the SVN client's <code>'svn status'</code>
* command to disregard default and <i>'svn:ignore'</i> property
* ignores), otherwise <span class="javakeyword">false</span>
* @param collectParentExternals
* <span class="javakeyword">false</span> to make the operation
* ignore information on externals definitions (like
* <i>'--ignore-externals'</i> option in the SVN client's <code>'svn status'</code>
* command), otherwise <span class="javakeyword">true</span>
* @param handler
* a caller's status handler that will be involved in processing
* status information
* @return the revision number the status information was collected against
* @throws SVNException
* @deprecated use
* {@link #doStatus(File, SVNRevision, SVNDepth, boolean, boolean, boolean, boolean, ISVNStatusHandler, Collection)}
* instead
*/
public long doStatus(File path, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, boolean collectParentExternals, final ISVNStatusHandler handler) throws SVNException {
return doStatus(path, SVNRevision.HEAD, SVNDepth.fromRecurse(recursive), remote, reportAll, includeIgnored, collectParentExternals, handler, null);
}
/**
* Collects status information on Working Copy items and passes it to a
* <code>handler</code>.
*
* @param path
* local item's path
* @param revision
* if <code>remote</code> is <span
* class="javakeyword">true</span> this revision is used to
* calculate status against
* @param recursive
* relevant only if <code>path</code> denotes a directory: <span
* class="javakeyword">true</span> to obtain status info
* recursively for all child entries, <span
* class="javakeyword">false</span> only for items located
* immediately in the directory itself
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @param reportAll
* <span class="javakeyword">true</span> to collect status
* information on all items including those ones that are in a
* <i>'normal'</i> state (unchanged), otherwise <span
* class="javakeyword">false</span>
* @param includeIgnored
* <span class="javakeyword">true</span> to force the operation
* to collect information on items that were set to be ignored
* (like <i>'--no-ignore'</i> option in the SVN client's <code>'svn status'</code>
* command to disregard default and <i>'svn:ignore'</i> property
* ignores), otherwise <span class="javakeyword">false</span>
* @param collectParentExternals
* <span class="javakeyword">false</span> to make the operation
* ignore information on externals definitions (like
* <i>'--ignore-externals'</i> option in the SVN client's <code>'svn status'</code>
* command), otherwise <span class="javakeyword">true</span>
* @param handler
* a caller's status handler that will be involved in processing
* status information
* @return the revision number the status information was collected against
* @throws SVNException
* @deprecated use
* {@link #doStatus(File, SVNRevision, SVNDepth, boolean, boolean, boolean, boolean, ISVNStatusHandler, Collection)}
* instead
*/
public long doStatus(File path, SVNRevision revision, boolean recursive, boolean remote, boolean reportAll, boolean includeIgnored, boolean collectParentExternals, final ISVNStatusHandler handler)
throws SVNException {
return doStatus(path, revision, SVNDepth.fromRecurse(recursive), remote, reportAll, includeIgnored, collectParentExternals, handler, null);
}
/**
* Given a <code>path</code> to a working copy directory (or single file),
* calls <code>handler</code> with a set of {@link SVNStatus} objects which
* describe the status of the <code>path</code>, and its children (recursing
* according to <code>depth</code>).
*
* <p/>
* If <code>reportAll</code> is set, retrieves all entries; otherwise,
* retrieves only "interesting" entries (local modifications and/or out of
* date).
*
* <p/>
* If <code>remote</code> is set, contacts the repository and augments the
* status objects with information about out-of-dateness (with respect to
* <code>revision</code>).
*
* <p/>
* If {@link #isIgnoreExternals()} returns <span
* class="javakeyword">false</span>, then recurses into externals
* definitions (if any exist and <code>depth</code> is either
* {@link SVNDepth#INFINITY} or {@link SVNDepth#UNKNOWN}) after handling the
* main target. This calls the client notification handler (
* {@link ISVNEventHandler}) with the {@link SVNEventAction#STATUS_EXTERNAL}
* action before handling each externals definition, and with
* {@link SVNEventAction#STATUS_COMPLETED} after each.
*
* <p/>
* <code>changeLists</code> is a collection of <code>String</code>
* changelist names, used as a restrictive filter on items whose statuses
* are reported; that is, doesn't report status about any item unless it's a
* member of one of those changelists. If <code>changeLists</code> is empty
* (or <span class="javakeyword">null</span>), no changelist filtering
* occurs.
*
* @param path
* working copy path
* @param revision
* if <code>remote</code> is <span
* class="javakeyword">true</span>, status is calculated against
* this revision
* @param depth
* tree depth to process
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @param reportAll
* <span class="javakeyword">true</span> to collect status
* information on all items including those ones that are in a
* <i>'normal'</i> state (unchanged), otherwise <span
* class="javakeyword">false</span>
* @param includeIgnored
* <span class="javakeyword">true</span> to force the operation
* to collect information on items that were set to be ignored
* (like <i>'--no-ignore'</i> option in the SVN client's <code>'svn status'</code>
* command to disregard default and <i>'svn:ignore'</i> property
* ignores), otherwise <span class="javakeyword">false</span>
* @param collectParentExternals
* obsolete (not used)
* @param handler
* a caller's status handler that will be involved in processing
* status information
* @param changeLists
* collection with changelist names
* @return returns the actual revision against which the working copy was
* compared; the return value is not meaningful (-1) unless
* <code>remote</code> is set
* @throws SVNException
* @since 1.2, SVN 1.5
*/
public long doStatus(File path, SVNRevision revision, SVNDepth depth, boolean remote, boolean reportAll, boolean includeIgnored, boolean collectParentExternals, final ISVNStatusHandler handler,
final Collection<String> changeLists) throws SVNException {
final SvnGetStatus getStatus = getOperationsFactory().createGetStatus();
getStatus.setReportExternals(!isIgnoreExternals());
getStatus.setFileListHook(SvnCodec.fileListHook(myFilesProvider));
getStatus.setApplicalbeChangelists(changeLists);
getStatus.setCollectParentExternals(collectParentExternals);
getStatus.setDepth(depth);
getStatus.setRevision(revision);
getStatus.setRemote(remote);
getStatus.setReportAll(reportAll);
getStatus.setReportIgnored(includeIgnored);
getStatus.setSingleTarget(SvnTarget.fromFile(path));
getStatus.setReceiver(new ISvnObjectReceiver<SvnStatus>() {
public void receive(SvnTarget target, SvnStatus status) throws SVNException {
SVNWCContext context = getStatus.getOperationFactory().getWcContext();
handler.handleStatus(SvnCodec.status(context, status));
}
});
getStatus.run();
return getStatus.getRemoteRevision();
}
/**
* Collects status information on a single Working Copy item.
*
* @param path
* local item's path
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @return an <b>SVNStatus</b> object representing status information for
* the item
* @throws SVNException
*/
public SVNStatus doStatus(final File path, boolean remote) throws SVNException {
return doStatus(path, remote, false);
}
/**
* Collects status information on a single Working Copy item.
*
* @param path
* local item's path
* @param remote
* <span class="javakeyword">true</span> to check up the status
* of the item in the repository, that will tell if the local
* item is out-of-date (like <i>'-u'</i> option in the SVN
* client's <code>'svn status'</code> command), otherwise <span
* class="javakeyword">false</span>
* @param collectParentExternals
* <span class="javakeyword">false</span> to make the operation
* ignore information on externals definitions (like
* <i>'--ignore-externals'</i> option in the SVN client's <code>'svn status'</code>
* command), otherwise <span class="javakeyword">false</span>
* @return an <b>SVNStatus</b> object representing status information for
* the item
* @throws SVNException
*/
public SVNStatus doStatus(File path, boolean remote, boolean collectParentExternals) throws SVNException {
final SVNStatus[] result = new SVNStatus[] {null};
final File absPath = path.getAbsoluteFile();
ISVNStatusHandler handler = new ISVNStatusHandler() {
public void handleStatus(SVNStatus status) {
if (absPath.equals(status.getFile())) {
if (result[0] != null && result[0].getContentsStatus() == SVNStatusType.STATUS_EXTERNAL && absPath.isDirectory()) {
result[0] = status;
result[0].markExternal();
} else if (result[0] == null) {
result[0] = status;
}
}
}
};
doStatus(absPath, SVNRevision.HEAD, SVNDepth.EMPTY, remote, true, true, collectParentExternals, handler, null);
return result[0];
}
public void setFilesProvider(ISVNStatusFileProvider filesProvider) {
myFilesProvider = filesProvider;
}
}