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;
858 mhunt 193
          mLogger.warn("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
214
          rippleBuildExclude(p, p.mId, "Package has no build environment", null);
814 mhunt 215
 
216
          // package is not reproducible, discard
217
          p.mBuildFile = -1;
858 mhunt 218
          mLogger.warn("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;
278
          mLogger.warn("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;
305
              mLogger.warn("planRelease set mBuildFile to -3 for package " + p.mAlias );
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;
858 mhunt 502
                    mLogger.warn("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;
858 mhunt 508
                    mLogger.warn("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;
858 mhunt 574
            mLogger.warn("planRelease 2 set mBuildFile to " + buildFile + " for package " + p.mAlias );
836 mhunt 575
 
814 mhunt 576
            if ( buildFile == 1 )
577
            {
578
              p.applyPV(mReleaseManager, mBaseline);
579
            }
580
            else
581
            {
582
              mLogger.info("planRelease package has future (downgraded) build requirement " + p.mName + " " + buildFile);              
583
            }
584
 
585
            buildFile = 2;
586
          }
587
        }
588
      }
589
 
590
      // are more build files required
591
      allProcessed = true;
592
 
593
      if (mDaemon)
594
      {
864 mhunt 595
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 596
        {
864 mhunt 597
          Package p = it.next();
814 mhunt 598
 
599
          if ( p.mBuildFile < 0 || ( !p.mDirectlyPlanned && !p.mIndirectlyPlanned ) )
600
          {
601
            // at this point...
602
            // only 1 package with a build requirement has a mBuildFile of 1,
603
            // all other packages with a build requirement have an mBuildFile of 2
604
            // give packages with no build requirement, reproducible or not, an mBuildFile of 3
605
            p.mBuildFile = 3;
858 mhunt 606
            mLogger.warn("planRelease 1 set mBuildFile to 3 for package " + p.mAlias );
814 mhunt 607
          }
608
        }
609
      }
610
      else
611
      {
612
        // this is escrow mode centric
864 mhunt 613
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 614
        {
864 mhunt 615
          Package p = it.next();
814 mhunt 616
 
617
          if ( p.mBuildFile == 0 )
618
          {
619
            // more build files are required
620
            allProcessed = false;
621
            mLogger.info("planRelease more build files are required for " + p.mName);
622
            break;
623
          }
624
        }
625
 
626
        buildFile++;
627
      }
628
    } while( !allProcessed );
629
 
630
    // persist the build files
631
    allProcessed = false;
632
    buildFile = 1;
633
 
634
    if ( mDaemon )
635
    {
636
      // all interesting packages in daemon mode match the following filter
637
      buildFile = 3;
638
    }
639
 
640
    mTimestamp = System.currentTimeMillis();
641
 
864 mhunt 642
    if ( !ReleaseManager.mUseDatabase )
814 mhunt 643
    {
644
      mTimestamp = 123456789;
645
    }
646
 
647
    do
648
    {
649
      String buildFileContent = new String( generateBuildFileHeader() );
650
 
864 mhunt 651
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 652
      {
864 mhunt 653
        Package p = it.next();
814 mhunt 654
 
655
        if ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) )
656
        {
657
          buildFileContent += generatePackageProperty(p);
658
        }
659
      }
660
 
661
      buildFileContent += generateTaskdef();
662
 
830 mhunt 663
      String set_up = new String("");
866 mhunt 664
      boolean daemonHasTarget = false;
814 mhunt 665
 
864 mhunt 666
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 667
      {
864 mhunt 668
        Package p = it.next();
814 mhunt 669
 
670
        if ( p.mBuildFile > 0 && p.mBuildFile <= buildFile )
671
        {
672
          buildFileContent += generateTarget(p, buildFile);
866 mhunt 673
 
674
          if ( p.mBuildFile == 1 )
675
          {
676
            daemonHasTarget = true;
677
          }
814 mhunt 678
        }
679
 
680
        if ( !mDaemon && buildFile == 1 )
681
        {
848 dpurdie 682
          // for the purposes of the set up, use /
683
          String loc = new String("");
684
          try
685
          {
686
            // The regular expression "\\\\" matches an escape character "\\" and a single backslash "\\"
687
            loc = p.mLocation.replaceAll("\\\\", "/");
688
          }
689
          catch( PatternSyntaxException e )
690
          {
691
          }
692
 
693
          set_up += "jats release -extractfiles"
694
                    + " \"-label=" + p.mLabel + "\""
695
                    + " \"-path=" + loc + "\""
696
                    + " \"-view=" + p.mAlias + "\""
697
                    + " -root=. -noprefix"
698
                    + lf;
814 mhunt 699
        }
700
      }
866 mhunt 701
 
702
      if ( mDaemon && !daemonHasTarget )
703
      {
704
        // must have AbtSetUp, AbtTearDown, and AbtPublish targets
705
        buildFileContent += "<target name=\"AbtSetUp\"/>" + lf +
706
                            "<target name=\"AbtTearDown\"/>" + lf +
707
                            "<target name=\"AbtPublish\"/>" + lf;
708
      }
709
 
848 dpurdie 710
      if ( !mDaemon && buildFile == 1 )
711
      {
830 mhunt 712
        mEscrowClearcaseSupportCollection.add(set_up);
713
        mEscrowClearcaseSupportCollection.add(raw_data);
814 mhunt 714
      }
715
 
716
      buildFileContent += generateDefaultTarget( buildFile);
717
      buildFileContent += generateBuildFileFooter();
718
 
719
      mBuildCollection.add(buildFileContent);
720
 
721
      // are more build files required
722
      allProcessed = true;
723
 
724
      if (!mDaemon)
725
      {
726
        // this is escrow mode centric
864 mhunt 727
        for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 728
        {
864 mhunt 729
          Package p = it.next();
814 mhunt 730
 
731
          if ( p.mBuildFile > buildFile )
732
          {
733
            // more build files are required
734
            allProcessed = false;
735
            mLogger.info("planRelease reiterating package has no build requirement " + p.mName + " " + p.mBuildFile + " " + buildFile);
736
            break;
737
          }
738
        } 
739
 
740
        buildFile++;
741
      }
742
    } while( !allProcessed );
743
 
866 mhunt 744
    if ( mDaemon )
745
    {
746
      // report what change in build exceptions happens as part of planRelease
747
      for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
748
      {
749
        BuildExclusion buildExclusion = it.next();
750
 
751
        if ( !buildExclusion.isProcessed() )
752
        {
753
          // notify
754
          buildExclusion.excludeFromBuild(mReleaseManager, mBaseline);
755
          buildExclusion.email(mPackageCollection, mMailServer, mMailSender, mBaselineName);
756
        }
757
      }
758
    }
759
 
814 mhunt 760
    mReleaseManager.disconnect();
761
    mLogger.warn("planRelease mDaemon " + mDaemon + " returned");
762
  }
763
 
764
  /**returns first build file content
765
   * returns false if no build file content exists
766
   */
767
  public boolean getFirstBuildFileContent(MutableString content)
768
  {
769
    mLogger.debug("getFirstBuildFileContent");
770
    boolean retVal = true;
771
 
772
    try
773
    {
774
      mBuildIndex = 0;
775
      content.value = (String)mBuildCollection.get( mBuildIndex );
776
    }
777
    catch( ArrayIndexOutOfBoundsException e )
778
    {
779
      retVal = false;
780
    }
781
 
782
    mLogger.info("getFirstBuildFileContent returned " + retVal);
783
    return retVal;
784
  }
785
 
786
  /**returns next build file content
787
   * returns false if no next build file content exists
788
   */
789
  public boolean getNextBuildFileContent(MutableString content)
790
  {
791
    mLogger.debug("getNextBuildFileContent");
792
    boolean retVal = true;
793
 
794
    try
795
    {
796
      mBuildIndex++;
797
      content.value = (String)mBuildCollection.get( mBuildIndex );
798
    }
799
    catch( ArrayIndexOutOfBoundsException e )
800
    {
801
      retVal = false;
802
    }
803
 
804
    mLogger.debug("getNextBuildFileContent returned " + retVal);
805
    return retVal;
806
  }
807
 
808
  /**collects meta data associated with the baseline
868 mhunt 809
   * this is sufficient to send an indefinite pause email notification
814 mhunt 810
   */
868 mhunt 811
  public void collectMetaData() throws SQLException, Exception
814 mhunt 812
  {
813
    mLogger.debug("collectMetaData mDaemon " + mDaemon);
814
    mGbeMachtypeCollection.removeAllElements();
868 mhunt 815
    mReleaseManager.connect();
814 mhunt 816
    mReleaseManager.queryMachtypes(mGbeMachtypeCollection, mDaemon, mBaseline);
817
 
818
    if (mDaemon)
819
    {
820
      mMailServer = mReleaseManager.queryMailServer();
821
      mMailSender = mReleaseManager.queryMailSender();
868 mhunt 822
      mGlobalTarget = mReleaseManager.queryGlobalAddresses();
814 mhunt 823
    }
824
    mBaselineName = mReleaseManager.queryBaselineName(mDaemon, mBaseline);
868 mhunt 825
    mReleaseManager.disconnect();
814 mhunt 826
  }
827
 
828
  /**returns the Package with the matching mAlias or NULL_PACKAGE if no package has the mID
829
   */
830
  private Package findPackage(String alias)
831
  {
832
    mLogger.debug("findPackage");
833
    Package retVal = ReleaseManager.NULL_PACKAGE;
834
 
864 mhunt 835
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 836
    {
864 mhunt 837
      Package p = it.next();
814 mhunt 838
 
839
      if ( p.mAlias.compareTo( alias ) == 0 )
840
      {
841
        retVal = p;
842
        break;
843
      }
844
    }
845
 
846
    mLogger.info("findPackage returned " + retVal.mName);
847
    return retVal;
848
  }
849
 
850
  /**sets the mBuildFile to -5 for the package and all dependent packages
851
   */
866 mhunt 852
  private void rippleBuildExclude(Package p, int root_pv_id, String root_cause, ListIterator<BuildExclusion> list )
814 mhunt 853
  {
854
    mLogger.debug("rippleBuildExclude");
855
    if ( p.mBuildFile == 0 )
856
    {
857
      p.mBuildFile = -5;
858 mhunt 858
      mLogger.warn("rippleBuildExclude set mBuildFile to -5 for package " + p.mAlias );
866 mhunt 859
 
860
      // if found, process it, else add it (unprocessed)
861
      boolean found = false;
862
      for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
863
      {
864
        BuildExclusion buildExclusion = it.next();
865
 
866
        if ( buildExclusion.compare(p.mId, root_pv_id, root_cause))
867
        {
868
          found = true;
869
          buildExclusion.process();
870
          break;
871
        }
872
      }
873
 
874
      if (!found)
875
      {
876
        // process all occurrences for this package
877
        // these will be superceded by a new build exclusion entry
878
        for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); )
879
        {
880
          BuildExclusion buildExclusion = it.next();
836 mhunt 881
 
866 mhunt 882
          if ( buildExclusion.compare(p.mId))
883
          {
884
            buildExclusion.process();
885
          }
886
        }
887
 
868 mhunt 888
        BuildExclusion buildExclusion = new BuildExclusion(p.mId, root_pv_id, root_cause);
866 mhunt 889
 
890
        if ( list == null )
891
        {
892
          mBuildExclusionCollection.add(buildExclusion);
893
        }
894
        else
895
        {
896
          // must use the ListIterator interface to add to the collection whilst iterating through it
897
          list.add(buildExclusion);
898
        }
899
      }
900
 
864 mhunt 901
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 902
      {
864 mhunt 903
        Package pkg = it.next();
814 mhunt 904
 
905
        if ( pkg != p )
906
        {
864 mhunt 907
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 908
          {
864 mhunt 909
            Package dependency = it2.next();
814 mhunt 910
 
911
            if ( dependency == p )
912
            {
866 mhunt 913
              rippleBuildExclude( pkg, root_pv_id, null, list );
814 mhunt 914
              break;
915
            }
916
          }
917
        }
918
      }
919
    }
920
    mLogger.info("rippleBuildExclude set " + p.mName + " " + p.mBuildFile);
921
  }
922
 
866 mhunt 923
  /**sets the mBuildFile to -5 for the package and all dependent packages
924
   */
925
  private void rippleBuildExclude(Package p, BuildExclusion buildExclusion, ListIterator<BuildExclusion> list )
926
  {
927
    mLogger.debug("rippleBuildExclude");
928
    if ( p.mBuildFile == 0 )
929
    {
930
      p.mBuildFile = -5;
931
      mLogger.warn("rippleBuildExclude set mBuildFile to -5 for package " + p.mAlias );
932
      buildExclusion.process();
933
 
934
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
935
      {
936
        Package pkg = it.next();
937
 
938
        if ( pkg != p )
939
        {
940
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
941
          {
942
            Package dependency = it2.next();
943
 
944
            if ( dependency == p )
945
            {
946
              rippleBuildExclude( pkg, p.mId, null, list );
947
              break;
948
            }
949
          }
950
        }
951
      }
952
    }
953
    mLogger.info("rippleBuildExclude set " + p.mName + " " + p.mBuildFile);
954
  }
955
 
814 mhunt 956
  /**returns a build file header for the mBaseline
957
   */
958
  private String generateBuildFileHeader()
959
  {
960
    mLogger.debug("generateBuildFileHeader");
961
    String lf = new String( System.getProperty("line.separator") );
962
    String retVal = new String("");
963
    retVal +=
862 mhunt 964
    "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>" + lf +
814 mhunt 965
    "<project name=\"mass\" default=\"full\" basedir=\".\">" + lf;
966
 
967
    if ( mDaemon )
968
    {
969
      retVal +=
970
      "<property name=\"abt_mail_server\" value=\"" + mMailServer + "\"/>" + lf +
971
      "<property name=\"abt_mail_sender\" value=\"" + mMailSender + "\"/>" + lf +
972
      "<property name=\"abt_rtag_id\" value=\"" + mBaseline + "\"/>" + lf +
973
      "<property name=\"abt_daemon\" value=\"" + mTimestamp + "\"/>" + lf;
866 mhunt 974
 
975
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
976
      {
977
        Package p = it.next();
978
 
979
        if ( p.mBuildFile == 1 )
980
        {
981
          retVal +=
982
          "<property name=\"abt_package_name\" value=\"" + p.mName + "\"/>" + lf +
983
          "<property name=\"abt_package_version\" value=\"" + p.mVersion + p.mExtension + "\"/>" + lf +
984
          "<property name=\"abt_package_extension\" value=\"" + p.mExtension + "\"/>" + lf +
985
          loc(p, "abt_package_location", lf) +
986
          "<property name=\"abt_package_depends\" value=\"";
987
 
988
          // depends in the form 'cs','25.1.0000.cr';'Dinkumware_STL','1.0.0.cots'
989
          String depends = new String();
990
 
991
          for (Iterator<Package> it3 = p.mPackageDependencyCollection.iterator(); it3.hasNext(); )
992
          {
993
            Package depend = it3.next();
994
 
995
            if ( depends.compareTo( "" ) != 0 )
996
            {
997
              depends += ";";
998
            }
999
            depends += "\'" + depend.mName + "\'";
1000
            depends += ",";
1001
            String dependsExtension = depend.mExtension;
1002
            String dependsVersion = depend.mVersion;
1003
 
1004
            if ( dependsExtension.length() > 0 )
1005
            {
1006
              dependsVersion += dependsExtension;
1007
            }
1008
            else
1009
            {
1010
              dependsExtension = ".";
1011
            }
1012
            depends += "\'" + dependsVersion + "\'";
1013
          }
1014
 
1015
          retVal += depends + "\"/>" + lf +
1016
          "<property name=\"abt_is_ripple\" value=\"";
1017
 
1018
          if ( p.mDirectlyPlanned )
1019
          {
1020
            retVal += "0";
1021
          }
1022
          else
1023
          {
1024
            retVal += "1";
1025
          }
1026
 
1027
          retVal += "\"/>" + lf +
1028
          "<property name=\"abt_package_version_id\" value=\"" + p.mId + "\"/>" + lf +
1029
          "<property name=\"abt_does_not_require_source_control_interaction\" value=\"";
1030
 
1031
          if ( ! p.mRequiresSourceControlInteraction )
1032
          {
1033
            retVal += "true";
1034
          }
1035
          else
1036
          {
1037
            retVal += "false";
1038
          }
1039
 
1040
          retVal += "\"/>" + lf;
1041
        }
1042
      }
814 mhunt 1043
    }
1044
    else
1045
    {
1046
      retVal +=
1047
      "<property name=\"abt_rtag_id\" value=\"-1\"/>" + lf;
1048
    }
1049
 
822 mhunt 1050
    String majorVersionNumber = this.getClass().getPackage().getSpecificationVersion();
1051
 
864 mhunt 1052
    if ( !ReleaseManager.mUseDatabase )
822 mhunt 1053
    {
1054
        // hard code 11 for unit test purposes
1055
         majorVersionNumber = "11";
1056
    }
1057
 
814 mhunt 1058
    retVal +=
1059
    "<property name=\"abt_release\" value=\"" + mBaselineName + "\"/>" + lf +
822 mhunt 1060
    "<property name=\"abt_buildtool_version\" value=\""+ majorVersionNumber + "\"/>" + lf +
814 mhunt 1061
    "<condition property=\"abt_family\" value=\"windows\">" + lf +
1062
    "  <os family=\"windows\"/>" + lf +
1063
    "</condition>" + lf +
1064
    "<property name=\"abt_family\" value=\"unix\"/>" + lf;
1065
    mLogger.info("generateBuildFileHeader returned " + retVal);
1066
    return retVal;
1067
  }
1068
 
1069
  /**returns an ant property for the passed Package
1070
   */
1071
  private String generatePackageProperty(Package p)
1072
  {
1073
    mLogger.debug("generatePackageProperty");
1074
    String lf = new String( System.getProperty("line.separator") );
1075
    String retVal = new String("");
1076
    retVal +=
1077
    "<property name=\"" + p.mAlias + "\" value=\"" + p.mName + " " + p.mVersion + p.mExtension + "\"/>" + lf;
1078
    mLogger.info("generatePackageProperty returned " + retVal);
1079
    return retVal;
1080
  }
1081
 
1082
  /**returns an ant taskdef for the abt ant task
1083
   */
1084
  private String generateTaskdef()
1085
  {
1086
    mLogger.debug("generateTaskdef");
1087
    String lf = new String( System.getProperty("line.separator") );
1088
    String retVal = new String("");
1089
    retVal +=
866 mhunt 1090
    "<taskdef name=\"abt\" classname=\"com.erggroup.buildtool.abt.ABT\"/>" + lf;
814 mhunt 1091
    return retVal;
1092
  }
1093
 
1094
  /**returns an ant target for the passed Package
1095
   * in daemon mode:
1096
   *  packages are categorised with one of three mBuildFile values:
1097
   *   1 the package to be built by this buildfile
1098
   *   2 the packages with a future build requirement
1099
   *   3 the packages with no build requirement
1100
   *  the returned target depends on this categorisation and will have
1101
   *   1 full abt info
1102
   *   2 full dependency info to determine future build ordering but no abt info (will not build this package)
1103
   *   3 only a name attribute (will not build this package)
1104
   * in escrow mode:
1105
   *  if the passed Package's mBuildFile is different (less than) the passed build file,
1106
   *  the returned target have only a name attribute (will not build this package) 
1107
   */
1108
  private String generateTarget(Package p, int buildFile)
1109
  {
1110
    mLogger.debug("generateTarget");
1111
 
832 mhunt 1112
    if ( ( mDaemon && p.mBuildFile == 1 ) || ( !mDaemon && !p.isGeneric() ) )
814 mhunt 1113
    {
1114
      // populate 'missing' BuildStandards
1115
      boolean solaris = false;
1116
      boolean linux = false;
1117
      boolean win32 = false;
1118
      boolean jats = false;
1119
      boolean determinedBuildStandard = false;
1120
 
864 mhunt 1121
      for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); )
814 mhunt 1122
      {
864 mhunt 1123
        BuildStandard bs = it.next();
814 mhunt 1124
 
1125
        if ( bs.getSolaris() )
1126
        {
1127
          solaris = true;
1128
        }
1129
        else
1130
        if ( bs.getLinux() )
1131
        {
1132
          linux = true;
1133
        }
1134
        else
1135
        if ( bs.getWin32() )
1136
        {
1137
          win32 = true;
1138
        }
1139
 
864 mhunt 1140
        if ( !determinedBuildStandard && bs.getBuildStandard(!ReleaseManager.mUseDatabase).contains("<jats") )
814 mhunt 1141
        {
1142
          jats = true;
1143
          determinedBuildStandard = true;
1144
        }
1145
      }
1146
 
1147
      if ( !solaris )
1148
      {
1149
        BuildStandard bs = new BuildStandard(this);
1150
        bs.setSolaris();
1151
 
1152
        if ( jats )
1153
        {
1154
          bs.setJatsNone();
1155
        }
1156
        else
1157
        {
1158
          bs.setAntNone();
1159
        }
1160
 
1161
        p.mBuildStandardCollection.add(bs);
1162
      }
1163
 
1164
      if ( !linux )
1165
      {
1166
        BuildStandard bs = new BuildStandard(this);
1167
        bs.setLinux();
1168
 
1169
        if ( jats )
1170
        {
1171
          bs.setJatsNone();
1172
        }
1173
        else
1174
        {
1175
          bs.setAntNone();
1176
        }
1177
 
1178
        p.mBuildStandardCollection.add(bs);
1179
      }
1180
 
1181
      if ( !win32 )
1182
      {
1183
        BuildStandard bs = new BuildStandard(this);
1184
        bs.setWin32();
1185
 
1186
        if ( jats )
1187
        {
1188
          bs.setJatsNone();
1189
        }
1190
        else
1191
        {
1192
          bs.setAntNone();
1193
        }
1194
 
1195
        p.mBuildStandardCollection.add(bs);
1196
      }
1197
    }
1198
 
1199
    String lf = new String( System.getProperty("line.separator") );
1200
    String retVal = new String("");
1201
 
1202
    if ( ( mDaemon && p.mBuildFile == 3 ) ||
1203
         ( !mDaemon && ( p.mBuildFile < buildFile ) ) )
1204
    {
1205
      retVal +=
1206
      "<target name=\"" + p.mAlias + "\"/>" + lf;
1207
    }
1208
    else
1209
    {
848 dpurdie 1210
      retVal +=
814 mhunt 1211
      "<target name=\"" + p.mAlias + ".wrap\"";
1212
 
1213
      if ( p.mPackageDependencyCollection.size() > 0 )
1214
      {
1215
        retVal +=" depends=\"";
1216
        boolean comma = false;
1217
 
864 mhunt 1218
        for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1219
        {
1220
          if (comma)
1221
          {
1222
            retVal += ",";
1223
          }
1224
          comma = true;
1225
 
864 mhunt 1226
          Package dependency = it.next();
814 mhunt 1227
          retVal += dependency.mAlias;
1228
        }
1229
 
1230
        retVal += "\"";
1231
      }
1232
      retVal += ">" + lf;
1233
 
1234
      if ( !mDaemon )
1235
      {
1236
        boolean hasDependenciesBuiltInThisIteration = false;
1237
        if ( ( p.mPackageDependencyCollection.size() > 0 ) )
1238
        {
864 mhunt 1239
          for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1240
          {
864 mhunt 1241
            Package dependency = it.next();
814 mhunt 1242
 
1243
            if ( dependency.mBuildFile == buildFile )
1244
            {
1245
              hasDependenciesBuiltInThisIteration = true;
1246
              break;
1247
            }
1248
          }
1249
        }
1250
 
1251
        if ( hasDependenciesBuiltInThisIteration )
1252
        {
1253
          retVal +=
1254
          "  <condition property=\"" + p.mAlias + ".build\">" + lf +
1255
          "    <and>" + lf;
1256
 
864 mhunt 1257
          for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1258
          {
864 mhunt 1259
            Package dependency = it.next();
814 mhunt 1260
 
1261
            if ( dependency.mBuildFile == buildFile )
1262
            {
1263
              retVal +=
1264
              "      <or>" + lf +
1265
              "        <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"0\"/>" + lf +
1266
              "        <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"257\"/>" + lf +
1267
              "      </or>" + lf;
1268
            }
1269
          }
1270
 
1271
          retVal +=
1272
          "    </and>" + lf +
1273
          "  </condition>" + lf;
1274
        }
1275
        else
1276
        {
1277
          retVal += "  <property name=\"" + p.mAlias + ".build\" value=\"\"/>" + lf;
1278
        }
1279
      }
1280
 
1281
      retVal +=
1282
      "</target>" + lf +
1283
      "<target name=\"" + p.mAlias + "\" depends=\"" + p.mAlias + ".wrap\"";
1284
 
1285
      if ( !mDaemon )
1286
      {
1287
        retVal += " if=\"" + p.mAlias + ".build\"";
1288
      }
1289
 
1290
      retVal += ">" + lf;
1291
 
1292
      if ( mDaemon && p.mBuildFile == 1 )
1293
      {
1294
        retVal +=
1295
        "<property name=\"" + p.mAlias + "pkg_id\" value=\"" + p.mPid + "\"/>" + lf +
1296
        "<property name=\"" + p.mAlias + "pv_id\" value=\"" + p.mId + "\"/>" + lf;
1297
      }
1298
 
1299
      if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon )
1300
      {
1301
        retVal +=
1302
        "<property name=\"" + p.mAlias + "packagename\" value=\"" + p.mName + "\"/>" + lf +
1303
        "<property name=\"" + p.mAlias + "packageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1304
        "<property name=\"" + p.mAlias + "packageextension\" value=\"";
1305
 
1306
        if ( p.mExtension.length() > 0 )
1307
        {
1308
          // drop the .
1309
          retVal += p.mExtension.substring(1);
1310
        }
1311
        else
1312
        {
1313
          retVal += p.mExtension;
1314
        }
1315
 
1316
        retVal += "\"/>" + lf +
1317
        "<property name=\"" + p.mAlias + "packagelabel\" value=\"" + p.mLabel + "\"/>" + lf;
1318
 
1319
        if ( p.mDirectlyPlanned )
1320
        {
1321
          retVal += "<property name=\"" + p.mAlias + "directchange\" value=\"\"/>" + lf;
1322
        }
1323
 
852 mhunt 1324
        if ( ! p.mRequiresSourceControlInteraction )
1325
        {
1326
          retVal += "<property name=\"" + p.mAlias + "doesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;
1327
        }
1328
 
814 mhunt 1329
        mAddendum = "non generic";
1330
 
1331
        if ( p.isGeneric() )
1332
        {
1333
          mAddendum = "generic";
1334
          retVal += "<property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;
1335
        }
1336
 
1337
        retVal += loc(p, p.mAlias + "loc", lf);
1338
 
830 mhunt 1339
        if ( p.mHasAutomatedUnitTests && mDaemon )
814 mhunt 1340
        {
1341
          retVal += 
1342
          "<property name=\"" + p.mAlias + "unittests\" value=\"\"/>" + lf;
1343
        }
1344
      }
1345
 
1346
      retVal += "<abt>" + lf;
1347
 
1348
      if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon )
1349
      {
864 mhunt 1350
        for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); )
814 mhunt 1351
        {
864 mhunt 1352
          Package dependency = it.next();
814 mhunt 1353
          retVal +=
1354
          "  <depend package_alias=\"${" + dependency.mAlias + "}\"/>" + lf;
1355
        }
1356
 
836 mhunt 1357
        retVal += buildInfo(p, lf, false);
814 mhunt 1358
      }
1359
 
1360
      if ( mDaemon && p.mBuildFile == 1 )
1361
      {
854 mhunt 1362
        retVal += p.emailInfo( lf );
814 mhunt 1363
      }
1364
 
1365
      retVal += "</abt>" + lf +
1366
      "</target>" + lf;
1367
 
1368
      if ( mDaemon && p.mBuildFile == 1 )
1369
      {
1370
        retVal +=
1371
        "<target name=\"AbtSetUp\">" + lf +
854 mhunt 1372
        "<property name=\"AbtSetUppackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
1373
        "<property name=\"AbtSetUppackagename\" value=\"" + p.mName + "\"/>" + lf;
814 mhunt 1374
 
1375
        retVal += loc(p, "AbtSetUppackagelocation", lf);
1376
 
1377
        retVal +=
1378
        "<abt>" + lf +
854 mhunt 1379
        p.emailInfo( lf ) +
814 mhunt 1380
        "</abt>" + lf +
1381
        "</target>" + lf +
1382
        "<target name=\"AbtTearDown\">" + lf +
1383
        "<property name=\"AbtTearDownpackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
1384
        "<property name=\"AbtTearDownpackagename\" value=\"" + p.mName + "\"/>" + lf +
1385
        "<property name=\"AbtTearDownpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1386
        "<property name=\"AbtTearDownpackageextension\" value=\"";
1387
 
1388
        if ( p.mExtension.length() > 0 )
1389
        {
1390
          // drop the .
1391
          retVal += p.mExtension.substring(1);
1392
        }
1393
        else
1394
        {
1395
          retVal += p.mExtension;
1396
        }
1397
 
1398
        retVal += "\"/>" + lf;
1399
 
1400
        if ( p.isGeneric() )
1401
        {
1402
          retVal += "<property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;
1403
        }
1404
 
1405
        retVal +=        
1406
        "<abt>" + lf +
836 mhunt 1407
        buildInfo(p, lf, false) +
854 mhunt 1408
        p.emailInfo( lf ) +
814 mhunt 1409
        "</abt>" + lf +
1410
        "</target>" + lf +
1411
        "<target name=\"AbtPublish\">" + lf +
1412
        "<property name=\"AbtPublishpackagelabel\" value=\"" + p.mLabel + "\"/>" + lf +
1413
        "<property name=\"AbtPublishpackagename\" value=\"" + p.mName + "\"/>" + lf +
1414
        "<property name=\"AbtPublishpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +
1415
        "<property name=\"AbtPublishpackageextension\" value=\"";
1416
 
1417
        if ( p.mExtension.length() > 0 )
1418
        {
1419
          // drop the .
1420
          retVal += p.mExtension.substring(1);
1421
        }
1422
        else
1423
        {
1424
          retVal += p.mExtension;
1425
        }
1426
 
1427
        retVal += "\"/>" + lf;
1428
 
1429
        if ( p.mDirectlyPlanned )
1430
        {
1431
          retVal += "<property name=\"AbtPublishdirectchange\" value=\"\"/>" + lf;
1432
        }
1433
 
852 mhunt 1434
        if ( ! p.mRequiresSourceControlInteraction )
1435
        {
1436
          retVal += "<property name=\"AbtPublishdoesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;
1437
        }
1438
 
814 mhunt 1439
        if ( p.isGeneric() )
1440
        {
1441
          retVal += "<property name=\"AbtPublishgeneric\" value=\"\"/>" + lf;
1442
        }
1443
 
1444
        retVal += loc(p, "AbtPublishloc", lf);
1445
        retVal +=
816 mhunt 1446
        "<abt>" + lf +
854 mhunt 1447
        buildInfo(p, lf, true) +
1448
        p.emailInfo( lf ) +
814 mhunt 1449
        "</abt>" + lf +
1450
        "</target>" + lf;
1451
      }
1452
    }
1453
    mLogger.info("generateTarget returned " + retVal);
1454
    return retVal;
1455
  }
1456
 
1457
  /**returns an ant default target for the current build iteration
1458
   */
1459
  private String generateDefaultTarget(int buildFile)
1460
  {
1461
    mLogger.debug("generateDefaultTarget");
1462
    String lf = new String( System.getProperty("line.separator") );
1463
    String retVal = new String("");
1464
    retVal +=
1465
    "<target name=\"fullstart\">" + lf;
1466
 
1467
    if (buildFile == 1)
1468
    {
1469
      retVal +=
1470
      "<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;
1471
 
864 mhunt 1472
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1473
      {
864 mhunt 1474
        Package p = it.next();
814 mhunt 1475
 
1476
        if ( p.mBuildFile == -1 )
1477
        {
1478
          retVal +=
1479
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1480
        }
1481
      }
1482
 
1483
      retVal +=
1484
      "<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;
1485
 
864 mhunt 1486
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1487
      {
864 mhunt 1488
        Package p = it.next();
814 mhunt 1489
 
1490
        if ( p.mBuildFile == -2 )
1491
        {
1492
          retVal +=
1493
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1494
        }
1495
      }
1496
 
1497
      retVal +=
1498
      "<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;
1499
 
864 mhunt 1500
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1501
      {
864 mhunt 1502
        Package p = it.next();
814 mhunt 1503
 
1504
        if ( p.mBuildFile == -4 )
1505
        {
1506
          retVal +=
1507
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1508
        }
1509
      }
1510
 
1511
      retVal +=
1512
      "<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;
1513
 
864 mhunt 1514
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1515
      {
864 mhunt 1516
        Package p = it.next();
814 mhunt 1517
 
1518
        if ( p.mBuildFile == -5 )
1519
        {
1520
          retVal +=
1521
          "<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1522
        }
1523
      }
1524
    }
1525
    if ( !mDaemon )
1526
    {
1527
      retVal +=
1528
      "<echo message=\"${line.separator}Build Started:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1529
    }
1530
 
1531
    retVal +=
1532
    "</target>" + lf +
1533
    "<target name=\"full\" depends=\"fullstart";
1534
 
864 mhunt 1535
    for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1536
    {
864 mhunt 1537
      Package p = it.next();
814 mhunt 1538
 
1539
      if ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) )
1540
      {
1541
        retVal += "," + p.mAlias;
1542
      }
1543
    }
1544
 
1545
    retVal +=
1546
    "\">" + lf;
1547
 
1548
    if ( !mDaemon )
1549
    {
1550
      retVal +=
1551
      "<echo message=\"${line.separator}Build Finished${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;
1552
    }
1553
 
1554
    retVal +=
1555
    "</target>" + lf;
1556
    return retVal;
1557
  }
1558
 
1559
  /**returns a build file footer
1560
   */
1561
  private String generateBuildFileFooter()
1562
  {
1563
    mLogger.debug("generateBuildFileFooter");
1564
    String retVal = new String("</project>");
1565
    return retVal;
1566
  }
1567
 
1568
  /**sets the mIndirectlyPlanned true for the package and all dependent packages
1569
   */
1570
  private void rippleIndirectlyPlanned(Package p)
1571
  {
1572
    mLogger.debug("rippleIndirectlyPlanned");
1573
    if ( !p.mIndirectlyPlanned && p.mBuildFile == 0 )
1574
    {
1575
      p.mIndirectlyPlanned = true;
1576
 
864 mhunt 1577
      for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); )
814 mhunt 1578
      {
864 mhunt 1579
        Package pkg = it.next();
814 mhunt 1580
 
1581
        if ( pkg != p )
1582
        {
864 mhunt 1583
          for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); )
814 mhunt 1584
          {
864 mhunt 1585
            Package dependency = it2.next();
814 mhunt 1586
 
1587
            if ( dependency == p )
1588
            {
1589
              rippleIndirectlyPlanned( pkg );
1590
              break;
1591
            }
1592
          }
1593
        }
1594
      }
1595
    }
1596
    mLogger.info("rippleIndirectlyPlanned set " + p.mName + " " + p.mIndirectlyPlanned);    
1597
  }
1598
 
1599
  /**accessor method
1600
   */
830 mhunt 1601
  public String getESCROWSetUp()
814 mhunt 1602
  {
830 mhunt 1603
    mLogger.debug("getESCROWSetUp");
814 mhunt 1604
    String retVal = new String("");
1605
 
1606
    try
1607
    {
830 mhunt 1608
      if ( mEscrowClearcaseSupportCollection.size() >= 1 )
814 mhunt 1609
      {
1610
        retVal = (String)mEscrowClearcaseSupportCollection.get(0);
1611
      }
1612
    }
1613
    catch( ArrayIndexOutOfBoundsException e )
1614
    {
1615
    }
1616
 
830 mhunt 1617
    mLogger.info("getESCROWSetUp returned " + retVal);
814 mhunt 1618
    return retVal;
1619
  }
1620
 
1621
  /**accessor method
1622
   */
830 mhunt 1623
  public String getRawData()
814 mhunt 1624
  {
830 mhunt 1625
    mLogger.debug("getRawData");
814 mhunt 1626
    String retVal = new String("");
1627
 
1628
    try
1629
    {
830 mhunt 1630
      if ( mEscrowClearcaseSupportCollection.size() >= 2 )
814 mhunt 1631
      {
1632
        retVal = (String)mEscrowClearcaseSupportCollection.get(1);
1633
      }
1634
    }
1635
    catch( ArrayIndexOutOfBoundsException e )
1636
    {
1637
    }
1638
 
830 mhunt 1639
    mLogger.info("getRawData returned " + retVal);
814 mhunt 1640
    return retVal;
1641
  }
1642
 
1643
  /**returns first build file content and addendum
1644
   * the addendum value is one of "non generic", "generic" or "dummy"
1645
   */
1646
  public void getFirstBuildFileContent(MutableString content, 
1647
                                MutableString addendum)
1648
  {
1649
    mLogger.debug("getFirstBuildFileContent");
1650
    try
1651
    {
1652
      mBuildIndex = 0;
1653
      content.value = (String)mBuildCollection.get( mBuildIndex );
1654
      addendum.value = mAddendum;
1655
    }
1656
    catch( ArrayIndexOutOfBoundsException e )
1657
    {
1658
    }
1659
    mLogger.info("getFirstBuildFileContent passed " + content.value + addendum.value);
1660
  }
1661
 
1662
  /**returns the built loc
1663
   */
1664
  private String loc(Package p, String target, String lf)
1665
  {
1666
    mLogger.debug("loc");
1667
    String retVal = new String();
1668
    String loc = new String("\\");
1669
 
864 mhunt 1670
    for (Iterator<String> it = mGbeMachtypeCollection.iterator(); it.hasNext(); )
814 mhunt 1671
    {
864 mhunt 1672
      String machtype = it.next();
814 mhunt 1673
 
1674
      if ( machtype.compareTo("win32") == 0 )
1675
      {
816 mhunt 1676
        if ( target.compareTo("AbtSetUppackagelocation") != 0 )
814 mhunt 1677
        {
816 mhunt 1678
          if (mDaemon)
814 mhunt 1679
          {
832 mhunt 1680
            loc += mBaseline + "\\" + mTimestamp + "\\" + p.mLabel;
814 mhunt 1681
          }
832 mhunt 1682
          else
1683
          {
848 dpurdie 1684
            // mAlias used with jats -extractfiles -view
1685
            loc += p.mAlias;
832 mhunt 1686
          }
1687
 
1688
          loc += p.mLocation;
814 mhunt 1689
        }
816 mhunt 1690
        else
1691
        {
1692
          loc = p.mLocation;
1693
        }
1694
        break;
814 mhunt 1695
      }
1696
    }
1697
 
1698
    loc = loc.replace('/', '\\');
1699
    retVal =
1700
    "<condition property=\"" + target + "\" value=\"" + loc + "\">" + lf +
1701
    "  <os family=\"windows\"/>" + lf +
1702
    "</condition>" + lf;
1703
 
1704
    loc = "/";
1705
 
864 mhunt 1706
    for (Iterator<String> it = mGbeMachtypeCollection.iterator(); it.hasNext(); )
814 mhunt 1707
    {
864 mhunt 1708
      String machtype = it.next();
814 mhunt 1709
 
1710
      if ( machtype.compareTo("linux_i386") == 0 )
1711
      {
816 mhunt 1712
        if ( target.compareTo("AbtSetUppackagelocation") != 0 )
814 mhunt 1713
        {
816 mhunt 1714
          if (mDaemon)
814 mhunt 1715
          {
816 mhunt 1716
            loc += mBaseline + "/" + mTimestamp + "/";
814 mhunt 1717
          }
832 mhunt 1718
 
1719
          if (mDaemon)
1720
          {
1721
            loc += p.mLabel;
848 dpurdie 1722
            // no vobs in escrow_set_up ie jats -extractfiles
1723
            loc += "/vobs";
832 mhunt 1724
          }
1725
          else
1726
          {
848 dpurdie 1727
            // mAlias used with jats -extractfiles -view
1728
            loc += p.mAlias;
832 mhunt 1729
          }
1730
 
1731
          loc += p.mLocation;
814 mhunt 1732
        }
816 mhunt 1733
        else
1734
        {
1735
          loc = p.mLocation;
1736
        }
1737
        break;
814 mhunt 1738
      }
1739
      else if ( machtype.compareTo("sparc") == 0
1740
             || machtype.compareTo("solaris10_x86") == 0
1741
             || machtype.compareTo("solaris10_sparc32") == 0 )
1742
      {
816 mhunt 1743
        if ( target.compareTo("AbtSetUppackagelocation") != 0 )
814 mhunt 1744
        {
816 mhunt 1745
          if (mDaemon)
814 mhunt 1746
          {
816 mhunt 1747
            loc += mBaseline + "/" + mTimestamp + "/";
1748
          }
814 mhunt 1749
 
832 mhunt 1750
          if (mDaemon)
1751
          {
1752
            loc += p.mLabel;
848 dpurdie 1753
            // no vobs in escrow_set_up ie jats -extractfiles
1754
            loc += "/vobs";
832 mhunt 1755
          }
1756
          else
1757
          {
848 dpurdie 1758
            // mAlias used with jats -extractfiles -view
1759
            loc += p.mAlias;
832 mhunt 1760
          }
1761
 
1762
          loc += p.mLocation;
816 mhunt 1763
        }
1764
        else
1765
        {
1766
          loc = p.mLocation;
1767
        }
1768
        break;
814 mhunt 1769
      }
1770
    }
1771
    loc = loc.replace('\\', '/');
1772
    retVal += 
1773
    "<property name=\"" + target + "\" value=\"" + loc + "\"/>" + lf;
1774
 
1775
    mLogger.info("loc returned " + retVal);
1776
    return retVal;
1777
  }
816 mhunt 1778
 
1779
  /**returns the buildInfo
1780
   */
836 mhunt 1781
  private String buildInfo(Package p, String lf, boolean filter)
816 mhunt 1782
  {
1783
    mLogger.debug("buildInfo");
1784
 
1785
    String platforms = new String();
1786
    String standards = new String();
1787
 
864 mhunt 1788
    for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); )
816 mhunt 1789
    {
864 mhunt 1790
      BuildStandard bs = it.next();
816 mhunt 1791
 
836 mhunt 1792
      if ( !filter )
816 mhunt 1793
      {
864 mhunt 1794
        String platform = bs.getPlatform(!ReleaseManager.mUseDatabase);
816 mhunt 1795
 
1796
        if ( platform.length() > 0 )
1797
        {
1798
          platforms += platform + lf;
1799
        }
1800
 
864 mhunt 1801
        String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase);
816 mhunt 1802
 
1803
        if ( standard.length() > 0 )
1804
        {
1805
          standards += standard + lf;
1806
        }
1807
      }
1808
      else
1809
      {
864 mhunt 1810
        if ( !bs.getBuildStandard(!ReleaseManager.mUseDatabase).contains("\"none\"") )
816 mhunt 1811
        {
864 mhunt 1812
          String platform = bs.getPlatform(!ReleaseManager.mUseDatabase);
816 mhunt 1813
 
1814
          if ( platform.length() > 0 )
1815
          {
1816
            platforms += platform + lf;
1817
          }
836 mhunt 1818
 
864 mhunt 1819
          String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase);
836 mhunt 1820
 
1821
          if ( standard.length() > 0 )
1822
          {
1823
            standards += standard + lf;
1824
          }
816 mhunt 1825
        }
1826
      }
1827
    }
1828
 
1829
    mLogger.info("buildInfo returned " + platforms + standards);
1830
    return platforms + standards;
1831
  }
866 mhunt 1832
 
814 mhunt 1833
}