Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
814 mhunt 1
package com.erggroup.buildtool.ripple;
2
 
3
import java.io.File;
4
 
5
import java.sql.SQLException;
6
 
7
import java.util.Iterator;
866 mhunt 8
import java.util.ListIterator;
814 mhunt 9
import java.util.Vector;
10
 
11
import org.apache.log4j.Logger;
12
 
830 mhunt 13
import java.util.regex.PatternSyntaxException;
14
 
814 mhunt 15
/**Plans release impact by generating a set of Strings containing build file content.
16
 */
17
public class RippleEngine
18
{
19
  /**collection of gbemachtypes in String form associated with the baseline
20
   * limited to the following items "win32", "sparc", "solaris10_sparc32", "solaris10_x86", "linux_i386"
21
   * accessed by Package::isLinuxBuilt, isSolarisBuilt, isWin32Built
22
   * @attribute
23
   */
864 mhunt 24
  Vector<String> mGbeMachtypeCollection = new Vector<String>();
866 mhunt 25
 
814 mhunt 26
  /**configured mail server
27
   * @attribute
28
   */
868 mhunt 29
  public String mMailServer = new String();
814 mhunt 30
 
31
  /**configured mail sender user
32
   * @attribute
33
   */
868 mhunt 34
  public String mMailSender = new String();
814 mhunt 35
 
868 mhunt 36
  /**configured global email target
37
   * @attribute
38
   */
39
  public String mGlobalTarget = new String();
40
 
814 mhunt 41
  /**name associated with the baseline
42
   * @attribute
43
   */
868 mhunt 44
  public String mBaselineName = new String();
814 mhunt 45
 
46
  /**collection of released pv_ids associated with the release
47
   * @attribute
48
   */
864 mhunt 49
  Vector<Integer> mReleasedPvIDCollection = new Vector<Integer>();
814 mhunt 50
 
51
  /**timestamp associated with build file generation
52
   * @attribute
53
   */
54
  long mTimestamp = 0;
55
 
56
  /**set to "non generic", "generic" or "dummy" to indicate the nature of the package in the build file in daemon mode
57
   * @attribute
58
   */
59
  String mAddendum = new String("dummy");
60
 
866 mhunt 61
  /**collection of build exceptions associated with the baseline
62
  /* used to determine (and report) what change in build exceptions happens as part of planRelease
63
   * deamon centric
64
   * @aggregation shared
65
   * @attribute
66
   */
67
  Vector<BuildExclusion> mBuildExclusionCollection = new Vector<BuildExclusion>();
68
 
814 mhunt 69
  /**Logger
70
   * @attribute
71
   */
72
  private static final Logger mLogger = Logger.getLogger(RippleEngine.class);
73
 
830 mhunt 74
  /**collection of escrow clearcase support file content in String form, set_up
814 mhunt 75
   * @attribute
76
   */
864 mhunt 77
  private Vector<String> mEscrowClearcaseSupportCollection = new Vector<String>();
814 mhunt 78
 
79
  /**package versions representing the baseline
866 mhunt 80
   * escrow centric
814 mhunt 81
   * @aggregation shared
82
   * @attribute
83
   */
864 mhunt 84
  private Vector<Package> mPackageCollection = new Vector<Package>();
814 mhunt 85
 
86
  /**index to current String item
87
   * @attribute
88
   */
89
  private int mBuildIndex;
90
 
91
  /**Database abstraction
92
   * @attribute
93
   */
94
  private ReleaseManager mReleaseManager;
95
 
96
  /**Baseline identifier (rtag_id for a release manager baseline, bom_id for deployment manager baseline)
97
   * @attribute
98
   */
99
  private int mBaseline;
100
 
101
  /**When true, mBuildCollection contains one item based on a release manager rtag_id and contains a daemon property
102
   * When false, mBuildCollection contains at least one item based on a deployment manager bom_id
103
   * Will be accessed by the Package class to calculate its mAlias
104
   * @attribute
105
   */
106
  boolean mDaemon;
107
 
108
  /**collection of build file content in String form
109
   * @attribute
110
   */
864 mhunt 111
  private Vector<String> mBuildCollection = new Vector<String>();
814 mhunt 112
 
113
  /**constructor
114
   */
115
  public RippleEngine(ReleaseManager releaseManager, int rtag_id, 
116
                      boolean isDaemon)
117
  {
118
    mLogger.debug("RippleEngine rtag_id " + rtag_id + " isDaemon " + isDaemon);
119
    mReleaseManager = releaseManager;
120
    mBaseline = rtag_id;
121
    mDaemon = isDaemon;
122
  }
123
 
124
  /**discards all build file content
125
   * plans new build file content
126
   */
127
  public void planRelease() throws SQLException, Exception
128
  {
129
    mLogger.warn("planRelease mDaemon " + mDaemon);
130
    mAddendum = "dummy";
131
    mBuildCollection.removeAllElements();
132
    mPackageCollection.removeAllElements();
133
    mReleasedPvIDCollection.removeAllElements();
134
 
135
    if ( !mDaemon )
136
    {
137
      mEscrowClearcaseSupportCollection.removeAllElements();  
138
    }
139
 
140
    mReleaseManager.connect();
141
 
142
    if ( mDaemon )
143
    {
144
      // claim the mutex
145
      mReleaseManager.claimMutex();
866 mhunt 146
      mBuildExclusionCollection.removeAllElements();
147
      Vector<BuildExclusion> tempBuildExclusionCollection = new Vector<BuildExclusion>();
148
 
149
      mReleaseManager.queryBuildExclusions(tempBuildExclusionCollection, mBaseline);
150
 
151
      // only populate mBuildExclusionCollection with tempBuildExclusionCollection entries which have a relevant root_pv_id
152
      // ie the root_pv_id is ONLY relevant if it is null (-1) or it points to a pv_id in the collection
153
      // the package with a pv_id which is a root_pv_id may be removed ie when fixing a build issue
154
      for (Iterator<BuildExclusion> it = tempBuildExclusionCollection.iterator(); it.hasNext(); )
155
      {
156
        BuildExclusion buildExclusion = it.next();
157
 
158
        if ( buildExclusion.isRelevant(tempBuildExclusionCollection) )
159
        {
160
          mBuildExclusionCollection.add(buildExclusion);
161
        }
162
        else
163
        {
164
          // this is just a cosmetic step
165
          // it includes package versions which have been indirectly excluded
166
          // the build daemon ignores this information, but it serves to clarify this point to users
167
          buildExclusion.includeToBuild(mReleaseManager, mBaseline);
168
        }
169
      }
814 mhunt 170
    }
171
 
172
    mReleaseManager.queryPackageVersions(this, mPackageCollection, mDaemon, mBaseline);
173
 
174
    // set up mPackageDependencyCollection
864 mhunt 175
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 176
    {
864 mhunt 177
      Package p = it.next();
814 mhunt 178
 
864 mhunt 179
      for (Iterator<String> it2 = p.mDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 180
      {
864 mhunt 181
        String alias = it2.next();
814 mhunt 182
        Package dependency = findPackage(alias);
183
 
184
        if (dependency == ReleaseManager.NULL_PACKAGE)
185
        {
186
          mLogger.info("planRelease dependency is not in the baseline " + alias);
187
          // exclude all dependent packages
866 mhunt 188
          // max 50 chars
189
          rippleBuildExclude(p, p.mId, "Package build dependency not in the release", null);
814 mhunt 190
 
191
          // take the package out of the build
192
          p.mBuildFile = -4;
894 mhunt 193
          mLogger.info("planRelease set mBuildFile to -4 for package " + p.mAlias );
814 mhunt 194
          break;
195
        }
196
 
197
        p.mPackageDependencyCollection.add(dependency);
198
      }
199
    }
200
 
201
    // process packages which are not reproducible, and all packages dependent upon them      
864 mhunt 202
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 203
    {
864 mhunt 204
      Package p = it.next();
814 mhunt 205
 
206
      if (p.mBuildFile == 0)
207
      {
208
        // package has yet to be processed
209
        if (!p.isReproducible())
210
        {
866 mhunt 211
          // for escrow build purposes, exclude all dependent package versions
212
          mLogger.info("planRelease package not reproducible " + p.mName);
213
          // max 50 chars
884 mhunt 214
          rippleBuildExclude(p, p.mId, "Package has no build environment", null);
870 dpurdie 215
 
814 mhunt 216
          // package is not reproducible, discard
217
          p.mBuildFile = -1;
894 mhunt 218
          mLogger.info("planRelease set mBuildFile to -1 for package " + p.mAlias );
814 mhunt 219
        }
220
      }
221
    }
222
 
223
    // process packages which are not reproducible on the build platforms configured for this baseline
864 mhunt 224
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 225
    {
864 mhunt 226
      Package p = it.next();
814 mhunt 227
 
228
      if (p.mBuildFile == 0)
229
      {
230
        // package has yet to be processed
858 mhunt 231
        // assume it does not need to be reproduced for this baseline
232
        boolean reproduce = false;
233
 
864 mhunt 234
        for (Iterator<String> it2 = mGbeMachtypeCollection.iterator(); it2.hasNext(); )
814 mhunt 235
        {
864 mhunt 236
          String machtype = it2.next();
858 mhunt 237
 
238
          if ( machtype.compareTo("linux_i386") == 0 )
814 mhunt 239
          {
858 mhunt 240
            if ( p.isLinuxBuilt() )
814 mhunt 241
            {
858 mhunt 242
              reproduce = true;
243
              mLogger.info("planRelease package built on linux " + p.mAlias );
244
              break;
814 mhunt 245
            }
858 mhunt 246
          }
247
          else if ( machtype.compareTo("win32") == 0 )
248
          {
249
            if ( p.isWin32Built() )
814 mhunt 250
            {
858 mhunt 251
              reproduce = true;
252
              mLogger.info("planRelease package built on win32 " + p.mAlias );
253
              break;
814 mhunt 254
            }
858 mhunt 255
          }
256
          else if ( machtype.compareTo("sparc") == 0
257
                 || machtype.compareTo("solaris10_x86") == 0
258
                 || machtype.compareTo("solaris10_sparc32") == 0 )
259
          {
260
            if ( p.isSolarisBuilt() )
814 mhunt 261
            {
858 mhunt 262
              reproduce = true;
263
              mLogger.info("planRelease package built on solaris " + p.mAlias );
264
              break;
814 mhunt 265
            }
266
          }
858 mhunt 267
        }
814 mhunt 268
 
858 mhunt 269
        if ( !reproduce )
270
        {
866 mhunt 271
          // for escrow build purposes, exclude all dependent package versions
272
          mLogger.info("planRelease package not reproducible on the build platforms configured for this baseline " + p.mName);
273
          // max 50 chars
274
          rippleBuildExclude(p, p.mId, "Package not built for configured platforms", null);
858 mhunt 275
 
276
          // package is not reproducible on the build platforms configured for this baseline, discard
277
          p.mBuildFile = -2;
894 mhunt 278
          mLogger.info("planRelease set mBuildFile to -2 for package " + p.mAlias );
814 mhunt 279
        }
280
      }
281
    }      
282
 
283
    if (mDaemon)
284
    {
866 mhunt 285
      // process packages which are not ripple buildable, and all packages dependent upon them
286
      for (ListIterator<BuildExclusion> it = mBuildExclusionCollection.listIterator(); it.hasNext(); )
814 mhunt 287
      {
866 mhunt 288
        BuildExclusion be = it.next();
289
 
290
        for (Iterator<Package> it1 = mPackageCollection.iterator(); it1.hasNext(); )
814 mhunt 291
        {
866 mhunt 292
          Package p = it1.next();
293
 
294
          if ( be.compare(p.mId) )
814 mhunt 295
          {
866 mhunt 296
            if ( p.mBuildFile == 0 )
297
            {
298
              // exclude all dependent package versions
299
              mLogger.info("planRelease do not ripple " + p.mName);
300
              // provide the root id and cause as recorded in the database
301
              rippleBuildExclude(p, be, it);
302
 
303
              // package is not reproducible, discard
304
              p.mBuildFile = -3;
894 mhunt 305
              mLogger.info("planRelease set mBuildFile to -3 for package " + p.mAlias );
866 mhunt 306
            }
307
            break;
814 mhunt 308
          }
309
        }
310
      }
311
 
312
      // process packages which need to be ripple built
864 mhunt 313
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 314
      {
864 mhunt 315
        Package p = it.next();
814 mhunt 316
 
317
        if (p.mBuildFile == 0)
318
        {
319
          // package has yet to be processed
320
          if (p.mDirectlyPlanned)
321
          {
322
            // a WIP exists on the package
323
            // exclude all dependent package versions
324
            mLogger.info("planRelease package has WIP " + p.mName);
325
            rippleIndirectlyPlanned(p);
326
          }
327
          else
328
          {
864 mhunt 329
            Iterator<Integer> it2 = p.mDependencyIDCollection.iterator();
330
            Iterator<Package> it3 = p.mPackageDependencyCollection.iterator();
814 mhunt 331
            for ( ; it2.hasNext() && it3.hasNext(); )
332
            {
864 mhunt 333
              Integer dpv_id = it2.next();
334
              Package dependency = it3.next();
814 mhunt 335
 
336
              if ( !dependency.mAdvisoryRipple )
337
              {
338
                // not advisory, ie has ripple build impact
339
                boolean found = false;
340
 
864 mhunt 341
                for ( Iterator<Integer> it4 = mReleasedPvIDCollection.iterator(); it4.hasNext(); )
814 mhunt 342
                {
864 mhunt 343
                  Integer pv_id = it4.next();
836 mhunt 344
 
814 mhunt 345
                  if ( pv_id.compareTo(dpv_id) == 0 )
346
                  {
347
                    found = true;
348
                    break;
349
                  }
350
                }
351
 
352
                if ( !found )
353
                {
354
                  // the package is out of date
355
                  // exclude all dependent package versions
356
                  mLogger.info("planRelease package out of date " + p.mName);
357
                  rippleIndirectlyPlanned(p);                 
358
                  break;
359
                }
360
              }
361
            }
362
          }
363
        }
364
      }
365
 
366
      // process packages which do not exist in the archive
864 mhunt 367
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 368
      {
864 mhunt 369
        Package p = it.next();
814 mhunt 370
 
371
        if (p.mBuildFile == 0)
372
        {
373
          // package has yet to be processed
374
          // for unit test purposes, assume all packages exist in the archive if released
864 mhunt 375
          if ( ReleaseManager.mUseDatabase )
814 mhunt 376
          {
377
            // only check existence outside the unit test
378
            if (!p.mDirectlyPlanned && !p.mIndirectlyPlanned)
379
            {
380
              // check package version archive existence
381
              if (!p.exists())
382
              {
383
                mLogger.info("planRelease package not found in archive " + p.mName);
852 mhunt 384
                // DEVI 47395 the cause of this build is not WIP or ripple induced,
385
                // it simply does not exist in the archive (has been removed)
386
                // prevent source control interaction
387
                p.mRequiresSourceControlInteraction = false;
814 mhunt 388
                rippleIndirectlyPlanned(p);
389
              }
390
            }
391
          }
392
        }
393
      }
394
    }
395
 
396
    // process remaining packages which need to be reproduced for this baseline
397
    // determine the build file for each package
398
    // for daemon builds, determine the first package that can be built now, this means the first package not dependent upon packages also to be built
399
    // set its mBuildNumber to 1, all remaining reproducible packages to 2
400
    // for escrow builds, determine the package versions that can be built in the build iteration
401
    // set their mBuildNumber to the build iteration
402
    // increment the build iteration and repeat until all package versions that need to be reproduced have been assigned a build iteration
403
    boolean allProcessed = false;
404
    int buildFile = 1;
405
 
406
    // delete the file <rtagId>official
407
    Integer rtag = new Integer(mBaseline);
408
    File rtagIdOfficial = new File(rtag + "official");
409
 
410
    if (rtagIdOfficial.exists())
411
    {
826 mhunt 412
      boolean del = rtagIdOfficial.delete();
413
 
414
      if ( !del )
415
      {
416
        // the delete failed
417
        // some literature suggests a forced garbage collection may free up resources associated with file handles
418
        // nothing to lose since the file "must" be deleted
419
        System.gc();
420
        del = rtagIdOfficial.delete();
421
 
422
        if ( !del )
423
        {
424
          mLogger.fatal("rtagIdOfficial.delete() returned " + del);
425
        }
426
      }
814 mhunt 427
    }
428
 
830 mhunt 429
    String raw_data = new String("");
430
    String lf = new String( System.getProperty("line.separator") );
431
 
814 mhunt 432
    do
433
    {
434
      boolean allDependenciesProcessed = true;
435
 
436
      do
437
      {
438
        // assume all dependencies have been processed
439
        allDependenciesProcessed = true;
440
 
864 mhunt 441
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 442
        {
864 mhunt 443
          Package p = it.next();
814 mhunt 444
 
445
          if ( mDaemon && ( ( !p.mDirectlyPlanned && !p.mIndirectlyPlanned ) || p.mBuildFile < 0 ) )
446
          {
447
            // flag packages with no build requirement as processed in daemon mode
448
            p.mProcessed = true;
449
            mLogger.info("planRelease package has no build requirement " + p.mName);            
450
          }
451
          else
452
          {
453
            if ( ( p.mBuildFile == 0 ) && ( (mDaemon && ( p.mDirectlyPlanned || p.mIndirectlyPlanned ) ) || ( !mDaemon ) ) )
454
            {
455
              // package yet to be processed and
456
              // in daemon mode has a build requirement or
457
              // in escrow mode
458
              boolean canBeBuiltNow = true;
459
              boolean allDependenciesForThisPackageProcessed = true;
460
 
864 mhunt 461
              for ( Iterator<Package> it2 = p.mPackageDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 462
              {
864 mhunt 463
                Package dependency = it2.next();
814 mhunt 464
 
465
                if ( !dependency.mProcessed )
466
                {
467
                  // cannot determine canBeBuiltNow until this dependency has been processed
468
                  allDependenciesForThisPackageProcessed = false;
469
                  allDependenciesProcessed = false;
470
                }
471
                else if ( ( mDaemon && ( dependency.mDirectlyPlanned ) || ( dependency.mIndirectlyPlanned ) ) || 
472
                          ( !mDaemon &&
473
                            ( ( dependency.mBuildFile == 0 ) ||
474
                              ( dependency.mBuildFile == buildFile &&
475
                                ( ( p.isLinuxBuilt() && !dependency.isLinuxBuilt() ) ||
476
                                  ( p.isWin32Built() && !dependency.isWin32Built() ) ||
834 mhunt 477
                                  ( p.isSolarisBuilt() && !dependency.isSolarisBuilt() ) ||
478
                                  ( !p.isLinuxBuilt() && dependency.isLinuxBuilt() ) ||
479
                                  ( !p.isWin32Built() && dependency.isWin32Built() ) ||
480
                                  ( !p.isSolarisBuilt() && dependency.isSolarisBuilt() ) ) ) ) ) )
814 mhunt 481
                {
482
                  // in daemon mode this processed dependency has a build requirement or
483
                  // in escrow mode...
484
                  // this processed dependency has not been assigned to a build iteration or
485
                  // this processed dependency has been assigned to this build iteration and does not build on this platform
486
                  canBeBuiltNow = false;
487
                  mLogger.info("planRelease package cannot be built in this iteration " + p.mName);
488
                  break;
489
                }
490
              }
491
 
492
              if (allDependenciesForThisPackageProcessed)
493
              {
494
                p.mProcessed = true;
495
 
496
                if ( mDaemon )
497
                {
498
                  if ( canBeBuiltNow )
499
                  {
500
                    // flag package with build requirement, may get downgraded to future build requirement
501
                    p.mBuildFile = 1;
894 mhunt 502
                    mLogger.info("planRelease set mBuildFile to 1 for package " + p.mAlias );
814 mhunt 503
                  }
504
                  else
505
                  {
506
                    // flag package with future build requirement
507
                    p.mBuildFile = 2;
894 mhunt 508
                    mLogger.info("planRelease set mBuildFile to 2 for package " + p.mAlias );
814 mhunt 509
                  }
510
                }
511
                else
512
                {
513
                  if ( canBeBuiltNow )
514
                  {
848 dpurdie 515
                    if ( !mDaemon )
516
                    {
517
                      String isWin32Built = new String("");
518
 
519
                      if ( p.isWin32Built() )
520
                      {
521
                        isWin32Built = "W";
522
                      }
523
 
524
                      String isLinuxBuilt = new String("");
525
 
526
                      if ( p.isLinuxBuilt() )
527
                      {
528
                        isLinuxBuilt = "L";
529
                      }
530
 
531
                      String isSolarisBuilt = new String("");
532
 
533
                      if ( p.isSolarisBuilt() )
534
                      {
535
                        isSolarisBuilt = "S";
536
                      }
537
 
538
                      String isGeneric = new String("");
539
 
540
                      if ( p.isGeneric() )
541
                      {
542
                        isGeneric = "G";
543
                      }
544
 
545
                      raw_data += p.mAlias + "," +
546
                                  isWin32Built + "," +
547
                                  isLinuxBuilt + "," +
548
                                  isSolarisBuilt + "," +
549
                                  isGeneric + "," +
550
                                  buildFile +
551
                                  lf;
552
                    }
553
 
858 mhunt 554
                    // not daemon
814 mhunt 555
                    p.mBuildFile = buildFile;
858 mhunt 556
                    mLogger.info("planRelease set mBuildFile to " + buildFile + " for package " + p.mAlias );
814 mhunt 557
                  }
558
                }
559
              }
560
            }
561
          }
562
        }
563
      } while( !allDependenciesProcessed );
564
 
565
      if ( mDaemon )
566
      {
864 mhunt 567
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 568
        {
864 mhunt 569
          Package p = it.next();
814 mhunt 570
 
571
          if ( p.mProcessed && p.mBuildFile == 1 )
572
          {
573
            p.mBuildFile = buildFile;
894 mhunt 574
            mLogger.info("planRelease 2 set mBuildFile to " + buildFile + " for package " + p.mAlias );
836 mhunt 575
 
814 mhunt 576
            if ( buildFile == 1 )
577
            {
874 mhunt 578
              int pvApplied = p.applyPV(mReleaseManager, mBaseline);
579
 
580
              if ( pvApplied == 1 )
581
              {
582
                // max 50 chars
583
                rippleBuildExclude(p, p.mId, "Package has non standard versioning", null);
584
              }
585
              else
586
              if ( pvApplied == 2 )
587
              {
588
                // max 50 chars
589
                rippleBuildExclude(p, p.mId, "Package has reached ripple field limitations", null);
590
              }
591
              else
592
              {
593
                buildFile = 2;
594
              }
814 mhunt 595
            }
596
            else
597
            {
598
              mLogger.info("planRelease package has future (downgraded) build requirement " + p.mName + " " + buildFile);              
599
            }
600
          }
601
        }
602
      }
603
 
604
      // are more build files required
605
      allProcessed = true;
606
 
607
      if (mDaemon)
608
      {
864 mhunt 609
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 610
        {
864 mhunt 611
          Package p = it.next();
814 mhunt 612
 
613
          if ( p.mBuildFile < 0 || ( !p.mDirectlyPlanned && !p.mIndirectlyPlanned ) )
614
          {
615
            // at this point...
616
            // only 1 package with a build requirement has a mBuildFile of 1,
617
            // all other packages with a build requirement have an mBuildFile of 2
618
            // give packages with no build requirement, reproducible or not, an mBuildFile of 3
619
            p.mBuildFile = 3;
894 mhunt 620
            mLogger.info("planRelease 1 set mBuildFile to 3 for package " + p.mAlias );
814 mhunt 621
          }
622
        }
623
      }
624
      else
625
      {
626
        // this is escrow mode centric
864 mhunt 627
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 628
        {
864 mhunt 629
          Package p = it.next();
814 mhunt 630
 
631
          if ( p.mBuildFile == 0 )
632
          {
633
            // more build files are required
634
            allProcessed = false;
635
            mLogger.info("planRelease more build files are required for " + p.mName);
636
            break;
637
          }
638
        }
639
 
640
        buildFile++;
641
      }
642
    } while( !allProcessed );
643
 
644
    // persist the build files
645
    allProcessed = false;
646
    buildFile = 1;
647
 
648
    if ( mDaemon )
649
    {
650
      // all interesting packages in daemon mode match the following filter
651
      buildFile = 3;
652
    }
653
 
654
    mTimestamp = System.currentTimeMillis();
655
 
864 mhunt 656
    if ( !ReleaseManager.mUseDatabase )
814 mhunt 657
    {
658
      mTimestamp = 123456789;
659
    }
660
 
661
    do
662
    {
663
      String buildFileContent = new String( generateBuildFileHeader() );
664
 
864 mhunt 665
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 666
      {
864 mhunt 667
        Package p = it.next();
814 mhunt 668
 
669
        if ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) )
670
        {
671
          buildFileContent += generatePackageProperty(p);
672
        }
673
      }
674
 
675
      buildFileContent += generateTaskdef();
676
 
830 mhunt 677
      String set_up = new String("");
866 mhunt 678
      boolean daemonHasTarget = false;
814 mhunt 679
 
864 mhunt 680
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 681
      {
864 mhunt 682
        Package p = it.next();
814 mhunt 683
 
684
        if ( p.mBuildFile > 0 && p.mBuildFile <= buildFile )
685
        {
686
          buildFileContent += generateTarget(p, buildFile);
866 mhunt 687
 
688
          if ( p.mBuildFile == 1 )
689
          {
690
            daemonHasTarget = true;
691
          }
814 mhunt 692
        }
693
 
694
        if ( !mDaemon && buildFile == 1 )
695
        {
848 dpurdie 696
          // for the purposes of the set up, use /
697
          String loc = new String("");
698
          try
699
          {
700
            // The regular expression "\\\\" matches an escape character "\\" and a single backslash "\\"
701
            loc = p.mLocation.replaceAll("\\\\", "/");
702
          }
703
          catch( PatternSyntaxException e )
704
          {
705
          }
706
 
707
          set_up += "jats release -extractfiles"
708
                    + " \"-label=" + p.mLabel + "\""
709
                    + " \"-path=" + loc + "\""
710
                    + " \"-view=" + p.mAlias + "\""
711
                    + " -root=. -noprefix"
712
                    + lf;
814 mhunt 713
        }
714
      }
866 mhunt 715
 
716
      if ( mDaemon && !daemonHasTarget )
717
      {
718
        // must have AbtSetUp, AbtTearDown, and AbtPublish targets
719
        buildFileContent += "<target name=\"AbtSetUp\"/>" + lf +
720
                            "<target name=\"AbtTearDown\"/>" + lf +
721
                            "<target name=\"AbtPublish\"/>" + lf;
722
      }
723
 
848 dpurdie 724
      if ( !mDaemon && buildFile == 1 )
725
      {
830 mhunt 726
        mEscrowClearcaseSupportCollection.add(set_up);
727
        mEscrowClearcaseSupportCollection.add(raw_data);
814 mhunt 728
      }
729
 
730
      buildFileContent += generateDefaultTarget( buildFile);
731
      buildFileContent += generateBuildFileFooter();
732
 
733
      mBuildCollection.add(buildFileContent);
734
 
735
      // are more build files required
736
      allProcessed = true;
737
 
738
      if (!mDaemon)
739
      {
740
        // this is escrow mode centric
864 mhunt 741
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 742
        {
864 mhunt 743
          Package p = it.next();
814 mhunt 744
 
745
          if ( p.mBuildFile > buildFile )
746
          {
747
            // more build files are required
748
            allProcessed = false;
749
            mLogger.info("planRelease reiterating package has no build requirement " + p.mName + " " + p.mBuildFile + " " + buildFile);
750
            break;
751
          }
752
        } 
753
 
754
        buildFile++;
755
      }
756
    } while( !allProcessed );
757
 
866 mhunt 758
    if ( mDaemon )
759
    {
760
      // report what change in build exceptions happens as part of planRelease
761
      for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
762
      {
763
        BuildExclusion buildExclusion = it.next();
764
 
765
        if ( !buildExclusion.isProcessed() )
766
        {
767
          // notify
768
          buildExclusion.excludeFromBuild(mReleaseManager, mBaseline);
769
          buildExclusion.email(mPackageCollection, mMailServer, mMailSender, mBaselineName);
770
        }
771
      }
772
    }
773
 
814 mhunt 774
    mReleaseManager.disconnect();
775
    mLogger.warn("planRelease mDaemon " + mDaemon + " returned");
776
  }
777
 
778
  /**returns first build file content
779
   * returns false if no build file content exists
780
   */
781
  public boolean getFirstBuildFileContent(MutableString content)
782
  {
783
    mLogger.debug("getFirstBuildFileContent");
784
    boolean retVal = true;
785
 
786
    try
787
    {
788
      mBuildIndex = 0;
789
      content.value = (String)mBuildCollection.get( mBuildIndex );
790
    }
791
    catch( ArrayIndexOutOfBoundsException e )
792
    {
793
      retVal = false;
794
    }
795
 
796
    mLogger.info("getFirstBuildFileContent returned " + retVal);
797
    return retVal;
798
  }
799
 
800
  /**returns next build file content
801
   * returns false if no next build file content exists
802
   */
803
  public boolean getNextBuildFileContent(MutableString content)
804
  {
805
    mLogger.debug("getNextBuildFileContent");
806
    boolean retVal = true;
807
 
808
    try
809
    {
810
      mBuildIndex++;
811
      content.value = (String)mBuildCollection.get( mBuildIndex );
812
    }
813
    catch( ArrayIndexOutOfBoundsException e )
814
    {
815
      retVal = false;
816
    }
817
 
818
    mLogger.debug("getNextBuildFileContent returned " + retVal);
819
    return retVal;
820
  }
821
 
822
  /**collects meta data associated with the baseline
868 mhunt 823
   * this is sufficient to send an indefinite pause email notification
814 mhunt 824
   */
868 mhunt 825
  public void collectMetaData() throws SQLException, Exception
814 mhunt 826
  {
827
    mLogger.debug("collectMetaData mDaemon " + mDaemon);
828
    mGbeMachtypeCollection.removeAllElements();
868 mhunt 829
    mReleaseManager.connect();
814 mhunt 830
    mReleaseManager.queryMachtypes(mGbeMachtypeCollection, mDaemon, mBaseline);
831
 
832
    if (mDaemon)
833
    {
834
      mMailServer = mReleaseManager.queryMailServer();
835
      mMailSender = mReleaseManager.queryMailSender();
868 mhunt 836
      mGlobalTarget = mReleaseManager.queryGlobalAddresses();
814 mhunt 837
    }
838
    mBaselineName = mReleaseManager.queryBaselineName(mDaemon, mBaseline);
868 mhunt 839
    mReleaseManager.disconnect();
814 mhunt 840
  }
841
 
842
  /**returns the Package with the matching mAlias or NULL_PACKAGE if no package has the mID
843
   */
844
  private Package findPackage(String alias)
845
  {
846
    mLogger.debug("findPackage");
847
    Package retVal = ReleaseManager.NULL_PACKAGE;
848
 
864 mhunt 849
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 850
    {
864 mhunt 851
      Package p = it.next();
814 mhunt 852
 
853
      if ( p.mAlias.compareTo( alias ) == 0 )
854
      {
855
        retVal = p;
856
        break;
857
      }
858
    }
859
 
860
    mLogger.info("findPackage returned " + retVal.mName);
861
    return retVal;
862
  }
863
 
864
  /**sets the mBuildFile to -5 for the package and all dependent packages
865
   */
866 mhunt 866
  private void rippleBuildExclude(Package p, int root_pv_id, String root_cause, ListIterator<BuildExclusion> list )
814 mhunt 867
  {
868
    mLogger.debug("rippleBuildExclude");
874 mhunt 869
    if ( p.mBuildFile == 0 || p.mBuildFile == 1 )
814 mhunt 870
    {
871
      p.mBuildFile = -5;
894 mhunt 872
      mLogger.info("rippleBuildExclude set mBuildFile to -5 for package " + p.mAlias );
866 mhunt 873
 
874
      // if found, process it, else add it (unprocessed)
875
      boolean found = false;
876
      for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
877
      {
878
        BuildExclusion buildExclusion = it.next();
879
 
880
        if ( buildExclusion.compare(p.mId, root_pv_id, root_cause))
881
        {
882
          found = true;
883
          buildExclusion.process();
884
          break;
885
        }
886
      }
887
 
888
      if (!found)
889
      {
890
        // process all occurrences for this package
891
        // these will be superceded by a new build exclusion entry
892
        for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
893
        {
894
          BuildExclusion buildExclusion = it.next();
836 mhunt 895
 
866 mhunt 896
          if ( buildExclusion.compare(p.mId))
897
          {
898
            buildExclusion.process();
899
          }
900
        }
901
 
868 mhunt 902
        BuildExclusion buildExclusion = new BuildExclusion(p.mId, root_pv_id, root_cause);
866 mhunt 903
 
904
        if ( list == null )
905
        {
906
          mBuildExclusionCollection.add(buildExclusion);
907
        }
908
        else
909
        {
910
          // must use the ListIterator interface to add to the collection whilst iterating through it
911
          list.add(buildExclusion);
912
        }
913
      }
914
 
864 mhunt 915
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 916
      {
864 mhunt 917
        Package pkg = it.next();
814 mhunt 918
 
919
        if ( pkg != p )
920
        {
864 mhunt 921
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 922
          {
864 mhunt 923
            Package dependency = it2.next();
814 mhunt 924
 
925
            if ( dependency == p )
926
            {
866 mhunt 927
              rippleBuildExclude( pkg, root_pv_id, null, list );
814 mhunt 928
              break;
929
            }
930
          }
931
        }
932
      }
933
    }
934
    mLogger.info("rippleBuildExclude set " + p.mName + " " + p.mBuildFile);
935
  }
936
 
866 mhunt 937
  /**sets the mBuildFile to -5 for the package and all dependent packages
938
   */
939
  private void rippleBuildExclude(Package p, BuildExclusion buildExclusion, ListIterator<BuildExclusion> list )
940
  {
941
    mLogger.debug("rippleBuildExclude");
874 mhunt 942
    if ( p.mBuildFile == 0 || p.mBuildFile == 1 )
866 mhunt 943
    {
944
      p.mBuildFile = -5;
945
      mLogger.warn("rippleBuildExclude set mBuildFile to -5 for package " + p.mAlias );
946
      buildExclusion.process();
947
 
948
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
949
      {
950
        Package pkg = it.next();
951
 
952
        if ( pkg != p )
953
        {
954
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
955
          {
956
            Package dependency = it2.next();
957
 
958
            if ( dependency == p )
959
            {
960
              rippleBuildExclude( pkg, p.mId, null, list );
961
              break;
962
            }
963
          }
964
        }
965
      }
966
    }
967
    mLogger.info("rippleBuildExclude set " + p.mName + " " + p.mBuildFile);
968
  }
969
 
814 mhunt 970
  /**returns a build file header for the mBaseline
971
   */
972
  private String generateBuildFileHeader()
973
  {
974
    mLogger.debug("generateBuildFileHeader");
975
    String lf = new String( System.getProperty("line.separator") );
976
    String retVal = new String("");
977
    retVal +=
862 mhunt 978
    "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>" + lf +
814 mhunt 979
    "<project name=\"mass\" default=\"full\" basedir=\".\">" + lf;
980
 
981
    if ( mDaemon )
982
    {
983
      retVal +=
984
      "<property name=\"abt_mail_server\" value=\"" + mMailServer + "\"/>" + lf +
985
      "<property name=\"abt_mail_sender\" value=\"" + mMailSender + "\"/>" + lf +
986
      "<property name=\"abt_rtag_id\" value=\"" + mBaseline + "\"/>" + lf +
987
      "<property name=\"abt_daemon\" value=\"" + mTimestamp + "\"/>" + lf;
866 mhunt 988
 
989
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
990
      {
991
        Package p = it.next();
992
 
993
        if ( p.mBuildFile == 1 )
994
        {
995
          retVal +=
996
          "<property name=\"abt_package_name\" value=\"" + p.mName + "\"/>" + lf +
997
          "<property name=\"abt_package_version\" value=\"" + p.mVersion + p.mExtension + "\"/>" + lf +
998
          "<property name=\"abt_package_extension\" value=\"" + p.mExtension + "\"/>" + lf +
999
          loc(p, "abt_package_location", lf) +
1000
          "<property name=\"abt_package_depends\" value=\"";
1001
 
1002
          // depends in the form 'cs','25.1.0000.cr';'Dinkumware_STL','1.0.0.cots'
1003
          String depends = new String();
1004
 
1005
          for (Iterator<Package> it3 = p.mPackageDependencyCollection.iterator(); it3.hasNext(); )
1006
          {
1007
            Package depend = it3.next();
1008
 
1009
            if ( depends.compareTo( "" ) != 0 )
1010
            {
1011
              depends += ";";
1012
            }
1013
            depends += "\'" + depend.mName + "\'";
1014
            depends += ",";
1015
            String dependsExtension = depend.mExtension;
1016
            String dependsVersion = depend.mVersion;
1017
 
1018
            if ( dependsExtension.length() > 0 )
1019
            {
1020
              dependsVersion += dependsExtension;
1021
            }
1022
            else
1023
            {
1024
              dependsExtension = ".";
1025
            }
1026
            depends += "\'" + dependsVersion + "\'";
1027
          }
1028
 
1029
          retVal += depends + "\"/>" + lf +
1030
          "<property name=\"abt_is_ripple\" value=\"";
1031
 
1032
          if ( p.mDirectlyPlanned )
1033
          {
1034
            retVal += "0";
1035
          }
1036
          else
1037
          {
1038
            retVal += "1";
1039
          }
1040
 
1041
          retVal += "\"/>" + lf +
1042
          "<property name=\"abt_package_version_id\" value=\"" + p.mId + "\"/>" + lf +
1043
          "<property name=\"abt_does_not_require_source_control_interaction\" value=\"";
1044
 
1045
          if ( ! p.mRequiresSourceControlInteraction )
1046
          {
1047
            retVal += "true";
1048
          }
1049
          else
1050
          {
1051
            retVal += "false";
1052
          }
1053
 
1054
          retVal += "\"/>" + lf;
1055
        }
1056
      }
814 mhunt 1057
    }
1058
    else
1059
    {
1060
      retVal +=
1061
      "<property name=\"abt_rtag_id\" value=\"-1\"/>" + lf;
1062
    }
1063
 
822 mhunt 1064
    String majorVersionNumber = this.getClass().getPackage().getSpecificationVersion();
1065
 
864 mhunt 1066
    if ( !ReleaseManager.mUseDatabase )
822 mhunt 1067
    {
1068
        // hard code 11 for unit test purposes
1069
         majorVersionNumber = "11";
1070
    }
1071
 
814 mhunt 1072
    retVal +=
1073
    "<property name=\"abt_release\" value=\"" + mBaselineName + "\"/>" + lf +
822 mhunt 1074
    "<property name=\"abt_buildtool_version\" value=\""+ majorVersionNumber + "\"/>" + lf +
814 mhunt 1075
    "<condition property=\"abt_family\" value=\"windows\">" + lf +
1076
    "  <os family=\"windows\"/>" + lf +
1077
    "</condition>" + lf +
1078
    "<property name=\"abt_family\" value=\"unix\"/>" + lf;
1079
    mLogger.info("generateBuildFileHeader returned " + retVal);
1080
    return retVal;
1081
  }
1082
 
1083
  /**returns an ant property for the passed Package
1084
   */
1085
  private String generatePackageProperty(Package p)
1086
  {
1087
    mLogger.debug("generatePackageProperty");
1088
    String lf = new String( System.getProperty("line.separator") );
1089
    String retVal = new String("");
1090
    retVal +=
1091
    "<property name=\"" + p.mAlias + "\" value=\"" + p.mName + " " + p.mVersion + p.mExtension + "\"/>" + lf;
1092
    mLogger.info("generatePackageProperty returned " + retVal);
1093
    return retVal;
1094
  }
1095
 
1096
  /**returns an ant taskdef for the abt ant task
1097
   */
1098
  private String generateTaskdef()
1099
  {
1100
    mLogger.debug("generateTaskdef");
1101
    String lf = new String( System.getProperty("line.separator") );
1102
    String retVal = new String("");
1103
    retVal +=
866 mhunt 1104
    "<taskdef name=\"abt\" classname=\"com.erggroup.buildtool.abt.ABT\"/>" + lf;
814 mhunt 1105
    return retVal;
1106
  }
1107
 
1108
  /**returns an ant target for the passed Package
1109
   * in daemon mode:
1110
   *  packages are categorised with one of three mBuildFile values:
1111
   *   1 the package to be built by this buildfile
1112
   *   2 the packages with a future build requirement
1113
   *   3 the packages with no build requirement
1114
   *  the returned target depends on this categorisation and will have
1115
   *   1 full abt info
1116
   *   2 full dependency info to determine future build ordering but no abt info (will not build this package)
1117
   *   3 only a name attribute (will not build this package)
1118
   * in escrow mode:
1119
   *  if the passed Package's mBuildFile is different (less than) the passed build file,
1120
   *  the returned target have only a name attribute (will not build this package) 
1121
   */
1122
  private String generateTarget(Package p, int buildFile)
1123
  {
1124
    mLogger.debug("generateTarget");
1125
 
832 mhunt 1126
    if ( ( mDaemon && p.mBuildFile == 1 ) || ( !mDaemon && !p.isGeneric() ) )
814 mhunt 1127
    {
1128
      // populate 'missing' BuildStandards
1129
      boolean solaris = false;
1130
      boolean linux = false;
1131
      boolean win32 = false;
1132
      boolean jats = false;
1133
      boolean determinedBuildStandard = false;
1134
 
864 mhunt 1135
      for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 1136
      {
864 mhunt 1137
        BuildStandard bs = it.next();
814 mhunt 1138
 
1139
        if ( bs.getSolaris() )
1140
        {
1141
          solaris = true;
1142
        }
1143
        else
1144
        if ( bs.getLinux() )
1145
        {
1146
          linux = true;
1147
        }
1148
        else
1149
        if ( bs.getWin32() )
1150
        {
1151
          win32 = true;
1152
        }
1153
 
864 mhunt 1154
        if ( !determinedBuildStandard && bs.getBuildStandard(!ReleaseManager.mUseDatabase).contains("<jats") )
814 mhunt 1155
        {
1156
          jats = true;
1157
          determinedBuildStandard = true;
1158
        }
1159
      }
1160
 
1161
      if ( !solaris )
1162
      {
1163
        BuildStandard bs = new BuildStandard(this);
1164
        bs.setSolaris();
1165
 
1166
        if ( jats )
1167
        {
1168
          bs.setJatsNone();
1169
        }
1170
        else
1171
        {
1172
          bs.setAntNone();
1173
        }
1174
 
1175
        p.mBuildStandardCollection.add(bs);
1176
      }
1177
 
1178
      if ( !linux )
1179
      {
1180
        BuildStandard bs = new BuildStandard(this);
1181
        bs.setLinux();
1182
 
1183
        if ( jats )
1184
        {
1185
          bs.setJatsNone();
1186
        }
1187
        else
1188
        {
1189
          bs.setAntNone();
1190
        }
1191
 
1192
        p.mBuildStandardCollection.add(bs);
1193
      }
1194
 
1195
      if ( !win32 )
1196
      {
1197
        BuildStandard bs = new BuildStandard(this);
1198
        bs.setWin32();
1199
 
1200
        if ( jats )
1201
        {
1202
          bs.setJatsNone();
1203
        }
1204
        else
1205
        {
1206
          bs.setAntNone();
1207
        }
1208
 
1209
        p.mBuildStandardCollection.add(bs);
1210
      }
1211
    }
1212
 
1213
    String lf = new String( System.getProperty("line.separator") );
1214
    String retVal = new String("");
1215
 
1216
    if ( ( mDaemon && p.mBuildFile == 3 ) ||
1217
         ( !mDaemon && ( p.mBuildFile < buildFile ) ) )
1218
    {
1219
      retVal +=
1220
      "<target name=\"" + p.mAlias + "\"/>" + lf;
1221
    }
1222
    else
1223
    {
848 dpurdie 1224
      retVal +=
814 mhunt 1225
      "<target name=\"" + p.mAlias + ".wrap\"";
1226
 
1227
      if ( p.mPackageDependencyCollection.size() > 0 )
1228
      {
1229
        retVal +=" depends=\"";
1230
        boolean comma = false;
1231
 
864 mhunt 1232
        for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1233
        {
1234
          if (comma)
1235
          {
1236
            retVal += ",";
1237
          }
1238
          comma = true;
1239
 
864 mhunt 1240
          Package dependency = it.next();
814 mhunt 1241
          retVal += dependency.mAlias;
1242
        }
1243
 
1244
        retVal += "\"";
1245
      }
1246
      retVal += ">" + lf;
1247
 
1248
      if ( !mDaemon )
1249
      {
1250
        boolean hasDependenciesBuiltInThisIteration = false;
1251
        if ( ( p.mPackageDependencyCollection.size() > 0 ) )
1252
        {
864 mhunt 1253
          for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1254
          {
864 mhunt 1255
            Package dependency = it.next();
814 mhunt 1256
 
1257
            if ( dependency.mBuildFile == buildFile )
1258
            {
1259
              hasDependenciesBuiltInThisIteration = true;
1260
              break;
1261
            }
1262
          }
1263
        }
1264
 
1265
        if ( hasDependenciesBuiltInThisIteration )
1266
        {
1267
          retVal +=
1268
          "  <condition property=\"" + p.mAlias + ".build\">" + lf +
1269
          "    <and>" + lf;
1270
 
864 mhunt 1271
          for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1272
          {
864 mhunt 1273
            Package dependency = it.next();
814 mhunt 1274
 
1275
            if ( dependency.mBuildFile == buildFile )
1276
            {
1277
              retVal +=
1278
              "      <or>" + lf +
1279
              "        <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"0\"/>" + lf +
1280
              "        <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"257\"/>" + lf +
1281
              "      </or>" + lf;
1282
            }
1283
          }
1284
 
1285
          retVal +=
1286
          "    </and>" + lf +
1287
          "  </condition>" + lf;
1288
        }
1289
        else
1290
        {
1291
          retVal += "  <property name=\"" + p.mAlias + ".build\" value=\"\"/>" + lf;
1292
        }
1293
      }
1294
 
1295
      retVal +=
1296
      "</target>" + lf +
1297
      "<target name=\"" + p.mAlias + "\" depends=\"" + p.mAlias + ".wrap\"";
1298
 
1299
      if ( !mDaemon )
1300
      {
1301
        retVal += " if=\"" + p.mAlias + ".build\"";
1302
      }
1303
 
1304
      retVal += ">" + lf;
1305
 
1306
      if ( mDaemon && p.mBuildFile == 1 )
1307
      {
1308
        retVal +=
1309
        "<property name=\"" + p.mAlias + "pkg_id\" value=\"" + p.mPid + "\"/>" + lf +
1310
        "<property name=\"" + p.mAlias + "pv_id\" value=\"" + p.mId + "\"/>" + lf;
1311
      }
1312
 
1313
      if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon )
1314
      {
1315
        retVal +=
1316
        "<property name=\"" + p.mAlias + "packagename\" value=\"" + p.mName + "\"/>" + lf +
1317
        "<property name=\"" + p.mAlias + "packageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1318
        "<property name=\"" + p.mAlias + "packageextension\" value=\"";
1319
 
1320
        if ( p.mExtension.length() > 0 )
1321
        {
1322
          // drop the .
1323
          retVal += p.mExtension.substring(1);
1324
        }
1325
        else
1326
        {
1327
          retVal += p.mExtension;
1328
        }
1329
 
1330
        retVal += "\"/>" + lf +
1331
        "<property name=\"" + p.mAlias + "packagelabel\" value=\"" + p.mLabel + "\"/>" + lf;
1332
 
1333
        if ( p.mDirectlyPlanned )
1334
        {
1335
          retVal += "<property name=\"" + p.mAlias + "directchange\" value=\"\"/>" + lf;
1336
        }
1337
 
852 mhunt 1338
        if ( ! p.mRequiresSourceControlInteraction )
1339
        {
1340
          retVal += "<property name=\"" + p.mAlias + "doesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;
1341
        }
1342
 
814 mhunt 1343
        mAddendum = "non generic";
1344
 
1345
        if ( p.isGeneric() )
1346
        {
1347
          mAddendum = "generic";
1348
          retVal += "<property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;
1349
        }
1350
 
1351
        retVal += loc(p, p.mAlias + "loc", lf);
1352
 
830 mhunt 1353
        if ( p.mHasAutomatedUnitTests && mDaemon )
814 mhunt 1354
        {
1355
          retVal += 
1356
          "<property name=\"" + p.mAlias + "unittests\" value=\"\"/>" + lf;
1357
        }
1358
      }
1359
 
1360
      retVal += "<abt>" + lf;
1361
 
1362
      if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon )
1363
      {
864 mhunt 1364
        for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1365
        {
864 mhunt 1366
          Package dependency = it.next();
814 mhunt 1367
          retVal +=
1368
          "  <depend package_alias=\"${" + dependency.mAlias + "}\"/>" + lf;
1369
        }
1370
 
836 mhunt 1371
        retVal += buildInfo(p, lf, false);
814 mhunt 1372
      }
1373
 
1374
      if ( mDaemon && p.mBuildFile == 1 )
1375
      {
854 mhunt 1376
        retVal += p.emailInfo( lf );
814 mhunt 1377
      }
1378
 
1379
      retVal += "</abt>" + lf +
1380
      "</target>" + lf;
1381
 
1382
      if ( mDaemon && p.mBuildFile == 1 )
1383
      {
1384
        retVal +=
1385
        "<target name=\"AbtSetUp\">" + lf +
854 mhunt 1386
        "<property name=\"AbtSetUppackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
872 dpurdie 1387
        "<property name=\"AbtSetUppackagename\" value=\"" + p.mName + "\"/>" + lf +
1388
        "<property name=\"AbtSetUppackageSrcPath\" value=\"" + p.mLocation.replace('\\', '/') + "\"/>" + lf;
814 mhunt 1389
 
1390
        retVal +=
1391
        "<abt>" + lf +
854 mhunt 1392
        p.emailInfo( lf ) +
814 mhunt 1393
        "</abt>" + lf +
872 dpurdie 1394
        "</target>" + lf;
1395
 
1396
        retVal +=
814 mhunt 1397
        "<target name=\"AbtTearDown\">" + lf +
1398
        "<property name=\"AbtTearDownpackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
1399
        "<property name=\"AbtTearDownpackagename\" value=\"" + p.mName + "\"/>" + lf +
1400
        "<property name=\"AbtTearDownpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1401
        "<property name=\"AbtTearDownpackageextension\" value=\"";
1402
 
1403
        if ( p.mExtension.length() > 0 )
1404
        {
1405
          // drop the .
1406
          retVal += p.mExtension.substring(1);
1407
        }
1408
        else
1409
        {
1410
          retVal += p.mExtension;
1411
        }
1412
 
1413
        retVal += "\"/>" + lf;
1414
 
1415
        if ( p.isGeneric() )
1416
        {
1417
          retVal += "<property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;
1418
        }
1419
 
1420
        retVal +=        
1421
        "<abt>" + lf +
836 mhunt 1422
        buildInfo(p, lf, false) +
854 mhunt 1423
        p.emailInfo( lf ) +
814 mhunt 1424
        "</abt>" + lf +
1425
        "</target>" + lf +
1426
        "<target name=\"AbtPublish\">" + lf +
1427
        "<property name=\"AbtPublishpackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
1428
        "<property name=\"AbtPublishpackagename\" value=\"" + p.mName + "\"/>" + lf +
1429
        "<property name=\"AbtPublishpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1430
        "<property name=\"AbtPublishpackageextension\" value=\"";
1431
 
1432
        if ( p.mExtension.length() > 0 )
1433
        {
1434
          // drop the .
1435
          retVal += p.mExtension.substring(1);
1436
        }
1437
        else
1438
        {
1439
          retVal += p.mExtension;
1440
        }
1441
 
1442
        retVal += "\"/>" + lf;
1443
 
1444
        if ( p.mDirectlyPlanned )
1445
        {
1446
          retVal += "<property name=\"AbtPublishdirectchange\" value=\"\"/>" + lf;
1447
        }
1448
 
852 mhunt 1449
        if ( ! p.mRequiresSourceControlInteraction )
1450
        {
1451
          retVal += "<property name=\"AbtPublishdoesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;
1452
        }
1453
 
814 mhunt 1454
        if ( p.isGeneric() )
1455
        {
1456
          retVal += "<property name=\"AbtPublishgeneric\" value=\"\"/>" + lf;
1457
        }
1458
 
1459
        retVal += loc(p, "AbtPublishloc", lf);
1460
        retVal +=
816 mhunt 1461
        "<abt>" + lf +
854 mhunt 1462
        buildInfo(p, lf, true) +
1463
        p.emailInfo( lf ) +
814 mhunt 1464
        "</abt>" + lf +
1465
        "</target>" + lf;
1466
      }
1467
    }
1468
    mLogger.info("generateTarget returned " + retVal);
1469
    return retVal;
1470
  }
1471
 
1472
  /**returns an ant default target for the current build iteration
1473
   */
1474
  private String generateDefaultTarget(int buildFile)
1475
  {
1476
    mLogger.debug("generateDefaultTarget");
1477
    String lf = new String( System.getProperty("line.separator") );
1478
    String retVal = new String("");
1479
    retVal +=
1480
    "<target name=\"fullstart\">" + lf;
1481
 
1482
    if (buildFile == 1)
1483
    {
1484
      retVal +=
1485
      "<echo message=\"${line.separator}The following package versions are not reproducible on any build platform:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1486
 
864 mhunt 1487
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1488
      {
864 mhunt 1489
        Package p = it.next();
814 mhunt 1490
 
1491
        if ( p.mBuildFile == -1 )
1492
        {
1493
          retVal +=
1494
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1495
        }
1496
      }
1497
 
1498
      retVal +=
1499
      "<echo message=\"${line.separator}The following package versions are not reproducible on the build platforms associated with this baseline:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1500
 
864 mhunt 1501
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1502
      {
864 mhunt 1503
        Package p = it.next();
814 mhunt 1504
 
1505
        if ( p.mBuildFile == -2 )
1506
        {
1507
          retVal +=
1508
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1509
        }
1510
      }
1511
 
1512
      retVal +=
1513
      "<echo message=\"${line.separator}The following package versions are not reproducible as they are directly dependent upon package versions not in the baseline:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1514
 
864 mhunt 1515
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1516
      {
864 mhunt 1517
        Package p = it.next();
814 mhunt 1518
 
1519
        if ( p.mBuildFile == -4 )
1520
        {
1521
          retVal +=
1522
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1523
        }
1524
      }
1525
 
1526
      retVal +=
1527
      "<echo message=\"${line.separator}The following package versions are not reproducible as they are directly/indirectly dependent upon not reproducible package versions:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1528
 
864 mhunt 1529
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1530
      {
864 mhunt 1531
        Package p = it.next();
814 mhunt 1532
 
1533
        if ( p.mBuildFile == -5 )
1534
        {
1535
          retVal +=
1536
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1537
        }
1538
      }
1539
    }
1540
    if ( !mDaemon )
1541
    {
1542
      retVal +=
1543
      "<echo message=\"${line.separator}Build Started:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1544
    }
1545
 
1546
    retVal +=
1547
    "</target>" + lf +
1548
    "<target name=\"full\" depends=\"fullstart";
1549
 
864 mhunt 1550
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1551
    {
864 mhunt 1552
      Package p = it.next();
814 mhunt 1553
 
1554
      if ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) )
1555
      {
1556
        retVal += "," + p.mAlias;
1557
      }
1558
    }
1559
 
1560
    retVal +=
1561
    "\">" + lf;
1562
 
1563
    if ( !mDaemon )
1564
    {
1565
      retVal +=
1566
      "<echo message=\"${line.separator}Build Finished${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1567
    }
1568
 
1569
    retVal +=
1570
    "</target>" + lf;
1571
    return retVal;
1572
  }
1573
 
1574
  /**returns a build file footer
1575
   */
1576
  private String generateBuildFileFooter()
1577
  {
1578
    mLogger.debug("generateBuildFileFooter");
1579
    String retVal = new String("</project>");
1580
    return retVal;
1581
  }
1582
 
1583
  /**sets the mIndirectlyPlanned true for the package and all dependent packages
1584
   */
1585
  private void rippleIndirectlyPlanned(Package p)
1586
  {
1587
    mLogger.debug("rippleIndirectlyPlanned");
1588
    if ( !p.mIndirectlyPlanned && p.mBuildFile == 0 )
1589
    {
1590
      p.mIndirectlyPlanned = true;
1591
 
864 mhunt 1592
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1593
      {
864 mhunt 1594
        Package pkg = it.next();
814 mhunt 1595
 
1596
        if ( pkg != p )
1597
        {
864 mhunt 1598
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 1599
          {
864 mhunt 1600
            Package dependency = it2.next();
814 mhunt 1601
 
1602
            if ( dependency == p )
1603
            {
1604
              rippleIndirectlyPlanned( pkg );
1605
              break;
1606
            }
1607
          }
1608
        }
1609
      }
1610
    }
1611
    mLogger.info("rippleIndirectlyPlanned set " + p.mName + " " + p.mIndirectlyPlanned);    
1612
  }
1613
 
1614
  /**accessor method
1615
   */
830 mhunt 1616
  public String getESCROWSetUp()
814 mhunt 1617
  {
830 mhunt 1618
    mLogger.debug("getESCROWSetUp");
814 mhunt 1619
    String retVal = new String("");
1620
 
1621
    try
1622
    {
830 mhunt 1623
      if ( mEscrowClearcaseSupportCollection.size() >= 1 )
814 mhunt 1624
      {
1625
        retVal = (String)mEscrowClearcaseSupportCollection.get(0);
1626
      }
1627
    }
1628
    catch( ArrayIndexOutOfBoundsException e )
1629
    {
1630
    }
1631
 
830 mhunt 1632
    mLogger.info("getESCROWSetUp returned " + retVal);
814 mhunt 1633
    return retVal;
1634
  }
1635
 
1636
  /**accessor method
1637
   */
830 mhunt 1638
  public String getRawData()
814 mhunt 1639
  {
830 mhunt 1640
    mLogger.debug("getRawData");
814 mhunt 1641
    String retVal = new String("");
1642
 
1643
    try
1644
    {
830 mhunt 1645
      if ( mEscrowClearcaseSupportCollection.size() >= 2 )
814 mhunt 1646
      {
1647
        retVal = (String)mEscrowClearcaseSupportCollection.get(1);
1648
      }
1649
    }
1650
    catch( ArrayIndexOutOfBoundsException e )
1651
    {
1652
    }
1653
 
830 mhunt 1654
    mLogger.info("getRawData returned " + retVal);
814 mhunt 1655
    return retVal;
1656
  }
1657
 
1658
  /**returns first build file content and addendum
1659
   * the addendum value is one of "non generic", "generic" or "dummy"
1660
   */
1661
  public void getFirstBuildFileContent(MutableString content, 
1662
                                MutableString addendum)
1663
  {
1664
    mLogger.debug("getFirstBuildFileContent");
1665
    try
1666
    {
1667
      mBuildIndex = 0;
1668
      content.value = (String)mBuildCollection.get( mBuildIndex );
1669
      addendum.value = mAddendum;
1670
    }
1671
    catch( ArrayIndexOutOfBoundsException e )
1672
    {
1673
    }
1674
    mLogger.info("getFirstBuildFileContent passed " + content.value + addendum.value);
1675
  }
1676
 
872 dpurdie 1677
  /**returns the build loc
814 mhunt 1678
   */
1679
  private String loc(Package p, String target, String lf)
1680
  {
1681
    mLogger.debug("loc");
1682
    String retVal = new String();
872 dpurdie 1683
    String loc = new String("/");
1684
 
1685
    if (mDaemon)
814 mhunt 1686
    {
872 dpurdie 1687
      // Daemon: Start in root of view/workspace
878 mhunt 1688
      loc += mBaseline + "/" + p.mLabel;
814 mhunt 1689
    }
872 dpurdie 1690
    else
814 mhunt 1691
    {
872 dpurdie 1692
      // mAlias used with jats -extractfiles -view
1693
      loc += p.mAlias;
1694
    }
814 mhunt 1695
 
872 dpurdie 1696
    //
1697
    //  Always use '/' as a path seperator - even if user has specified '\'
1698
    //  Ant can handle it.
1699
    //
814 mhunt 1700
    loc = loc.replace('\\', '/');
1701
    retVal += 
1702
    "<property name=\"" + target + "\" value=\"" + loc + "\"/>" + lf;
1703
 
1704
    mLogger.info("loc returned " + retVal);
1705
    return retVal;
1706
  }
816 mhunt 1707
 
1708
  /**returns the buildInfo
1709
   */
836 mhunt 1710
  private String buildInfo(Package p, String lf, boolean filter)
816 mhunt 1711
  {
1712
    mLogger.debug("buildInfo");
1713
 
1714
    String platforms = new String();
1715
    String standards = new String();
1716
 
864 mhunt 1717
    for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); )
816 mhunt 1718
    {
864 mhunt 1719
      BuildStandard bs = it.next();
816 mhunt 1720
 
836 mhunt 1721
      if ( !filter )
816 mhunt 1722
      {
864 mhunt 1723
        String platform = bs.getPlatform(!ReleaseManager.mUseDatabase);
816 mhunt 1724
 
1725
        if ( platform.length() > 0 )
1726
        {
1727
          platforms += platform + lf;
1728
        }
1729
 
864 mhunt 1730
        String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase);
816 mhunt 1731
 
1732
        if ( standard.length() > 0 )
1733
        {
1734
          standards += standard + lf;
1735
        }
1736
      }
1737
      else
1738
      {
864 mhunt 1739
        if ( !bs.getBuildStandard(!ReleaseManager.mUseDatabase).contains("\"none\"") )
816 mhunt 1740
        {
864 mhunt 1741
          String platform = bs.getPlatform(!ReleaseManager.mUseDatabase);
816 mhunt 1742
 
1743
          if ( platform.length() > 0 )
1744
          {
1745
            platforms += platform + lf;
1746
          }
836 mhunt 1747
 
864 mhunt 1748
          String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase);
836 mhunt 1749
 
1750
          if ( standard.length() > 0 )
1751
          {
1752
            standards += standard + lf;
1753
          }
816 mhunt 1754
        }
1755
      }
1756
    }
1757
 
1758
    mLogger.info("buildInfo returned " + platforms + standards);
1759
    return platforms + standards;
1760
  }
866 mhunt 1761
 
814 mhunt 1762
}