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