001: /*
002: * ====================================================================
003: * Copyright (c) 2004-2008 TMate Software Ltd. All rights reserved.
004: *
005: * This software is licensed as described in the file COPYING, which
006: * you should have received as part of this distribution. The terms
007: * are also available at http://svnkit.com/license.html
008: * If newer versions of this license are posted there, you may use a
009: * newer version instead, at your option.
010: * ====================================================================
011: */
012: package org.tmatesoft.svn.core.wc;
013:
014: import org.tmatesoft.svn.core.ISVNCanceller;
015: import org.tmatesoft.svn.core.SVNException;
016: import org.tmatesoft.svn.core.SVNURL;
017: import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
018: import org.tmatesoft.svn.core.io.SVNRepository;
019: import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
020: import org.tmatesoft.svn.core.wc.admin.SVNAdminClient;
021: import org.tmatesoft.svn.core.wc.admin.SVNLookClient;
022: import org.tmatesoft.svn.util.ISVNDebugLog;
023: import org.tmatesoft.svn.util.SVNDebugLog;
024:
025: /**
026: * The <b>SVNClientManager</b> class is used to manage <b>SVN</b>*<b>Client</b>
027: * objects as well as for providing them to a user what makes the user's work
028: * easier and his code - pretty clear and flexible.
029: *
030: * <p>
031: * When you don't have special needs to create, keep and manage
032: * separate <b>SVN</b>*<b>Client</b> objects by yourself, you should
033: * use <b>SVNClientManager</b> that takes care of all that work for you.
034: * These are some of advantages of using <b>SVNClientManager</b>:
035: * <ol>
036: * <li>If you instantiate an <b>SVN</b>*<b>Client</b> object by yourself
037: * you need to provide a run-time configuration driver - {@link ISVNOptions} -
038: * as well as an authentication and network layers driver -
039: * {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager}. When
040: * using an <b>SVNClientManager</b> you have multiple choices to provide
041: * and use those drivers:
042: * <pre class="javacode">
043: * <span class="javacomment">//1.default options and authentication drivers to use</span>
044: * SVNClientManager clientManager = SVNClientManager.newInstance();
045: *
046: * ...
047: *
048: * <span class="javacomment">//2.provided options and default authentication drivers to use</span>
049: * ISVNOptions myOptions;
050: * ...
051: * SVNClientManager clientManager = SVNClientManager.newInstance(myOptions);
052: *
053: * ...
054: *
055: * <span class="javacomment">//3.provided options and authentication drivers to use</span>
056: * ISVNOptions myOptions;
057: * ISVNAuthenticationManager myAuthManager;
058: * ...
059: * SVNClientManager clientManager = SVNClientManager.newInstance(myOptions, myAuthManager);
060: *
061: * ...
062: *
063: * <span class="javacomment">//4.provided options driver and user's credentials to make</span>
064: * <span class="javacomment">//a default authentication driver use them</span>
065: * ISVNOptions myOptions;
066: * ...
067: * SVNClientManager
068: * clientManager = SVNClientManager.newInstance(myOptions, <span class="javastring">"name"</span>, <span class="javastring">"passw"</span>);
069: * </pre><br />
070: * Having instantiated an <b>SVNClientManager</b> in one of these ways, all
071: * the <b>SVN</b>*<b>Client</b> objects it will provide you will share those
072: * drivers, so you don't need to code much to provide the same drivers to each
073: * <b>SVN</b>*<b>Client</b> instance by yourself.
074: * <li>With <b>SVNClientManager</b> you don't need to create and keep your
075: * <b>SVN</b>*<b>Client</b> objects by youself - <b>SVNClientManager</b> will
076: * do all the work for you, so this will certainly bring down your efforts
077: * on coding and your code will be clearer and more flexible. All you need is
078: * to create an <b>SVNClientManager</b> instance.
079: * <li>Actually every <b>SVN</b>*<b>Client</b> object is instantiated only at
080: * the moment of the first call to an appropriate <b>SVNClientManager</b>'s
081: * <code>get</code> method:
082: * <pre class="javacode">
083: * SVNClientManager clientManager;
084: * ...
085: * <span class="javacomment">//an update client will be created only at that moment when you</span>
086: * <span class="javacomment">//first call this method for getting your update client, but if you</span>
087: * <span class="javacomment">//have already called it once before, then the method will return</span>
088: * <span class="javacomment">//that update client object instantiated in previous... so, it's</span>
089: * <span class="javacomment">//quite cheap, you see..</span>
090: * SVNUpdateClient updateClient = clientManager.getUpdateClient();</pre><br />
091: * <li>You can provide a single event handler that will be used by all
092: * <b>SVN</b>*<b>Client</b> objects provided by <b>SVNClientManager</b>:
093: * <pre class="javacode">
094: * <span class="javakeyword">import</span> org.tmatesoft.svn.core.wc.ISVNEventHandler;
095: *
096: * ...
097: *
098: * ISVNEventHandler commonEventHandler;
099: * SVNClientManager clientManager = SVNClientManager.newInstance();
100: * ...
101: * <span class="javacomment">//will be used by all SVN*Client objects</span>
102: * <span class="javacomment">//obtained from your client manager</span>
103: * clientManager.setEventHandler(commonEventHandler);
104: * </pre>
105: * <li>
106: * </ol>
107: *
108: * @version 1.1.1
109: * @author TMate Software Ltd.
110: * @see ISVNEventHandler
111: * @see <a target="_top" href="http://svnkit.com/kb/examples/">Examples</a>
112: */
113: public class SVNClientManager implements ISVNRepositoryPool {
114:
115: private ISVNOptions myOptions;
116:
117: private SVNCommitClient myCommitClient;
118: private SVNCopyClient myCopyClient;
119: private SVNDiffClient myDiffClient;
120: private SVNLogClient myLogClient;
121: private SVNMoveClient myMoveClient;
122: private SVNStatusClient myStatusClient;
123: private SVNUpdateClient myUpdateClient;
124: private SVNWCClient myWCClient;
125: private SVNAdminClient myAdminClient;
126: private SVNLookClient myLookClient;
127:
128: private ISVNEventHandler myEventHandler;
129: private ISVNRepositoryPool myRepositoryPool;
130: private ISVNDebugLog myDebugLog;
131:
132: private SVNClientManager(ISVNOptions options,
133: ISVNRepositoryPool repositoryPool) {
134: myOptions = options;
135: if (myOptions == null) {
136: myOptions = SVNWCUtil.createDefaultOptions(true);
137: }
138: myRepositoryPool = repositoryPool;
139: }
140:
141: private SVNClientManager(ISVNOptions options,
142: final ISVNAuthenticationManager authManager) {
143: this (options, new DefaultSVNRepositoryPool(
144: authManager == null ? SVNWCUtil
145: .createDefaultAuthenticationManager()
146: : authManager, options));
147: }
148:
149: /**
150: * Creates a new instance of this class using default {@link ISVNOptions}
151: * and {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager} drivers.
152: * That means this <b>SVNClientManager</b> will use the SVN's default run-time
153: * configuration area.
154: *
155: * @return a new <b>SVNClientManager</b> instance
156: */
157: public static SVNClientManager newInstance() {
158: return new SVNClientManager(null,
159: (ISVNAuthenticationManager) null);
160: }
161:
162: /**
163: * Creates a new instance of this class using the provided {@link ISVNOptions}
164: * and default {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager} drivers.
165: * That means this <b>SVNClientManager</b> will use the caller's configuration options
166: * (which correspond to options found in the default SVN's <i>config</i>
167: * file) and the default SVN's <i>servers</i> configuration and auth storage.
168: *
169: * @param options a config driver
170: * @return a new <b>SVNClientManager</b> instance
171: */
172: public static SVNClientManager newInstance(ISVNOptions options) {
173: return new SVNClientManager(options,
174: (ISVNAuthenticationManager) null);
175: }
176:
177: /**
178: * Creates a new instance of this class using the provided {@link ISVNOptions}
179: * and {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager} drivers.
180: * That means this <b>SVNClientManager</b> will use the caller's configuration options
181: * (which correspond to options found in the default SVN's <i>config</i>
182: * file) as well as authentication credentials and servers options (similar to
183: * options found in the default SVN's <i>servers</i>).
184: *
185: * @param options a config driver
186: * @param authManager an authentication driver
187: * @return a new <b>SVNClientManager</b> instance
188: */
189: public static SVNClientManager newInstance(ISVNOptions options,
190: ISVNAuthenticationManager authManager) {
191: return new SVNClientManager(options, authManager);
192: }
193:
194: /**
195: * Creates a new instance of this class using the provided
196: * config driver and creator of of <b>SVNRepository</b> objects.
197: *
198: * @param options a config driver
199: * @param repositoryPool a creator of <b>SVNRepository</b> objects
200: * @return a new <b>SVNClientManager</b> instance
201: */
202: public static SVNClientManager newInstance(ISVNOptions options,
203: ISVNRepositoryPool repositoryPool) {
204: return new SVNClientManager(options, repositoryPool);
205: }
206:
207: /**
208: * Creates a new instance of this class using the provided {@link ISVNOptions}
209: * driver and user's credentials to make a default implementation of
210: * {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager} use them.
211: * That means this <b>SVNClientManager</b> will use the caller's configuration options
212: * (which correspond to options found in the default SVN's <i>config</i>
213: * file), the default SVN's <i>servers</i> configuration and the caller's
214: * credentials.
215: *
216: * @param options a config driver
217: * @param userName a user account name
218: * @param password a user password
219: * @return a new <b>SVNClientManager</b> instance
220: */
221: public static SVNClientManager newInstance(ISVNOptions options,
222: String userName, String password) {
223: boolean storeAuth = options == null ? true : options
224: .isAuthStorageEnabled();
225: ISVNAuthenticationManager authManager = SVNWCUtil
226: .createDefaultAuthenticationManager(null, userName,
227: password, storeAuth);
228: return new SVNClientManager(options, authManager);
229: }
230:
231: /**
232: * Creates a low-level SVN protocol driver to directly work with
233: * a repository.
234: *
235: * <p>
236: * The driver created will be set a default {@link org.tmatesoft.svn.core.auth.ISVNAuthenticationManager}
237: * manager.
238: *
239: * <p>
240: * Used by <b>SVN</b>*<b>Client</b> objects (managed by this
241: * <b>SVNClientManager</b>) to access a repository when needed.
242: *
243: * @param url a repository location to establish a
244: * connection with (will be the root directory
245: * for the working session)
246: * @param mayReuse if <span class="javakeyword">true</span> then tries
247: * first tries to find a reusable driver or creates a new
248: * reusable one
249: * @return a low-level API driver for direct interacting
250: * with a repository
251: * @throws SVNException
252: */
253: public SVNRepository createRepository(SVNURL url, boolean mayReuse)
254: throws SVNException {
255: if (myRepositoryPool != null) {
256: return myRepositoryPool.createRepository(url, mayReuse);
257: }
258: SVNRepository repository = SVNRepositoryFactory.create(url);
259: repository.setAuthenticationManager(SVNWCUtil
260: .createDefaultAuthenticationManager());
261: repository.setDebugLog(getDebugLog());
262: return repository;
263: }
264:
265: public void shutdownConnections(boolean shutdownAll) {
266: if (myRepositoryPool != null) {
267: myRepositoryPool.dispose();
268: }
269: }
270:
271: public void dispose() {
272: if (myRepositoryPool != null) {
273: myRepositoryPool.dispose();
274: }
275: }
276:
277: /**
278: * Returns the run-time configuration options driver
279: * which kept by this object.
280: *
281: * @return a run-time options driver
282: */
283: public ISVNOptions getOptions() {
284: return myOptions;
285: }
286:
287: /**
288: * Sets an event handler to all <b>SVN</b>*<b>Client</b> objects
289: * created and kept by this <b>SVNClientManager</b>.
290: *
291: * <p>
292: * The provided event handler will be set only to only those objects
293: * that have been already created (<b>SVN</b>*<b>Client</b> objects are
294: * instantiated by an <b>SVNClientManager</b> at the moment of the
295: * first call to a <code>get*Client()</code> method). So, the handler
296: * won't be set for those ones that have never been requested. However
297: * as they are first requested (and thus created) the handler will be
298: * set to them, too, since <b>SVNClientManager</b> is still keeping the handler.
299: *
300: * @param handler an event handler
301: */
302: public void setEventHandler(ISVNEventHandler handler) {
303: myEventHandler = handler;
304: setCanceller(handler);
305: if (myCommitClient != null) {
306: myCommitClient.setEventHandler(handler);
307: }
308: if (myCopyClient != null) {
309: myCopyClient.setEventHandler(handler);
310: }
311: if (myDiffClient != null) {
312: myDiffClient.setEventHandler(handler);
313: }
314: if (myLogClient != null) {
315: myLogClient.setEventHandler(handler);
316: }
317: if (myMoveClient != null) {
318: myMoveClient.setEventHandler(handler);
319: }
320: if (myStatusClient != null) {
321: myStatusClient.setEventHandler(handler);
322: }
323: if (myUpdateClient != null) {
324: myUpdateClient.setEventHandler(handler);
325: }
326: if (myWCClient != null) {
327: myWCClient.setEventHandler(handler);
328: }
329: if (myAdminClient != null) {
330: myAdminClient.setEventHandler(handler);
331: }
332: if (myLookClient != null) {
333: myLookClient.setEventHandler(handler);
334: }
335: }
336:
337: public void setOptions(ISVNOptions options) {
338: myOptions = options;
339: if (myCommitClient != null) {
340: myCommitClient.setOptions(options);
341: }
342: if (myCopyClient != null) {
343: myCopyClient.setOptions(options);
344: }
345: if (myDiffClient != null) {
346: myDiffClient.setOptions(options);
347: }
348: if (myLogClient != null) {
349: myLogClient.setOptions(options);
350: }
351: if (myMoveClient != null) {
352: myMoveClient.setOptions(options);
353: }
354: if (myStatusClient != null) {
355: myStatusClient.setOptions(options);
356: }
357: if (myUpdateClient != null) {
358: myUpdateClient.setOptions(options);
359: }
360: if (myWCClient != null) {
361: myWCClient.setOptions(options);
362: }
363: if (myAdminClient != null) {
364: myAdminClient.setOptions(options);
365: }
366: if (myLookClient != null) {
367: myLookClient.setOptions(options);
368: }
369: }
370:
371: /**
372: * Returns an instance of the {@link SVNCommitClient} class.
373: *
374: * <p>
375: * If it's the first time this method is being called the object is
376: * created, initialized and then returned. Further calls to this
377: * method will get the same object instantiated at that moment of
378: * the first call. <b>SVNClientManager</b> does not reinstantiate
379: * its <b>SVN</b>*<b>Client</b> objects.
380: *
381: * @return an <b>SVNCommitClient</b> instance
382: */
383: public SVNCommitClient getCommitClient() {
384: if (myCommitClient == null) {
385: myCommitClient = new SVNCommitClient(this , myOptions);
386: myCommitClient.setEventHandler(myEventHandler);
387: myCommitClient.setDebugLog(getDebugLog());
388: }
389: return myCommitClient;
390: }
391:
392: /**
393: * Returns an instance of the {@link org.tmatesoft.svn.core.wc.admin.SVNAdminClient} class.
394: *
395: * <p>
396: * If it's the first time this method is being called the object is
397: * created, initialized and then returned. Further calls to this
398: * method will get the same object instantiated at that moment of
399: * the first call. <b>SVNClientManager</b> does not reinstantiate
400: * its <b>SVN</b>*<b>Client</b> objects.
401: *
402: * @return an <b>SVNAdminClient</b> instance
403: */
404: public SVNAdminClient getAdminClient() {
405: if (myAdminClient == null) {
406: myAdminClient = new SVNAdminClient(this , myOptions);
407: myAdminClient.setEventHandler(myEventHandler);
408: myAdminClient.setDebugLog(getDebugLog());
409: }
410: return myAdminClient;
411: }
412:
413: /**
414: * Returns an instance of the {@link org.tmatesoft.svn.core.wc.admin.SVNLookClient} class.
415: *
416: * <p>
417: * If it's the first time this method is being called the object is
418: * created, initialized and then returned. Further calls to this
419: * method will get the same object instantiated at that moment of
420: * the first call. <b>SVNClientManager</b> does not reinstantiate
421: * its <b>SVN</b>*<b>Client</b> objects.
422: *
423: * @return an <b>SVNLookClient</b> instance
424: */
425: public SVNLookClient getLookClient() {
426: if (myLookClient == null) {
427: myLookClient = new SVNLookClient(this , myOptions);
428: myLookClient.setEventHandler(myEventHandler);
429: myLookClient.setDebugLog(getDebugLog());
430: }
431: return myLookClient;
432: }
433:
434: /**
435: * Returns an instance of the {@link SVNCopyClient} class.
436: *
437: * <p>
438: * If it's the first time this method is being called the object is
439: * created, initialized and then returned. Further calls to this
440: * method will get the same object instantiated at that moment of
441: * the first call. <b>SVNClientManager</b> does not reinstantiate
442: * its <b>SVN</b>*<b>Client</b> objects.
443: *
444: * @return an <b>SVNCopyClient</b> instance
445: */
446: public SVNCopyClient getCopyClient() {
447: if (myCopyClient == null) {
448: myCopyClient = new SVNCopyClient(this , myOptions);
449: myCopyClient.setEventHandler(myEventHandler);
450: myCopyClient.setDebugLog(getDebugLog());
451: }
452: return myCopyClient;
453: }
454:
455: /**
456: * Returns an instance of the {@link SVNDiffClient} class.
457: *
458: * <p>
459: * If it's the first time this method is being called the object is
460: * created, initialized and then returned. Further calls to this
461: * method will get the same object instantiated at that moment of
462: * the first call. <b>SVNClientManager</b> does not reinstantiate
463: * its <b>SVN</b>*<b>Client</b> objects.
464: *
465: * @return an <b>SVNDiffClient</b> instance
466: */
467: public SVNDiffClient getDiffClient() {
468: if (myDiffClient == null) {
469: myDiffClient = new SVNDiffClient(this , myOptions);
470: myDiffClient.setEventHandler(myEventHandler);
471: myDiffClient.setDebugLog(getDebugLog());
472: }
473: return myDiffClient;
474: }
475:
476: /**
477: * Returns an instance of the {@link SVNLogClient} class.
478: *
479: * <p>
480: * If it's the first time this method is being called the object is
481: * created, initialized and then returned. Further calls to this
482: * method will get the same object instantiated at that moment of
483: * the first call. <b>SVNClientManager</b> does not reinstantiate
484: * its <b>SVN</b>*<b>Client</b> objects.
485: *
486: * @return an <b>SVNLogClient</b> instance
487: */
488: public SVNLogClient getLogClient() {
489: if (myLogClient == null) {
490: myLogClient = new SVNLogClient(this , myOptions);
491: myLogClient.setEventHandler(myEventHandler);
492: myLogClient.setDebugLog(getDebugLog());
493: }
494: return myLogClient;
495: }
496:
497: /**
498: * Returns an instance of the {@link SVNMoveClient} class.
499: *
500: * <p>
501: * If it's the first time this method is being called the object is
502: * created, initialized and then returned. Further calls to this
503: * method will get the same object instantiated at that moment of
504: * the first call. <b>SVNClientManager</b> does not reinstantiate
505: * its <b>SVN</b>*<b>Client</b> objects.
506: *
507: * @return an <b>SVNMoveClient</b> instance
508: */
509: public SVNMoveClient getMoveClient() {
510: if (myMoveClient == null) {
511: myMoveClient = new SVNMoveClient(this , myOptions);
512: myMoveClient.setEventHandler(myEventHandler);
513: myMoveClient.setDebugLog(getDebugLog());
514: }
515: return myMoveClient;
516: }
517:
518: /**
519: * Returns an instance of the {@link SVNStatusClient} class.
520: *
521: * <p>
522: * If it's the first time this method is being called the object is
523: * created, initialized and then returned. Further calls to this
524: * method will get the same object instantiated at that moment of
525: * the first call. <b>SVNClientManager</b> does not reinstantiate
526: * its <b>SVN</b>*<b>Client</b> objects.
527: *
528: * @return an <b>SVNStatusClient</b> instance
529: */
530: public SVNStatusClient getStatusClient() {
531: if (myStatusClient == null) {
532: myStatusClient = new SVNStatusClient(this , myOptions);
533: myStatusClient.setEventHandler(myEventHandler);
534: myStatusClient.setDebugLog(getDebugLog());
535: }
536: return myStatusClient;
537: }
538:
539: /**
540: * Returns an instance of the {@link SVNUpdateClient} class.
541: *
542: * <p>
543: * If it's the first time this method is being called the object is
544: * created, initialized and then returned. Further calls to this
545: * method will get the same object instantiated at that moment of
546: * the first call. <b>SVNClientManager</b> does not reinstantiate
547: * its <b>SVN</b>*<b>Client</b> objects.
548: *
549: * @return an <b>SVNUpdateClient</b> instance
550: */
551: public SVNUpdateClient getUpdateClient() {
552: if (myUpdateClient == null) {
553: myUpdateClient = new SVNUpdateClient(this , myOptions);
554: myUpdateClient.setEventHandler(myEventHandler);
555: myUpdateClient.setDebugLog(getDebugLog());
556: }
557: return myUpdateClient;
558: }
559:
560: /**
561: * Returns an instance of the {@link SVNWCClient} class.
562: *
563: * <p>
564: * If it's the first time this method is being called the object is
565: * created, initialized and then returned. Further calls to this
566: * method will get the same object instantiated at that moment of
567: * the first call. <b>SVNClientManager</b> does not reinstantiate
568: * its <b>SVN</b>*<b>Client</b> objects.
569: *
570: * @return an <b>SVNWCClient</b> instance
571: */
572: public SVNWCClient getWCClient() {
573: if (myWCClient == null) {
574: myWCClient = new SVNWCClient(this , myOptions);
575: myWCClient.setEventHandler(myEventHandler);
576: myWCClient.setDebugLog(getDebugLog());
577: }
578: return myWCClient;
579: }
580:
581: /**
582: * Returns the debug logger currently in use.
583: *
584: * <p>
585: * If no debug logger has been specified by the time this call occurs,
586: * a default one (returned by <code>org.tmatesoft.svn.util.SVNDebugLog.getDefaultLog()</code>)
587: * will be created and used.
588: *
589: * @return a debug logger
590: */
591: public ISVNDebugLog getDebugLog() {
592: if (myDebugLog == null) {
593: return SVNDebugLog.getDefaultLog();
594: }
595: return myDebugLog;
596: }
597:
598: /**
599: * Sets a logger to write debug log information to. Sets this same logger
600: * object to all <b>SVN</b>*<b>Client</b> objects instantiated by this
601: * moment.
602: *
603: * @param log a debug logger
604: */
605: public void setDebugLog(ISVNDebugLog log) {
606: myDebugLog = log;
607: if (myCommitClient != null) {
608: myCommitClient.setDebugLog(log);
609: }
610: if (myCopyClient != null) {
611: myCopyClient.setDebugLog(log);
612: }
613: if (myDiffClient != null) {
614: myDiffClient.setDebugLog(log);
615: }
616: if (myLogClient != null) {
617: myLogClient.setDebugLog(log);
618: }
619: if (myMoveClient != null) {
620: myMoveClient.setDebugLog(log);
621: }
622: if (myStatusClient != null) {
623: myStatusClient.setDebugLog(log);
624: }
625: if (myUpdateClient != null) {
626: myUpdateClient.setDebugLog(log);
627: }
628: if (myWCClient != null) {
629: myWCClient.setDebugLog(log);
630: }
631: if (myAdminClient != null) {
632: myAdminClient.setDebugLog(log);
633: }
634: if (myLookClient != null) {
635: myLookClient.setDebugLog(log);
636: }
637: if (myRepositoryPool != null) {
638: myRepositoryPool.setDebugLog(log);
639: }
640: }
641:
642: public void setAuthenticationManager(
643: ISVNAuthenticationManager authManager) {
644: if (myRepositoryPool != null) {
645: myRepositoryPool.setAuthenticationManager(authManager);
646: }
647: }
648:
649: public void setCanceller(ISVNCanceller canceller) {
650: if (myRepositoryPool != null) {
651: myRepositoryPool.setCanceller(canceller);
652: }
653: }
654: }
|