View Javadoc
1   package org.apache.maven.scm.provider.synergy.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.text.SimpleDateFormat;
25  import java.util.ArrayList;
26  import java.util.Date;
27  import java.util.List;
28  import java.util.Locale;
29  
30  import org.apache.maven.scm.ChangeFile;
31  import org.apache.maven.scm.ScmException;
32  import org.apache.maven.scm.ScmVersion;
33  import org.apache.maven.scm.log.ScmLogger;
34  import org.apache.maven.scm.provider.synergy.consumer.SynergyCreateTaskConsumer;
35  import org.apache.maven.scm.provider.synergy.consumer.SynergyGetCompletedTasksConsumer;
36  import org.apache.maven.scm.provider.synergy.consumer.SynergyGetTaskObjectsConsumer;
37  import org.apache.maven.scm.provider.synergy.consumer.SynergyGetWorkingFilesConsumer;
38  import org.apache.maven.scm.provider.synergy.consumer.SynergyGetWorkingProjectConsumer;
39  import org.apache.maven.scm.provider.synergy.consumer.SynergyShowDefaultTaskConsumer;
40  import org.apache.maven.scm.provider.synergy.consumer.SynergyWorkareaConsumer;
41  import org.codehaus.plexus.util.cli.CommandLineException;
42  import org.codehaus.plexus.util.cli.CommandLineUtils;
43  import org.codehaus.plexus.util.cli.CommandLineUtils.StringStreamConsumer;
44  import org.codehaus.plexus.util.cli.Commandline;
45  import org.codehaus.plexus.util.cli.StreamConsumer;
46  
47  /**
48   * This class contains functional methods for Synergy.
49   *
50   * @author <a href="mailto:julien.henry@capgemini.com">Julien Henry</a>
51   * @author Olivier Lamy
52   *
53   */
54  public final class SynergyUtil
55  {
56  
57      private SynergyUtil()
58      {
59      }
60  
61      /**
62       * Separator used with formatted result
63       */
64      public static final String SEPARATOR = "#####";
65  
66      /**
67       * Remove prefix path from a path. Example: removeParent("c:\tmp",
68       * "c:\tmp\foo.bar") returns "foo.bar"
69       *
70       * @param prefix parent path (prefix).
71       * @param file   file path.
72       * @return suffix
73       * @throws ScmException if parent is not a prefix of file
74       */
75      public static String removePrefix( File prefix, File file )
76          throws ScmException
77      {
78          try
79          {
80              String prefixStr = prefix.getCanonicalPath();
81              String fileStr = file.getCanonicalPath();
82              if ( !fileStr.startsWith( prefixStr ) )
83              {
84                  throw new ScmException( prefixStr + " is not a prefix of " + fileStr );
85              }
86              return fileStr.substring( prefixStr.length() );
87          }
88          catch ( IOException e )
89          {
90              throw new ScmException( "IOException", e );
91          }
92  
93      }
94  
95      /**
96       * Get a working project whose predecessor is given.
97       *
98       * @param logger       a logger.
99       * @param projectSpec predecessor (prep project)
100      * @param username     owner of working project
101      * @param ccmAddr      Synergy session ID.
102      * @return projectSpec of the working checkout, or null if none
103      */
104     public static String getWorkingProject( ScmLogger logger, String projectSpec, String username, String ccmAddr )
105         throws ScmException
106     {
107         if ( logger.isDebugEnabled() )
108         {
109             logger.debug( "Synergy : Entering getWorkingProject method" );
110         }
111 
112         String query =
113             "owner='" + username + "' and status='working' and type='project' and has_predecessor('" + projectSpec
114                 + "')";
115                 //+ ":project:1')"; SCM-261
116 
117         Commandline cl = SynergyCCM.query( query, "%objectname", ccmAddr );
118 
119         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
120         SynergyGetWorkingProjectConsumer stdout = new SynergyGetWorkingProjectConsumer( logger );
121 
122         int errorCode = executeSynergyCommand( logger, cl, stderr, stdout, false );
123 
124         if ( logger.isDebugEnabled() )
125         {
126             logger.debug( "Synergy : getWorkingProject returns " + stdout.getProjectSpec() + " with code "
127                 + errorCode );
128         }
129 
130         return stdout.getProjectSpec();
131     }
132 
133     /**
134      * Get working file(s) in a given project.
135      *
136      * @param logger       a logger.
137      * @param projectSpec (project)
138      * @param release      release
139      * @param ccmAddr      Synergy session ID.
140      * @return list of working files.
141      */
142     public static List<String> getWorkingFiles( ScmLogger logger, String projectSpec, String release, String ccmAddr )
143         throws ScmException
144     {
145         if ( logger.isDebugEnabled() )
146         {
147             logger.debug( "Synergy : Entering getWorkingFiles method" );
148         }
149 
150         String query = "status='working' and release='" + release + "' and is_member_of('" + projectSpec + "')";
151 
152         Commandline cl = SynergyCCM.query( query, SynergyGetWorkingFilesConsumer.OUTPUT_FORMAT, ccmAddr );
153 
154         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
155         SynergyGetWorkingFilesConsumer stdout = new SynergyGetWorkingFilesConsumer( logger );
156 
157         int errorCode = executeSynergyCommand( logger, cl, stderr, stdout, false );
158 
159         if ( logger.isDebugEnabled() )
160         {
161             logger.debug( "Synergy : getWorkingFiles returns " + stdout.getFiles().size() + " files with code "
162                 + errorCode );
163         }
164 
165         return stdout.getFiles();
166     }
167 
168     /**
169      * Populate the object list of a Modification by querying for objects
170      * associated with the task.
171      *
172      * @param logger  a logger.
173      * @param numTask task number.
174      * @param ccmAddr Synergy session ID.
175      */
176     public static List<ChangeFile> getModifiedObjects( ScmLogger logger, int numTask, String ccmAddr )
177         throws ScmException
178     {
179         if ( logger.isDebugEnabled() )
180         {
181             logger.debug( "Synergy : Entering getModifiedObjects method" );
182         }
183 
184         Commandline cl = SynergyCCM.showTaskObjects( numTask, SynergyGetTaskObjectsConsumer.OUTPUT_FORMAT, ccmAddr );
185 
186         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
187         SynergyGetTaskObjectsConsumer stdout = new SynergyGetTaskObjectsConsumer( logger );
188         int errorCode = executeSynergyCommand( logger, cl, stderr, stdout, false );
189 
190         if ( logger.isDebugEnabled() )
191         {
192             logger.debug( "Synergy : getModifiedObjects returns " + stdout.getFiles().size() + " files with code "
193                 + errorCode );
194         }
195 
196         return stdout.getFiles();
197 
198     }
199 
200     /**
201      * Get a list of all tasks which are contained in all folders in the
202      * reconfigure properties of the specified project and were completed after
203      * startDate and before endDate.
204      *
205      * @param logger      a logger.
206      * @param projectSpec projectSpec.
207      * @param startDate   start date.
208      * @param endDate     end date.
209      * @param ccmAddr     Synergy session ID.
210      * @return A list of  {@link SynergyTask}
211      */
212     public static List<SynergyTask> getCompletedTasks( ScmLogger logger, String projectSpec, Date startDate,
213                                                        Date endDate, String ccmAddr )
214         throws ScmException
215     {
216         if ( logger.isDebugEnabled() )
217         {
218             logger.debug( "Synergy : Entering getCompletedTasks method" );
219         }
220 
221         // The format used for converting Java dates into CM Synergy dates
222         // Note that the format used to submit commands differs from the
223         // format used in the results of that command!?!
224         SimpleDateFormat toCcmDate = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss", new Locale( "en", "US" ) );
225 
226         // Construct the query string
227         String query = "is_task_in_folder_of(is_folder_in_rp_of('" + projectSpec + "'))";
228         if ( startDate != null )
229         {
230             query = query + "and completion_date>time('" + toCcmDate.format( startDate ) + "')";
231         }
232         if ( endDate != null )
233         {
234             query = query + "and completion_date<time('" + toCcmDate.format( endDate ) + "')";
235         }
236 
237         Commandline cl = SynergyCCM.query( query, SynergyGetCompletedTasksConsumer.OUTPUT_FORMAT, ccmAddr );
238 
239         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
240         SynergyGetCompletedTasksConsumer stdout = new SynergyGetCompletedTasksConsumer( logger );
241 
242         executeSynergyCommand( logger, cl, stderr, stdout, false );
243 
244         if ( logger.isDebugEnabled() )
245         {
246             logger.debug( "Synergy : getCompletedTasks method returns " + stdout.getTasks().size() + " tasks" );
247         }
248 
249         return stdout.getTasks();
250     }
251 
252     /**
253      * Create a baseline.
254      *
255      * @param logger      a logger.
256      * @param projectSpec the projectSpec.
257      * @param name        name of the baseline.
258      * @param release     the release.
259      * @param purpose     the purpose.
260      * @param ccmAddr     used to run in multi-session.
261      * @throws ScmException
262      */
263     public static void createBaseline( ScmLogger logger, String projectSpec, String name, String release,
264                                        String purpose, String ccmAddr )
265         throws ScmException
266     {
267         if ( logger.isDebugEnabled() )
268         {
269             logger.debug( "Synergy : Entering createBaseline method" );
270         }
271 
272         Commandline cl = SynergyCCM.createBaseline( projectSpec, name, release, purpose, ccmAddr );
273 
274         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
275         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
276 
277         executeSynergyCommand( logger, cl, stderr, stdout, true );
278     }
279 
280     /**
281      * Add new file to Synergy database.
282      *
283      * @param logger  a logger.
284      * @param file    file to be added.
285      * @param message log message for Synergy.
286      * @param ccmAddr used to run in multi-session.
287      * @throws ScmException
288      */
289     public static void create( ScmLogger logger, File file, String message, String ccmAddr )
290         throws ScmException
291     {
292         if ( logger.isDebugEnabled() )
293         {
294             logger.debug( "Synergy : Entering create method" );
295         }
296 
297         List<File> files = new ArrayList<File>();
298         files.add( file );
299         Commandline cl = SynergyCCM.create( files, message, ccmAddr );
300 
301         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
302         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
303 
304         executeSynergyCommand( logger, cl, stderr, stdout, true );
305     }
306 
307     /**
308      * Create new task.
309      *
310      * @param logger      a logger.
311      * @param synopsis    short description of task.
312      * @param release     release.
313      * @param defaultTask should this task become the default task?
314      * @param ccmAddr     used to run in multi-session.
315      * @return Task number
316      * @throws ScmException
317      */
318     public static int createTask( ScmLogger logger, String synopsis, String release, boolean defaultTask,
319                                   String ccmAddr )
320         throws ScmException
321     {
322         if ( logger.isDebugEnabled() )
323         {
324             logger.debug( "Synergy : Entering createTask method of SynergyUtil" );
325         }
326 
327         if ( synopsis == null || synopsis.equals( "" ) )
328         {
329             throw new ScmException( "A synopsis must be specified to create a task." );
330         }
331 
332         Commandline cl = SynergyCCM.createTask( synopsis, release, defaultTask, ccmAddr );
333 
334         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
335         SynergyCreateTaskConsumer stdout = new SynergyCreateTaskConsumer( logger );
336 
337         executeSynergyCommand( logger, cl, stderr, stdout, true );
338 
339         if ( logger.isDebugEnabled() )
340         {
341             logger.debug( "createTask returns " + stdout.getTask() );
342         }
343 
344         return stdout.getTask();
345     }
346 
347     /**
348      * Checkin the default task.
349      *
350      * @param logger  a logger.
351      * @param comment a comment.
352      * @param ccmAddr Synergy session ID.
353      * @throws ScmException
354      */
355     public static void checkinDefaultTask( ScmLogger logger, String comment, String ccmAddr )
356         throws ScmException
357     {
358         if ( logger.isDebugEnabled() )
359         {
360             logger.debug( "Synergy : Entering checkinDefaultTask method" );
361         }
362 
363         Commandline cl = SynergyCCM.checkinTask( "default", comment, ccmAddr );
364 
365         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
366         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
367 
368         executeSynergyCommand( logger, cl, stderr, stdout, true );
369     }
370 
371     /**
372      * Checkin a task.
373      *
374      * @param logger     a logger.
375      * @param taskNumber task number.
376      * @param comment    a comment.
377      * @param ccmAddr    Synergy session ID.
378      * @throws ScmException
379      */
380     public static void checkinTask( ScmLogger logger, int taskNumber, String comment, String ccmAddr )
381         throws ScmException
382     {
383         if ( logger.isDebugEnabled() )
384         {
385             logger.debug( "Synergy : Entering checkinTask method" );
386         }
387 
388         Commandline cl = SynergyCCM.checkinTask( "" + taskNumber, comment, ccmAddr );
389 
390         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
391         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
392 
393         executeSynergyCommand( logger, cl, stderr, stdout, true );
394     }
395 
396     /**
397      * Delete file from Synergy database.
398      *
399      * @param logger  a logger.
400      * @param file    file to be deleted.
401      * @param ccmAddr used to run in multi-session.
402      * @throws ScmException
403      */
404     public static void delete( ScmLogger logger, File file, String ccmAddr, boolean replace )
405         throws ScmException
406     {
407         if ( logger.isDebugEnabled() )
408         {
409             logger.debug( "Synergy : Entering delete method" );
410         }
411 
412         List<File> list = new ArrayList<File>();
413         list.add( file );
414 
415         Commandline cl = SynergyCCM.delete( list, ccmAddr, replace );
416 
417         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
418         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
419 
420         executeSynergyCommand( logger, cl, stderr, stdout, true );
421     }
422 
423     /**
424      * Reconfigure a project.
425      *
426      * @param logger       a logger.
427      * @param projectSpec projectSpec (i.e. myProject~1).
428      * @param ccmAddr      used to run in multi-session.
429      * @throws ScmException
430      */
431     public static void reconfigure( ScmLogger logger, String projectSpec, String ccmAddr )
432         throws ScmException
433     {
434         if ( logger.isDebugEnabled() )
435         {
436             logger.debug( "Synergy : Entering reconfigure method" );
437         }
438         Commandline cl = SynergyCCM.reconfigure( projectSpec, ccmAddr );
439 
440         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
441         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
442 
443         executeSynergyCommand( logger, cl, stderr, stdout, true );
444     }
445 
446     /**
447      * Reconfigure properties of a project.
448      *
449      * @param logger       a logger.
450      * @param projectSpec projectSpec (i.e. myProject~1).
451      * @param ccmAddr      used to run in multi-session.
452      * @throws ScmException
453      */
454     public static void reconfigureProperties( ScmLogger logger, String projectSpec, String ccmAddr )
455         throws ScmException
456     {
457         if ( logger.isDebugEnabled() )
458         {
459             logger.debug( "Synergy : Entering reconfigureProperties method" );
460         }
461         Commandline cl = SynergyCCM.reconfigureProperties( projectSpec, ccmAddr );
462 
463         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
464         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
465 
466         executeSynergyCommand( logger, cl, stderr, stdout, true );
467     }
468 
469     /**
470      * Reconcile a project with -uwa option.
471      *
472      * @param logger       a logger.
473      * @param projectSpec projectSpec (i.e. myProject~1).
474      * @param ccmAddr      used to run in multi-session.
475      * @throws ScmException
476      */
477     public static void reconcileUwa( ScmLogger logger, String projectSpec, String ccmAddr )
478         throws ScmException
479     {
480         if ( logger.isDebugEnabled() )
481         {
482             logger.debug( "Synergy : Entering reconcileUwa method" );
483         }
484         Commandline cl = SynergyCCM.reconcileUwa( projectSpec, ccmAddr );
485 
486         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
487         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
488 
489         executeSynergyCommand( logger, cl, stderr, stdout, true );
490     }
491 
492     /**
493      * Reconcile a project with -udb option.
494      *
495      * @param logger       a logger.
496      * @param projectSpec projectSpec (i.e. myProject~1).
497      * @param ccmAddr      used to run in multi-session.
498      * @throws ScmException
499      */
500     public static void reconcileUdb( ScmLogger logger, String projectSpec, String ccmAddr )
501         throws ScmException
502     {
503         if ( logger.isDebugEnabled() )
504         {
505             logger.debug( "Synergy : Entering reconcileUdb method" );
506         }
507         Commandline cl = SynergyCCM.reconcileUdb( projectSpec, ccmAddr );
508 
509         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
510         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
511 
512         executeSynergyCommand( logger, cl, stderr, stdout, true );
513     }
514 
515     /**
516      * Checkout given files or directory.
517      *
518      * @param logger  a logger.
519      * @param files   files to add.
520      * @param ccmAddr Synergy session ID.
521      * @throws ScmException
522      */
523     public static void checkoutFiles( ScmLogger logger, List<File> files, String ccmAddr )
524         throws ScmException
525     {
526         if ( logger.isDebugEnabled() )
527         {
528             logger.debug( "Synergy : Entering checkoutFiles files method" );
529         }
530 
531         Commandline cl = SynergyCCM.checkoutFiles( files, ccmAddr );
532 
533         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
534         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
535 
536         executeSynergyCommand( logger, cl, stderr, stdout, true );
537     }
538 
539     /**
540      * Checkout a given project.
541      *
542      * @param logger       a logger.
543      * @param directory    new project work area, or null if you want to use default wa.
544      * @param projectSpec projectSpec (i.e. myProject~1).
545      * @param ccmAddr      used to run in multi-session.
546      * @return checkout directory (directory + new project spec)
547      * @throws ScmException
548      */
549     public static void checkoutProject( ScmLogger logger, File directory, String projectSpec, ScmVersion version,
550                                         String purpose, String release, String ccmAddr )
551         throws ScmException
552     {
553         if ( logger.isDebugEnabled() )
554         {
555             logger.debug( "Synergy : Entering checkoutProject project method" );
556         }
557 
558         Commandline cl = SynergyCCM.checkoutProject( directory, projectSpec, version, purpose, release, ccmAddr );
559 
560         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
561         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
562 
563         executeSynergyCommand( logger, cl, stderr, stdout, true );
564 
565     }
566 
567     /**
568      * Checkin a given project.
569      *
570      * @param logger       a logger.
571      * @param projectSpec projectSpec (i.e. myProject~1).
572      * @param comment      message.
573      * @param ccmAddr      used to run in multi-session.
574      * @return checkout directory (directory + new project spec)
575      * @throws ScmException
576      */
577     public static void checkinProject( ScmLogger logger, String projectSpec, String comment, String ccmAddr )
578         throws ScmException
579     {
580         if ( logger.isDebugEnabled() )
581         {
582             logger.debug( "Synergy : Entering checkinProject project method" );
583         }
584 
585         Commandline cl = SynergyCCM.checkinProject( projectSpec, comment, ccmAddr );
586 
587         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
588         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
589 
590         executeSynergyCommand( logger, cl, stderr, stdout, true );
591 
592     }
593 
594     /**
595      * Checkin a file set.
596      *
597      * @param logger  a logger.
598      * @param ccmAddr used to run in multi-session.
599      * @return checkout directory (directory + new project spec)
600      * @throws ScmException
601      */
602     public static void checkinFiles( ScmLogger logger, List<File> files, String comment, String ccmAddr )
603         throws ScmException
604     {
605         if ( logger.isDebugEnabled() )
606         {
607             logger.debug( "Synergy : Entering checkinFiles project method" );
608         }
609 
610         Commandline cl = SynergyCCM.checkinFiles( files, comment, ccmAddr );
611 
612         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
613         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
614 
615         executeSynergyCommand( logger, cl, stderr, stdout, true );
616 
617     }
618     
619     /**
620      * Get the number of the current (ie default) task.
621      * 
622      * @param logger  a logger.
623      * @param ccmAddr current Synergy session id.
624      * @return the number of the current (ie default) task. 0 if current task 
625      *            is not set.
626      * @throws ScmException
627      */
628     public static int getDefaultTask( ScmLogger logger, String ccmAddr )
629         throws ScmException
630     {
631         if ( logger.isDebugEnabled() )
632         {
633             logger.debug( "Synergy : Entering getDefaultTask method" );
634         }
635 
636         Commandline cl = SynergyCCM.showDefaultTask( ccmAddr );
637 
638         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
639         SynergyShowDefaultTaskConsumer stdout = new SynergyShowDefaultTaskConsumer( logger );
640 
641         int errorCode = executeSynergyCommand( logger, cl, stderr, stdout, false );
642 
643         if ( logger.isDebugEnabled() )
644         {
645             logger.debug( "getDefaultTask returns " + stdout.getTask() + " with error code " + errorCode );
646         }
647 
648         return stdout.getTask();
649     }
650 
651     /**
652      * Set the current (ie default) task.
653      * 
654      * @param logger  a logger.
655      * @param task      the number of the task to set as current task. 
656      * @param ccmAddr current Synergy session id.
657      * @throws ScmException
658      */
659     public static void setDefaultTask( ScmLogger logger, int task, String ccmAddr )
660         throws ScmException
661     {
662         if ( logger.isDebugEnabled() )
663         {
664             logger.debug( "Synergy : Entering setDefaultTask method" );
665         }
666 
667         Commandline cl = SynergyCCM.setDefaultTask( task, ccmAddr );
668 
669         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
670         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
671 
672         executeSynergyCommand( logger, cl, stderr, stdout, true );
673     }
674 
675     /**
676      * Synchronize a given project.
677      *
678      * @param logger       a logger.
679      * @param projectSpec projectSpec (i.e. myProject~1).
680      * @param ccmAddr      used to run in multi-session.
681      * @throws ScmException
682      */
683     public static void synchronize( ScmLogger logger, String projectSpec, String ccmAddr )
684         throws ScmException
685     {
686         if ( logger.isDebugEnabled() )
687         {
688             logger.debug( "Synergy : Entering synchronize method" );
689         }
690 
691         Commandline cl = SynergyCCM.synchronize( projectSpec, ccmAddr );
692 
693         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
694         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
695 
696         executeSynergyCommand( logger, cl, stderr, stdout, true );
697     }
698 
699     /**
700      * Get the work area of a given project.
701      *
702      * @param logger       a logger.
703      * @param projectSpec projectSpec (i.e. myProject~1).
704      * @param ccmAddr      used to run in multi-session.
705      * @throws ScmException
706      */
707     public static File getWorkArea( ScmLogger logger, String projectSpec, String ccmAddr )
708         throws ScmException
709     {
710         if ( logger.isDebugEnabled() )
711         {
712             logger.debug( "Synergy : Entering getWorkArea method" );
713         }
714 
715         Commandline cl = SynergyCCM.showWorkArea( projectSpec, ccmAddr );
716 
717         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
718         SynergyWorkareaConsumer stdout = new SynergyWorkareaConsumer( logger );
719 
720         executeSynergyCommand( logger, cl, stderr, stdout, true );
721 
722         if ( logger.isDebugEnabled() )
723         {
724             logger.debug( "Synergy : getWorkArea returns " + stdout.getWorkAreaPath() );
725         }
726 
727         return stdout.getWorkAreaPath();
728     }
729 
730     /**
731      * Stop a ccm session.
732      *
733      * @param logger  a logger.
734      * @param ccmAddr used to run in multi-session.
735      * @throws ScmException
736      */
737     public static void stop( ScmLogger logger, String ccmAddr )
738         throws ScmException
739     {
740         if ( logger.isDebugEnabled() )
741         {
742             logger.debug( "Synergy : Entering stop method" );
743         }
744         Commandline cl = SynergyCCM.stop( ccmAddr );
745 
746         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
747         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
748 
749         executeSynergyCommand( logger, cl, stderr, stdout, true );
750     }
751 
752     /**
753      * Start a session Synergy
754      *
755      * @param logger   a logger.
756      * @param username username.
757      * @param password password.
758      * @param role     role or null if none.
759      * @return ccmAddr value to use with this session.
760      */
761     public static String start( ScmLogger logger, String username, String password, SynergyRole role )
762         throws ScmException
763     {
764         if ( logger.isDebugEnabled() )
765         {
766             logger.debug( "Synergy : Entering start method" );
767         }
768 
769         if ( username == null )
770         {
771             throw new ScmException( "username can't be null" );
772         }
773 
774         if ( password == null )
775         {
776             throw new ScmException( "password can't be null" );
777         }
778 
779         Commandline cl = SynergyCCM.start( username, password, role );
780 
781         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
782         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
783 
784         //executeSynergyCommand( logger, cl, stderr, stdout, true );
785         
786         int exitCode = executeSynergyCommand( logger, cl, stderr, stdout, false );
787         
788         if ( logger.isDebugEnabled() )
789         {
790             logger.debug( "Synergy : start returns with error code " + exitCode );
791         }        
792         
793         if ( exitCode != 0 )
794         {
795             cl = SynergyCCM.startRemote( username, password, role );
796 
797             stderr = new CommandLineUtils.StringStreamConsumer();
798             stdout = new CommandLineUtils.StringStreamConsumer();
799 
800             executeSynergyCommand( logger, cl, stderr, stdout, true );
801         }
802 
803         return stdout.getOutput();
804     }
805 
806     /**
807      * Get Database delimiter
808      *
809      * @param logger  a logger.
810      * @param ccmAddr Synergy session ID.
811      * @return delimiter of the database (i.e. ~).
812      */
813     public static String delimiter( ScmLogger logger, String ccmAddr )
814         throws ScmException
815     {
816         if ( logger.isDebugEnabled() )
817         {
818             logger.debug( "Synergy : Entering delimiter method" );
819         }
820 
821         Commandline cl = SynergyCCM.delimiter( ccmAddr );
822 
823         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
824         CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
825 
826         executeSynergyCommand( logger, cl, stderr, stdout, true );
827 
828         return stdout.getOutput();
829     }
830 
831     /**
832      * Execute a command line for Synergy.
833      *
834      * @param logger      a logger.
835      * @param cl          command line.
836      * @param stderr      stderr.
837      * @param stdout      stdout.
838      * @param failOnError should we raise an exception when exit code != 0
839      * @return exit code.
840      * @throws ScmException on error or if exit code != 0 and failOnError = true
841      */
842     protected static int executeSynergyCommand( ScmLogger logger, Commandline cl, StringStreamConsumer stderr,
843                                                 StreamConsumer stdout, boolean failOnError )
844         throws ScmException
845     {
846         int exitCode;
847 
848         try
849         {
850             if ( logger.isDebugEnabled() )
851             {
852                 logger.debug( "Executing: " + cl.toString() );
853             }
854             exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
855         }
856         catch ( CommandLineException ex )
857         {
858             throw new ScmException( "Error while executing synergy command [" + cl.toString() + "].", ex );
859         }
860 
861         if ( logger.isDebugEnabled() )
862         {
863             logger.debug( "Exit code :" + exitCode );
864         }
865         if ( stdout instanceof StringStreamConsumer )
866         {
867             if ( logger.isDebugEnabled() )
868             {
869                 logger.debug( "STDOUT :" + ( (StringStreamConsumer) stdout ).getOutput() );
870             }
871         }
872         else
873         {
874             if ( logger.isDebugEnabled() )
875             {
876                 logger.debug( "STDOUT : unavailable" );
877             }
878         }
879         if ( logger.isDebugEnabled() )
880         {
881             logger.debug( "STDERR :" + stderr.getOutput() );
882         }
883 
884         if ( exitCode != 0 && failOnError )
885         {
886             if ( stdout instanceof StringStreamConsumer )
887             {
888                 throw new ScmException( "Commandeline = " + cl.toString() + "\nSTDOUT = "
889                     + ( (StringStreamConsumer) stdout ).getOutput() + "\nSTDERR = " + stderr.getOutput() + "\n" );
890             }
891             else
892             {
893                 throw new ScmException( "Commandeline = " + cl.toString() + "\nSTDOUT = unavailable" + "\nSTDERR = "
894                     + stderr.getOutput() + "\n" );
895             }
896         }
897 
898         return exitCode;
899     }
900 
901 }