001package 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 022import org.apache.maven.scm.ScmException; 023import org.apache.maven.scm.ScmVersion; 024import org.codehaus.plexus.util.StringUtils; 025import org.codehaus.plexus.util.cli.CommandLineUtils; 026import org.codehaus.plexus.util.cli.Commandline; 027 028import java.io.File; 029import java.io.IOException; 030import java.util.Calendar; 031import java.util.Iterator; 032import java.util.List; 033import 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 */ 041public 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}