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