Subversion Repositories DevTools

Rev

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