/* * ==================================================================== * 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.io.OutputStream; import java.util.Collection; import org.tmatesoft.svn.core.SVNCommitInfo; import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNProperties; import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.SVNPropertyValue; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.wc.SVNFileType; import org.tmatesoft.svn.core.internal.wc.admin.ISVNEntryHandler; import org.tmatesoft.svn.core.internal.wc16.SVNWCClient16; import org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.wc2.*; /** * The <b>SVNWCClient</b> class combines a number of version control operations * mainly intended for local work with Working Copy items. This class includes * those operations that are destined only for local work on a Working Copy as * well as those that are moreover able to access a repository. * <p/> * <p/> * Here's a list of the <b>SVNWCClient</b>'s methods matched against * corresponing commands of the SVN command line client: * <p/> * <table cellpadding="3" cellspacing="1" border="0" width="70%" bgcolor="#999933"> * <tr bgcolor="#ADB8D9" align="left"> * <td><b>SVNKit</b></td> * <td><b>Subversion</b></td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doAdd()</td> * <td>'svn add'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doGetFileContents()</td> * <td>'svn cat'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doDelete()</td> * <td>'svn delete'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doCleanup()</td> * <td>'svn cleanup'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doInfo()</td> * <td>'svn info'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doLock()</td> * <td>'svn lock'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doUnlock()</td> * <td>'svn unlock'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td> * doSetProperty()</td> * <td> *'svn propset PROPNAME PROPVAL PATH'<br /> *'svn propdel PROPNAME PATH'<br /> *'svn propedit PROPNAME PATH'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doSetRevisionProperty()</td> * <td> *'svn propset PROPNAME --revprop -r REV PROPVAL [URL]'<br /> *'svn propdel PROPNAME --revprop -r REV [URL]'<br /> *'svn propedit PROPNAME --revprop -r REV [URL]'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td> * doGetProperty()</td> * <td> *'svn propget PROPNAME PATH'<br /> *'svn proplist PATH'</td> * <tr bgcolor="#EAEAEA" align="left"> * <td>doGetRevisionProperty()</td> * <td> *'svn propget PROPNAME --revprop -r REV [URL]'<br /> *'svn proplist --revprop -r REV [URL]'</td> * </tr> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doResolve()</td> * <td>'svn resolved'</td> * </tr> * <tr bgcolor="#EAEAEA" align="left"> * <td>doRevert()</td> * <td>'svn revert'</td> * </tr> * </table> * * @version 1.3 * @author TMate Software Ltd. * @since 1.2 * @see <a target="_top" href="http://svnkit.com/kb/examples/">Examples</a> */ public class SVNWCClient extends SVNBasicClient { private ISVNAddParameters addParameters; private ISVNCommitHandler commitHandler; private boolean revertMissingDirectories; /** * Default implementation of {@link ISVNAddParameters} which * <code>onInconsistentEOLs(File file)</code> always returns the * {@link ISVNAddParameters#REPORT_ERROR} action. * * @since 1.2 */ public static ISVNAddParameters DEFAULT_ADD_PARAMETERS = new ISVNAddParameters() { public Action onInconsistentEOLs(File file) { return ISVNAddParameters.REPORT_ERROR; } }; /** * Constructs and initializes an <b>SVNWCClient</b> object with the * specified run-time configuration and authentication drivers. * <p/> * <p/> * If <code>options</code> is <span class="javakeyword">null</span>, then * this <b>SVNWCClient</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/> * <p/> * If <code>authManager</code> is <span class="javakeyword">null</span>, * then this <b>SVNWCClient</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 SVNWCClient(ISVNAuthenticationManager authManager, ISVNOptions options) { super(authManager, options); } /** * Constructs and initializes an <b>SVNWCClient</b> object with the * specified run-time configuration and repository pool object. * <p/> * <p/> * If <code>options</code> is <span class="javakeyword">null</span>, then * this <b>SVNWCClient</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/> * <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 SVNWCClient(ISVNRepositoryPool repositoryPool, ISVNOptions options) { super(repositoryPool, options); } public SVNWCClient(SvnOperationFactory of) { super(of); } protected void initDefaults() { setCommitHandler(null); setAddParameters(null); } /** * Sets custom add parameters to this client object. * * @param addParameters * extra parameters for add operations * @since 1.2 */ public void setAddParameters(ISVNAddParameters addParameters) { if (addParameters == null) { addParameters = DEFAULT_ADD_PARAMETERS; } this.addParameters = addParameters; } /** * Returns the specified commit handler (if set) being in use or a default * one (<b>DefaultSVNCommitHandler</b>) if no special implementations of * <b>ISVNCommitHandler</b> were previousely provided. * * @return the commit handler being in use or a default one * @see #setCommitHandler(ISVNCommitHandler) * @see DefaultSVNCommitHandler */ public ISVNCommitHandler getCommitHandler() { return this.commitHandler; } /** * Sets an implementation of <b>ISVNCommitHandler</b> to the commit handler * that will be used during commit operations to handle commit log messages. * The handler will receive a clien's log message and items (represented as * <b>SVNCommitItem</b> objects) that will be committed. Depending on * implementor's aims the initial log message can be modified (or something * else) and returned back. * <p/> * <p/> * If using <b>SVNWCClient</b> without specifying any commit handler then a * default one will be used - {@link DefaultSVNCommitHandler}. * * @param handler * an implementor's handler that will be used to handle commit * log messages * @see #getCommitHandler() * @see ISVNCommitHandler */ public void setCommitHandler(ISVNCommitHandler handler) { if (handler == null) { handler = new DefaultSVNCommitHandler(); } this.commitHandler = handler; } public void setRevertMissingDirectories(boolean revertMissing) { this.revertMissingDirectories = revertMissing; } public boolean isRevertMissingDirectories() { return revertMissingDirectories; } /** * Outputs the content of file identified by <code>path</code> and * <code>revision</code> to the stream <code>dst</code>. The actual node * revision selected is determined by the path as it exists in * <code>pegRevision</code>. If <code>pegRevision</code> is * {@link SVNRevision#UNDEFINED}, then it defaults to * {@link SVNRevision#WORKING}. * * <p/> * If <vode>revision</code> is one of: * <ul> * <li>{@link SVNRevision#BASE} * <li>{@link SVNRevision#WORKING} * <li>{@link SVNRevision#COMMITTED} * </ul> * then the file contents are taken from the working copy file item (no * network connection is needed). Otherwise the file item's contents are * taken from the repository at a particular revision. * * @param path * working copy path * @param pegRevision * revision in which the file item is first looked up * @param revision * target revision * @param expandKeywords * if <span class="javakeyword">true</span> then all keywords * presenting in the file and listed in the file's * {@link org.tmatesoft.svn.core.SVNProperty#KEYWORDS} property * (if set) will be substituted, otherwise not * @param dst * the destination where the file contents will be written to * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> refers to a directory <li><code>path * </code> does not exist <li><code>path</code> is not under * version control * </ul> * @see #doGetFileContents(SVNURL,SVNRevision,SVNRevision,boolean,OutputStream) */ public void doGetFileContents(File path, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst) throws SVNException { SvnCat cat = getOperationsFactory().createCat(); if (revision == SVNRevision.UNDEFINED) { if (pegRevision != null && pegRevision.isValid()) { revision = pegRevision; } else { revision = SVNRevision.BASE; } } cat.setSingleTarget(SvnTarget.fromFile(path, pegRevision)); cat.setRevision(revision); cat.setExpandKeywords(expandKeywords); cat.setOutput(dst); cat.run(); } /** * Outputs the content of file identified by <code>url</code> and * <code>revision</code> to the stream <code>dst</code>. The actual node * revision selected is determined by the path as it exists in * <code>pegRevision</code>. If <code>pegRevision</code> is * {@link SVNRevision#UNDEFINED}, then it defaults to * {@link SVNRevision#HEAD}. * * @param url * a file item's repository location * @param pegRevision * a revision in which the file item is first looked up * @param revision * a target revision * @param expandKeywords * if <span class="javakeyword">true</span> then all keywords * presenting in the file and listed in the file's * {@link org.tmatesoft.svn.core.SVNProperty#KEYWORDS} property * (if set) will be substituted, otherwise not * @param dst * the destination where the file contents will be written to * @throws SVNException * if one of the following is true: * <ul> * <li><code>url</code> refers to a directory * <li>it's impossible to create temporary files ( * {@link java.io.File#createTempFile(java.lang.String,java.lang.String) * createTempFile()} fails) necessary for file translating * </ul> * @see #doGetFileContents(File,SVNRevision,SVNRevision,boolean,OutputStream) */ public void doGetFileContents(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean expandKeywords, OutputStream dst) throws SVNException { SvnCat cat = getOperationsFactory().createCat(); if (revision == SVNRevision.UNDEFINED) { if (pegRevision != null && pegRevision.isValid()) { revision = pegRevision; } else { revision = SVNRevision.HEAD; } } cat.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); cat.setRevision(revision); cat.setExpandKeywords(expandKeywords); cat.setOutput(dst); cat.run(); } /** * Cleans up a working copy. This method is equivalent to a call to * <code>doCleanup(path, false)</code>. * * @param path * a WC path to start a cleanup from * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> does not exist * <li><code>path</code>'s parent directory is not under version * control * </ul> * @see #doCleanup(File, boolean) */ public void doCleanup(File path) throws SVNException { SvnCleanup cleanup = getOperationsFactory().createCleanup(); cleanup.setSingleTarget(SvnTarget.fromFile(path)); cleanup.run(); } /** * Recursively cleans up the working copy, removing locks and resuming * unfinished operations. * * <p/> * If you ever get a "working copy locked" error, use this method to remove * stale locks and get your working copy into a usable state again. * * <p> * This method operates only on working copies and does not open any network * connection. * * @param path * a WC path to start a cleanup from * @param deleteWCProperties * if <span class="javakeyword">true</span>, removes DAV specific * <span class="javastring">"svn:wc:"</span> properties from the * working copy * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> does not exist <li><code>path</code>'s * parent directory is not under version control * </ul> */ public void doCleanup(File path, boolean deleteWCProperties) throws SVNException { SvnCleanup cleanup = getOperationsFactory().createCleanup(); cleanup.setSingleTarget(SvnTarget.fromFile(path)); cleanup.setDeleteWCProperties(deleteWCProperties); cleanup.run(); } /** * Sets <code>propName</code> to <code>propValue</code> on <code>path</code> * . A <code>propValue</code> of <span class="javakeyword">null</span> will * delete the property. * * <p/> * If <code>depth</code> is {@link org.tmatesoft.svn.core.SVNDepth#EMPTY}, * set the property on <code>path</code> only; if {@link SVNDepth#FILES}, * set it on <code>path</code> and its file children (if any); if * {@link SVNDepth#IMMEDIATES}, on <code>path</code> and all of its * immediate children (both files and directories); if * {@link SVNDepth#INFINITY}, on <code>path</code> and everything beneath * it. * * <p/> * If <code>propName</code> is an svn-controlled property (i.e. prefixed * with <span class="javastring">"svn:"</span>), then the caller is * responsible for ensuring that the value uses LF line-endings. * * <p/> * If <code>skipChecks</code> is <span class="javakeyword">true</span>, this * method does no validity checking. But if <code>skipChecks</code> is <span * class="javakeyword">false</span>, and <code>propName</code> is not a * valid property for <code>path</code>, it throws an exception, either with * an error code {@link org.tmatesoft.svn.core.SVNErrorCode#ILLEGAL_TARGET} * (if the property is not appropriate for <code>path</code>), or with * {@link org.tmatesoft.svn.core.SVNErrorCode#BAD_MIME_TYPE} (if * <code>propName</code> is <span class="javastring">"svn:mime-type"</span>, * but <code>propVal</code> is not a valid mime-type). * * <p/> * <code>changeLists</code> is a collection of <code>String</code> * changelist names, used as a restrictive filter on items whose properties * are set; that is, don't set properties on 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. * * <p> * This method operates only on working copies and does not open any network * connection. * * @param path * working copy path * @param propName * property name * @param propValue * property value * @param skipChecks * <span class="javakeyword">true</span> to force the operation * to run without validity checking * @param depth * working copy tree depth to process * @param handler * a caller's property handler * @param changeLists * changelist names * @throws SVNException * <ul> * <li><code>path</code> does not exist <li>exception with * {@link SVNErrorCode#CLIENT_PROPERTY_NAME} error code - if * <code>propName</code> is a revision property name or not a * valid property name or not a regular property name (one * starting with a <span class="javastring">"svn:entry"</span> * or <span class="javastring">"svn:wc"</span> prefix) * </ul> * @see #doSetProperty(SVNURL, String, SVNPropertyValue, SVNRevision, * String, SVNProperties, boolean, ISVNPropertyHandler) * @since 1.2, SVN 1.5 */ public void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean skipChecks, SVNDepth depth, final ISVNPropertyHandler handler, Collection<String> changeLists) throws SVNException { SvnSetProperty ps = getOperationsFactory().createSetProperty(); ps.setPropertyName(propName); ps.setPropertyValue(propValue); ps.setForce(skipChecks); ps.setDepth(depth); ps.setSingleTarget(SvnTarget.fromFile(path)); ps.setApplicalbeChangelists(changeLists); ps.setReceiver(SvnCodec.propertyReceiver(handler)); ps.run(); } /** * Crawls the working copy at <code>path</code> and calls * {@link ISVNPropertyValueProvider#providePropertyValues(java.io.File, org.tmatesoft.svn.core.SVNProperties)} * to get properties to be change on each path being traversed * * <p/> * If <code>depth</code> is {@link org.tmatesoft.svn.core.SVNDepth#EMPTY}, * change the properties on <code>path</code> only; if * {@link SVNDepth#FILES}, change the properties on <code>path</code> and * its file children (if any); if {@link SVNDepth#IMMEDIATES}, on * <code>path</code> and all of its immediate children (both files and * directories); if {@link SVNDepth#INFINITY}, on <code>path</code> and * everything beneath it. * * <p/> * If <code>skipChecks</code> is <span class="javakeyword">true</span>, this * method does no validity checking of changed properties. But if * <code>skipChecks</code> is <span class="javakeyword">false</span>, and * changed property name is not a valid property for <code>path</code>, it * throws an exception, either with an error code * {@link org.tmatesoft.svn.core.SVNErrorCode#ILLEGAL_TARGET} (if the * property is not appropriate for <code>path</code>), or with * {@link org.tmatesoft.svn.core.SVNErrorCode#BAD_MIME_TYPE} (if changed * propery name is <span class="javastring">"svn:mime-type"</span>, but * changed property value is not a valid mime-type). * * <p/> * <code>changeLists</code> is a collection of <code>String</code> * changelist names, used as a restrictive filter on items whose properties * are set; that is, don't set properties on 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. * * <p> * This method operates only on working copies and does not open any network * connection. * * @param path * working copy path * @param propertyValueProvider * changed properties provider * @param skipChecks * <span class="javakeyword">true</span> to force the operation * to run without validity checking * @param depth * working copy tree depth to process * @param handler * a caller's property handler * @param changeLists * changelist names * @throws SVNException * <ul> * <li><code>path</code> does not exist <li>exception with * {@link SVNErrorCode#CLIENT_PROPERTY_NAME} error code - if * changed property name is a revision property name or not a * valid property name or not a regular property name (one * starting with a <span class="javastring">"svn:entry"</span> * or <span class="javastring">"svn:wc"</span> prefix) * </ul> * @see #doSetProperty(java.io.File, String, * org.tmatesoft.svn.core.SVNPropertyValue, boolean, * org.tmatesoft.svn.core.SVNDepth, ISVNPropertyHandler, * java.util.Collection) * @since 1.2, SVN 1.5 */ public void doSetProperty(File path, ISVNPropertyValueProvider propertyValueProvider, boolean skipChecks, SVNDepth depth, ISVNPropertyHandler handler, Collection<String> changeLists) throws SVNException { SvnSetProperty ps = getOperationsFactory().createSetProperty(); ps.setPropertyValueProvider(SvnCodec.propertyValueProvider(propertyValueProvider)); ps.setForce(skipChecks); ps.setDepth(depth); ps.setSingleTarget(SvnTarget.fromFile(path)); ps.setApplicalbeChangelists(changeLists); ps.setReceiver(SvnCodec.propertyReceiver(handler)); ps.run(); } /** * Sets <code>propName</code> to <code>propValue</code> on <code>path</code> * . A <code>propValue</code> of <span class="javakeyword">null</span> will * delete the property. * * <p/> * <code>baseRevision</code> must not be null; in this case, the property * will only be set if it has not changed since <code>baseRevision</code>. * * <p/> * The {@link ISVNAuthenticationManager authentication manager} and * {@link ISVNCommitHandler commit handler}, either provided by a caller or * default ones, will be used to immediately attempt to commit the property * change in the repository. * * <p/> * If <code>propName</code> is an svn-controlled property (i.e. prefixed * with <span class="javastring">"svn:"</span>), then the caller is * responsible for ensuring that the value uses LF line-endings. * * <p/> * If <code>skipChecks</code> is <span class="javakeyword">true</span>, this * method does no validity checking. But if <code>skipChecks</code> is <span * class="javakeyword">false</span>, and <code>propName</code> is not a * valid property for <code>path</code>, it throws an exception, either with * an error code {@link org.tmatesoft.svn.core.SVNErrorCode#ILLEGAL_TARGET} * (if the property is not appropriate for <code>path</code>), or with * {@link org.tmatesoft.svn.core.SVNErrorCode#BAD_MIME_TYPE} (if * <code>propName</code> is <span class="javastring">"svn:mime-type"</span>, * but <code>propVal</code> is not a valid mime-type). * * <p/> * If non-<span class="javakeyword">null</span>, * <code>revisionProperties</code> is an {@link SVNProperties} object * holding additional, custom revision properties (<code>String</code> names * mapped to <code>String</code> values) to be set on the new revision in * the event that this is a committing operation. This table cannot contain * any standard Subversion properties. * * @param url * versioned item url * @param propName * property name * @param propValue * property value * @param baseRevision * revision to change properties against * @param commitMessage * commit log message * @param revisionProperties * custom revision properties to set * @param skipChecks * <span class="javakeyword">true</span> to force the operation * to run without validity checking * @param handler * a caller's property handler * @return commit information if the commit succeeds * @throws SVNException * <ul> * <li><code>url</code> does not exist in <code>baseRevision * </code> <li>exception with * {@link SVNErrorCode#CLIENT_PROPERTY_NAME} error code - if * <code>propName</code> is a revision property name or not a * valid property name or not a regular property name (one * starting with an <span class="javastring">"svn:entry"</span> * or <span class="javastring">"svn:wc"</span> prefix) <li> * exception with {@link SVNErrorCode#UNSUPPORTED_FEATURE} error * code - if <code>propName</code> is either equal to * {@link SVNProperty#EOL_STYLE} or {@link SVNProperty#KEYWORDS} * or {@link SVNProperty#CHARSET} * </ul> * @see #doSetProperty(File, String, SVNPropertyValue, boolean, SVNDepth, * ISVNPropertyHandler, Collection) * @since 1.2, SVN 1.5 */ public SVNCommitInfo doSetProperty(SVNURL url, String propName, SVNPropertyValue propValue, SVNRevision baseRevision, String commitMessage, SVNProperties revisionProperties, boolean skipChecks, final ISVNPropertyHandler handler) throws SVNException { SvnRemoteSetProperty ps = getOperationsFactory().createRemoteSetProperty(); ps.setSingleTarget(SvnTarget.fromURL(url)); ps.setPropertyName(propName); ps.setPropertyValue(propValue); ps.setCommitHandler(SvnCodec.commitHandler(getCommitHandler())); ps.setRevisionProperties(revisionProperties); ps.setCommitMessage(commitMessage); ps.setPropertyReceiver(new ISvnObjectReceiver<SVNPropertyData>() { public void receive(SvnTarget target, SVNPropertyData object) throws SVNException { if (handler != null) { handler.handleProperty(target.getURL(), object); } } }); return ps.run(); } /** * Set <code>propName</code> to <code>propValue</code> on revision * <code>revision</code> in the repository represented by <code>path</code>. * * <p/> * This method simply obtains a url given a working path and calls * {@link #doSetRevisionProperty(SVNURL, SVNRevision, String, SVNPropertyValue, boolean, ISVNPropertyHandler)} * passing this url and the rest parameters. * * @param path * working copy path * @param revision * revision which properties are to be modified * @param propName * property name * @param propValue * property value * @param force * if <span class="javakeyword">true</span> allows newlines in * the author property * @param handler * caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li>exception with {@link SVNErrorCode#CLIENT_PROPERTY_NAME} * error code - if <code>propName</code> is invalid <li> * exceptions thrown by * {@link #doSetRevisionProperty(SVNURL, SVNRevision, String, SVNPropertyValue, boolean, ISVNPropertyHandler)} * </ul> */ public void doSetRevisionProperty(File path, SVNRevision revision, String propName, SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException { SvnSetProperty ps = getOperationsFactory().createSetProperty(); ps.setRevisionProperty(true); ps.setSingleTarget(SvnTarget.fromFile(path)); ps.setRevision(revision); ps.setPropertyName(propName); ps.setPropertyValue(propValue); ps.setForce(force); SVNPropertyData propertyData = ps.run(); if (handler != null) { handler.handleProperty(revision != null ? revision.getNumber() : -1, propertyData); } } /** * Set <code>propName</code> to <code>propValue</code> on revision * <code>revision</code> in the repository represented by <code>path</code>. * * A <code>propValue</code> of <span class="javakeyword">null</span> will * delete the property. The {@link ISVNAuthenticationManager authentication * manager}, either provided by a caller or a default one, will be used for * authentication. * * <p/> * If <code>propName</code> is an svn-controlled property (i.e. prefixed * with <span class="javastring">"svn:"</span>), then the caller is * responsible for ensuring that the value is UTF8-encoded and uses LF * line-endings. * * <p/> * Although this routine accepts a working copy path it doesn't affect the * working copy at all; it's a pure network operation that changes an * *unversioned* property attached to a revision. This can be used to tweak * log messages, dates, authors, and the like. Be careful: it's a lossy * operation. * * <p> * Also note that unless the administrator creates a pre-revprop-change hook * in the repository, this feature will fail. * * @param url * repository URL * @param revision * revision which properties are to be modified * @param propName * property name * @param propValue * property value * @param force * if <span class="javakeyword">true</span> allows newlines in * the author property * @param handler * caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li>the operation can not be performed without forcing <li> * <code>propName</code> is either invalid or not a regular * property name (one starting with an <span * class="javastring">"svn:entry"</span> or <span * class="javastring">"svn:wc"</span> prefix) * </ul> * @see #doSetRevisionProperty(File, SVNRevision, String, SVNPropertyValue, * boolean, ISVNPropertyHandler) */ public void doSetRevisionProperty(SVNURL url, SVNRevision revision, String propName, SVNPropertyValue propValue, boolean force, ISVNPropertyHandler handler) throws SVNException { SvnSetProperty ps = getOperationsFactory().createSetProperty(); ps.setRevisionProperty(true); ps.setSingleTarget(SvnTarget.fromURL(url)); ps.setRevision(revision); ps.setPropertyName(propName); ps.setPropertyValue(propValue); ps.setForce(force); SVNPropertyData propertyData = ps.run(); if (handler != null) { handler.handleProperty(revision != null ? revision.getNumber() : -1, propertyData); } } /** * Gets the value of the property <code>propName</code> for * <code>path</code>. This method simply creates an implementation of * {@link ISVNPropertyHandler} which stores the value only for * <code>path</code> which is then used in the following call to * * <code>doGetProperty(path, propName, pegRevision, revision, SVNDepth.EMPTY, handler, null)</code> * . * * @param path * a WC item's path * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved but only the first of them returned * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision; * @return the item's property * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * <li><code>path</code> is not under version control * </ul> * @see #doGetProperty(File, String, SVNRevision, SVNRevision, SVNDepth, * ISVNPropertyHandler, Collection) */ public SVNPropertyData doGetProperty(final File path, final String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException { final SVNPropertyData[] data = new SVNPropertyData[1]; SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromFile(path, pegRevision)); getProperties.setRevision(revision); getProperties.setDepth(SVNDepth.EMPTY); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName != null && object.containsName(propName)) { data[0] = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); } } }); getProperties.run(); return data[0]; } /** * Gets the value of the property <code>propName</code> for <code>url</code> * . This method simply creates an implementation of * {@link ISVNPropertyHandler} which stores the value only for * <code>path</code> which is then used in the following call to * <code>doGetProperty(url, propName, pegRevision, revision, SVNDepth.EMPTY, handler)</code> * . * * @param url * an item's repository location * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved but only the first of them returned * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision; * @return the item's property * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * <li><code>path</code> is not under version control * </ul> * @see #doGetProperty(SVNURL, String, SVNRevision, SVNRevision, SVNDepth, * ISVNPropertyHandler) */ public SVNPropertyData doGetProperty(final SVNURL url, final String propName, SVNRevision pegRevision, SVNRevision revision) throws SVNException { final SVNPropertyData[] data = new SVNPropertyData[1]; SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); getProperties.setRevision(revision); getProperties.setDepth(SVNDepth.EMPTY); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName != null && object.containsName(propName)) { data[0] = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); } } }); getProperties.run(); return data[0]; } /** * Gets an item's versioned property and passes it to a provided property * handler. It's possible to get either a local property (from a Working * Copy) or a remote one (located in a repository). If <vode>revision</code> * is one of: * <ul> * <li>{@link SVNRevision#BASE BASE} * <li>{@link SVNRevision#WORKING WORKING} * <li>{@link SVNRevision#COMMITTED COMMITTED} * </ul> * then the result is a WC item's property. Otherwise the property is taken * from a repository (using the item's URL). * * @param path * a WC item's path * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved and passed to <code>handler</code> for * processing * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision; * @param recursive * <span class="javakeyword">true</span> to descend recursively * @param handler * a caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * <li><code>path</code> is not under version control * </ul> * @deprecated use * {@link #doGetProperty(File, String, SVNRevision, SVNRevision, SVNDepth, ISVNPropertyHandler, Collection)} * instead */ public void doGetProperty(File path, String propName, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNPropertyHandler handler) throws SVNException { doGetProperty(path, propName, pegRevision, revision, SVNDepth.getInfinityOrEmptyDepth(recursive), handler, null); } /** * Invokes <code>handler</code> on paths covered by <code>depth</code> * starting with the specified <code>path</code>. * * <p/> * If both <vode>revision</code> and <code>pegRevision</code> are ones of: * <ul> * <li>{@link SVNRevision#BASE BASE} * <li>{@link SVNRevision#WORKING WORKING} * <li>{@link SVNRevision#COMMITTED COMMITTED} * <li>{@link SVNRevision#UNDEFINED} * </ul> * then this method gets properties from the working copy without connecting * to the repository. Otherwise properties are taken from the repository * (using the item's URL). * * <p/> * The actual node revision selected is determined by the path as it exists * in <code>pegRevision</code>. If <code>pegRevision</code> is * {@link SVNRevision#UNDEFINED}, then it defaults to * {@link SVNRevision#WORKING}. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, fetch the property from * <code>path</code> only; if {@link SVNDepth#FILES}, fetch from * <code>path</code> and its file children (if any); if * {@link SVNDepth#IMMEDIATES}, from <code>path</code> and all of its * immediate children (both files and directories); if * {@link SVNDepth#INFINITY}, from <code>path</code> and everything beneath * it. * * <p/> * <code>changeLists</code> is a collection of <code>String</tt> changelist * names, used as a restrictive filter on items whose properties are * set; that is, don't set properties on 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 * a WC item's path * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved and passed to <code>handler</code> for * processing * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision * @param depth * tree depth * @param handler * a caller's property handler * @param changeLists * collection of changelist names * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX} * prefix <li><code>path</code> is not under version control * </ul> * @since 1.2, SVN 1.5 */ public void doGetProperty(File path, final String propName, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, final ISVNPropertyHandler handler, Collection<String> changeLists) throws SVNException { SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromFile(path, pegRevision)); getProperties.setRevision(revision); getProperties.setDepth(depth); getProperties.setApplicalbeChangelists(changeLists); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName != null && object.containsName(propName)) { SVNPropertyData propertyData = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); if (target.isFile()) { handler.handleProperty(target.getFile(), propertyData); } else { handler.handleProperty(target.getURL(), propertyData); } } else if (propName == null) { for (Object propertyName : object.nameSet()) { String name = propertyName.toString(); SVNPropertyData propertyData = new SVNPropertyData(name, object.getSVNPropertyValue(name), getOptions()); if (target.isFile()) { handler.handleProperty(target.getFile(), propertyData); } else { handler.handleProperty(target.getURL(), propertyData); } } } } }); getProperties.run(); } /** * Gets an item's versioned property from a repository and passes it to a * provided property handler. This method is useful when having no Working * Copy at all. * * @param url * an item's repository location * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved and passed to <code>handler</code> for * processing * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision * @param recursive * <span class="javakeyword">true</span> to descend recursively * @param handler * a caller's property handler * @throws SVNException * if <code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * @deprecated use * {@link #doGetProperty(SVNURL, String, SVNRevision, SVNRevision, SVNDepth, ISVNPropertyHandler)} * instead */ public void doGetProperty(SVNURL url, String propName, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNPropertyHandler handler) throws SVNException { doGetProperty(url, propName, pegRevision, revision, SVNDepth.getInfinityOrEmptyDepth(recursive), handler); } /** * Invokes <code>handler</code> on paths covered by <code>depth</code> * starting with the specified <code>path</code>. * * <p/> * If <code></code> is {@link SVNRevision#UNDEFINED} then get properties * from the repository head. Else get the properties as of * <code>revision</code>. The actual node revision selected is determined by * the path as it exists in <code>pegRevision</code>. If * <code>pegRevision</code> is {@link SVNRevision#UNDEFINED}, then it * defaults to {@link SVNRevision#HEAD}. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, fetch the property from * <code>path</code> only; if {@link SVNDepth#FILES}, fetch from * <code>path</code> and its file children (if any); if * {@link SVNDepth#IMMEDIATES}, from <code>path</code> and all of its * immediate children (both files and directories); if * {@link SVNDepth#INFINITY}, from <code>path</code> and everything beneath * it. * * @param url * versioned item url * @param propName * an item's property name; if it's <span * class="javakeyword">null</span> then all the item's properties * will be retrieved and passed to <code>handler</code> for * processing * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision * @param depth * tree depth * @param handler * a caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX} * prefix <li><code>path</code> is not under version control * </ul> * @since 1.2, SVN 1.5 */ public void doGetProperty(SVNURL url, final String propName, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, final ISVNPropertyHandler handler) throws SVNException { SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); getProperties.setRevision(revision); getProperties.setDepth(depth); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName != null && object.containsName(propName)) { SVNPropertyData propertyData = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); handler.handleProperty(target.getURL(), propertyData); } else if (propName == null) { for (Object propertyName : object.nameSet()) { String name = propertyName.toString(); SVNPropertyData propertyData = new SVNPropertyData(name, object.getSVNPropertyValue(name), getOptions()); handler.handleProperty(target.getURL(), propertyData); } } } }); getProperties.run(); } /** * Gets an unversioned revision property from a repository (getting a * repository URL from a Working Copy) and passes it to a provided property * handler. * * @param path * a local Working Copy item which repository location is used to * connect to a repository * @param propName * a revision property name; if this parameter is <span * class="javakeyword">null</span> then all the revision * properties will be retrieved and passed to * <code>handler</code> for processing * @param revision * a revision which property is to be retrieved * @param handler * a caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>revision</code> is invalid * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * </ul> * @see #doGetRevisionProperty(SVNURL,String,SVNRevision,ISVNPropertyHandler) */ public long doGetRevisionProperty(File path, final String propName, final SVNRevision revision, final ISVNPropertyHandler handler) throws SVNException { final SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromFile(path)); getProperties.setRevisionProperties(true); getProperties.setRevision(revision); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName == null) { for (String name : object.nameSet()) { SVNPropertyData pdata = new SVNPropertyData(name, object.getSVNPropertyValue(name), getOptions()); if (handler != null) { handler.handleProperty(getProperties.getRevisionNumber(), pdata); } } } else if (propName != null && object.containsName(propName)) { SVNPropertyData pdata = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); if (handler != null) { handler.handleProperty(getProperties.getRevisionNumber(), pdata); } } } }); getProperties.run(); return getProperties.getRevisionNumber(); } /** * Gets an unversioned revision property from a repository and passes it to * a provided property handler. * * @param url * a URL pointing to a repository location which revision * property is to be got * @param propName * a revision property name; if this parameter is <span * class="javakeyword">null</span> then all the revision * properties will be retrieved and passed to * <code>handler</code> for processing * @param revision * a revision which property is to be retrieved * @param handler * a caller's property handler * @return actual revision number to which <code>revision</code> is resolved * @throws SVNException * if one of the following is true: * <ul> * <li><code>revision</code> is invalid * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * </ul> * @see #doGetRevisionProperty(File,String,SVNRevision,ISVNPropertyHandler) */ public long doGetRevisionProperty(SVNURL url, final String propName, final SVNRevision revision, final ISVNPropertyHandler handler) throws SVNException { final SvnGetProperties getProperties = getOperationsFactory().createGetProperties(); getProperties.setSingleTarget(SvnTarget.fromURL(url)); getProperties.setRevisionProperties(true); getProperties.setRevision(revision); getProperties.setReceiver(new ISvnObjectReceiver<SVNProperties>() { public void receive(SvnTarget target, SVNProperties object) throws SVNException { if (propName == null) { for (String name : object.nameSet()) { SVNPropertyData pdata = new SVNPropertyData(name, object.getSVNPropertyValue(name), getOptions()); if (handler != null) { handler.handleProperty(getProperties.getRevisionNumber(), pdata); } } } else if (propName != null && object.containsName(propName)) { SVNPropertyData pdata = new SVNPropertyData(propName, object.getSVNPropertyValue(propName), getOptions()); if (handler != null) { handler.handleProperty(getProperties.getRevisionNumber(), pdata); } } } }); getProperties.run(); return getProperties.getRevisionNumber(); } /** * Schedules a Working Copy item for deletion. This method is equivalent to * <code>doDelete(path, force, true, dryRun)</code>. * * @param path * a WC item to be deleted * @param force * <span class="javakeyword">true</span> to force the operation * to run * @param dryRun * <span class="javakeyword">true</span> only to try the delete * operation without actual deleting * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control * <li>can not delete <code>path</code> without forcing * </ul> * @see #doDelete(File,boolean,boolean,boolean) */ public void doDelete(File path, boolean force, boolean dryRun) throws SVNException { doDelete(path, force, true, dryRun); } /** * Schedules a Working Copy item for deletion. This method allows to choose * - whether file item(s) are to be deleted from the filesystem or not. * Another version of the {@link #doDelete(File,boolean,boolean) doDelete()} * method is similar to the corresponding SVN client's command - <code>'svn delete'</code> as * it always deletes files from the filesystem. * * <p/> * This method deletes only local working copy paths without connecting to * the repository. * * @param path * a WC item to be deleted * @param force * <span class="javakeyword">true</span> to force the operation * to run * @param deleteFiles * if <span class="javakeyword">true</span> then files will be * scheduled for deletion as well as deleted from the filesystem, * otherwise files will be only scheduled for deletion and still * be present in the filesystem * @param dryRun * <span class="javakeyword">true</span> only to try the delete * operation without actual deleting * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control <li>can * not delete <code>path</code> without forcing * </ul> */ public void doDelete(File path, boolean force, boolean deleteFiles, boolean dryRun) throws SVNException { SvnScheduleForRemoval remove = getOperationsFactory().createScheduleForRemoval(); remove.setSingleTarget(SvnTarget.fromFile(path)); remove.setForce(force); remove.setDeleteFiles(deleteFiles); remove.setDryRun(dryRun); remove.run(); } /** * Schedules an unversioned item for addition to a repository thus putting * it under version control. * <p/> * <p/> * To create and add to version control a new directory, set * <code>mkdir</code> to <span class="javakeyword">true</span>. * <p/> * <p/> * Calling this method is equivalent to * <code>doAdd(path, force, mkdir, climbUnversionedParents, recursive, false)</code>. * * @param path * a path to be put under version control (will be added to a * repository in next commit) * @param force * when <span class="javakeyword">true</span> forces the * operation to run on already versioned files or directories * without reporting error. When ran recursively, all unversioned * files and directories in a tree will be scheduled for * addition. * @param mkdir * if <span class="javakeyword">true</span> - creates a new * directory and schedules it for addition * @param climbUnversionedParents * if <span class="javakeyword">true</span> and <code>path</code> * is located in an unversioned parent directory then the parent * will be automatically scheduled for addition, too * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> doesn't belong to a Working Copy <li> * <code>path</code> doesn't exist and <code>mkdir</code> is * <span class="javakeyword">false</span> <li><code>path</code> * is the root directory of the Working Copy * @deprecated use * {@link #doAdd(File, boolean, boolean, boolean, SVNDepth, boolean, boolean)} * instead */ public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive) throws SVNException { File[] paths = new File[] {path}; doAdd(paths, force, mkdir, climbUnversionedParents, SVNDepth.fromRecurse(recursive), false, false, climbUnversionedParents); } /** * Schedules an unversioned item for addition to a repository thus putting * it under version control. * <p/> * <p/> * To create and add to version control a new directory, set * <code>mkdir</code> to <span class="javakeyword">true</span>. * * @param path * a path to be put under version control (will be added to a * repository in next commit) * @param force * when <span class="javakeyword">true</span> forces the * operation to run on already versioned files or directories * without reporting error. When ran recursively, all unversioned * files and directories in a tree will be scheduled for * addition. * @param mkdir * if <span class="javakeyword">true</span> - creates a new * directory and schedules it for addition * @param climbUnversionedParents * if <span class="javakeyword">true</span> and <code>path</code> * is located in an unversioned parent directory then the parent * will be automatically scheduled for addition, too * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @param includeIgnored * controls whether ignored items must be also added * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> doesn't belong to a Working Copy <li> * <code>path</code> doesn't exist and <code>mkdir</code> is * <span class="javakeyword">false</span> <li><code>path</code> * is the root directory of the Working Copy * </ul> * @since 1.1 * @deprecated use * {@link #doAdd(File, boolean, boolean, boolean, SVNDepth, boolean, boolean)} * instead */ public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, boolean recursive, boolean includeIgnored) throws SVNException { File[] paths = new File[] {path}; doAdd(paths, force, mkdir, climbUnversionedParents, SVNDepth.fromRecurse(recursive), false, includeIgnored, climbUnversionedParents); } /** * Schedules a working copy <code>path</code> for addition to the * repository. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, adds just * <code>path</code> and nothing below it. If {@link SVNDepth#FILES}, adds * <code>path</code> and any file children of <code>path</code>. If * {@link SVNDepth#IMMEDIATES}, adds <code>path</code>, any file children, * and any immediate subdirectories (but nothing underneath those * subdirectories). If {@link SVNDepth#INFINITY}, adds <code>path</code> and * everything under it fully recursively. * * <p/> * <code>path</code>'s parent must be under revision control already (unless * <code>makeParents</code> is <span class="javakeyword">true</span>), but * <code>path</code> is not. * * <p/> * If <code>force</code> is set, <code>path</code> is a directory, * <code>depth</code> is {@link SVNDepth#INFINITY}, then schedules for * addition unversioned files and directories scattered deep within a * versioned tree. * * <p/> * If <code>includeIgnored</code> is <span class="javakeyword">false</span>, * doesn't add files or directories that match ignore patterns. * * <p/> * If <code>makeParents</code> is <span class="javakeyword">true</span>, * recurse up <code>path</code>'s directory and look for a versioned * directory. If found, add all intermediate paths between it and * <code>path</code>. * * <p/> * Important: this is a *scheduling* operation. No changes will happen to * the repository until a commit occurs. This scheduling can be removed with * a call to {@link #doRevert(File[], SVNDepth, Collection)}. * * @param path * working copy path * @param force * if <span class="javakeyword">true</span>, this method does not * throw exceptions on already-versioned items * @param mkdir * if <span class="javakeyword">true</span>, create a directory * also at <code>path</code> * @param climbUnversionedParents * not used; make use of <code>makeParents</code> instead * @param depth * tree depth * @param includeIgnored * if <span class="javakeyword">true</span>, does not apply * ignore patterns to paths being added * @param makeParents * if <span class="javakeyword">true</span>, climb upper and * schedule also all unversioned paths in the way * @throws SVNException * <ul> * <li/>exception with {@link SVNErrorCode#ENTRY_EXISTS} error * code - if <code>force</code> is not set and <code>path</code> * is already under version <li/>exception with * {@link SVNErrorCode#CLIENT_NO_VERSIONED_PARENT} error code - * if <code>makeParents</code> is <span * class="javakeyword">true</span> but no unversioned paths * stepping upper from <code>path</code> are found * @since 1.2, SVN 1.5 */ public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, SVNDepth depth, boolean includeIgnored, boolean makeParents) throws SVNException { File[] paths = new File[] {path}; doAdd(paths, force, mkdir, climbUnversionedParents, depth, false, includeIgnored, makeParents); } /** * Schedules working copy <code>paths</code> for addition to the repository. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, adds just * <code>paths</code> and nothing below it. If {@link SVNDepth#FILES}, adds * <code>paths</code> and any file children of <code>paths</code>. If * {@link SVNDepth#IMMEDIATES}, adds <code>paths</code>, any file children, * and any immediate subdirectories (but nothing underneath those * subdirectories). If {@link SVNDepth#INFINITY}, adds <code>paths</code> * and everything under it fully recursively. * * <p/> * <code>paths</code>' parent must be under revision control already (unless * <code>makeParents</code> is <span class="javakeyword">true</span>), but * <code>paths</code> are not. * * <p/> * If <code>force</code> is set, path is a directory, <code>depth</code> is * {@link SVNDepth#INFINITY}, then schedules for addition unversioned files * and directories scattered deep within a versioned tree. * * <p/> * If <code>includeIgnored</code> is <span class="javakeyword">false</span>, * doesn't add files or directories that match ignore patterns. * * <p/> * If <code>makeParents</code> is <span class="javakeyword">true</span>, * recurse up path's directory and look for a versioned directory. If found, * add all intermediate paths between it and the path. * * <p/> * Important: this is a *scheduling* operation. No changes will happen to * the repository until a commit occurs. This scheduling can be removed with * a call to {@link #doRevert(File[], SVNDepth, Collection)}. * * @param paths * working copy paths to add * @param force * if <span class="javakeyword">true</span>, this method does not * throw exceptions on already-versioned items * @param mkdir * if <span class="javakeyword">true</span>, create a directory * also at <code>path</code> * @param climbUnversionedParents * not used; make use of <code>makeParents</code> instead * @param depth * tree depth * @param depthIsSticky * if depth should be recorded to the working copy * @param includeIgnored * if <span class="javakeyword">true</span>, does not apply * ignore patterns to paths being added * @param makeParents * if <span class="javakeyword">true</span>, climb upper and * schedule also all unversioned paths in the way * @throws SVNException * <ul> * <li/>exception with {@link SVNErrorCode#ENTRY_EXISTS} error * code - if <code>force</code> is not set and a path is already * under version <li/>exception with * {@link SVNErrorCode#CLIENT_NO_VERSIONED_PARENT} error code - * if <code>makeParents</code> is <span * class="javakeyword">true</span> but no unversioned paths * stepping upper from a path are found * @since 1.3 */ public void doAdd(File[] paths, boolean force, boolean mkdir, boolean climbUnversionedParents, SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException { doAdd(paths, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents, true); } /** * Schedules working copy <code>paths</code> for addition to the repository. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, adds just * <code>paths</code> and nothing below it. If {@link SVNDepth#FILES}, adds * <code>paths</code> and any file children of <code>paths</code>. If * {@link SVNDepth#IMMEDIATES}, adds <code>paths</code>, any file children, * and any immediate subdirectories (but nothing underneath those * subdirectories). If {@link SVNDepth#INFINITY}, adds <code>paths</code> * and everything under it fully recursively. * * <p/> * <code>paths</code>' parent must be under revision control already (unless * <code>makeParents</code> is <span class="javakeyword">true</span>), but * <code>paths</code> are not. * * <p/> * If <code>force</code> is set, path is a directory, <code>depth</code> is * {@link SVNDepth#INFINITY}, then schedules for addition unversioned files * and directories scattered deep within a versioned tree. * * <p/> * If <code>includeIgnored</code> is <span class="javakeyword">false</span>, * doesn't add files or directories that match ignore patterns. * * <p/> * If <code>makeParents</code> is <span class="javakeyword">true</span>, * recurse up path's directory and look for a versioned directory. If found, * add all intermediate paths between it and the path. * * <p/> * Important: this is a *scheduling* operation. No changes will happen to * the repository until a commit occurs. This scheduling can be removed with * a call to {@link #doRevert(File[], SVNDepth, Collection)}. * * @param paths * working copy paths to add * @param force * if <span class="javakeyword">true</span>, this method does not * throw exceptions on already-versioned items * @param mkdir * if <span class="javakeyword">true</span>, create a directory * also at <code>path</code> * @param climbUnversionedParents * not used; make use of <code>makeParents</code> instead * @param depth * tree depth * @param depthIsSticky * if depth should be recorded to the working copy * @param includeIgnored * if <span class="javakeyword">true</span>, does not apply * ignore patterns to paths being added * @param makeParents * if <span class="javakeyword">true</span>, climb upper and * schedule also all unversioned paths in the way * @param applyAutoProperties * if <span class="javakeyword">true</span>, applies auto-properties on file addition * otherwise auto-properties application is disabled * @throws SVNException * <ul> * <li/>exception with {@link SVNErrorCode#ENTRY_EXISTS} error * code - if <code>force</code> is not set and a path is already * under version <li/>exception with * {@link SVNErrorCode#CLIENT_NO_VERSIONED_PARENT} error code - * if <code>makeParents</code> is <span * class="javakeyword">true</span> but no unversioned paths * stepping upper from a path are found * @since 1.8 */ public void doAdd(File[] paths, boolean force, boolean mkdir, boolean climbUnversionedParents, SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents, boolean applyAutoProperties) throws SVNException { SvnScheduleForAddition add = getOperationsFactory().createScheduleForAddition(); for (int i = 0; i < paths.length; i++) { add.addTarget(SvnTarget.fromFile(paths[i])); } add.setMkDir(mkdir); add.setForce(force); add.setDepth(depth); add.setDepth(depth); add.setIncludeIgnored(includeIgnored); add.setAddParents(makeParents); add.setAddParameters(SvnCodec.addParameters(addParameters)); add.setApplyAutoProperties(applyAutoProperties); add.run(); } /** * Schedules a working copy <code>path</code> for addition to the * repository. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, adds just * <code>path</code> and nothing below it. If {@link SVNDepth#FILES}, adds * <code>path</code> and any file children of <code>path</code>. If * {@link SVNDepth#IMMEDIATES}, adds <code>path</code>, any file children, * and any immediate subdirectories (but nothing underneath those * subdirectories). If {@link SVNDepth#INFINITY}, adds <code>path</code> and * everything under it fully recursively. * * <p/> * <code>path</code>'s parent must be under revision control already (unless * <code>makeParents</code> is <span class="javakeyword">true</span>), but * <code>path</code> is not. * * <p/> * If <code>force</code> is set, <code>path</code> is a directory, * <code>depth</code> is {@link SVNDepth#INFINITY}, then schedules for * addition unversioned files and directories scattered deep within a * versioned tree. * * <p/> * If <code>includeIgnored</code> is <span class="javakeyword">false</span>, * doesn't add files or directories that match ignore patterns. * * <p/> * If <code>makeParents</code> is <span class="javakeyword">true</span>, * recurse up <code>path</code>'s directory and look for a versioned * directory. If found, add all intermediate paths between it and * <code>path</code>. * * <p/> * Important: this is a *scheduling* operation. No changes will happen to * the repository until a commit occurs. This scheduling can be removed with * a call to {@link #doRevert(File[], SVNDepth, Collection)}. * * @param path * working copy path * @param force * if <span class="javakeyword">true</span>, this method does not * throw exceptions on already-versioned items * @param mkdir * if <span class="javakeyword">true</span>, create a directory * also at <code>path</code> * @param climbUnversionedParents * not used; make use of <code>makeParents</code> instead * @param depth * tree depth * @param depthIsSticky * if depth should be recorded to the working copy * @param includeIgnored * if <span class="javakeyword">true</span>, does not apply * ignore patterns to paths being added * @param makeParents * if <span class="javakeyword">true</span>, climb upper and * schedule also all unversioned paths in the way * @throws SVNException * <ul> * <li/>exception with {@link SVNErrorCode#ENTRY_EXISTS} error * code - if <code>force</code> is not set and <code>path</code> * is already under version <li/>exception with * {@link SVNErrorCode#CLIENT_NO_VERSIONED_PARENT} error code - * if <code>makeParents</code> is <span * class="javakeyword">true</span> but no unversioned paths * stepping upper from <code>path</code> are found * @since 1.3 */ public void doAdd(File path, boolean force, boolean mkdir, boolean climbUnversionedParents, SVNDepth depth, boolean depthIsSticky, boolean includeIgnored, boolean makeParents) throws SVNException { File[] paths = new File[] {path}; doAdd(paths, force, mkdir, climbUnversionedParents, depth, depthIsSticky, includeIgnored, makeParents); } /** * Schedules <code>path</code> as being replaced. This method does not * perform any deletion\addition in the filesysem nor does it require a * connection to the repository. It just marks the current <code>path</code> * item as being replaced. * * @param path * working copy path to mark as * @throws SVNException * @since 1.2 */ public void doMarkReplaced(File path) throws SVNException { SvnMarkReplaced mr = getOperationsFactory().createMarkReplaced(); mr.setSingleTarget(SvnTarget.fromFile(path)); mr.run(); } /** * Reverts all local changes made to a Working Copy item(s) thus bringing it * to a 'pristine' state. * * @param path * a WC path to perform a revert on * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control * <li>when trying to revert an addition of a directory from * within the directory itself * </ul> * @see #doRevert(File[],boolean) * @deprecated use {@link #doRevert(File[], SVNDepth, Collection)} */ public void doRevert(File path, boolean recursive) throws SVNException { doRevert(new File[] {path}, SVNDepth.fromRecurse(recursive), null); } /** * Reverts all local changes made to a Working Copy item(s) thus bringing it * to a 'pristine' state. * * @param paths * a WC paths to perform a revert on * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control * <li>when trying to revert an addition of a directory from * within the directory itself * </ul> * <p/> * Exception will not be thrown if there are multiple paths * passed. Instead caller should process events received by * <code>ISVNEventHandler</code> instance to get information on * whether certain path was reverted or not. * @deprecated use {@link #doRevert(File[], SVNDepth, Collection)} instead */ public void doRevert(File[] paths, boolean recursive) throws SVNException { doRevert(paths, SVNDepth.fromRecurse(recursive), null); } /** * Restores the pristine version of working copy <code>paths</code>, * effectively undoing any local mods. For each path in <code>paths</code>, * reverts it if it is a file. Else if it is a directory, reverts according * to <code>depth</code>: * * <p/> * If </code>depth</code> is {@link SVNDepth#EMPTY}, reverts just the * properties on the directory; else if {@link SVNDepth#FILES}, reverts the * properties and any files immediately under the directory; else if * {@link SVNDepth#IMMEDIATES}, reverts all of the preceding plus properties * on immediate subdirectories; else if {@link SVNDepth#INFINITY}, reverts * path and everything under it fully recursively. * * <p/> * <code>changeLists</code> is a collection of <code>String</code> * changelist names, used as a restrictive filter on items reverted; that * is, doesn't revert 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. * * <p/> * If an item specified for reversion is not under version control, then * does not fail with an exception, just invokes {@link ISVNEventHandler} * using notification code {@link SVNEventAction#SKIP}. * * @param paths * working copy paths to revert * @param depth * tree depth * @param changeLists * collection with changelist names * @throws SVNException * @since 1.2, SVN 1.5 */ public void doRevert(File[] paths, SVNDepth depth, Collection<String> changeLists) throws SVNException { SvnRevert revert = getOperationsFactory().createRevert(); for (int i = 0; i < paths.length; i++) { revert.addTarget(SvnTarget.fromFile(paths[i])); } revert.setDepth(depth); revert.setApplicalbeChangelists(changeLists); revert.setRevertMissingDirectories(revertMissingDirectories); revert.run(); } /** * Resolves a 'conflicted' state on a Working Copy item. * * @param path * a WC item to be resolved * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) - this will resolve the entire tree * @throws SVNException * if <code>path</code> is not under version control * @deprecated use {@link #doResolve(File, SVNDepth, SVNConflictChoice)} * instead */ public void doResolve(File path, boolean recursive) throws SVNException { doResolve(path, SVNDepth.fromRecurse(recursive), SVNConflictChoice.MINE_FULL); } /** * Performs automatic conflict resolution on a working copy * <code>path</code>. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, acts only on * <code>path</code>; if {@link SVNDepth#FILES}, resolves <code>path</code> * and its conflicted file children (if any); if {@link SVNDepth#IMMEDIATES} * , resolves <code>path</code> and all its immediate conflicted children * (both files and directories, if any); if {@link SVNDepth#INFINITY}, * resolves <code>path</code> and every conflicted file or directory * anywhere beneath it. * * <p/> * If <code>conflictChoice</code> is {@link SVNConflictChoice#BASE}, * resolves the conflict with the old file contents; if * {@link SVNConflictChoice#MINE_FULL}, uses the original working contents; * if {@link SVNConflictChoice#THEIRS_FULL}, the new contents; and if * {@link SVNConflictChoice#MERGED}, doesn't change the contents at all, * just removes the conflict status, which is the pre-1.2 (pre-SVN 1.5) * behavior. * * <p/> * {@link SVNConflictChoice#THEIRS_CONFLICT} and * {@link SVNConflictChoice#MINE_CONFLICT} are not legal for binary files or * properties. * * <p/> * If <code>path</code> is not in a state of conflict to begin with, does * nothing. If <code>path</code>'s conflict state is removed and caller's * {@link ISVNEntryHandler} is not <span class="javakeyword">null</span>, * then an {@link SVNEventAction#RESOLVED} event is dispatched to the * handler. * * <p/> * This is equivalent to calling * <code>doResolve(path, depth, true, true, conflictChoice)</code>. * * @param path * working copy path * @param depth * tree depth * @param conflictChoice * choice object for making decision while resolving * @throws SVNException * @since 1.2, SVN 1.5 */ public void doResolve(File path, SVNDepth depth, SVNConflictChoice conflictChoice) throws SVNException { SvnResolve resolve = getOperationsFactory().createResolve(); resolve.addTarget(SvnTarget.fromFile(path)); resolve.setDepth(depth); resolve.setConflictChoice(conflictChoice); resolve.run(); } /** * Performs automatic conflict resolution on a working copy * <code>path</code>. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, acts only on * <code>path</code>; if {@link SVNDepth#FILES}, resolves <code>path</code> * and its conflicted file children (if any); if {@link SVNDepth#IMMEDIATES} * , resolves <code>path</code> and all its immediate conflicted children * (both files and directories, if any); if {@link SVNDepth#INFINITY}, * resolves <code>path</code> and every conflicted file or directory * anywhere beneath it. * * <p/> * If <code>conflictChoice</code> is {@link SVNConflictChoice#BASE}, * resolves the conflict with the old file contents; if * {@link SVNConflictChoice#MINE_FULL}, uses the original working contents; * if {@link SVNConflictChoice#THEIRS_FULL}, the new contents; and if * {@link SVNConflictChoice#MERGED}, doesn't change the contents at all, * just removes the conflict status, which is the pre-1.2 (pre-SVN 1.5) * behavior. * * <p/> * {@link SVNConflictChoice#THEIRS_CONFLICT} and * {@link SVNConflictChoice#MINE_CONFLICT} are not legal for binary files or * properties. * * <p/> * If <code>path</code> is not in a state of conflict to begin with, does * nothing. If <code>path</code>'s conflict state is removed and caller's * {@link ISVNEntryHandler} is not <span class="javakeyword">null</span>, * then an {@link SVNEventAction#RESOLVED} event is dispatched to the * handler. * * @param path * working copy path * @param depth * tree depth * @param resolveContents * resolve content conflict * @param resolveProperties * resolve property conflict * @param conflictChoice * choice object for making decision while resolving * @throws SVNException * @since 1.2, SVN 1.5 */ public void doResolve(File path, SVNDepth depth, final boolean resolveContents, final boolean resolveProperties, SVNConflictChoice conflictChoice) throws SVNException { SvnResolve resolve = getOperationsFactory().createResolve(); resolve.addTarget(SvnTarget.fromFile(path)); resolve.setDepth(depth); resolve.setResolveContents(resolveContents); resolve.setResolveProperties(resolveProperties); resolve.setConflictChoice(conflictChoice); resolve.run(); } /** * Performs automatic conflict resolution on a working copy * <code>path</code>. * * <p/> * If <code>depth</code> is {@link SVNDepth#EMPTY}, acts only on * <code>path</code>; if {@link SVNDepth#FILES}, resolves <code>path</code> * and its conflicted file children (if any); if {@link SVNDepth#IMMEDIATES} * , resolves <code>path</code> and all its immediate conflicted children * (both files and directories, if any); if {@link SVNDepth#INFINITY}, * resolves <code>path</code> and every conflicted file or directory * anywhere beneath it. * * <p/> * If <code>conflictChoice</code> is {@link SVNConflictChoice#BASE}, * resolves the conflict with the old file contents; if * {@link SVNConflictChoice#MINE_FULL}, uses the original working contents; * if {@link SVNConflictChoice#THEIRS_FULL}, the new contents; and if * {@link SVNConflictChoice#MERGED}, doesn't change the contents at all, * just removes the conflict status, which is the pre-1.2 (pre-SVN 1.5) * behavior. * * <p/> * {@link SVNConflictChoice#THEIRS_CONFLICT} and * {@link SVNConflictChoice#MINE_CONFLICT} are not legal for binary files or * properties. * * <p/> * If <code>path</code> is not in a state of conflict to begin with, does * nothing. If <code>path</code>'s conflict state is removed and caller's * {@link ISVNEntryHandler} is not <span class="javakeyword">null</span>, * then an {@link SVNEventAction#RESOLVED} event is dispatched to the * handler. * * @param path * working copy path * @param depth * tree depth * @param resolveContents * resolve content conflict * @param resolveProperties * resolve property conflict * @param resolveTree * n resolve any tree conlicts * @param conflictChoice * choice object for making decision while resolving * @throws SVNException * @since 1.3, SVN 1.6 */ public void doResolve(File path, SVNDepth depth, final boolean resolveContents, final boolean resolveProperties, final boolean resolveTree, SVNConflictChoice conflictChoice) throws SVNException { SvnResolve resolve = getOperationsFactory().createResolve(); resolve.addTarget(SvnTarget.fromFile(path)); resolve.setDepth(depth); resolve.setResolveContents(resolveContents); resolve.setResolveProperties(resolveProperties); resolve.setResolveTree(resolveTree); resolve.setConflictChoice(conflictChoice); resolve.run(); } /** * Locks file items in a Working Copy as well as in a repository so that no * other user can commit changes to them. * * @param paths * an array of local WC file paths that should be locked * @param stealLock * if <span class="javakeyword">true</span> then all existing * locks on the specified <code>paths</code> will be "stolen" * @param lockMessage * an optional lock comment * @throws SVNException * if one of the following is true: * <ul> * <li>a path to be locked is not under version control * <li>can not obtain a URL of a local path to lock it in the * repository - there's no such entry * <li><code>paths</code> to be locked belong to different * repositories * </ul> * @see #doLock(SVNURL[],boolean,String) */ public void doLock(File[] paths, boolean stealLock, String lockMessage) throws SVNException { SvnSetLock lock = getOperationsFactory().createSetLock(); for (int i = 0; i < paths.length; i++) { lock.addTarget(SvnTarget.fromFile(paths[i])); } lock.setStealLock(stealLock); lock.setLockMessage(lockMessage); lock.run(); } /** * Locks file items in a repository so that no other user can commit changes * to them. * * @param urls * an array of URLs to be locked * @param stealLock * if <span class="javakeyword">true</span> then all existing * locks on the specified <code>urls</code> will be "stolen" * @param lockMessage * an optional lock comment * @throws SVNException * @see #doLock(File[],boolean,String) */ public void doLock(SVNURL[] urls, boolean stealLock, String lockMessage) throws SVNException { SvnSetLock lock = getOperationsFactory().createSetLock(); for (int i = 0; i < urls.length; i++) { lock.addTarget(SvnTarget.fromURL(urls[i])); } lock.setStealLock(stealLock); lock.setLockMessage(lockMessage); lock.run(); } /** * Unlocks file items in a Working Copy as well as in a repository. * * @param paths * an array of local WC file paths that should be unlocked * @param breakLock * if <span class="javakeyword">true</span> and there are locks * that belong to different users then those locks will be also * unlocked - that is "broken" * @throws SVNException * if one of the following is true: * <ul> * <li>a path is not under version control * <li>can not obtain a URL of a local path to unlock it in the * repository - there's no such entry * <li>if a path is not locked in the Working Copy and * <code>breakLock</code> is <span * class="javakeyword">false</span> * <li><code>paths</code> to be unlocked belong to different * repositories * </ul> * @see #doUnlock(SVNURL[],boolean) */ public void doUnlock(File[] paths, boolean breakLock) throws SVNException { SvnUnlock unlock = getOperationsFactory().createUnlock(); for (int i = 0; i < paths.length; i++) { unlock.addTarget(SvnTarget.fromFile(paths[i])); } unlock.setBreakLock(breakLock); unlock.run(); } /** * Unlocks file items in a repository. * * @param urls * an array of URLs that should be unlocked * @param breakLock * if <span class="javakeyword">true</span> and there are locks * that belong to different users then those locks will be also * unlocked - that is "broken" * @throws SVNException * @see #doUnlock(File[],boolean) */ public void doUnlock(SVNURL[] urls, boolean breakLock) throws SVNException { SvnUnlock unlock = getOperationsFactory().createUnlock(); for (int i = 0; i < urls.length; i++) { unlock.addTarget(SvnTarget.fromURL(urls[i])); } unlock.setBreakLock(breakLock); unlock.run(); } /** * Collects information about Working Copy item(s) and passes it to an info * handler. * <p/> * <p/> * If <code>revision</code> is valid and not local, then information will be * collected on remote items (that is taken from a repository). Otherwise * information is gathered on local items not accessing a repository. * * @param path * a WC item on which info should be obtained * @param revision * a target revision * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @param handler * a caller's info handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control <li>can * not obtain a URL corresponding to <code>path</code> to get * its information from the repository - there's no such entry * <li>if a remote info: <code>path</code> is an item that does * not exist in the specified <code>revision</code> * </ul> * @deprecated use * {@link #doInfo(File, SVNRevision, SVNRevision, SVNDepth, Collection, ISVNInfoHandler)} * instead */ public void doInfo(File path, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException { doInfo(path, SVNRevision.UNDEFINED, revision, SVNDepth.getInfinityOrEmptyDepth(recursive), null, handler); } /** * Collects information about Working Copy item(s) and passes it to an info * handler. * <p/> * <p/> * If <code>revision</code> & <code>pegRevision</code> are valid and not * local, then information will be collected on remote items (that is taken * from a repository). Otherwise information is gathered on local items not * accessing a repository. * * @param path * a WC item on which info should be obtained * @param pegRevision * a revision in which <code>path</code> is first looked up * @param revision * a target revision * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @param handler * a caller's info handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control <li>can * not obtain a URL corresponding to <code>path</code> to get * its information from the repository - there's no such entry * <li>if a remote info: <code>path</code> is an item that does * not exist in the specified <code>revision</code> * </ul> * @deprecated use * {@link #doInfo(File, SVNRevision, SVNRevision, SVNDepth, Collection, ISVNInfoHandler)} * instead */ public void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException { doInfo(path, pegRevision, revision, SVNDepth.getInfinityOrEmptyDepth(recursive), null, handler); } /** * Invokes <code>handler</code> to return information about * <code>path</code> in <code>revision</code>. The information returned is * system-generated metadata, not the sort of "property" metadata created by * users. See {@link SVNInfo}. * * <p/> * If both revision arguments are either <span * class="javakeyword">null</span> or {@link SVNRevision#isLocal() local}, * or {@link SVNRevision#isValid() invalid}, then information will be pulled * solely from the working copy; no network connections will be made. * * <p/> * Otherwise, information will be pulled from a repository. The actual node * revision selected is determined by the <code>path</code> as it exists in * <code>pegRevision</code>. If <code>pegRevision</code> is * {@link SVNRevision#UNDEFINED}, then it defaults to * {@link SVNRevision#WORKING}. * * <p/> * If <code>path</code> is a file, just invokes <code>handler</code> on it. * If it is a directory, then descends according to <code>depth</code>. If * <code>depth</code> is {@link SVNDepth#EMPTY}, invokes * <code>handler</code> on <code>path</code> and nothing else; if * {@link SVNDepth#FILES}, on <code>path</code> and its immediate file * children; if {@link SVNDepth#IMMEDIATES}, the preceding plus on each * immediate subdirectory; if {@link SVNDepth#INFINITY}, then recurses * fully, invoking <code>handler</code> on <code>path</code> and everything * beneath it. * * <p/> * <code>changeLists</code> is a collection of <code>String</code> * changelist names, used as a restrictive filter on items whose info is * reported; that is, doesn't report info 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 * a WC item on which info should be obtained * @param pegRevision * a revision in which <code>path</code> is first looked up * @param revision * a target revision * @param depth * tree depth * @param changeLists * collection changelist names * @param handler * caller's info handler * @throws SVNException * @since 1.2, SVN 1.5 */ public void doInfo(File path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, Collection<String> changeLists, final ISVNInfoHandler handler) throws SVNException { SvnGetInfo getInfo = getOperationsFactory().createGetInfo(); getInfo.setSingleTarget(SvnTarget.fromFile(path, pegRevision)); getInfo.setRevision(revision); getInfo.setDepth(depth); getInfo.setApplicalbeChangelists(changeLists); getInfo.setReceiver(new ISvnObjectReceiver<SvnInfo>() { public void receive(SvnTarget target, SvnInfo object) throws SVNException { handler.handleInfo(SvnCodec.info(object)); } }); getInfo.run(); } /** * Collects information about item(s) in a repository and passes it to an * info handler. * * @param url * a URL of an item which information is to be obtained and * processed * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision * @param recursive * <span class="javakeyword">true</span> to descend recursively * (relevant for directories) * @param handler * a caller's info handler * @throws SVNException * if <code>url</code> is an item that does not exist in the * specified <code>revision</code> * @deprecated use * {@link #doInfo(SVNURL, SVNRevision, SVNRevision, SVNDepth, ISVNInfoHandler)} * instead */ public void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler) throws SVNException { doInfo(url, pegRevision, revision, SVNDepth.getInfinityOrEmptyDepth(recursive), handler); } /** * Invokes <code>handler</code> to return information about <code>url</code> * in <code>revision</code>. The information returned is system-generated * metadata, not the sort of "property" metadata created by users. See * {@link SVNInfo}. * * <p/> * If <code>revision</code> argument is either <span * class="javakeyword">null</span> or {@link SVNRevision#isValid() invalid}, * it defaults to {@link SVNRevision#HEAD}. If <code>revision</code> is * {@link SVNRevision#PREVIOUS} (or some other kind that requires a local * path), an error will be returned, because the desired revision cannot be * determined. If <code>pegRevision</code> argument is either <span * class="javakeyword">null</span> or {@link SVNRevision#isValid() invalid}, * it defaults to <code>revision</code>. * * <p/> * Information will be pulled from the repository. The actual node revision * selected is determined by the <code>url</code> as it exists in * <code>pegRevision</code>. If <code>pegRevision</code> is * {@link SVNRevision#UNDEFINED}, then it defaults to * {@link SVNRevision#WORKING}. * * <p/> * If <code>url</code> is a file, just invokes <code>handler</code> on it. * If it is a directory, then descends according to <code>depth</code>. If * <code>depth</code> is {@link SVNDepth#EMPTY}, invokes * <code>handler</code> on <code>url</code> and nothing else; if * {@link SVNDepth#FILES}, on <code>url</code> and its immediate file * children; if {@link SVNDepth#IMMEDIATES}, the preceding plus on each * immediate subdirectory; if {@link SVNDepth#INFINITY}, then recurses * fully, invoking <code>handler</code> on <code>url</code> and everything * beneath it. * * @param url * versioned item url * @param pegRevision * revision in which <code>path</code> is first looked up * @param revision * target revision * @param depth * tree depth * @param handler * caller's info handler * @throws SVNException * @since 1.2, SVN 1.5 */ public void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, final ISVNInfoHandler handler) throws SVNException { SvnGetInfo getInfo = getOperationsFactory().createGetInfo(); getInfo.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); getInfo.setRevision(revision); getInfo.setDepth(depth); getInfo.setReceiver(new ISvnObjectReceiver<SvnInfo>() { public void receive(SvnTarget target, SvnInfo object) throws SVNException { handler.handleInfo(SvnCodec.info(object)); } }); getInfo.run(); } /** * Returns the current Working Copy min- and max- revisions as well as * changes and switch status within a single string. * * <p/> * This method is the same as * <code>doGetWorkingCopyID(path, trailURL, false)</code>. * * @param path * a local path * @param trailURL * optional: if not <span class="javakeyword">null</span> * specifies the name of the item that should be met in the URL * corresponding to the repository location of the * <code>path</code>; if that URL ends with something different * than this optional parameter - the Working Copy will be * considered "switched" * @return brief info on the Working Copy or the string "exported" if * <code>path</code> is a clean directory * @throws SVNException * if <code>path</code> is neither versioned nor even exported * @see #doGetWorkingCopyID(File, String, boolean) */ public String doGetWorkingCopyID(final File path, String trailURL) throws SVNException { return doGetWorkingCopyID(path, trailURL, false); } /** * Returns the current Working Copy min- and max- revisions as well as * changes and switch status within a single string. * <p/> * <p/> * A return string has a form of <code>"minR[:maxR][M][S]"</code> where: * <ul> * <li><code>minR</code> - is the smallest revision number met in the * Working Copy * <li><code>maxR</code> - is the biggest revision number met in the Working * Copy; appears only if there are different revision in the Working Copy * <li><code>M</code> - appears only if there're local edits to the Working * Copy - that means 'Modified' * <li><code>S</code> - appears only if the Working Copy is switched against * a different URL * </ul> * If <code>path</code> is a directory - this method recursively descends * into the Working Copy, collects and processes local information. * * <p/> * This method operates on local working copies only without accessing a * repository. * * @param path * a local path * @param trailURL * optional: if not <span class="javakeyword">null</span> * specifies the name of the item that should be met in the URL * corresponding to the repository location of the * <code>path</code>; if that URL ends with something different * than this optional parameter - the Working Copy will be * considered "switched" * @param committed * if <span class="javakeyword">true</span> committed (last * chaned) revisions instead of working copy ones are reported * @return brief info on the Working Copy or the string "exported" if * <code>path</code> is a clean directory * @throws SVNException * if <code>path</code> is neither versioned nor even exported * @since 1.2 */ public String doGetWorkingCopyID(final File path, String trailURL, final boolean committed) throws SVNException { SvnGetStatusSummary gs = getOperationsFactory().createGetStatusSummary(); gs.addTarget(SvnTarget.fromFile(path)); gs.setTrailUrl(trailURL); gs.setCommitted(committed); SvnStatusSummary summary; try { summary = gs.run(); } catch (SVNException e) { if (e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_PATH_NOT_FOUND || e.getErrorMessage().getErrorCode() == SVNErrorCode.WC_NOT_WORKING_COPY) { SVNFileType ft = SVNFileType.getType(path); if (ft == SVNFileType.SYMLINK) { return "Unversioned symlink"; } else if (ft == SVNFileType.DIRECTORY) { return "Unversioned directory"; } else if (ft == SVNFileType.FILE) { return "Unversioned file"; } return "'" + path.getPath() + "' doesn't exist"; } else { throw e; } } if (summary.getMinRevision() < 0) { return "Uncommitted local addition, copy or move"; } StringBuffer result = new StringBuffer(); result.append(summary.getMinRevision()); if (summary.getMaxRevision() != summary.getMinRevision()) { result.append(":"); result.append(summary.getMaxRevision()); } result.append(summary.isModified() ? "M" : ""); result.append(summary.isSwitched() ? "S" : ""); result.append(summary.isSparseCheckout() ? "P" : ""); return result.toString(); } /** * Collects and returns information on a single Working Copy item. * * <p/> * This method is the same as * <code>doInfo(path, SVNRevision.UNDEFINED, revision, SVNDepth.EMPTY, null, handler)</code> * where <code>handler</code> just stores {@link SVNInfo} for the * <code>path</code> and then returns it to the caller. * * @param path * a WC item on which info should be obtained * @param revision * a target revision * @return collected info * @throws SVNException * if one of the following is true: * <ul> * <li><code>path</code> is not under version control <li>can * not obtain a URL corresponding to <code>path</code> to get * its information from the repository - there's no such entry * <li>if a remote info: <code>path</code> is an item that does * not exist in the specified <code>revision</code> * </ul> * @see #doInfo(File, SVNRevision, SVNRevision, SVNDepth, Collection, * ISVNInfoHandler) */ public SVNInfo doInfo(File path, SVNRevision revision) throws SVNException { final SVNInfo[] info = new SVNInfo[1]; SvnGetInfo getInfo = getOperationsFactory().createGetInfo(); getInfo.setSingleTarget(SvnTarget.fromFile(path)); getInfo.setRevision(revision); getInfo.setDepth(SVNDepth.EMPTY); getInfo.setReceiver(new ISvnObjectReceiver<SvnInfo>() { public void receive(SvnTarget target, SvnInfo object) throws SVNException { if (info[0] == null) { info[0] = SvnCodec.info(object); } } }); getInfo.run(); return info[0]; } /** * Collects and returns information on a single item in a repository. * * <p/> * This method is the same as * <code>doInfo(url, pegRevision, revision, SVNDepth.EMPTY, handler)</code> * where <code>handler</code> just stores {@link SVNInfo} for the * <code>url</code>. * * @param url * a URL of an item which information is to be obtained * @param pegRevision * a revision in which the item is first looked up * @param revision * a target revision * @return collected info * @throws SVNException * if <code>url</code> is an item that does not exist in the * specified <code>revision</code> * @see #doInfo(SVNURL, SVNRevision, SVNRevision, SVNDepth, ISVNInfoHandler) */ public SVNInfo doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision) throws SVNException { final SVNInfo[] info = new SVNInfo[1]; SvnGetInfo getInfo = getOperationsFactory().createGetInfo(); getInfo.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); getInfo.setRevision(revision); getInfo.setDepth(SVNDepth.EMPTY); getInfo.setReceiver(new ISvnObjectReceiver<SvnInfo>() { public void receive(SvnTarget target, SvnInfo object) throws SVNException { if (info[0] == null) { info[0] = SvnCodec.info(object); } } }); getInfo.run(); return info[0]; } /** * Recursively removes all DAV-specific <span * class="javakeyword">"svn:wc:"</span> properties from the * <code>directory</code> and beneath. * * <p> * This method does not connect to a repository, it's a local operation * only. Nor does it change any user's versioned data. Changes are made only * in administrative version control files. * * @param directory * working copy path * @throws SVNException * @since 1.2 */ public void doCleanupWCProperties(File directory) throws SVNException { SVNWCClient16 oldClient = new SVNWCClient16(getOperationsFactory().getAuthenticationManager(), getOptions()); oldClient.doCleanupWCProperties(directory); } /** * Changes working copy format. This method may be used to upgrade\downgrade * working copy formats. * * <p> * If externals are not {@link SVNBasicClient#isIgnoreExternals() ignored} * then external working copies are also converted to the new working copy * <code>format</code>. * * <p> * This method does not connect to a repository, it's a local operation * only. Nor does it change any user's versioned data. Changes are made only * in administrative version control files. * * <p> * Once upgraded to 1.7 format (12) working copy format could not be downgraded. * * @param directory * working copy directory * @param format * format to set, supported formats are: 12 (SVN 1.7), 10 (SVN 1.6), 9 (SVN 1.5), 8 (SVN 1.4) * and 4 (SVN 1.2) * @throws SVNException * @since 1.2 */ public void doSetWCFormat(File directory, int format) throws SVNException { if (format >= 12) { SvnUpgrade upgrade = getOperationsFactory().createUpgrade(); upgrade.setSingleTarget(SvnTarget.fromFile(directory)); upgrade.setDepth(SVNDepth.INFINITY); upgrade.run(); } else { SVNWCClient16 oldClient = new SVNWCClient16(getOperationsFactory().getAuthenticationManager(), getOptions()); oldClient.doSetWCFormat(directory, format); } } /** * This method is deprecated. * * @param path * a WC item which properties are to be modified * @param propName * a property name * @param propValue * a property value * @param force * <span class="javakeyword">true</span> to force the operation * to run * @param recursive * <span class="javakeyword">true</span> to descend recursively * @param handler * a caller's property handler * @throws SVNException * if one of the following is true: * <ul> * <li><code>propName</code> is a revision property * <li><code>propName</code> starts with the * {@link org.tmatesoft.svn.core.SVNProperty#SVN_WC_PREFIX * svn:wc:} prefix * </ul> * @deprecated use * {@link #doSetProperty(File, String, SVNPropertyValue, boolean, SVNDepth, ISVNPropertyHandler, Collection)} * instead */ public void doSetProperty(File path, String propName, SVNPropertyValue propValue, boolean force, boolean recursive, ISVNPropertyHandler handler) throws SVNException { doSetProperty(path, propName, propValue, force, SVNDepth.fromRecurse(recursive), handler, null); } }