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