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 org.apache.maven.scm.ScmException;
023 import org.apache.maven.scm.ScmVersion;
024 import org.codehaus.plexus.util.StringUtils;
025 import org.codehaus.plexus.util.cli.CommandLineUtils;
026 import org.codehaus.plexus.util.cli.Commandline;
027
028 import java.io.File;
029 import java.io.IOException;
030 import java.util.Calendar;
031 import java.util.Iterator;
032 import java.util.List;
033 import java.util.Properties;
034
035 /**
036 * This class contains methods to execute Synergy <code>ccm</code> command line.
037 *
038 * @author <a href="mailto:julien.henry@capgemini.com">Julien Henry</a>
039 *
040 */
041 public class SynergyCCM
042 {
043
044 private static final String CCM = "ccm";
045
046 private static final String BASELINE = "baseline";
047
048 private static final String CI = "ci";
049
050 private static final String CO = "co";
051
052 private static final String CREATE = "create";
053
054 private static final String DELETE = "delete";
055
056 private static final String DELIMITER = "delimiter";
057
058 private static final String DIR = "dir";
059
060 private static final String QUERY = "query";
061
062 private static final String RECONCILE = "rwa";
063
064 private static final String RECONFIGURE = "reconfigure";
065
066 private static final String RECONFIGURE_PROPERTIES = "reconfigure_properties";
067
068 private static final String START = "start";
069
070 private static final String STOP = "stop";
071
072 private static final String SYNC = "sync";
073
074 private static final String TASK = "task";
075
076 private static final String WA = "wa";
077
078 /**
079 * Create commandline for getting list of objects in a task.
080 *
081 * @param taskNumber Task number.
082 * @param format Output format.
083 * @param ccmAddr
084 * @return the commandline.
085 * @throws ScmException
086 */
087 public static Commandline showTaskObjects( int taskNumber, String format, String ccmAddr )
088 throws ScmException
089 {
090 // Construct the CM Synergy command
091 Commandline cl = new Commandline();
092
093 configureEnvironment( cl, ccmAddr );
094
095 cl.setExecutable( CCM );
096
097 cl.createArg().setValue( TASK );
098 cl.createArg().setValue( "-show" );
099 cl.createArg().setValue( "objects" );
100
101 // Set up the output format
102 if ( format != null && !format.equals( "" ) )
103 {
104 cl.createArg().setValue( "-f" );
105 cl.createArg().setValue( format );
106 }
107
108 cl.createArg().setValue( Integer.toString( taskNumber ) );
109
110 return cl;
111 }
112
113 /**
114 * Create commandline for query.
115 *
116 * @param query query.
117 * @param format Output format
118 * @param ccmAddr
119 * @return the command line.
120 * @throws ScmException
121 */
122 public static Commandline query( String query, String format, String ccmAddr )
123 throws ScmException
124 {
125
126 // Construct the CM Synergy command
127 Commandline cl = new Commandline();
128
129 configureEnvironment( cl, ccmAddr );
130
131 cl.setExecutable( CCM );
132 cl.createArg().setValue( QUERY );
133
134 cl.createArg().setValue( "-u" );
135
136 // Set up the output format
137 if ( format != null && !format.equals( "" ) )
138 {
139 cl.createArg().setValue( "-f" );
140 cl.createArg().setValue( format );
141 }
142
143 cl.createArg().setValue( query );
144
145 return cl;
146 }
147
148 /**
149 * Create command line for creating a baseline.
150 *
151 * @param projectSpec project_name~project_version
152 * @param name Name of the baseline
153 * @param release the release.
154 * @param purpose the purpose.
155 * @param ccmAddr
156 * @return the command line.
157 * @throws ScmException
158 */
159 public static Commandline createBaseline( String projectSpec, String name, String release, String purpose,
160 String ccmAddr )
161 throws ScmException
162 {
163 Commandline cl = new Commandline();
164
165 configureEnvironment( cl, ccmAddr );
166
167 cl.setExecutable( CCM );
168 cl.createArg().setValue( BASELINE );
169
170 cl.createArg().setValue( "-create" );
171 cl.createArg().setValue( name );
172
173 cl.createArg().setValue( "-p" );
174 cl.createArg().setValue( projectSpec );
175
176 cl.createArg().setValue( "-release" );
177 cl.createArg().setValue( release );
178
179 cl.createArg().setValue( "-purpose" );
180 cl.createArg().setValue( purpose );
181
182 return cl;
183
184 }
185
186 /**
187 * Create command line for adding a fileset to a project
188 *
189 * @param files fileset.
190 * @param message message log, or null if none.
191 * @param ccmAddr
192 * @return the command line.
193 * @throws ScmException
194 */
195 public static Commandline create( List<File> files, String message, String ccmAddr )
196 throws ScmException
197 {
198 Commandline cl = new Commandline();
199
200 configureEnvironment( cl, ccmAddr );
201
202 cl.setExecutable( CCM );
203 cl.createArg().setValue( CREATE );
204
205 if ( message != null && !message.equals( "" ) )
206 {
207
208 cl.createArg().setValue( "-c" );
209
210 cl.createArg().setValue( message );
211
212 }
213
214 for ( File f : files )
215 {
216 try
217 {
218 cl.createArg().setValue( f.getCanonicalPath() );
219 }
220 catch ( IOException e )
221 {
222 throw new ScmException( "Invalid file path " + f.toString(), e );
223 }
224 }
225
226 return cl;
227
228 }
229
230 /**
231 * Create command line for creating a task
232 *
233 * @param synopsis synopsis.
234 * @param release release.
235 * @param defaultTask default.
236 * @param ccmAddr
237 * @return the command line.
238 * @throws ScmException
239 */
240 public static Commandline createTask( String synopsis, String release, boolean defaultTask, String ccmAddr )
241 throws ScmException
242 {
243 Commandline cl = new Commandline();
244
245 configureEnvironment( cl, ccmAddr );
246
247 cl.setExecutable( CCM );
248 cl.createArg().setValue( TASK );
249
250 cl.createArg().setValue( "-create" );
251
252 cl.createArg().setValue( "-synopsis" );
253 cl.createArg().setValue( synopsis );
254
255 if ( release != null && !release.equals( "" ) )
256 {
257 cl.createArg().setValue( "-release" );
258 cl.createArg().setValue( release );
259 }
260
261 if ( defaultTask )
262 {
263 cl.createArg().setValue( "-default" );
264 }
265
266 cl.createArg().setValue( "-description" );
267 cl.createArg().setValue(
268 "This task was created by Maven SCM Synergy provider on " + Calendar.getInstance().getTime() );
269
270 return cl;
271
272 }
273
274 /**
275 * Create command line for checkin a task
276 *
277 * @param taskSpecs task_specs or default
278 * @param comment comment.
279 * @param ccmAddr
280 * @return
281 * @throws ScmException
282 */
283 public static Commandline checkinTask( String taskSpecs, String comment, String ccmAddr )
284 throws ScmException
285 {
286 Commandline cl = new Commandline();
287
288 configureEnvironment( cl, ccmAddr );
289
290 cl.setExecutable( CCM );
291 cl.createArg().setValue( TASK );
292
293 cl.createArg().setValue( "-checkin" );
294
295 cl.createArg().setValue( taskSpecs );
296
297 cl.createArg().setValue( "-comment" );
298 cl.createArg().setValue( comment );
299
300 return cl;
301
302 }
303
304 /**
305 * Create command line for deleting file(s).
306 *
307 * @param files fileset.
308 * @param ccmAddr
309 * @param replace replace with previous version of file ?
310 * @return
311 * @throws ScmException
312 */
313 public static Commandline delete( List<File> files, String ccmAddr, boolean replace )
314 throws ScmException
315 {
316 Commandline cl = new Commandline();
317
318 configureEnvironment( cl, ccmAddr );
319
320 cl.setExecutable( CCM );
321 cl.createArg().setValue( DELETE );
322
323 if ( replace )
324 {
325 cl.createArg().setValue( "-replace" );
326 }
327
328 for ( File f : files )
329 {
330 try
331 {
332 cl.createArg().setValue( f.getCanonicalPath() );
333 }
334 catch ( IOException e )
335 {
336 throw new ScmException( "Invalid file path " + f.toString(), e );
337 }
338 }
339
340 return cl;
341
342 }
343
344 /**
345 * Create commandline to reconfigure a project.
346 *
347 * @param projectSpec
348 * @param ccmAddr
349 * @return the command line.
350 * @throws ScmException
351 */
352 public static Commandline reconfigure( String projectSpec, String ccmAddr )
353 throws ScmException
354 {
355 Commandline cl = new Commandline();
356
357 configureEnvironment( cl, ccmAddr );
358
359 cl.setExecutable( CCM );
360 cl.createArg().setValue( RECONFIGURE );
361
362 cl.createArg().setValue( "-recurse" );
363
364 if ( projectSpec != null )
365 {
366 cl.createArg().setValue( "-p" );
367 cl.createArg().setValue( projectSpec );
368 }
369
370 return cl;
371
372 }
373
374 /**
375 * Create commandline to reconfigure properties of a project.
376 *
377 * @param projectSpec
378 * @param ccmAddr
379 * @return
380 * @throws ScmException
381 */
382 public static Commandline reconfigureProperties( String projectSpec, String ccmAddr )
383 throws ScmException
384 {
385 Commandline cl = new Commandline();
386
387 configureEnvironment( cl, ccmAddr );
388
389 cl.setExecutable( CCM );
390 cl.createArg().setValue( RECONFIGURE_PROPERTIES );
391
392 cl.createArg().setValue( "-refresh" );
393 cl.createArg().setValue( projectSpec );
394
395 return cl;
396
397 }
398
399 /**
400 * Create command line to reconcile a project with uwa option.
401 *
402 * @param projectSpec
403 * @param ccmAddr
404 * @return
405 * @throws ScmException
406 */
407 public static Commandline reconcileUwa( String projectSpec, String ccmAddr )
408 throws ScmException
409 {
410 Commandline cl = new Commandline();
411
412 configureEnvironment( cl, ccmAddr );
413
414 cl.setExecutable( CCM );
415 cl.createArg().setValue( RECONCILE );
416
417 cl.createArg().setValue( "-r" );
418 cl.createArg().setValue( "-uwa" ); // Update wa from database
419
420 if ( projectSpec != null )
421 {
422 cl.createArg().setValue( "-p" );
423 cl.createArg().setValue( projectSpec );
424 }
425
426 return cl;
427
428 }
429
430 /**
431 * Create command line to reconcile a project with udb option.
432 *
433 * @param projectSpec
434 * @param ccmAddr
435 * @return
436 * @throws ScmException
437 */
438 public static Commandline reconcileUdb( String projectSpec, String ccmAddr )
439 throws ScmException
440 {
441 Commandline cl = new Commandline();
442
443 configureEnvironment( cl, ccmAddr );
444
445 cl.setExecutable( CCM );
446 cl.createArg().setValue( RECONCILE );
447
448 cl.createArg().setValue( "-r" );
449 cl.createArg().setValue( "-udb" ); // Update database from wa
450
451 if ( projectSpec != null )
452 {
453 cl.createArg().setValue( "-p" );
454 cl.createArg().setValue( projectSpec );
455 }
456
457 return cl;
458
459 }
460
461 /**
462 * Create command line to perform a dir on the directory.
463 *
464 * @param directory
465 * @param format Output format.
466 * @param ccmAddr
467 * @return
468 * @throws ScmException
469 */
470 public static Commandline dir( File directory, String format, String ccmAddr )
471 throws ScmException
472 {
473 Commandline cl = new Commandline();
474
475 configureEnvironment( cl, ccmAddr );
476
477 try
478 {
479 cl.setWorkingDirectory( directory.getCanonicalPath() );
480 }
481 catch ( IOException e )
482 {
483 throw new ScmException( "Invalid directory", e );
484 }
485
486 cl.setExecutable( CCM );
487 cl.createArg().setValue( DIR );
488 cl.createArg().setValue( "-m" );
489
490 // Set up the output format
491 if ( format != null && !format.equals( "" ) )
492 {
493 cl.createArg().setValue( "-f" );
494 cl.createArg().setValue( format );
495 }
496
497 return cl;
498
499 }
500
501 /**
502 * Create commandline to checkout a fileset.
503 *
504 * @param files fileset.
505 * @param ccmAddr
506 * @return the command line.
507 * @throws ScmException
508 */
509 public static Commandline checkoutFiles( List<File> files, String ccmAddr )
510 throws ScmException
511 {
512 Commandline cl = new Commandline();
513
514 configureEnvironment( cl, ccmAddr );
515
516 cl.setExecutable( CCM );
517 cl.createArg().setValue( CO );
518
519 for ( File f : files )
520 {
521 try
522 {
523 cl.createArg().setValue( f.getCanonicalPath() );
524 }
525 catch ( IOException e )
526 {
527 throw new ScmException( "Invalid file path " + f.toString(), e );
528 }
529 }
530
531 return cl;
532 }
533
534 /**
535 * Create commandline to checkout a project
536 *
537 * @param directory target WA, or null if using default directory
538 * @param projectSpec
539 * @param version new version of the project, or null if using default Synergy
540 * mecanism
541 * @param ccmAddr
542 * @return
543 * @throws ScmException
544 */
545 public static Commandline checkoutProject( File directory, String projectSpec, ScmVersion version, String purpose,
546 String release, String ccmAddr )
547 throws ScmException
548 {
549 Commandline cl = new Commandline();
550
551 configureEnvironment( cl, ccmAddr );
552
553 cl.setExecutable( CCM );
554 cl.createArg().setValue( CO );
555 cl.createArg().setValue( "-subprojects" ); // Checkout sub-projects
556 cl.createArg().setValue( "-rel" ); // Relative
557
558 if ( version != null && StringUtils.isNotEmpty( version.getName() ) )
559 {
560 cl.createArg().setValue( "-t" ); // Version
561 cl.createArg().setValue( version.getName() );
562 }
563
564 if ( purpose != null && !purpose.equals( "" ) )
565 {
566 cl.createArg().setValue( "-purpose" );
567 cl.createArg().setValue( purpose );
568 }
569
570 if ( release != null && !release.equals( "" ) )
571 {
572 cl.createArg().setValue( "-release" );
573 cl.createArg().setValue( release );
574 }
575
576 if ( directory != null )
577 {
578 cl.createArg().setValue( "-path" );
579 try
580 {
581 cl.createArg().setValue( directory.getCanonicalPath() );
582 }
583 catch ( IOException e )
584 {
585 throw new ScmException( "Invalid directory", e );
586 }
587 }
588 cl.createArg().setValue( "-p" );
589 cl.createArg().setValue( projectSpec );
590
591 return cl;
592 }
593
594 /**
595 * Create commandline to checkin a project
596 *
597 * @param projectSpec
598 * @param comment
599 * @param ccmAddr
600 * @return
601 * @throws ScmException
602 */
603 public static Commandline checkinProject( String projectSpec, String comment, String ccmAddr )
604 throws ScmException
605 {
606 Commandline cl = new Commandline();
607
608 configureEnvironment( cl, ccmAddr );
609
610 cl.setExecutable( CCM );
611 cl.createArg().setValue( CI );
612 if ( comment != null && !comment.equals( "" ) )
613 {
614 cl.createArg().setValue( "-c" );
615 cl.createArg().setValue( comment );
616 }
617 cl.createArg().setValue( "-p" );
618 cl.createArg().setValue( projectSpec );
619
620 return cl;
621 }
622
623 /**
624 * Create commandline to checkin a fileset
625 *
626 * @param files fileset.
627 * @param comment
628 * @param ccmAddr
629 * @return
630 * @throws ScmException
631 */
632 public static Commandline checkinFiles( List<File> files, String comment, String ccmAddr )
633 throws ScmException
634 {
635 Commandline cl = new Commandline();
636
637 configureEnvironment( cl, ccmAddr );
638
639 cl.setExecutable( CCM );
640 cl.createArg().setValue( CI );
641 if ( comment != null && !comment.equals( "" ) )
642 {
643 cl.createArg().setValue( "-c" );
644 cl.createArg().setValue( comment );
645 }
646
647 if ( files.size() > 0 )
648 {
649 for ( File f : files )
650 {
651 try
652 {
653 cl.createArg().setValue( f.getCanonicalPath() );
654 }
655 catch ( IOException e )
656 {
657 throw new ScmException( "Invalid file path " + f.toString(), e );
658 }
659 }
660 }
661 return cl;
662 }
663
664 /**
665 * Create commandline to synchronize a project
666 *
667 * @param projectSpec
668 * @param ccmAddr
669 * @return
670 * @throws ScmException
671 */
672 public static Commandline synchronize( String projectSpec, String ccmAddr )
673 throws ScmException
674 {
675 Commandline cl = new Commandline();
676
677 configureEnvironment( cl, ccmAddr );
678
679 cl.setExecutable( CCM );
680 cl.createArg().setValue( SYNC );
681 cl.createArg().setValue( "-r" ); // Recursive
682 cl.createArg().setValue( "-p" );
683 cl.createArg().setValue( projectSpec );
684
685 return cl;
686 }
687
688 /**
689 * Create commandline to get workarea informations for a given project.
690 *
691 * @param projectSpec
692 * @param ccmAddr
693 * @return
694 * @throws ScmException
695 */
696 public static Commandline showWorkArea( String projectSpec, String ccmAddr )
697 throws ScmException
698 {
699 Commandline cl = new Commandline();
700
701 configureEnvironment( cl, ccmAddr );
702
703 cl.setExecutable( CCM );
704 cl.createArg().setValue( WA );
705 cl.createArg().setValue( "-show" );
706 cl.createArg().setValue( projectSpec );
707
708 return cl;
709 }
710
711 /**
712 * Create commandline to stop a Synergy session
713 *
714 * @param ccmAddr
715 * @return
716 * @throws ScmException
717 */
718 public static Commandline stop( String ccmAddr )
719 throws ScmException
720 {
721 Commandline cl = new Commandline();
722
723 configureEnvironment( cl, ccmAddr );
724
725 cl.setExecutable( CCM );
726 cl.createArg().setValue( STOP );
727
728 return cl;
729 }
730
731 /**
732 * Configure a commandline to use environment variables ($PATH)
733 *
734 * @param cl
735 * @param ccmAddr
736 * @throws ScmException
737 */
738 private static void configureEnvironment( Commandline cl, String ccmAddr )
739 throws ScmException
740 {
741 // We need PATH to be set for using CCM
742 try
743 {
744 Properties envVars = CommandLineUtils.getSystemEnvVars();
745
746 for ( @SuppressWarnings( "rawtypes" )
747 Iterator i = envVars.keySet().iterator(); i.hasNext(); )
748 {
749 String key = (String) i.next();
750
751 if ( !key.equalsIgnoreCase( "CCM_ADDR" ) )
752 {
753
754 cl.addEnvironment( key, envVars.getProperty( key ) );
755
756 }
757 }
758 }
759 catch ( Exception e1 )
760 {
761 throw new ScmException( "Fail to add PATH environment variable.", e1 );
762
763 }
764 cl.addEnvironment( "CCM_ADDR", ccmAddr );
765
766 }
767
768 /**
769 * Create commandline to start a Synergy session
770 *
771 * @param username
772 * @param password
773 * @param role
774 * @return
775 * @throws ScmException
776 */
777 public static Commandline start( String username, String password, SynergyRole role )
778 throws ScmException
779 {
780 Commandline cl = new Commandline();
781
782 cl.setExecutable( CCM );
783 cl.createArg().setValue( START );
784 cl.createArg().setValue( "-nogui" );
785 cl.createArg().setValue( "-m" ); // Multissesion
786 cl.createArg().setValue( "-q" ); // Quiet (return only CCM_ADDR)
787 cl.createArg().setValue( "-n" );
788 cl.createArg().setValue( username );
789 cl.createArg().setValue( "-pw" );
790 cl.createArg().setValue( password );
791 if ( role != null )
792 {
793 cl.createArg().setValue( "-r" );
794 cl.createArg().setValue( role.toString() );
795 }
796
797 return cl;
798 }
799
800 /**
801 * Create commandline to start a remote Synergy session
802 *
803 * @param username
804 * @param password
805 * @param role
806 * @return
807 * @throws ScmException
808 */
809 public static Commandline startRemote( String username, String password, SynergyRole role )
810 throws ScmException
811 {
812 Commandline cl = new Commandline();
813
814 cl.setExecutable( CCM );
815 cl.createArg().setValue( START );
816 cl.createArg().setValue( "-nogui" );
817 cl.createArg().setValue( "-m" ); // Multissesion
818 cl.createArg().setValue( "-q" ); // Quiet (return only CCM_ADDR)
819 cl.createArg().setValue( "-rc" ); //Remote client
820 cl.createArg().setValue( "-n" );
821 cl.createArg().setValue( username );
822 cl.createArg().setValue( "-pw" );
823 cl.createArg().setValue( password );
824 if ( role != null )
825 {
826 cl.createArg().setValue( "-r" );
827 cl.createArg().setValue( role.toString() );
828 }
829
830 return cl;
831 }
832
833 /**
834 * Create commandline to get Synergy database delimiter
835 *
836 * @return
837 * @throws ScmException
838 */
839 public static Commandline delimiter( String ccmAddr )
840 throws ScmException
841 {
842 Commandline cl = new Commandline();
843
844 configureEnvironment( cl, ccmAddr );
845
846 cl.setExecutable( CCM );
847 cl.createArg().setValue( DELIMITER );
848
849 return cl;
850 }
851
852 /**
853 * Create commandline to get current (i.e. default) task
854 *
855 * @param ccmAddr current Synergy session ID
856 * @return
857 * @throws ScmException
858 */
859 public static Commandline showDefaultTask( String ccmAddr )
860 throws ScmException
861 {
862 Commandline cl = new Commandline();
863
864 configureEnvironment( cl, ccmAddr );
865 cl.setExecutable( CCM );
866 cl.createArg().setValue( TASK );
867 cl.createArg().setValue( "-default" );
868
869 return cl;
870 }
871
872 /**
873 * Create commandline to set current (i.e. default) task
874 *
875 * @param task the number of the task to set as current task
876 * @param ccmAddr current Synergy session ID
877 * @return
878 * @throws ScmException
879 */
880 public static Commandline setDefaultTask( int task, String ccmAddr )
881 throws ScmException
882 {
883 Commandline cl = new Commandline();
884
885 configureEnvironment( cl, ccmAddr );
886 cl.setExecutable( CCM );
887 cl.createArg().setValue( TASK );
888 cl.createArg().setValue( "-default" );
889 cl.createArg().setValue( String.valueOf( task ) );
890 return cl;
891 }
892 }