0001: /*
0002: * ====================================================================
0003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
0004: *
0005: * This software is licensed as described in the file COPYING, which
0006: * you should have received as part of this distribution. The terms
0007: * are also available at http://svnkit.com/license.html
0008: * If newer versions of this license are posted there, you may use a
0009: * newer version instead, at your option.
0010: * ====================================================================
0011: */
0012: package org.tmatesoft.svn.core.io;
0013:
0014: import java.io.OutputStream;
0015: import java.util.Collection;
0016: import java.util.Date;
0017: import java.util.HashMap;
0018: import java.util.HashSet;
0019: import java.util.Iterator;
0020: import java.util.LinkedList;
0021: import java.util.Map;
0022:
0023: import org.tmatesoft.svn.core.ISVNCanceller;
0024: import org.tmatesoft.svn.core.ISVNDirEntryHandler;
0025: import org.tmatesoft.svn.core.ISVNLogEntryHandler;
0026: import org.tmatesoft.svn.core.SVNDirEntry;
0027: import org.tmatesoft.svn.core.SVNErrorCode;
0028: import org.tmatesoft.svn.core.SVNErrorMessage;
0029: import org.tmatesoft.svn.core.SVNException;
0030: import org.tmatesoft.svn.core.SVNLock;
0031: import org.tmatesoft.svn.core.SVNLogEntry;
0032: import org.tmatesoft.svn.core.SVNNodeKind;
0033: import org.tmatesoft.svn.core.SVNURL;
0034: import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
0035: import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
0036: import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
0037: import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
0038: import org.tmatesoft.svn.core.io.diff.SVNDiffWindow;
0039: import org.tmatesoft.svn.util.ISVNDebugLog;
0040: import org.tmatesoft.svn.util.SVNDebugLog;
0041:
0042: /**
0043: * The abstract class <b>SVNRepository</b> provides an interface for protocol
0044: * specific drivers used for direct working with a Subversion repository.
0045: * <b>SVNRepository</b> joins all low-level API methods needed for repository
0046: * access operations.
0047: *
0048: * <p>
0049: * In particular this low-level protocol driver is used by the high-level API
0050: * (represented by the <B><A HREF="../wc/package-summary.html">org.tmatesoft.svn.core.wc</A></B> package)
0051: * when an access to a repository is needed.
0052: *
0053: * <p>
0054: * It is important to say that before using the library it must be configured
0055: * according to implimentations to be used. That is if a repository is assumed
0056: * to be accessed either via the <i>WebDAV</i> protocol (<code>http://</code> or
0057: * <code>https://</code>), or a custom <i>svn</i> one (<code>svn://</code> or <code>svn+ssh://</code>)
0058: * or immediately on the local machine (<code>file:///</code>) a user must initialize the library
0059: * in a proper way:
0060: * <pre class="javacode">
0061: * <span class="javacomment">//import neccessary classes</span>
0062: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
0063: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
0064: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
0065: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.SVNURL;
0066: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.io.SVNRepository;
0067: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.io.SVNRepositoryFactory;
0068: * <span class="javakeyword">import</span> import org.tmatesoft.svn.core.wc.SVNWCUtil;
0069: * <span class="javakeyword">import</span> import org.tmatesoft.svn.core.SVNException;
0070: * ...
0071: *
0072: * <span class="javacomment">//Set up connection protocols support:</span>
0073: * <span class="javacomment">//http:// and https://</span>
0074: * DAVRepositoryFactory.setup();
0075: * <span class="javacomment">//svn://, svn+xxx:// (svn+ssh:// in particular)</span>
0076: * SVNRepositoryFactoryImpl.setup();
0077: * <span class="javacomment">//file:///</span>
0078: * FSRepositoryFactory.setup();
0079: * </pre>
0080: * <code>svn+xxx://</code> can be any tunnel scheme for tunneled working with a
0081: * repository. <code>xxx</code> URL scheme is looked up in the section <code>tunnels</code> of the
0082: * standard Subversion <code>config</code> file.
0083: *
0084: * <p>
0085: * So, only after these setup steps the client can create http | svn | file protocol
0086: * implementations of the <code>SVNRepository</code> abstract class to access
0087: * the repository.
0088: *
0089: * <p>
0090: * This is a general way how a user creates an <b>SVNRepository</b> driver object:
0091: * <pre class="javacode">
0092: * String url=<span class="javastring">"http://svn.collab.net/svn/trunk"</span>;
0093: * String name=<span class="javastring">"my name"</span>;
0094: * String password=<span class="javastring">"my password"</span>;
0095: * repository = <span class="javakeyword">null</span>;
0096: * <span class="javakeyword">try</span> {
0097: * repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(url));
0098: * ISVNAuthenticationManager authManager =
0099: * SVNWCUtil.createDefaultAuthenticationManager(name, password);
0100: * repository.setAuthenticationManager(authManager);
0101: * ...
0102: * } <span class="javakeyword">catch</span> (SVNException e){
0103: * e.printStackTrace();
0104: * System.exit(1);
0105: * }
0106: * <span class="javacomment">//work with the repository</span>
0107: * ... </pre>
0108: * <p>
0109: * <b>SVNRepository</b> objects are not thread-safe, we're strongly recommend
0110: * you not to use one <b>SVNRepository</b> object from within multiple threads.
0111: *
0112: * <p>
0113: * Also methods of <b>SVNRepository</b> objects are not reenterable - that is,
0114: * you can not call operation methods of an <b>SVNRepository</b> driver neither
0115: * from within those handlers that are passed to some of the driver's methods, nor
0116: * during committing with the help of a commit editor (until the editor's {@link ISVNEditor#closeEdit() closeEdit()}
0117: * method is called).
0118: *
0119: * <p>
0120: * To authenticate a user over network <b>SVNRepository</b> drivers use
0121: * <b>ISVNAuthenticationManager</b> auth drivers.
0122: *
0123: * @version 1.1.1
0124: * @author TMate Software Ltd.
0125: * @see SVNRepositoryFactory
0126: * @see org.tmatesoft.svn.core.auth.ISVNAuthenticationManager
0127: * @see <a target="_top" href="http://svnkit.com/kb/examples/">Examples</a>
0128: */
0129: public abstract class SVNRepository {
0130:
0131: protected String myRepositoryUUID;
0132: protected SVNURL myRepositoryRoot;
0133: protected SVNURL myLocation;
0134:
0135: private int myLockCount;
0136: private Thread myLocker;
0137: private ISVNAuthenticationManager myAuthManager;
0138: private ISVNSession myOptions;
0139: private ISVNTunnelProvider myTunnelProvider;
0140: private ISVNDebugLog myDebugLog;
0141: private ISVNCanceller myCanceller;
0142: private Collection myConnectionListeners;
0143:
0144: protected SVNRepository(SVNURL location, ISVNSession options) {
0145: myLocation = location;
0146: myOptions = options;
0147: myConnectionListeners = new HashSet();
0148: }
0149:
0150: /**
0151: * Returns the repository location to which this object is set.
0152: * It may be the location that was used to create this object
0153: * (see {@link SVNRepositoryFactory#create(SVNURL)}), or the recent
0154: * one the object was set to.
0155: *
0156: * @return a repository location set for this driver
0157: * @see #setLocation(SVNURL, boolean)
0158: *
0159: */
0160: public SVNURL getLocation() {
0161: return myLocation;
0162: }
0163:
0164: /**
0165: * Sets a new repository location for this object. The ability to reset
0166: * an old repository location to a new one (to switch the working location)
0167: * lets a developer to use the same <b>SVNRepository</b> object instead of
0168: * creating a new object per each repository location. This advantage gives
0169: * memory & coding efforts economy.
0170: *
0171: * <p>
0172: * But you can not specify a new repository location url with a protocol
0173: * different from the one used for the previous (essentially, the current)
0174: * repository location, since <b>SVNRepository</b> objects are protocol dependent.
0175: *
0176: * <p>
0177: * If a new <code>url</code> is located within the same repository, this object
0178: * just switches to that <code>url</code> not closing the current session (i.e.
0179: * not calling {@link #closeSession()}).
0180: *
0181: * <p>
0182: * If either a new <code>url</code> refers to the same host (including a port
0183: * number), or refers to an absolutely different host, or this object has got
0184: * no repository root location cached (hasn't ever accessed a repository yet),
0185: * or <code>forceReconnect</code> is <span class="javakeyword">true</span>, then
0186: * the current session is closed, cached repository credentials (UUID and repository
0187: * root directory location ) are reset and this object is switched to a new
0188: * repository location.
0189: *
0190: * @param url a new repository location url
0191: * @param forceReconnect if <span class="javakeyword">true</span> then
0192: * forces to close the current session, resets the
0193: * cached repository credentials and switches this object to
0194: * a new location (doesn't matter whether it's on the same
0195: * host or not)
0196: * @throws SVNException if the old url and a new one has got different
0197: * protocols
0198: */
0199: public void setLocation(SVNURL url, boolean forceReconnect)
0200: throws SVNException {
0201: lock();
0202: try {
0203: if (url == null) {
0204: return;
0205: } else if (!url.getProtocol().equals(
0206: myLocation.getProtocol())) {
0207: SVNErrorMessage err = SVNErrorMessage
0208: .create(
0209: SVNErrorCode.RA_NOT_IMPLEMENTED,
0210: "SVNRepository URL could not be changed from ''{0}'' to ''{1}''; create new SVNRepository instance instead",
0211: new Object[] { myLocation, url });
0212: SVNErrorManager.error(err);
0213: }
0214: if (forceReconnect) {
0215: closeSession();
0216: myRepositoryRoot = null;
0217: myRepositoryUUID = null;
0218: } else if (myRepositoryRoot == null) {
0219: // no way to check whether repos is the same. just compare urls
0220: if (!(url.toString().startsWith(
0221: myLocation.toString() + "/") || url
0222: .equals(getLocation()))) {
0223: closeSession();
0224: myRepositoryRoot = null;
0225: myRepositoryUUID = null;
0226: }
0227: } else if (url.toString().startsWith(
0228: myRepositoryRoot.toString() + "/")
0229: || myRepositoryRoot.equals(url)) {
0230: // just do nothing, we are still below old root.
0231: } else {
0232: closeSession();
0233: myRepositoryRoot = null;
0234: myRepositoryUUID = null;
0235: }
0236: myLocation = url;
0237: } finally {
0238: unlock();
0239: }
0240: }
0241:
0242: /**
0243: * @return the UUID of a repository
0244: * @deprecated use {@link #getRepositoryUUID(boolean) } instead
0245: */
0246: public String getRepositoryUUID() {
0247: try {
0248: return getRepositoryUUID(false);
0249: } catch (SVNException e) {
0250: }
0251: return myRepositoryUUID;
0252: }
0253:
0254: /**
0255: * Gets the Universal Unique IDentifier (UUID) of the repository this
0256: * driver is created for.
0257: *
0258: * @param forceConnection if <span class="javakeyword">true</span> then forces
0259: * this driver to test a connection - try to access a
0260: * repository
0261: * @return the UUID of a repository
0262: * @throws SVNException
0263: */
0264: public String getRepositoryUUID(boolean forceConnection)
0265: throws SVNException {
0266: if (forceConnection && myRepositoryUUID == null) {
0267: testConnection();
0268: }
0269: return myRepositoryUUID;
0270: }
0271:
0272: /**
0273: * @return the repository root directory location url
0274: * @see #getRepositoryRoot(boolean)
0275: *
0276: * @deprecated use #getRepositoryRoot(boolean) instead
0277: */
0278: public SVNURL getRepositoryRoot() {
0279: try {
0280: return getRepositoryRoot(false);
0281: } catch (SVNException e) {
0282: // will not be thrown.
0283: }
0284: return null;
0285: }
0286:
0287: /**
0288: * Gets a repository's root directory location.
0289: * If this driver object is switched to a different repository location during
0290: * runtime (probably to an absolutely different repository, see {@link #setLocation(SVNURL, boolean) setLocation()}),
0291: * the root directory location may be changed.
0292: *
0293: * @param forceConnection if <span class="javakeyword">true</span> then forces
0294: * this driver to test a connection - try to access a
0295: * repository
0296: * @return the repository root directory location url
0297: * @throws SVNException
0298: * @see #testConnection()
0299: */
0300: public SVNURL getRepositoryRoot(boolean forceConnection)
0301: throws SVNException {
0302: if (forceConnection && myRepositoryRoot == null) {
0303: testConnection();
0304: }
0305: return myRepositoryRoot;
0306: }
0307:
0308: /**
0309: * Sets an authentication driver for this object. The auth driver
0310: * may be implemented to retrieve cached credentials, to prompt
0311: * a user for credentials or something else (actually, this is up
0312: * to an implementor). Also there's a default implementation - see
0313: * the {@link org.tmatesoft.svn.core.wc.SVNWCUtil} class for more
0314: * details.
0315: *
0316: * @param authManager an authentication driver to provide user
0317: * credentials
0318: * @see #getAuthenticationManager()
0319: */
0320: public void setAuthenticationManager(
0321: ISVNAuthenticationManager authManager) {
0322: myAuthManager = authManager;
0323: }
0324:
0325: /**
0326: * Returns the authentication driver registered for this
0327: * object.
0328: *
0329: * @return an authentication driver that is used by this object
0330: * to authenticate a user over network
0331: */
0332: public ISVNAuthenticationManager getAuthenticationManager() {
0333: return myAuthManager;
0334: }
0335:
0336: /**
0337: * Sets a tunnel provider. Actually relevant only to
0338: * <code>svn+xxx://</code> scheme cases. The provider is responsible
0339: * for matching <code>xxx</code> to the tunnel command string.
0340: *
0341: * <p>
0342: * If one would like to have a standard Subversion behaviour
0343: * (when tunnel commands are fetched from the <code>config</code> file
0344: * beneath the section named <code>tunnels</code>), he should provide a
0345: * default provider (default implementation of the {@link org.tmatesoft.svn.core.wc.ISVNOptions}
0346: * interface). Refer to {@link org.tmatesoft.svn.core.wc.SVNWCUtil} class
0347: * for more details on how to get a default options driver.
0348: *
0349: * @param tunnelProvider a tunnel provider
0350: * @see #getTunnelProvider()
0351: */
0352: public void setTunnelProvider(ISVNTunnelProvider tunnelProvider) {
0353: myTunnelProvider = tunnelProvider;
0354: }
0355:
0356: /**
0357: * Returns a tunnel provider.
0358: *
0359: * @return a tunnel provider
0360: * @see #setTunnelProvider(ISVNTunnelProvider)
0361: */
0362: public ISVNTunnelProvider getTunnelProvider() {
0363: return myTunnelProvider;
0364: }
0365:
0366: public void setCanceller(ISVNCanceller canceller) {
0367: myCanceller = canceller;
0368: }
0369:
0370: public ISVNCanceller getCanceller() {
0371: return myCanceller == null ? ISVNCanceller.NULL : myCanceller;
0372: }
0373:
0374: /**
0375: * Caches identification parameters (UUID, rood directory location)
0376: * of the repository with which this driver is working.
0377: *
0378: * @param uuid the repository's Universal Unique IDentifier
0379: * (UUID)
0380: * @param rootURL the repository's root directory location
0381: * @see #getRepositoryRoot(boolean)
0382: * @see #getRepositoryUUID(boolean)
0383: */
0384: protected void setRepositoryCredentials(String uuid, SVNURL rootURL) {
0385: if (uuid != null && rootURL != null) {
0386: myRepositoryUUID = uuid;
0387: myRepositoryRoot = rootURL;
0388: }
0389: }
0390:
0391: /**
0392: * Tries to access a repository. Used to check if there're no problems
0393: * with accessing a repository and to cache a repository UUID and root
0394: * directory location.
0395: *
0396: * @throws SVNException if a failure occured while connecting to a repository
0397: * or the user's authentication failed (see
0398: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0399: */
0400: public abstract void testConnection() throws SVNException;
0401:
0402: /**
0403: * Returns the number of the latest revision of the repository this
0404: * driver is working with.
0405: *
0406: * @return the latest revision number
0407: * @throws SVNException if a failure occured while connecting to a repository
0408: * or the user's authentication failed (see
0409: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0410: */
0411: public abstract long getLatestRevision() throws SVNException;
0412:
0413: /**
0414: * Returns the recent repository revision number for the particular moment
0415: * in time - the closest one before or at the specified datestamp.
0416: *
0417: * <p>
0418: * Example: if you specify a single date without specifying a time of the day
0419: * (e.g. 2002-11-27) the timestamp is assumed to 00:00:00 and the method won't
0420: * return any revisions for the day you have specified but for the day just
0421: * before it.
0422: *
0423: * @param date a datestamp for defining the needed
0424: * moment in time
0425: * @return the revision of the repository
0426: * for that time
0427: * @throws SVNException if a failure occured while connecting to a repository
0428: * or the user's authentication failed (see
0429: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0430: */
0431: public abstract long getDatedRevision(Date date)
0432: throws SVNException;
0433:
0434: /**
0435: * Returns unversioned revision properties for a particular revision.
0436: * Property names (keys) are mapped to their values. You may use
0437: * <b>SVNRevisionProperty</b> constants to retrieve property values
0438: * from the map.
0439: *
0440: * @param revision a revision number
0441: * @param properties if not <span class="javakeyword">null</span> then
0442: * properties will be placed in this map, otherwise
0443: * a new map will be created
0444: * @return a map containing unversioned revision properties
0445: * @throws SVNException in the following cases:
0446: * <ul>
0447: * <li><code>revision</code> number is invalid
0448: * <li>there's no such <code>revision</code> at all
0449: * <li>a failure occured while connecting to a repository
0450: * <li>the user authentication failed
0451: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0452: * </ul>
0453: * @see org.tmatesoft.svn.core.SVNRevisionProperty
0454: */
0455: public abstract Map getRevisionProperties(long revision,
0456: Map properties) throws SVNException;
0457:
0458: /**
0459: * Sets a revision property with the specified name to a new value.
0460: *
0461: * <p>
0462: * <b>NOTE:</b> revision properties are not versioned. So, the old values
0463: * may be lost forever.
0464: *
0465: * @param revision the number of the revision which property is to
0466: * be changed
0467: * @param propertyName a revision property name
0468: * @param propertyValue the value of the revision property
0469: * @throws SVNException in the following cases:
0470: * <ul>
0471: * <li>the repository is configured not to allow clients
0472: * to modify revision properties (e.g. a pre-revprop-change-hook
0473: * program is not found or failed)
0474: * <li><code>revision</code> is invalid or doesn't
0475: * exist at all
0476: * <li>a failure occured while connecting to a repository
0477: * <li>the user authentication failed
0478: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0479: * </ul>
0480: * @see org.tmatesoft.svn.core.SVNRevisionProperty
0481: */
0482: public abstract void setRevisionPropertyValue(long revision,
0483: String propertyName, String propertyValue)
0484: throws SVNException;
0485:
0486: /**
0487: * Gets the value of an unversioned property.
0488: *
0489: *
0490: * @param revision a revision number
0491: * @param propertyName a property name
0492: * @return a revision property value or <span class="javakeyword">null</span>
0493: * if there's no such revision property
0494: * @throws SVNException in the following cases:
0495: * <ul>
0496: * <li><code>revision</code> number is invalid or
0497: * if there's no such <code>revision</code> at all.
0498: * <li>a failure occured while connecting to a repository
0499: * <li>the user authentication failed
0500: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0501: * </ul>
0502: */
0503: public abstract String getRevisionPropertyValue(long revision,
0504: String propertyName) throws SVNException;
0505:
0506: /**
0507: * Returns the kind of an item located at the specified path in
0508: * a particular revision. If the <code>path</code> does not exist
0509: * under the specified <code>revision</code>, {@link org.tmatesoft.svn.core.SVNNodeKind#NONE SVNNodeKind.NONE}
0510: * will be returned.
0511: *
0512: * <p>
0513: * The <code>path</code> arg can be both relative to the location of
0514: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0515: *
0516: * @param path an item's path
0517: * @param revision a revision number
0518: * @return the node kind for the given <code>path</code> at the given
0519: * <code>revision</code>
0520: * @throws SVNException if a failure occured while connecting to a repository
0521: * or the user's authentication failed (see
0522: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0523: */
0524: public abstract SVNNodeKind checkPath(String path, long revision)
0525: throws SVNException;
0526:
0527: /**
0528: * Fetches the contents and/or properties of a file located at the specified path
0529: * in a particular revision.
0530: *
0531: * <p>
0532: * If <code>contents</code> arg is not <span class="javakeyword">null</span> it
0533: * will be written with file contents.
0534: *
0535: * <p>
0536: * If <code>properties</code> arg is not <span class="javakeyword">null</span> it will
0537: * receive the properties of the file. This includes all properties: not just ones
0538: * controlled by a user and stored in the repository filesystem, but also non-tweakable
0539: * ones (e.g. 'wcprops', 'entryprops', etc.). Property names (keys) are mapped to property
0540: * values.
0541: *
0542: * <p>
0543: * The <code>path</code> arg can be both relative to the location of
0544: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0545: *
0546: * <p>
0547: * If <code>revision</code> is invalid (negative), HEAD revision will be used.
0548: *
0549: * @param path a file path
0550: * @param revision a file revision
0551: * @param properties a file properties receiver map
0552: * @param contents an output stream to write the file contents to
0553: * @return the revision the file has been taken at
0554: * @throws SVNException in the following cases:
0555: * <ul>
0556: * <li>there's no such <code>path</code> in <code>revision</code>
0557: * <li>a failure occured while connecting to a repository
0558: * <li>the user authentication failed
0559: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0560: * </ul>
0561: */
0562: public abstract long getFile(String path, long revision,
0563: Map properties, OutputStream contents) throws SVNException;
0564:
0565: /**
0566: * Fetches the contents and/or properties of a directory located at the specified path
0567: * in a particular revision.
0568: *
0569: * <p>
0570: * If <code>handler</code> arg is not <span class="javakeyword">null</span> it
0571: * will be dispatched information of each directory entry represented by an
0572: * <b>SVNDirEntry</b> object.
0573: *
0574: * <p>
0575: * If <code>properties</code> arg is not <span class="javakeyword">null</span> it will
0576: * receive the properties of the file. This includes all properties: not just ones
0577: * controlled by a user and stored in the repository filesystem, but also non-tweakable
0578: * ones (e.g. 'wcprops', 'entryprops', etc.). Property names (keys) are mapped to property
0579: * values.
0580: *
0581: * <p>
0582: * The <code>path</code> arg can be both relative to the location of
0583: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0584: *
0585: * <p>
0586: * If <code>revision</code> is invalid (negative), HEAD revision will be used.
0587: *
0588: * <b>NOTE:</b> you may not invoke operation methods of this <b>SVNRepository</b>
0589: * object from within the provided <code>handler</code>.
0590: *
0591: * @param path a directory path
0592: * @param revision a directory revision
0593: * @param properties a directory properties receiver map
0594: * @param handler a handler to process directory entries
0595: * @return the revision of the directory
0596: * @throws SVNException in the following cases:
0597: * <ul>
0598: * <li><code>path</code> not found in the specified <code>revision</code>
0599: * <li><code>path</code> is not a directory
0600: * <li>a failure occured while connecting to a repository
0601: * <li>the user authentication failed
0602: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0603: * </ul>
0604: * @see #getDir(String, long, Map, Collection)
0605: * @see #getDir(String, long, boolean, Collection)
0606: * @see org.tmatesoft.svn.core.SVNDirEntry
0607: */
0608: public abstract long getDir(String path, long revision,
0609: Map properties, ISVNDirEntryHandler handler)
0610: throws SVNException;
0611:
0612: /**
0613: * Retrieves interesting file revisions for the specified file.
0614: *
0615: * <p>
0616: * A file revision is represented by an <b>SVNFileRevision</b> object. Each
0617: * file revision is handled by the file revision handler provided. Only those
0618: * revisions will be retrieved in which the file was changed.
0619: * The iteration will begin at the first such revision starting from the
0620: * <code>startRevision</code> and so on - up to the <code>endRevision</code>.
0621: * If the method succeeds, the provided <code>handler</code> will have
0622: * been invoked at least once.
0623: *
0624: * <p>
0625: * For the first interesting revision the file contents
0626: * will be provided to the <code>handler</code> as a text delta against an empty file.
0627: * For the following revisions, the delta will be against the fulltext contents of the
0628: * previous revision.
0629: *
0630: * <p>
0631: * The <code>path</code> arg can be both relative to the location of
0632: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0633: *
0634: * <p>
0635: * <b>NOTES:</b>
0636: * <ul>
0637: * <li>you may not invoke methods of this <b>SVNRepository</b>
0638: * object from within the provided <code>handler</code>
0639: * <li>this functionality is not available in pre-1.1 servers
0640: * </ul>
0641: *
0642: * @param path a file path
0643: * @param startRevision a revision to start from
0644: * @param endRevision a revision to stop at
0645: * @param handler a handler that processes file revisions passed
0646: * @return the number of retrieved file revisions
0647: * @throws SVNException if a failure occured while connecting to a repository
0648: * or the user's authentication failed (see
0649: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0650: * @see #getFileRevisions(String, Collection, long, long)
0651: * @see SVNFileRevision
0652: * @since SVN 1.1
0653: */
0654: public abstract int getFileRevisions(String path,
0655: long startRevision, long endRevision,
0656: ISVNFileRevisionHandler handler) throws SVNException;
0657:
0658: /**
0659: * Traverses revisions history. In other words, collects per revision
0660: * information that includes the revision number, author, datestamp,
0661: * log message and maybe a list of changed paths (optional). For each
0662: * revision this information is represented by an <b>SVNLogEntry</b>
0663: * object. Such objects are passed to the provided <code>handler</code>.
0664: *
0665: * <p>
0666: * This method invokes <code>handler</code> on each log entry from
0667: * <code>startRevision</code> to <code>endRevision</code>.
0668: * <code>startRevision</code> may be greater or less than
0669: * <code>endRevision</code>; this just controls whether the log messages are
0670: * processed in descending or ascending revision number order.
0671: *
0672: * <p>
0673: * If <code>startRevision</code> or <code>endRevision</code> is invalid, it
0674: * defaults to the youngest.
0675: *
0676: * <p>
0677: * If <code>targetPaths</code> has one or more elements, then
0678: * only those revisions are processed in which at least one of <code>targetPaths</code> was
0679: * changed (i.e., if a file text or properties changed; if dir properties
0680: * changed or an entry was added or deleted). Each path is relative
0681: * to the repository location that this object is set to.
0682: *
0683: * <p>
0684: * If <code>changedPath</code> is <span class="javakeyword">true</span>, then each
0685: * <b>SVNLogEntry</b> passed to the handler will contain info about all
0686: * paths changed in that revision it represents. To get them call
0687: * {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()} that returns a map,
0688: * which keys are the changed paths and the values are <b>SVNLogEntryPath</b> objects.
0689: * If <code>changedPath</code> is <span class="javakeyword">false</span>, changed paths
0690: * info will not be provided.
0691: *
0692: * <p>
0693: * If <code>strictNode</code> is <span class="javakeyword">true</span>, copy history will
0694: * not be traversed (if any exists) when harvesting the revision logs for each path.
0695: *
0696: * <p>
0697: * Target paths can be both relative to the location of
0698: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0699: *
0700: * <p>
0701: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
0702: * object from within the provided <code>handler</code>.
0703: *
0704: * @param targetPaths paths that mean only those revisions at which they were
0705: * changed
0706: * @param startRevision a revision to start from
0707: * @param endRevision a revision to end at
0708: * @param changedPath if <span class="javakeyword">true</span> then
0709: * revision information will also include all changed paths per
0710: * revision, otherwise not
0711: * @param strictNode if <span class="javakeyword">true</span> then copy history (if any) is not
0712: * to be traversed
0713: * @param handler a caller's handler that will be dispatched log entry objects
0714: * @return the number of revisions traversed
0715: * @throws SVNException if a failure occured while connecting to a repository
0716: * or the user's authentication failed (see
0717: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0718: * @see #log(String[], Collection, long, long, boolean, boolean)
0719: * @see #log(String[], long, long, boolean, boolean, long, ISVNLogEntryHandler)
0720: * @see org.tmatesoft.svn.core.ISVNLogEntryHandler
0721: * @see org.tmatesoft.svn.core.SVNLogEntry
0722: * @see org.tmatesoft.svn.core.SVNLogEntryPath
0723: */
0724: public long log(String[] targetPaths, long startRevision,
0725: long endRevision, boolean changedPath, boolean strictNode,
0726: ISVNLogEntryHandler handler) throws SVNException {
0727: return log(targetPaths, startRevision, endRevision,
0728: changedPath, strictNode, 0, handler);
0729: }
0730:
0731: /**
0732: * Traverses revisions history. In other words, collects per revision
0733: * information that includes the revision number, author, datestamp,
0734: * log message and maybe a list of changed paths (optional). For each
0735: * revision this information is represented by an <b>SVNLogEntry</b>
0736: * object. Such objects are passed to the provided <code>handler</code>.
0737: *
0738: * <p>
0739: * This method invokes <code>handler</code> on each log entry from
0740: * <code>startRevision</code> to <code>endRevision</code>.
0741: * <code>startRevision</code> may be greater or less than
0742: * <code>endRevision</code>; this just controls whether the log messages are
0743: * processed in descending or ascending revision number order.
0744: *
0745: * <p>
0746: * If <code>startRevision</code> or <code>endRevision</code> is invalid, it
0747: * defaults to the youngest.
0748: *
0749: * <p>
0750: * If <code>targetPaths</code> has one or more elements, then
0751: * only those revisions are processed in which at least one of <code>targetPaths</code> was
0752: * changed (i.e., if a file text or properties changed; if dir properties
0753: * changed or an entry was added or deleted). Each path is relative
0754: * to the repository location that this object is set to.
0755: *
0756: * <p>
0757: * If <code>changedPath</code> is <span class="javakeyword">true</span>, then each
0758: * <b>SVNLogEntry</b> passed to the handler will contain info about all
0759: * paths changed in that revision it represents. To get them call
0760: * {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()} that returns a map,
0761: * which keys are the changed paths and the values are <b>SVNLogEntryPath</b> objects.
0762: * If <code>changedPath</code> is <span class="javakeyword">false</span>, changed paths
0763: * info will not be provided.
0764: *
0765: * <p>
0766: * If <code>strictNode</code> is <span class="javakeyword">true</span>, copy history will
0767: * not be traversed (if any exists) when harvesting the revision logs for each path.
0768: *
0769: * <p>
0770: * If <code>limit</code> is > 0 then only the first <code>limit</code> log entries
0771: * will be handled. Otherwise (i.e. if <code>limit</code> is 0) this number is ignored.
0772: *
0773: * <p>
0774: * Target paths can be both relative to the location of
0775: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0776: *
0777: * <p>
0778: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
0779: * object from within the provided <code>handler</code>.
0780: *
0781: * @param targetPaths paths that mean only those revisions at which they were
0782: * changed
0783: * @param startRevision a revision to start from
0784: * @param endRevision a revision to end at
0785: * @param changedPath if <span class="javakeyword">true</span> then
0786: * revision information will also include all changed paths per
0787: * revision, otherwise not
0788: * @param strictNode if <span class="javakeyword">true</span> then copy history (if any) is not
0789: * to be traversed
0790: * @param limit the maximum number of log entries to process
0791: * @param handler a caller's handler that will be dispatched log entry objects
0792: * @return the number of revisions traversed
0793: * @throws SVNException if a failure occured while connecting to a repository
0794: * or the user's authentication failed (see
0795: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0796: * @see #log(String[], Collection, long, long, boolean, boolean)
0797: * @see #log(String[], long, long, boolean, boolean, long, ISVNLogEntryHandler)
0798: * @see org.tmatesoft.svn.core.ISVNLogEntryHandler
0799: * @see org.tmatesoft.svn.core.SVNLogEntry
0800: * @see org.tmatesoft.svn.core.SVNLogEntryPath
0801: */
0802: public abstract long log(String[] targetPaths, long startRevision,
0803: long endRevision, boolean changedPath, boolean strictNode,
0804: long limit, ISVNLogEntryHandler handler)
0805: throws SVNException;
0806:
0807: /**
0808: * Gets entry locations in time. The location of an entry in a repository
0809: * may change from revision to revision. This method allows to trace entry locations
0810: * in different revisions.
0811: *
0812: * <p>
0813: * For each interesting revision (taken from <code>revisions</code>) an entry location
0814: * is represented by an <b>SVNLocationEntry</b> object which is passed to the provided
0815: * <code>handler</code>. Each <b>SVNLocationEntry</b> object represents a repository path
0816: * in a definite revision.
0817: *
0818: * <p>
0819: * The <code>path</code> arg can be both relative to the location of
0820: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0821: *
0822: * <p>
0823: * <b>NOTES:</b>
0824: * <ul>
0825: * <li>you may not invoke methods of this <b>SVNRepository</b>
0826: * object from within the provided <code>handler</code>
0827: * <li>this functionality is not available in pre-1.1 servers
0828: * </ul>
0829: *
0830: * @param path an item's path
0831: * @param pegRevision a revision in which <code>path</code> is first
0832: * looked up
0833: * @param revisions an array of numbers of interesting revisions in which
0834: * locations are looked up. If <code>path</code>
0835: * doesn't exist in an interesting revision, that revision
0836: * will be ignored.
0837: * @param handler a location entry handler that will handle all found entry
0838: * locations
0839: * @return the number of the entry locations found
0840: * @throws SVNException in the following cases:
0841: * <ul>
0842: * <li><code>path</code> not found in the specified <code>pegRevision</code>
0843: * <li><code>pegRevision</code> is not valid
0844: * <li>a failure occured while connecting to a repository
0845: * <li>the user authentication failed
0846: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0847: * </ul>
0848: * @see #getLocations(String, Collection, long, long[])
0849: * @see #getLocations(String, Map, long, long[])
0850: * @see ISVNLocationEntryHandler
0851: * @see SVNLocationEntry
0852: * @since SVN 1.1
0853: */
0854: public abstract int getLocations(String path, long pegRevision,
0855: long[] revisions, ISVNLocationEntryHandler handler)
0856: throws SVNException;
0857:
0858: /**
0859: * Retrieves and returns interesting file revisions for the specified file.
0860: *
0861: * <p>
0862: * A file revision is represented by an <b>SVNFileRevision</b> object.
0863: * Only those revisions will be retrieved in which the file was changed.
0864: * The iteration will begin at the first such revision starting from the
0865: * <code>startRevision</code> and so on - up to the <code>endRevision</code>.
0866: *
0867: * <p>
0868: * The <code>path</code> arg can be both relative to the location of
0869: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0870: *
0871: * <p>
0872: * <b>NOTE:</b> this functionality is not available in pre-1.1 servers
0873: *
0874: * @param path a file path
0875: * @param revisions if not <span class="javakeyword">null</span> this collection
0876: * will receive all the fetched file revisions
0877: * @param sRevision a revision to start from
0878: * @param eRevision a revision to stop at
0879: * @return a collection that keeps file revisions - {@link SVNFileRevision} instances
0880: * @throws SVNException if a failure occured while connecting to a repository
0881: * or the user's authentication failed (see
0882: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0883: * @see #getFileRevisions(String, long, long, ISVNFileRevisionHandler)
0884: * @see SVNFileRevision
0885: * @since SVN 1.1
0886: */
0887: public Collection getFileRevisions(String path,
0888: Collection revisions, long sRevision, long eRevision)
0889: throws SVNException {
0890: final Collection result = revisions != null ? revisions
0891: : new LinkedList();
0892: ISVNFileRevisionHandler handler = new ISVNFileRevisionHandler() {
0893: public void openRevision(SVNFileRevision fileRevision)
0894: throws SVNException {
0895: result.add(fileRevision);
0896: }
0897:
0898: public void applyTextDelta(String path, String baseChecksum)
0899: throws SVNException {
0900: }
0901:
0902: public OutputStream textDeltaChunk(String token,
0903: SVNDiffWindow diffWindow) throws SVNException {
0904: return SVNFileUtil.DUMMY_OUT;
0905: }
0906:
0907: public void textDeltaEnd(String token) throws SVNException {
0908: }
0909:
0910: public void closeRevision(String token) throws SVNException {
0911: }
0912: };
0913: getFileRevisions(path, sRevision, eRevision, handler);
0914: return result;
0915: }
0916:
0917: /**
0918: * Fetches the contents and properties of a directory located at the specified path
0919: * in a particular revision. Information of each directory
0920: * entry is represented by a single <b>SVNDirEntry</b> object.
0921: *
0922: * <p>
0923: * The <code>path</code> arg can be both relative to the location of
0924: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0925: *
0926: * @param path a directory path
0927: * @param revision a revision number
0928: * @param properties if not <span class="javakeyword">null</span> then all
0929: * directory properties (including non-tweakable ones)
0930: * will be put into this map (where keys are property names
0931: * and mappings are property values)
0932: * @param dirEntries if not <span class="javakeyword">null</span> then this
0933: * collection receives fetched dir entries (<b>SVNDirEntry</b> objects)
0934: * @return a collection containing fetched directory entries (<b>SVNDirEntry</b> objects)
0935: * @throws SVNException in the following cases:
0936: * <ul>
0937: * <li><code>path</code> not found in the specified <code>revision</code>
0938: * <li><code>path</code> is not a directory
0939: * <li>a failure occured while connecting to a repository
0940: * <li>the user authentication failed
0941: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0942: * </ul>
0943: * @see #getDir(String, long, Map, ISVNDirEntryHandler)
0944: * @see #getDir(String, long, boolean, Collection)
0945: * @see org.tmatesoft.svn.core.SVNDirEntry
0946: */
0947: public Collection getDir(String path, long revision,
0948: Map properties, Collection dirEntries) throws SVNException {
0949: final Collection result = dirEntries != null ? dirEntries
0950: : new LinkedList();
0951: ISVNDirEntryHandler handler;
0952: handler = new ISVNDirEntryHandler() {
0953: public void handleDirEntry(SVNDirEntry dirEntry) {
0954: result.add(dirEntry);
0955: }
0956: };
0957: getDir(path, revision, properties, handler);
0958: return result;
0959: }
0960:
0961: /**
0962: * Fetches the contents of a directory into the provided
0963: * collection object and returns the directory entry itself.
0964: *
0965: * <p>
0966: * If <code>entries</code> arg is not <span class="javakeyword">null</span> it
0967: * receives the directory entries. Information of each directory entry is
0968: * represented by an <b>SVNDirEntry</b> object.
0969: *
0970: * <p>
0971: * The <code>path</code> arg can be both relative to the location of
0972: * this driver and absolute to the repository root (starts with <code>"/"</code>).
0973: *
0974: * @param path a directory path
0975: * @param revision a revision number
0976: * @param includeCommitMessages if <span class="javakeyword">true</span> then
0977: * dir entries (<b>SVNDirEntry</b> objects) will be supplied
0978: * with commit log messages, otherwise not
0979: * @param entries a collection that receives fetched dir entries
0980: * @return the directory entry itself which contents
0981: * are fetched into <code>entries</code>
0982: * @throws SVNException in the following cases:
0983: * <ul>
0984: * <li><code>path</code> not found in the specified <code>revision</code>
0985: * <li><code>path</code> is not a directory
0986: * <li>a failure occured while connecting to a repository
0987: * <li>the user authentication failed
0988: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
0989: * </ul>
0990: * @see #getDir(String, long, Map, ISVNDirEntryHandler)
0991: * @see #getDir(String, long, Map, Collection)
0992: * @see org.tmatesoft.svn.core.SVNDirEntry
0993: */
0994: public abstract SVNDirEntry getDir(String path, long revision,
0995: boolean includeCommitMessages, Collection entries)
0996: throws SVNException;
0997:
0998: /**
0999: * Traverses revisions history and returns a collection of log entries. In
1000: * other words, collects per revision information that includes the revision number,
1001: * author, datestamp, log message and maybe a list of changed paths (optional). For each
1002: * revision this information is represented by an <b>SVNLogEntry</b>.
1003: * object.
1004: *
1005: * <p>
1006: * <code>startRevision</code> may be greater or less than
1007: * <code>endRevision</code>; this just controls whether the log messages are
1008: * processed in descending or ascending revision number order.
1009: *
1010: * <p>
1011: * If <code>startRevision</code> or <code>endRevision</code> is invalid, it
1012: * defaults to the youngest.
1013: *
1014: * <p>
1015: * If <code>targetPaths</code> has one or more elements, then
1016: * only those revisions are processed in which at least one of <code>targetPaths</code> was
1017: * changed (i.e., if a file text or properties changed; if dir properties
1018: * changed or an entry was added or deleted). Each path is relative
1019: * to the repository location that this object is set to.
1020: *
1021: * <p>
1022: * If <code>changedPath</code> is <span class="javakeyword">true</span>, then each
1023: * <b>SVNLogEntry</b> object is supplied with info about all
1024: * paths changed in that revision it represents. To get them call
1025: * {@link org.tmatesoft.svn.core.SVNLogEntry#getChangedPaths()} that returns a map,
1026: * which keys are the changed paths and the mappings are <b>SVNLogEntryPath</b> objects.
1027: * If <code>changedPath</code> is <span class="javakeyword">false</span>, changed paths
1028: * info will not be provided.
1029: *
1030: * <p>
1031: * If <code>strictNode</code> is <span class="javakeyword">true</span>, copy history will
1032: * not be traversed (if any exists) when harvesting the revision logs for each path.
1033: *
1034: * <p>
1035: * Target paths can be both relative to the location of
1036: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1037: *
1038: * @param targetPaths paths that mean only those revisions at which they were
1039: * changed
1040: * @param entries if not <span class="javakeyword">null</span> then this collection
1041: * will receive log entries
1042: * @param startRevision a revision to start from
1043: * @param endRevision a revision to end at
1044: * @param changedPath if <span class="javakeyword">true</span> then
1045: * revision information will also include all changed paths per
1046: * revision, otherwise not
1047: * @param strictNode if <span class="javakeyword">true</span> then copy history (if any) is not
1048: * to be traversed
1049: * @return a collection with log entries
1050: * @throws SVNException if a failure occured while connecting to a repository
1051: * or the user's authentication failed (see
1052: * {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1053: * @see #log(String[], long, long, boolean, boolean, ISVNLogEntryHandler)
1054: * @see #log(String[], long, long, boolean, boolean, long, ISVNLogEntryHandler)
1055: * @see org.tmatesoft.svn.core.ISVNLogEntryHandler
1056: * @see org.tmatesoft.svn.core.SVNLogEntry
1057: * @see org.tmatesoft.svn.core.SVNLogEntryPath
1058: */
1059: public Collection log(String[] targetPaths, Collection entries,
1060: long startRevision, long endRevision, boolean changedPath,
1061: boolean strictNode) throws SVNException {
1062: final Collection result = entries != null ? entries
1063: : new LinkedList();
1064: log(targetPaths, startRevision, endRevision, changedPath,
1065: strictNode, new ISVNLogEntryHandler() {
1066: public void handleLogEntry(SVNLogEntry logEntry) {
1067: result.add(logEntry);
1068: }
1069: });
1070: return result;
1071: }
1072:
1073: /**
1074: * Gets entry locations in time. The location of an entry in a repository
1075: * may change from revision to revision. This method allows to trace entry locations
1076: * in different revisions.
1077: *
1078: * <p>
1079: * For each interesting revision (taken from <code>revisions</code>) an entry location
1080: * is represented by an <b>SVNLocationEntry</b> object. Each <b>SVNLocationEntry</b>
1081: * object represents a repository path in a definite revision.
1082: *
1083: * <p>
1084: * The <code>path</code> arg can be both relative to the location of
1085: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1086: *
1087: * <p>
1088: * <b>NOTE:</b> this functionality is not available in pre-1.1 servers
1089: *
1090: * @param path an item's path
1091: * @param entries if not <span class="javakeyword">null</span> then this
1092: * collection object receives entry locations
1093: * @param pegRevision a revision in which <code>path</code> is first
1094: * looked up
1095: * @param revisions an array of numbers of interesting revisions in which
1096: * locations are looked up. If <code>path</code>
1097: * doesn't exist in an interesting revision, that revision
1098: * will be ignored.
1099: * @return a collection with retrieved entry locations
1100: * @throws SVNException in the following cases:
1101: * <ul>
1102: * <li><code>path</code> not found in the specified <code>pegRevision</code>
1103: * <li><code>pegRevision</code> is not valid
1104: * <li>a failure occured while connecting to a repository
1105: * <li>the user authentication failed
1106: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1107: * </ul>
1108: * @see #getLocations(String, long, long[], ISVNLocationEntryHandler)
1109: * @see #getLocations(String, Map, long, long[])
1110: * @see SVNLocationEntry
1111: * @see ISVNLocationEntryHandler
1112: * @since SVN 1.1
1113: */
1114: public Collection getLocations(String path, Collection entries,
1115: long pegRevision, long[] revisions) throws SVNException {
1116: final Collection result = entries != null ? entries
1117: : new LinkedList();
1118: getLocations(path, pegRevision, revisions,
1119: new ISVNLocationEntryHandler() {
1120: public void handleLocationEntry(
1121: SVNLocationEntry locationEntry) {
1122: result.add(locationEntry);
1123: }
1124: });
1125: return result;
1126: }
1127:
1128: /**
1129: * Gets entry locations in time. The location of an entry in a repository
1130: * may change from revision to revision. This method allows to trace entry locations
1131: * in different revisions.
1132: *
1133: * <p>
1134: * For each interesting revision (taken from <code>revisions</code>) an entry location
1135: * is represented by an <b>SVNLocationEntry</b> object. Each <b>SVNLocationEntry</b>
1136: * object represents a repository path in a definite revision.
1137: *
1138: * <p>
1139: * The <code>path</code> arg can be both relative to the location of
1140: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1141: *
1142: * <p>
1143: * <b>NOTE:</b> this functionality is not available in pre-1.1 servers
1144: *
1145: * @param path an item's path
1146: * @param entries if not <span class="javakeyword">null</span> then this
1147: * map object receives entry locations (which keys are revision
1148: * numbers as Longs and mappings are entry locations objects)
1149: * @param pegRevision a revision in which <code>path</code> is first
1150: * looked up
1151: * @param revisions an array of numbers of interesting revisions in which
1152: * locations are looked up. If <code>path</code>
1153: * doesn't exist in an interesting revision, that revision
1154: * will be ignored.
1155: * @return a map (which keys are revision numbers as Longs and mappings
1156: * are entry locations objects) with collected entry locations
1157: * @throws SVNException in the following cases:
1158: * <ul>
1159: * <li><code>path</code> not found in the specified <code>pegRevision</code>
1160: * <li><code>pegRevision</code> is not valid
1161: * <li>a failure occured while connecting to a repository
1162: * <li>the user authentication failed
1163: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1164: * </ul>
1165: * @see #getLocations(String, long, long[], ISVNLocationEntryHandler)
1166: * @see #getLocations(String, Collection, long, long[])
1167: * @see SVNLocationEntry
1168: * @see ISVNLocationEntryHandler
1169: * @since SVN 1.1
1170: */
1171: public Map getLocations(String path, Map entries, long pegRevision,
1172: long[] revisions) throws SVNException {
1173: final Map result = entries != null ? entries : new HashMap();
1174: getLocations(path, pegRevision, revisions,
1175: new ISVNLocationEntryHandler() {
1176: public void handleLocationEntry(
1177: SVNLocationEntry locationEntry) {
1178: result.put(
1179: new Long(locationEntry.getRevision()),
1180: locationEntry);
1181: }
1182: });
1183: return result;
1184: }
1185:
1186: /**
1187: * Calculates the differences between two items.
1188: *
1189: * <p>
1190: * <code>target</code> is the name (one-level path component) of an entry that will restrict
1191: * the scope of the diff operation to this entry. In other words <code>target</code> is a child entry of the
1192: * directory represented by the repository location to which this object is set. For
1193: * example, if we have something like <code>"/dirA/dirB"</code> in a repository, then
1194: * this object's repository location may be set to <code>"svn://host:port/path/to/repos/dirA"</code>,
1195: * and <code>target</code> may be <code>"dirB"</code>.
1196: *
1197: * <p>
1198: * If <code>target</code> is <span class="javakeyword">null</span> or empty (<code>""</code>)
1199: * then the scope of the diff operation is the repository location to which
1200: * this object is set.
1201: *
1202: * <p>
1203: * The <code>reporter</code> is used to describe the state of the target item(s) (i.e.
1204: * items' revision numbers). All the paths described by the <code>reporter</code>
1205: * should be relative to the repository location to which this object is set.
1206: *
1207: * <p>
1208: * After that the <code>editor</code> is used to carry out all the work on
1209: * evaluating differences against <code>url</code>. This <code>editor</code> contains
1210: * knowledge of where the change will begin (when {@link ISVNEditor#openRoot(long) ISVNEditor.openRoot()}
1211: * is called).
1212: *
1213: * <p>
1214: * If <code>ignoreAncestry</code> is <span class="javakeyword">false</span> then
1215: * the ancestry of the paths being diffed is taken into consideration - they
1216: * are treated as related. In this case, for example, if calculating differences between
1217: * two files with identical contents but different ancestry,
1218: * the entire contents of the target file is considered as having been removed and
1219: * added again.
1220: *
1221: * <p>
1222: * If <code>ignoreAncestry</code> is <span class="javakeyword">true</span>
1223: * then the two paths are merely compared ignoring the ancestry.
1224: *
1225: * <p>
1226: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1227: * object from within the provided <code>reporter</code> and <code>editor</code>.
1228: *
1229: * @param url a repository location of the entry against which
1230: * differences are calculated
1231: * @param targetRevision a revision number of the entry located at the
1232: * specified <code>url</code>; defaults to the
1233: * latest revision (HEAD) if this arg is invalid
1234: * @param revision a revision number of the repository location to which
1235: * this driver object is set
1236: * @param target a target entry name (optional)
1237: * @param ignoreAncestry if <span class="javakeyword">true</span> then
1238: * the ancestry of the two entries to be diffed is
1239: * ignored, otherwise not
1240: * @param recursive if <span class="javakeyword">true</span> and the diff scope
1241: * is a directory, descends recursively, otherwise not
1242: * @param getContents if <span class="javakeyword">false</span> contents (diff windows) will not be sent ot
1243: * the editor.
1244: * @param reporter a caller's reporter
1245: * @param editor a caller's editor
1246: * @throws SVNException in the following cases:
1247: * <ul>
1248: * <li><code>url</code> not found neither in the specified
1249: * <code>revision</code> nor in the HEAD revision
1250: * <li>a failure occured while connecting to a repository
1251: * <li>the user authentication failed
1252: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1253: * </ul>
1254: * @see ISVNReporterBaton
1255: * @see ISVNReporter
1256: * @see ISVNEditor
1257: */
1258: public abstract void diff(SVNURL url, long targetRevision,
1259: long revision, String target, boolean ignoreAncestry,
1260: boolean recursive, boolean getContents,
1261: ISVNReporterBaton reporter, ISVNEditor editor)
1262: throws SVNException;
1263:
1264: /**
1265: * @deprecated
1266: */
1267: public abstract void diff(SVNURL url, long targetRevision,
1268: long revision, String target, boolean ignoreAncestry,
1269: boolean recursive, ISVNReporterBaton reporter,
1270: ISVNEditor editor) throws SVNException;
1271:
1272: /**
1273: * Calculates the differences between two items.
1274: *
1275: * <p>
1276: * <code>target</code> is the name (one-level path component) of an entry that will restrict
1277: * the scope of the diff operation to this entry. In other words <code>target</code> is a child entry of the
1278: * directory represented by the repository location to which this object is set. For
1279: * example, if we have something like <code>"/dirA/dirB"</code> in a repository, then
1280: * this object's repository location may be set to <code>"svn://host:port/path/to/repos/dirA"</code>,
1281: * and <code>target</code> may be <code>"dirB"</code>.
1282: *
1283: * <p>
1284: * If <code>target</code> is <span class="javakeyword">null</span> or empty (<code>""</code>)
1285: * then the scope of the diff operation is the repository location to which
1286: * this object is set.
1287: *
1288: * <p>
1289: * The <code>reporter</code> is used to describe the state of the target item(s) (i.e.
1290: * items' revision numbers). All the paths described by the <code>reporter</code>
1291: * should be relative to the repository location to which this object is set.
1292: *
1293: * <p>
1294: * After that the <code>editor</code> is used to carry out all the work on
1295: * evaluating differences against <code>url</code>. This <code>editor</code> contains
1296: * knowledge of where the change will begin (when {@link ISVNEditor#openRoot(long) ISVNEditor.openRoot()}
1297: * is called).
1298: *
1299: * <p>
1300: * If <code>ignoreAncestry</code> is <span class="javakeyword">false</span> then
1301: * the ancestry of the paths being diffed is taken into consideration - they
1302: * are treated as related. In this case, for example, if calculating differences between
1303: * two files with identical contents but different ancestry,
1304: * the entire contents of the target file is considered as having been removed and
1305: * added again.
1306: *
1307: * <p>
1308: * If <code>ignoreAncestry</code> is <span class="javakeyword">true</span>
1309: * then the two paths are merely compared ignoring the ancestry.
1310: *
1311: * <p>
1312: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1313: * object from within the provided <code>reporter</code> and <code>editor</code>.
1314: *
1315: * @param url a repository location of the entry against which
1316: * differences are calculated
1317: * @param revision a revision number of the repository location to which
1318: * this driver object is set
1319: * @param target a target entry name (optional)
1320: * @param ignoreAncestry if <span class="javakeyword">true</span> then
1321: * the ancestry of the two entries to be diffed is
1322: * ignored, otherwise not
1323: * @param recursive if <span class="javakeyword">true</span> and the diff scope
1324: * is a directory, descends recursively, otherwise not
1325: * @param reporter a caller's reporter
1326: * @param editor a caller's editor
1327: * @throws SVNException in the following cases:
1328: * <ul>
1329: * <li><code>url</code> not found neither in the specified
1330: * <code>revision</code> nor in the HEAD revision
1331: * <li>a failure occured while connecting to a repository
1332: * <li>the user authentication failed
1333: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1334: * </ul>
1335: * @deprecated use {@link #diff(SVNURL, long, long, String, boolean, boolean, ISVNReporterBaton, ISVNEditor)} instead
1336: * @see ISVNReporterBaton
1337: * @see ISVNReporter
1338: * @see ISVNEditor
1339: */
1340: public abstract void diff(SVNURL url, long revision, String target,
1341: boolean ignoreAncestry, boolean recursive,
1342: ISVNReporterBaton reporter, ISVNEditor editor)
1343: throws SVNException;
1344:
1345: /**
1346: * Updates a path receiving changes from a repository.
1347: *
1348: * <p>
1349: * <code>target</code> is the name (one-level path component) of an entry that will
1350: * restrict the scope of the update to this entry. In other words <code>target</code> is a child entry of the
1351: * directory represented by the repository location to which this object is set. For
1352: * example, if we have something like <code>"/dirA/dirB"</code> in a repository, then
1353: * this object's repository location may be set to <code>"svn://host:port/path/to/repos/dirA"</code>,
1354: * and <code>target</code> may be <code>"dirB"</code>.
1355: *
1356: * <p>
1357: * If <code>target</code> is <span class="javakeyword">null</span> or empty (<code>""</code>)
1358: * then the scope of the update operation is the repository location to which
1359: * this object is set.
1360: *
1361: * <p>
1362: * The <code>reporter</code> is used to describe the state of the local item(s) (i.e.
1363: * items' revision numbers, deleted, switched items). All the paths described by the
1364: * <code>reporter</code> should be relative to the repository location to which this
1365: * object is set.
1366: *
1367: * <p>
1368: * After that the <code>editor</code> is used to carry out all the work on
1369: * updating. This <code>editor</code> contains
1370: * knowledge of where the change will begin (when {@link ISVNEditor#openRoot(long) ISVNEditor.openRoot()}
1371: * is called).
1372: *
1373: * <p>
1374: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1375: * object from within the provided <code>reporter</code> and <code>editor</code>.
1376: *
1377: * @param revision a desired revision to make update to; defaults to
1378: * the latest revision (HEAD)
1379: * @param target an entry name (optional)
1380: * @param recursive if <span class="javakeyword">true</span> and the update scope
1381: * is a directory, descends recursively, otherwise not
1382: * @param reporter a caller's reporter
1383: * @param editor a caller's editor
1384: * @throws SVNException in the following cases:
1385: * <ul>
1386: * <li>a failure occured while connecting to a repository
1387: * <li>the user authentication failed
1388: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1389: * </ul>
1390: * @see #update(SVNURL, long, String, boolean, ISVNReporterBaton, ISVNEditor)
1391: * @see ISVNReporterBaton
1392: * @see ISVNReporter
1393: * @see ISVNEditor
1394: * @see <a href="http://svnkit.com/kb/dev-guide-update-operation.html">Using ISVNReporter/ISVNEditor in update-related operations</a>
1395: */
1396: public abstract void update(long revision, String target,
1397: boolean recursive, ISVNReporterBaton reporter,
1398: ISVNEditor editor) throws SVNException;
1399:
1400: /**
1401: * Gets status of a path.
1402: *
1403: * <p>
1404: * <code>target</code> is the name (one-level path component) of an entry that will
1405: * restrict the scope of the status to this entry. In other words <code>target</code> is a child entry of the
1406: * directory represented by the repository location to which this object is set. For
1407: * example, if we have something like <code>"/dirA/dirB"</code> in a repository, then
1408: * this object's repository location may be set to <code>"svn://host:port/path/to/repos/dirA"</code>,
1409: * and <code>target</code> may be <code>"dirB"</code>.
1410: *
1411: * <p>
1412: * If <code>target</code> is <span class="javakeyword">null</span> or empty (<code>""</code>)
1413: * then the scope of the update operation is the repository location to which
1414: * this object is set.
1415: *
1416: * <p>
1417: * The <code>reporter</code> is used to describe the state of the local item(s) (i.e.
1418: * items' revision numbers, deleted, switched items). All the paths described by the
1419: * <code>reporter</code> should be relative to the repository location to which this
1420: * object is set.
1421: *
1422: * <p>
1423: * After that the <code>editor</code> is used to carry out all the work on
1424: * performing status. This <code>editor</code> contains
1425: * knowledge of where the change will begin (when {@link ISVNEditor#openRoot(long) ISVNEditor.openRoot()}
1426: * is called).
1427: *
1428: * <p>
1429: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1430: * object from within the provided <code>reporter</code> and <code>editor</code>.
1431: *
1432: * @param revision a desired revision to get status against; defaults to
1433: * the latest revision (HEAD)
1434: * @param target an entry name (optional)
1435: * @param recursive if <span class="javakeyword">true</span> and the status scope
1436: * is a directory, descends recursively, otherwise not
1437: * @param reporter a client's reporter-baton
1438: * @param editor a client's status editor
1439: * @throws SVNException in the following cases:
1440: * <ul>
1441: * <li>a failure occured while connecting to a repository
1442: * <li>the user authentication failed
1443: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1444: * </ul>
1445: * @see ISVNReporterBaton
1446: * @see ISVNEditor
1447: */
1448: public abstract void status(long revision, String target,
1449: boolean recursive, ISVNReporterBaton reporter,
1450: ISVNEditor editor) throws SVNException;
1451:
1452: /**
1453: * Updates a path switching it to a new repository location.
1454: *
1455: * <p>
1456: * Updates a path as it's described for the {@link #update(long, String, boolean, ISVNReporterBaton, ISVNEditor) update()}
1457: * method using the provided <code>reporter</code> and <code>editor</code>, and switching
1458: * it to a new repository location.
1459: *
1460: * <p>
1461: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1462: * object from within the provided <code>reporter</code> and <code>editor</code>.
1463: *
1464: * @param url a new location in the repository to switch to
1465: * @param revision a desired revision to make update to; defaults
1466: * to the latest revision (HEAD)
1467: * @param target an entry name (optional)
1468: * @param recursive if <span class="javakeyword">true</span> and the switch scope
1469: * is a directory, descends recursively, otherwise not
1470: * @param reporter a caller's reporter
1471: * @param editor a caller's editor
1472: * @throws SVNException in the following cases:
1473: * <ul>
1474: * <li>a failure occured while connecting to a repository
1475: * <li>the user authentication failed
1476: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1477: * </ul>
1478: * @see #update(long, String, boolean, ISVNReporterBaton, ISVNEditor)
1479: * @see ISVNReporterBaton
1480: * @see ISVNReporter
1481: * @see ISVNEditor
1482: * @see <a href="http://svnkit.com/kb/dev-guide-update-operation.html">Using ISVNReporter/ISVNEditor in update-related operations</a>
1483: */
1484: public abstract void update(SVNURL url, long revision,
1485: String target, boolean recursive,
1486: ISVNReporterBaton reporter, ISVNEditor editor)
1487: throws SVNException;
1488:
1489: /**
1490: * Checks out a directory from a repository .
1491: *
1492: * <p>
1493: * <code>target</code> is the name (one-level path component) of an entry that will
1494: * restrict the scope of the checkout to this entry. In other words <code>target</code> is a child entry of the
1495: * directory represented by the repository location to which this object is set. For
1496: * example, if we have something like <code>"/dirA/dirB"</code> in a repository, then
1497: * this object's repository location may be set to <code>"svn://host:port/path/to/repos/dirA"</code>,
1498: * and <code>target</code> may be <code>"dirB"</code>.
1499: *
1500: * <p>
1501: * If <code>target</code> is <span class="javakeyword">null</span> or empty (<code>""</code>)
1502: * then the scope of the checkout operation is the repository location to which
1503: * this object is set.
1504: *
1505: * <p>
1506: * The provided <code>editor</code> is used to carry out all the work on
1507: * building a local tree of dirs and files being checked out.
1508: *
1509: * <p>
1510: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1511: * object from within the provided <code>editor</code>.
1512: *
1513: * @param revision a desired revision of a dir to check out; defaults
1514: * to the latest revision (HEAD)
1515: * @param target an entry name (optional)
1516: * @param recursive if <span class="javakeyword">true</span> and the checkout
1517: * scope is a directory, descends recursively, otherwise not
1518: * @param editor a caller's checkout editor
1519: * @throws SVNException in the following cases:
1520: * <ul>
1521: * <li>the checkout scope is not a directory (only dirs can
1522: * be checked out)
1523: * <li>a failure occured while connecting to a repository
1524: * <li>the user authentication failed
1525: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1526: * </ul>
1527: * @see #update(long, String, boolean, ISVNReporterBaton, ISVNEditor)
1528: * @see ISVNEditor
1529: *
1530: */
1531: public void checkout(long revision, String target,
1532: boolean recursive, ISVNEditor editor) throws SVNException {
1533: final long lastRev = revision >= 0 ? revision
1534: : getLatestRevision();
1535: // check path?
1536: SVNNodeKind nodeKind = checkPath("", revision);
1537: if (nodeKind == SVNNodeKind.FILE) {
1538: SVNErrorMessage err = SVNErrorMessage.create(
1539: SVNErrorCode.RA_ILLEGAL_URL,
1540: "URL ''{0}'' refers to a file, not a directory",
1541: getLocation());
1542: SVNErrorManager.error(err);
1543: } else if (nodeKind == SVNNodeKind.NONE) {
1544: SVNErrorMessage err = SVNErrorMessage.create(
1545: SVNErrorCode.RA_ILLEGAL_URL,
1546: "URL ''{0}'' doesn't exist", getLocation());
1547: SVNErrorManager.error(err);
1548: }
1549: update(revision, target, recursive, new ISVNReporterBaton() {
1550: public void report(ISVNReporter reporter)
1551: throws SVNException {
1552: reporter.setPath("", null, lastRev, true);
1553: reporter.finishReport();
1554: }
1555: }, editor);
1556: }
1557:
1558: /**
1559: * Replays the changes from the specified revision through the given editor.
1560: *
1561: * <p>
1562: * Changes will be limited to those that occur under a session's URL, and
1563: * the server will assume that the client has no knowledge of revisions
1564: * prior to a <code>lowRevision</code>. These two limiting factors define the portion
1565: * of the tree that the server will assume the client already has knowledge of,
1566: * and thus any copies of data from outside that part of the tree will be
1567: * sent in their entirety, not as simple copies or deltas against a previous
1568: * version.
1569: *
1570: * <p>
1571: * If <code>sendDeltas</code> is <span class="javakeyword">null</span>, the actual text
1572: * and property changes in the revision will be sent, otherwise no text deltas and
1573: * <span class="javakeyword">null</span> property changes will be sent instead.
1574: *
1575: * <p>
1576: * If <code>lowRevision</code> is invalid, it defaults to 0.
1577: *
1578: * @param lowRevision a low revision point beyond which a client has no
1579: * knowledge of paths history
1580: * @param revision a revision to replay
1581: * @param sendDeltas controls whether text and property changes are to be
1582: * sent
1583: * @param editor a commit editor to receive changes
1584: * @throws SVNException
1585: * @since 1.1, new in SVN 1.4
1586: */
1587: public abstract void replay(long lowRevision, long revision,
1588: boolean sendDeltas, ISVNEditor editor) throws SVNException;
1589:
1590: /* write methods */
1591: /**
1592: * Gets an editor for committing changes to a repository. Having got the editor
1593: * traverse a local tree of dirs and/or files to be committed, handling them
1594: * with corresponding methods of the editor.
1595: *
1596: * <p>
1597: * <code>mediator</code> is used for temporary delta data storage allocations.
1598: *
1599: * <p>
1600: * The root path of the commit is the current repository location to which
1601: * this object is set.
1602: *
1603: * <p>
1604: * After the commit has succeeded {@link ISVNEditor#closeEdit()
1605: * ISVNEditor.closeEdit()} returns an <b>SVNCommitInfo</b> object
1606: * that contains a new revision number, the commit date, commit author.
1607: *
1608: * <p>
1609: * This method should be rather used with pre-1.2 repositories.
1610: *
1611: * <p>
1612: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1613: * object from within the returned commit editor.
1614: *
1615: * @param logMessage a commit log message
1616: * @param mediator temp delta storage provider; used also to cache
1617: * wcprops while committing
1618: * @return an editor to commit a local tree of dirs and/or files
1619: * @throws SVNException in the following cases:
1620: * <ul>
1621: * <li>the repository location this object is set to is not a
1622: * directory
1623: * <li>a failure occured while connecting to a repository
1624: * <li>the user authentication failed
1625: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1626: * </ul>
1627: * @see ISVNEditor
1628: * @see ISVNWorkspaceMediator
1629: * @see <a href="http://svnkit.com/kb/dev-guide-commit-operation.html">Using ISVNEditor in commit operations</a>
1630: */
1631: public ISVNEditor getCommitEditor(String logMessage,
1632: final ISVNWorkspaceMediator mediator) throws SVNException {
1633: return getCommitEditor(logMessage, null, false, mediator);
1634: }
1635:
1636: /**
1637: * Gives information about an entry located at the specified path in a particular
1638: * revision.
1639: *
1640: * <p>
1641: * The <code>path</code> arg can be both relative to the location of
1642: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1643: *
1644: * @param path an item's path
1645: * @param revision a revision of the entry; defaults to the latest
1646: * revision (HEAD)
1647: * @return an <b>SVNDirEntry</b> containing information about
1648: * the entry or <span class="javakeyword">null</span> if
1649: * there's no entry with at the specified <code>path</code>
1650: * under the specified <code>revision</code>
1651: * @throws SVNException in the following cases:
1652: * <ul>
1653: * <li>a failure occured while connecting to a repository
1654: * <li>the user authentication failed
1655: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1656: * </ul>
1657: */
1658: public abstract SVNDirEntry info(String path, long revision)
1659: throws SVNException;
1660:
1661: /**
1662: * Gets an editor for committing changes to a repository. Having got the editor
1663: * traverse a local tree of dirs and/or files to be committed, handling them
1664: * with corresponding methods of the editor.
1665: *
1666: * <p>
1667: * <code>locks</code> is a map used to provide lock tokens on the locked paths.
1668: * Keys are locked paths in a local tree, and each value for a key is a lock
1669: * token. <code>locks</code> must live during the whole commit operation.
1670: *
1671: * <p>
1672: * If <code>keepLocks</code> is <span class="javakeyword">true</span>, then the locked
1673: * paths won't be unlocked after a successful commit. Otherwise, if
1674: * <span class="javakeyword">false</span>, locks will be automatically released.
1675: *
1676: * <p>
1677: * <code>mediator</code> is used for temporary delta data storage allocations.
1678: *
1679: * <p>
1680: * The root path of the commit is the current repository location to which
1681: * this object is set.
1682: *
1683: * <p>
1684: * After the commit has succeeded {@link ISVNEditor#closeEdit()
1685: * ISVNEditor.closeEdit()} returns an <b>SVNCommitInfo</b> object
1686: * that contains a new revision number, the commit date, commit author.
1687: *
1688: * <p>
1689: * <b>NOTE:</b> you may not invoke methods of this <b>SVNRepository</b>
1690: * object from within the returned commit editor.
1691: *
1692: * @param logMessage a commit log message
1693: * @param locks a map containing locked paths mapped to lock
1694: * tokens
1695: * @param keepLocks <span class="javakeyword">true</span> to keep
1696: * existing locks; <span class="javakeyword">false</span>
1697: * to release locks after the commit
1698: * @param mediator temp delta storage provider; used also to cache
1699: * wcprops while committing
1700: * @return an editor to commit a local tree of dirs and/or files
1701: * @throws SVNException in the following cases:
1702: * <ul>
1703: * <li>the repository location this object is set to is not a
1704: * directory
1705: * <li>a failure occured while connecting to a repository
1706: * <li>the user authentication failed
1707: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1708: * </ul>
1709: * @see #getCommitEditor(String, ISVNWorkspaceMediator)
1710: * @see <a href="http://svnkit.com/kb/dev-guide-commit-operation.html">Using ISVNEditor in commit operations</a>
1711: */
1712: public abstract ISVNEditor getCommitEditor(String logMessage,
1713: Map locks, boolean keepLocks,
1714: final ISVNWorkspaceMediator mediator) throws SVNException;
1715:
1716: /**
1717: * Gets the lock for the file located at the specified path.
1718: * If the file has no lock the method returns <span class="javakeyword">null</span>.
1719: *
1720: * <p>
1721: * The <code>path</code> arg can be both relative to the location of
1722: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1723: *
1724: * @param path a file path
1725: * @return an <b>SVNLock</b> instance (representing the lock) or
1726: * <span class="javakeyword">null</span> if there's no lock
1727: * @throws SVNException in the following cases:
1728: * <ul>
1729: * <li>a failure occured while connecting to a repository
1730: * <li>the user authentication failed
1731: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1732: * </ul>
1733: * @see #lock(Map, String, boolean, ISVNLockHandler)
1734: * @see #unlock(Map, boolean, ISVNLockHandler)
1735: * @see #getLocks(String)
1736: * @see org.tmatesoft.svn.core.SVNLock
1737: * @since SVN 1.2
1738: */
1739: public abstract SVNLock getLock(String path) throws SVNException;
1740:
1741: /**
1742: * Gets all locks on or below the <code>path</code>, that is if the repository
1743: * entry (located at the <code>path</code>) is a directory then the method
1744: * returns locks of all locked files (if any) in it.
1745: *
1746: * <p>
1747: * The <code>path</code> arg can be both relative to the location of
1748: * this driver and absolute to the repository root (starts with <code>"/"</code>).
1749: *
1750: * @param path a path under which locks are to be retrieved
1751: * @return an array of <b>SVNLock</b> objects (representing locks)
1752: * @throws SVNException in the following cases:
1753: * <ul>
1754: * <li>a failure occured while connecting to a repository
1755: * <li>the user authentication failed
1756: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1757: * </ul>
1758: * @see #lock(Map, String, boolean, ISVNLockHandler)
1759: * @see #unlock(Map, boolean, ISVNLockHandler)
1760: * @see #getLock(String)
1761: * @see org.tmatesoft.svn.core.SVNLock
1762: * @since SVN 1.2
1763: */
1764: public abstract SVNLock[] getLocks(String path) throws SVNException;
1765:
1766: /**
1767: * Locks path(s) at definite revision(s).
1768: *
1769: * <p>
1770: * Note that locking is never anonymous, so any server implementing
1771: * this function will have to "pull" a username from the client, if
1772: * it hasn't done so already.
1773: *
1774: * <p>
1775: * Each path to be locked is handled with the provided <code>handler</code>.
1776: * If a path was successfully locked, the <code>handler</code>'s
1777: * {@link ISVNLockHandler#handleLock(String, SVNLock, SVNErrorMessage) handleLock()}
1778: * is called that receives the path and either a lock object (representing the lock
1779: * that was set on the path) or an error exception, if locking failed for that path.
1780: *
1781: * <p>
1782: * If any path is already locked by a different user and the
1783: * <code>force</code> flag is <span class="javakeyword">false</span>, then this call fails
1784: * with throwing an <b>SVNException</b>. But if <code>force</code> is
1785: * <span class="javakeyword">true</span>, then the existing lock(s) will be "stolen" anyway,
1786: * even if the user name does not match the current lock's owner.
1787: *
1788: * <p>
1789: * Paths can be both relative to the location of this driver and absolute to
1790: * the repository root (starting with <code>"/"</code>).
1791: *
1792: * @param pathsToRevisions a map which keys are paths and values are
1793: * revision numbers (as Longs); paths are strings and revision
1794: * numbers are Long objects
1795: * @param comment a comment string for the lock (optional)
1796: * @param force <span class="javakeyword">true</span> if the file is to be
1797: * locked in any way (even if it's already locked by someone else)
1798: * @param handler if not <span class="javakeyword">null</span>, the lock
1799: * handler is invoked on each path to be locked
1800: * @throws SVNException in the following cases:
1801: * <ul>
1802: * <li><code>force</code> is <span class="javakeyword">false</span>
1803: * and a path is already locked by someone else
1804: * <li>a revision of a path is less than its last changed revision
1805: * <li>a path does not exist in the latest revision
1806: * <li>a failure occured while connecting to a repository
1807: * <li>the user authentication failed
1808: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1809: * </ul>
1810: * @see #unlock(Map, boolean, ISVNLockHandler)
1811: * @see #getLocks(String)
1812: * @see #getLock(String)
1813: * @see org.tmatesoft.svn.core.SVNLock
1814: * @since SVN 1.2
1815: */
1816: public abstract void lock(Map pathsToRevisions, String comment,
1817: boolean force, ISVNLockHandler handler) throws SVNException;
1818:
1819: /**
1820: * Removes lock(s) from the file(s).
1821: *
1822: * <p>
1823: * Note that unlocking is never anonymous, so any server
1824: * implementing this function will have to "pull" a username from
1825: * the client, if it hasn't done so already.
1826: *
1827: * <p>
1828: * Each path to be unlocked is handled with the provided <code>handler</code>.
1829: * If a path was successfully unlocked, the <code>handler</code>'s
1830: * {@link ISVNLockHandler#handleUnlock(String, SVNLock, SVNErrorMessage) handleUnlock()}
1831: * is called that receives the path and either a lock object (representing the lock
1832: * that was removed from the path) or an error exception, if unlocking failed for
1833: * that path.
1834: *
1835: * <p>
1836: * If the username doesn't match the lock's owner and <code>force</code> is
1837: * <span class="javakeyword">false</span>, this method call fails with
1838: * throwing an <b>SVNException</b>. But if the <code>force</code>
1839: * flag is <span class="javakeyword">true</span>, the lock will be "broken"
1840: * by the current user.
1841: *
1842: * <p>
1843: * Also if the lock token is incorrect or <span class="javakeyword">null</span>
1844: * and <code>force</code> is <span class="javakeyword">false</span>, the method
1845: * fails with throwing a <b>SVNException</b>. However, if <code>force</code> is
1846: * <span class="javakeyword">true</span> the lock will be removed anyway.
1847: *
1848: * <p>
1849: * Paths can be both relative to the location of this driver and absolute to
1850: * the repository root (starting with <code>"/"</code>).
1851: *
1852: * @param pathToTokens a map which keys are file paths and values are file lock
1853: * tokens (both keys and values are strings)
1854: * @param force <span class="javakeyword">true</span> to remove the
1855: * lock in any case - i.e. to "break" the lock
1856: * @param handler if not <span class="javakeyword">null</span>, the lock
1857: * handler is invoked on each path to be unlocked
1858: * @throws SVNException in the following cases:
1859: * <ul>
1860: * <li><code>force</code> is <span class="javakeyword">false</span>
1861: * and the name of the user who tries to unlock a path does not match
1862: * the lock owner
1863: * <li>a lock token is incorrect for a path
1864: * <li>a failure occurred while connecting to a repository
1865: * <li>the user authentication failed
1866: * (see {@link org.tmatesoft.svn.core.SVNAuthenticationException})
1867: * </ul>
1868: * @see #lock(Map, String, boolean, ISVNLockHandler)
1869: * @see #getLocks(String)
1870: * @see #getLock(String)
1871: * @see org.tmatesoft.svn.core.SVNLock
1872: * @since SVN 1.2
1873: */
1874: public abstract void unlock(Map pathToTokens, boolean force,
1875: ISVNLockHandler handler) throws SVNException;
1876:
1877: /**
1878: * Closes the current session closing a socket connection used by
1879: * this object.
1880: * If this driver object keeps a single connection for
1881: * all the data i/o, this method helps to reset the connection.
1882: *
1883: * @throws SVNException if some i/o error has occurred
1884: */
1885: public abstract void closeSession();
1886:
1887: /**
1888: * Returns the session options object this driver is using.
1889: * If no options object was provided to create this driver then
1890: * it uses a default one - {@link ISVNSession#DEFAULT}.
1891: *
1892: * @return a session options object
1893: */
1894: public ISVNSession getOptions() {
1895: if (myOptions == null) {
1896: myOptions = ISVNSession.DEFAULT;
1897: }
1898: return myOptions;
1899: }
1900:
1901: public void addConnectionListener(ISVNConnectionListener listener) {
1902: myConnectionListeners.add(listener);
1903: }
1904:
1905: public void removeConnectionListener(ISVNConnectionListener listener) {
1906: myConnectionListeners.remove(listener);
1907: }
1908:
1909: protected void fireConnectionOpened() {
1910: for (Iterator listeners = myConnectionListeners.iterator(); listeners
1911: .hasNext();) {
1912: ISVNConnectionListener listener = (ISVNConnectionListener) listeners
1913: .next();
1914: listener.connectionOpened(this );
1915: }
1916: }
1917:
1918: protected void fireConnectionClosed() {
1919: for (Iterator listeners = myConnectionListeners.iterator(); listeners
1920: .hasNext();) {
1921: ISVNConnectionListener listener = (ISVNConnectionListener) listeners
1922: .next();
1923: listener.connectionClosed(this );
1924: }
1925: }
1926:
1927: protected synchronized void lock() {
1928: lock(false);
1929: }
1930:
1931: protected synchronized void lock(boolean force) {
1932: try {
1933: synchronized (this ) {
1934: if (Thread.currentThread() == myLocker) {
1935: if (!force) {
1936: getDebugLog().info(new Exception());
1937: throw new Error(
1938: "SVNRepository methods are not reenterable");
1939: }
1940: myLockCount++;
1941: return;
1942: }
1943: while (myLocker != null) {
1944: wait();
1945: }
1946: myLocker = Thread.currentThread();
1947: myLockCount++;
1948: }
1949: } catch (InterruptedException e) {
1950: throw new Error("Interrupted attempt to aquire write lock");
1951: }
1952: }
1953:
1954: protected synchronized void unlock() {
1955: synchronized (this ) {
1956: if (--myLockCount <= 0) {
1957: myLockCount = 0;
1958: myLocker = null;
1959: notify();
1960: }
1961: }
1962: }
1963:
1964: protected static boolean isInvalidRevision(long revision) {
1965: return revision < 0;
1966: }
1967:
1968: protected static boolean isValidRevision(long revision) {
1969: return revision >= 0;
1970: }
1971:
1972: protected static Long getRevisionObject(long revision) {
1973: return isValidRevision(revision) ? new Long(revision) : null;
1974: }
1975:
1976: protected static void assertValidRevision(long revision)
1977: throws SVNException {
1978: if (!isValidRevision(revision)) {
1979: SVNErrorMessage err = SVNErrorMessage.create(
1980: SVNErrorCode.CLIENT_BAD_REVISION,
1981: "Invalid revision number ''{0}''", new Long(
1982: revision));
1983: SVNErrorManager.error(err);
1984: }
1985: }
1986:
1987: // all paths are uri-decoded.
1988: //
1989: // get repository path (path starting with /, relative to repository root).
1990: // get full path (path starting with /, relative to host).
1991: // get relative path (repository path, now relative to repository location, not starting with '/').
1992:
1993: /**
1994: * Returns a path relative to the repository root directory given
1995: * a path relative to the location to which this driver object is set.
1996: *
1997: * @param relativePath a path relative to the location to which
1998: * this <b>SVNRepository</b> is set
1999: * @return a path relative to the repository root
2000: * @throws SVNException
2001: */
2002: public String getRepositoryPath(String relativePath)
2003: throws SVNException {
2004: if (relativePath == null) {
2005: return "/";
2006: }
2007: if (relativePath.length() > 0 && relativePath.charAt(0) == '/') {
2008: return relativePath;
2009: }
2010: String fullPath = SVNPathUtil.append(getLocation().getPath(),
2011: relativePath);
2012: String repositoryPath = fullPath.substring(getRepositoryRoot(
2013: true).getPath().length());
2014: if ("".equals(repositoryPath)) {
2015: return "/";
2016: }
2017: return repositoryPath;
2018: }
2019:
2020: /**
2021: * Resolves a path, relative either to the location to which this
2022: * driver object is set or to the repository root directory, to a
2023: * path, relative to the host.
2024: *
2025: * @param relativeOrRepositoryPath a relative path within the
2026: * repository
2027: * @return a path relative to the host
2028: * @throws SVNException
2029: */
2030: public String getFullPath(String relativeOrRepositoryPath)
2031: throws SVNException {
2032: if (relativeOrRepositoryPath == null) {
2033: return getFullPath("/");
2034: }
2035: String fullPath;
2036: if (relativeOrRepositoryPath.length() > 0
2037: && relativeOrRepositoryPath.charAt(0) == '/') {
2038: fullPath = SVNPathUtil.append(getRepositoryRoot(true)
2039: .getPath(), relativeOrRepositoryPath);
2040: } else {
2041: fullPath = SVNPathUtil.append(getLocation().getPath(),
2042: relativeOrRepositoryPath);
2043: }
2044: if (!fullPath.startsWith("/")) {
2045: fullPath = "/" + fullPath;
2046: }
2047: return fullPath;
2048: }
2049:
2050: /**
2051: * Sets a logger to write debug log information to.
2052: *
2053: * @param log a debug logger
2054: */
2055: public void setDebugLog(ISVNDebugLog log) {
2056: myDebugLog = log;
2057: }
2058:
2059: /**
2060: * Returns the debug logger currently in use.
2061: *
2062: * <p>
2063: * If no debug logger has been specified by the time this call occurs,
2064: * a default one (returned by <code>org.tmatesoft.svn.util.SVNDebugLog.getDefaultLog()</code>)
2065: * will be created and used.
2066: *
2067: * @return a debug logger
2068: */
2069: public ISVNDebugLog getDebugLog() {
2070: if (myDebugLog == null) {
2071: return SVNDebugLog.getDefaultLog();
2072: }
2073: return myDebugLog;
2074: }
2075: }
|