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