/* * ==================================================================== * 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 org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea; import org.tmatesoft.svn.core.internal.wc.admin.SVNWCAccess; import org.tmatesoft.svn.core.internal.wc16.SVNBasicDelegate; import org.tmatesoft.svn.core.wc2.SvnGetInfo; import org.tmatesoft.svn.core.wc2.SvnInfo; import org.tmatesoft.svn.core.wc2.SvnOperationFactory; import org.tmatesoft.svn.core.wc2.SvnTarget; import org.tmatesoft.svn.util.ISVNDebugLog; import org.tmatesoft.svn.util.SVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; /** * The <b>SVNBasicClient</b> is the base class of all <b>SVN</b>*<b>Client</b> * classes that provides a common interface and realization. * * <p> * All of <b>SVN</b>*<b>Client</b> classes use inherited methods of * <b>SVNBasicClient</b> to access Working Copies metadata, to create a driver * object to access a repository if it's necessary, etc. In addition * <b>SVNBasicClient</b> provides some interface methods - such as those that * allow you to set your {@link ISVNEventHandler event handler}, obtain run-time * configuration options, and others. * * @version 1.3 * @author TMate Software Ltd. * @since 1.2 */ public class SVNBasicClient { private static final String SVNKIT_WC_17_PROPERTY = "svnkit.wc.17"; private static final String SVNKIT_WC_17_DEFAULT = "true"; private static final String SVNKIT_WC_17_EXPECTED = "true"; private SvnOperationFactory operationFactory; private boolean ignoreExternals; private boolean leaveConflictsUnresolved; private ISVNPathListHandler pathListHandler; private ISVNDebugLog debugLog; protected SVNBasicClient(ISVNAuthenticationManager authManager, ISVNOptions options) { if (authManager == null) { authManager = SVNWCUtil.createDefaultAuthenticationManager(); } if (options == null) { options = SVNWCUtil.createDefaultOptions(true); } this.operationFactory = new SvnOperationFactory(); setOptions(options); this.operationFactory.setAuthenticationManager(authManager); this.operationFactory.setRepositoryPool(new DefaultSVNRepositoryPool(authManager, options)); this.operationFactory.setAutoDisposeRepositoryPool(true); initDefaults(); } protected SVNBasicClient(ISVNRepositoryPool pool, ISVNOptions options) { boolean autoDisposeRepositoryPool = false; if (pool == null) { pool = new DefaultSVNRepositoryPool(SVNWCUtil.createDefaultAuthenticationManager(), options); autoDisposeRepositoryPool = true; } if (options == null) { options = SVNWCUtil.createDefaultOptions(true); } this.operationFactory = new SvnOperationFactory(); setOptions(options); this.operationFactory.setRepositoryPool(pool); this.operationFactory.setAutoDisposeRepositoryPool(autoDisposeRepositoryPool); initDefaults(); } protected SVNBasicClient(SvnOperationFactory of) { this.operationFactory = of; setOptions(of.getOptions()); initDefaults(); } protected void initDefaults() { setPathListHandler(null); setDebugLog(null); setEventPathPrefix(null); setEventHandler(null); } public static boolean isWC17Supported() { return SVNKIT_WC_17_EXPECTED.equalsIgnoreCase(System.getProperty(SVNKIT_WC_17_PROPERTY, SVNKIT_WC_17_DEFAULT)); } protected static SVNBasicDelegate dontWC17Support() throws SVNException { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.WC_UNSUPPORTED_FORMAT); SVNErrorManager.error(err, SVNLogType.CLIENT); return null; } /** * Gets run-time configuration options used by this object. * * @return the run-time options being in use */ public ISVNOptions getOptions() { return getOperationsFactory().getOptions(); } /** * Sets run-time global configuration options to this object. * * @param options * the run-time configuration options */ public void setOptions(ISVNOptions options) { if (options == null) { options = SVNWCUtil.createDefaultOptions(true); } getOperationsFactory().setOptions(options); } /** * Sets externals definitions to be ignored or not during operations. * * <p> * For example, if external definitions are set to be ignored then a * checkout operation won't fetch them into a Working Copy. * * @param ignore * <span class="javakeyword">true</span> to ignore externals * definitions, <span class="javakeyword">false</span> - not to * @see #isIgnoreExternals() */ public void setIgnoreExternals(boolean ignore) { this.ignoreExternals = ignore; } /** * Determines if externals definitions are ignored. * * @return <span class="javakeyword">true</span> if ignored, otherwise <span * class="javakeyword">false</span> * @see #setIgnoreExternals(boolean) */ public boolean isIgnoreExternals() { return this.ignoreExternals; } /** * Sets (or unsets) all conflicted working files to be untouched by update * and merge operations. * * <p> * By default when a file receives changes from the repository that are in * conflict with local edits, an update operation places two sections for * each conflicting snatch into the working file one of which is a user's * local edit and the second is the one just received from the repository. * Like this: * * <pre class="javacode"> * <<<<<<< .mine * user's text * ======= * received text * >>>>>>> .r2 * </pre> * * <br /> * Also the operation creates three temporary files that appear in the same * directory as the working file. Now if you call this method with * <code>leave</code> set to <span class="javakeyword">true</span>, an * update will still create temporary files but won't place those two * sections into your working file. And this behaviour also concerns merge * operations: any merging to a conflicted file will be prevented. In * addition if there is any registered event handler for an * <b>SVNDiffClient</b> or <b>SVNUpdateClient</b> instance then the handler * will be dispatched an event with the status type set to * {@link SVNStatusType#CONFLICTED_UNRESOLVED}. * * <p> * The default value is <span class="javakeyword">false</span> until a * caller explicitly changes it calling this method. * * @param leave * <span class="javakeyword">true</span> to prevent conflicted * files from merging (all merging operations will be skipped), * otherwise <span class="javakeyword">false</span> * @see #isLeaveConflictsUnresolved() * @see SVNUpdateClient * @see SVNDiffClient * @see ISVNEventHandler * @deprecated this method should not be used anymore */ public void setLeaveConflictsUnresolved(boolean leave) { this.leaveConflictsUnresolved = leave; } /** * Determines if conflicted files should be left unresolved preventing from * merging their contents during update and merge operations. * * @return <span class="javakeyword">true</span> if conflicted files are set * to be prevented from merging, <span * class="javakeyword">false</span> if there's no such restriction * @see #setLeaveConflictsUnresolved(boolean) * @deprecated this method should not be used anymore */ public boolean isLeaveConflictsUnresolved() { return leaveConflictsUnresolved; } /** * Sets an event handler for this object. This event handler will be * dispatched {@link SVNEvent} objects to provide detailed information about * actions and progress state of version control operations performed by * <b>do</b>*<b>()</b> methods of <b>SVN</b>*<b>Client</b> classes. * * @param dispatcher * an event handler */ public void setEventHandler(ISVNEventHandler dispatcher) { getOperationsFactory().setEventHandler(dispatcher); } /** * Sets a path list handler implementation to this object. * * @param handler * handler implementation * @since 1.2.0 */ public void setPathListHandler(ISVNPathListHandler handler) { this.pathListHandler = handler; } public ISVNPathListHandler getPathListHandler() { return this.pathListHandler; } /** * Sets a logger to write debug log information to. * * @param log * a debug logger */ public void setDebugLog(ISVNDebugLog log) { if (log == null) { log = SVNDebugLog.getDefaultLog(); } this.debugLog = log; } /** * Returns the debug logger currently in use. * * <p> * If no debug logger has been specified by the time this call occurs, a * default one (returned by * <code>org.tmatesoft.svn.util.SVNDebugLog.getDefaultLog()</code>) will be * created and used. * * @return a debug logger */ public ISVNDebugLog getDebugLog() { return debugLog; } /** * Returns the root of the repository. * * <p/> * If <code>path</code> is not <span class="javakeyword">null</span> and * <code>pegRevision</code> is either {@link SVNRevision#WORKING} or * {@link SVNRevision#BASE}, then attempts to fetch the repository root from * the working copy represented by <code>path</code>. If these conditions * are not met or if the repository root is not recorded in the working * copy, then a repository connection is established and the repository root * is fetched from the session. * * <p/> * When fetching the repository root from the working copy and if * <code>access</code> is <span class="javakeyword">null</span>, a new * working copy access will be created and the working copy will be opened * non-recursively for reading only. * * <p/> * All necessary cleanup (session or|and working copy close) will be * performed automatically as the routine finishes. * * @param path * working copy path * @param url * repository url * @param pegRevision * revision in which the target is valid * @param adminArea * working copy administrative area object * @param access * working copy access object * @return repository root url * @throws SVNException * @since 1.2.0 * * @deprecated */ public SVNURL getReposRoot(File path, SVNURL url, SVNRevision pegRevision, SVNAdminArea adminArea, SVNWCAccess access) throws SVNException { SVNBasicDelegate delegate = new SVNBasicDelegate(getOperationsFactory().getAuthenticationManager(), getOperationsFactory().getOptions()); return delegate.getReposRoot(path, url, pegRevision, adminArea, access); } /** * Returns the root of the repository. * * <p/> * If <code>path</code> is not <span class="javakeyword">null</span> and * <code>pegRevision</code> is either {@link SVNRevision#WORKING} or * {@link SVNRevision#BASE}, then attempts to fetch the repository root from * the working copy represented by <code>path</code>. If these conditions * are not met or if the repository root is not recorded in the working * copy, then a repository connection is established and the repository root * is fetched from the session. * * <p/> * All necessary cleanup (session or|and working copy close) will be * performed automatically as the routine finishes. * * @param path * working copy path * @param url * repository url * @param pegRevision * revision in which the target is valid * @return repository root url * @throws SVNException * @since 1.2.0 * */ public SVNURL getReposRoot(File path, SVNURL url, SVNRevision pegRevision) throws SVNException { SvnGetInfo info = getOperationsFactory().createGetInfo(); if (path != null) { info.setSingleTarget(SvnTarget.fromFile(path, pegRevision)); } else { info.setSingleTarget(SvnTarget.fromURL(url, pegRevision)); } info.setDepth(SVNDepth.EMPTY); SvnInfo i = info.run(); return i != null ? i.getRepositoryRootUrl() : null; } /** * Removes or adds a path prefix. This method is not intended for users * (from an API point of view). * * @param prefix * a path prefix * @deprecated */ public void setEventPathPrefix(String prefix) { } public SvnOperationFactory getOperationsFactory() { return this.operationFactory; } }