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