Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

package com.erggroup.buildtool.ripple;

import java.sql.CallableStatement;
import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.sql.Timestamp;

import java.sql.Types;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;

import oracle.jdbc.driver.OracleDriver;

import org.apache.log4j.Logger;

/**Release Manager schema abstraction
 */
public class ReleaseManager
{
  /**Unit test hook.
   * Prevents Oracle interaction when false.
   * @attribute
   */
  public static boolean mUseDatabase = true;

  /**Unit test hook
   * Container of persisted run levels for unit test usage
   * Must be managed by the unit test code
   * @attribute
   */
  public static Vector mPersistedRunLevelCollection = new Vector();

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_CANNOT_CONTINUE = 1;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_PAUSED = 2;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_ACTIVE = 3;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_IDLE = 4;

  /**database represented enumerated value
   * @attribute
   */
  public static final int DB_WAITING = 5;

  /**package object of no consequence
   * @attribute
   */
  static final Package NULL_PACKAGE = new Package();

  /**registered status
   * @attribute
   */
  static boolean mRegistered = false;

  /**Logger
   * @attribute
   */
  private static final Logger mLogger = Logger.getLogger(ReleaseManager.class);

  /**database session handle
   * @attribute
   */
  private Connection mConnection = null;

  /**index to current ReleaseConfig item
   * @attribute
   */
  private int mReleaseConfigIndex = -1;

  /**index to current RunLevel item
   * @attribute
   */
  private int mRunLevelIndex = -1;

  /**collection of ReleaseConfig objects
   * @attribute
   */
  private Vector mReleaseConfigCollection = new Vector();

  /**database connection string
   * @attribute
   */
  private static String mConnectionString = new String();

  /**database username
   * @attribute
   */
  private static String mUsername = new String();

  /**database password
   * @attribute
   */
  private static String mPassword = new String();

  /**collection of RunLevel objects
   * @attribute
   */
  private Vector mRunLevelCollection = new Vector();

  /**in daemon mode
   *   select gm.gbe_value from release_config rc, gbe_machtype gm
   *   where rc.rtag_id=<baseline> and gm.gbe_id=rc.gbe_id;
   * in escrow mode
   *   select gm.gbe_value from boms b, release_manager.release_config rc,
   *   release_manager.gbe_machtype gm
   *   where b.bom_id=<baseline> and rc.rtag_id=b.rtag_id_fk and gm.gbe_id=rc.gbe_id;
   * populates the machtypeCollection with the resultset
   */
  void queryMachtypes(Vector machtypeCollection, boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryMachtypes " + daemonMode);
    if ( !mUseDatabase )
    {
      mLogger.info("queryMachtypes !mUseDatabase");
      // a highly unlikely set of machtypes
      String machtype = new String("linux_i386");
      machtypeCollection.add(machtype);
      machtype = new String("sparc");
      machtypeCollection.add(machtype);
      machtype = new String("solaris10_x86");
      machtypeCollection.add(machtype);
    }
    else
    {
      String sql = new String("");
      
      if ( daemonMode )
      {
        sql = "select gm.gbe_value from release_manager.release_config rc, release_manager.gbe_machtype gm where rc.rtag_id=" + baseline + " and gm.gbe_id=rc.gbe_id";
      }
      else
      {
        sql = 
        "select gm.gbe_value from boms b, release_manager.release_config rc, release_manager.gbe_machtype gm where b.bom_id=" + 
        baseline + " and rc.rtag_id=b.rtag_id_fk and gm.gbe_id=rc.gbe_id";
      }
      
      try
      {
        CallableStatement stmt = mConnection.prepareCall(sql);
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String machtype = rset.getString("gbe_value");
          
          if ( machtype != null )
          {
            machtypeCollection.add(machtype);
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMachtypes database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMachtypes show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**in daemon mode
   *   select p.proj_name, rt.rtag_name from projects p, release_tags rt
   *   where rt.rtag_id=<baseline> and p.proj_id=rt.proj_id;
   * returns a concatenation of the proj_name and rtag_name
   * in escrow mode
   *   select dp.proj_name, br.branch_name, b.bom_version, b.bom_lifecycle
   *   from dm_projects dp, branches br, boms b
   *   where b.bom_id=<baseline> and br.branch_id=b.branch_id and dp.proj_id=br.proj_id;
   * returns a concatenation of the proj_name, branch_name, bom_version and bom_lifecycle
   */
  String queryBaselineName(boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryBaselineName " + daemonMode);
    String retVal = new String();

    if ( !mUseDatabase )
    {
      mLogger.info("queryBaselineName !mUseDatabase");
      // a highly unlikely baseline name
      if (daemonMode)
      {
        retVal = "TIMBUKTU (TIM) > R7";
      }
      else
      {
        retVal = "TIMBUKTU (TIM) > R7 7.9";
      }
    }
    else
    {
      String sql = new String("");
      
      if ( daemonMode )
      {
        sql = "select p.proj_name, rt.rtag_name from release_manager.projects p, release_manager.release_tags rt where rt.rtag_id=" + baseline + " and p.proj_id=rt.proj_id";
      }
      else
      {
        sql = 
        "select dp.proj_name, br.branch_name, b.bom_version, b.bom_lifecycle from dm_projects dp, branches br, boms b where b.bom_id=" + 
        baseline + " and br.branch_id=b.branch_id and dp.proj_id=br.proj_id";
      }
      
      try
      {
        CallableStatement stmt = mConnection.prepareCall(sql);
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String proj_name = rset.getString("proj_name");
          
          if ( proj_name != null )
          {
            retVal += proj_name;
          }
          
          if ( daemonMode )
          {
            String rtag_name = rset.getString("rtag_name");
            
            if ( rtag_name != null )
            {
              retVal += " > " + rtag_name;
            }
          }
          else
          {
            String branch_name = rset.getString("branch_name");
            
            if ( branch_name != null )
            {
              retVal += " > " + branch_name;
            }
            
            String bom_version = rset.getString("bom_version");
            
            if ( bom_version != null )
            {
              retVal += " " + bom_version;
            }
            
            String bom_lifecycle = rset.getString("bom_lifecycle");
            
            if ( bom_lifecycle != null )
            {
              retVal += "." + bom_lifecycle;
            }
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryBaselineName database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryBaselineName show stopper");
          throw new Exception();
        }
      }
    }
    mLogger.info("queryBaselineName returned " + retVal);
    return retVal;
  }

  /**in daemon mode
   *  1 get planned package info
   *     select pl.pv_id, p.pkg_id, p.pkg_name, pv.v_ext, pv.pkg_label, pv.src_path, pv.change_type
   *     from planned pl, package_versions pv, packages p
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id=pl.pv_id and p.pkg_id=pv.pkg_id
   *     order by pl.pv_id;
   *  2 get planned package dependency info
   *     select pl.pv_id, p.pkg_name, dpv.v_ext
   *     from planned pl, package_versions pv, package_dependencies pd, package_versions dpv, packages p
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and pd.pv_id=pl.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *     order by pl.pv_id;
   *  3 get planned package build info
   *     select pl.pv_id, bm.bm_name, bsa.bsa_name
   *     from planned pl, package_versions pv, package_build_info pbi, build_machines bm, build_standards_addendum bsa
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   *     order by pl.pv_id;
   *  4 get planned package unit test info
   *     select pl.pv_id, tt.test_type_name
   *     from planned pl, package_versions pv, unit_tests ut, test_types tt
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk
   *     order by pl.pv_id;
   *  5 get planned package build failure info
   *     select pl.pv_id, u.user_email
   *     from planned pl, release_tags rt, package_versions pv, autobuild_failure af, members_group mg, users u
   *     where pl.rtag_id=<mBaseline> and rt.rtag_id=pl.rtag_id and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and af.view_id=pl.view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id
   *     order by pl.pv_id;
   *  6 get planned package do not ripple info
   *     select pl.pv_id
   *     from planned pl, package_versions pv, do_not_ripple dnr
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and dnr.rtag_id=pl.rtag_id and dnr.pv_id=pl.pv_id
   *     order by pl.pv_id;
   *  7 get planned package advisory ripple info
   *     select pl.pv_id
   *     from planned pl, package_versions pv, advisory_ripple ar
   *     where pl.rtag_id=<mBaseline> and pv.build_type='A' and pv.dlocked='A'
   *     and pv.pv_id = pl.pv_id and ar.rtag_id=pl.rtag_id and ar.pv_id=pl.pv_id
   *     order by pl.pv_id;
   *  8 get released package info
   *     select rc.pv_id, p.pkg_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_label, pv.src_path, pv.ripple_field
   *     from release_content rc, package_versions pv, packages p
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and p.pkg_id = pv.pkg_id
   *     order by rc.pv_id;
   *  9 get released package dependency info
   *     select rc.pv_id, dpv.pv_id, p.pkg_name, dpv.v_ext
   *     from release_content rc, package_versions pv, package_dependencies pd, package_versions dpv, packages p
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *     order by rc.pv_id;
   * 10 get released package build info
   *     select rc.pv_id, bm.bm_name, bsa.bsa_name
   *     from release_content rc, package_versions pv, package_build_info pbi, build_machines bm, build_standards_addendum bsa
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   *     order by rc.pv_id;
   * 11 get released package unit test info
   *     select rc.pv_id, tt.test_type_name
   *     from release_content rc, package_versions pv, unit_tests ut, test_types tt
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk
   *     order by rc.pv_id;
   * 12 get released package build failure email info
   *     select rc.pv_id, u.user_email
   *     from release_content rc, release_tags rt, package_versions pv, autobuild_failure af, members_group mg, users u
   *     where rc.rtag_id=<mBaseline> and rt.rtag_id=rc.rtag_id
   *     and pv.pv_id = rc.pv_id and af.view_id=rc.base_view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id
   *     order by rc.pv_id;
   * 13 get released package do not ripple info
   *     select rc.pv_id
   *     from release_content rc, package_versions pv, do_not_ripple dnr
   *     where rc.rtag_id=3741
   *     and pv.pv_id = rc.pv_id and dnr.rtag_id=rc.rtag_id and dnr.pv_id=rc.pv_id
   *     order by rc.pv_id;
   * 14 get released advisory ripple info
   *     select rc.pv_id
   *     from release_content rc, package_versions pv, advisory_ripple ar
   *     where rc.rtag_id=<mBaseline>
   *     and pv.pv_id = rc.pv_id and ar.rtag_id=rc.rtag_id and ar.pv_id=rc.pv_id
   *     order by rc.pv_id;
   * in escrow mode
   *  1 get released product info
   *     select oc.prod_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_label, pv.src_path
   *     from bom_contents bc, operating_systems os, os_contents oc, release_manager.package_versions pv, release_manager.packages p
   *     where bc.bom_id=<mBaseline> and os.node_id=bc.node_id and oc.os_id=os.os_id and pv.pv_id=oc.prod_id and p.pkg_id=pv.pkg_id
   *     order by oc.prod_id;
   *    this will generate a list of pv_ids associtaed with products
   *    many in the list will reference cots products outside the scope of a escrow build
   *  2 for each <pv_id>, call traverseDependencies( packageCollection, pv_id, false ) to traverse its set of dependencies
   *  3 for each Package, call queryBuildInfo to get released package build info
   *  
   * Supports
   *    test_type_name="Autobuild UTF"
   *    bm_name="Generic"|"Linux"|"Solaris"|"Win32"
   *    bsa_name="Debug"|"Production"|"Production and Debug"|"Java 1.4"|"Java 1.5"|"Java 1.6"
   */
  void queryPackageVersions(RippleEngine rippleEngine, 
                            Vector packageCollection, boolean daemonMode, int baseline) throws SQLException, Exception
  {
    mLogger.debug("queryPackageVersions " + daemonMode);
  
    if ( !mUseDatabase )
    {
      mLogger.info("queryPackageVersions !mUseDatabase");
      
      if (daemonMode)
      {
        /* a highly unlikely set of packages
         * planned info
         * pv_id pkg_id pkg_name                     v_ext pkg_label src_path                          change_type
         * 0     76     UncommonDependency           .tim  0.TIM.WIP \vob\UncommonDependency           P
         * 1     1011   DependencyMissingFromRelease .tim  1.TIM.WIP \vob\DependencyMissingFromRelease M
         * 2     34     CommonDependency             .tim  2.TIM.WIP \vob\CommonDependency             M
         * 3     908    SolarisCentricProduct        .tim  3.TIM.WIP \vob\SolarisCentricProduct        N
         * 4     6      GenericProduct               .tim  4.TIM.WIP \vob\GenericProduct               P
         * 5     11     Product                      .tim  5.TIM.WIP \vob\Product                      M
         * 6     113    UnfinishedProduct            .tim  6.TIM.WIP \vob\UnfinishedProduct            M
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           Package p = new Package(0, "UncommonDependency", ".tim", "UncommonDependency.tim", "0.TIM.WIP", "\\vob\\UncommonDependency", 'P');
           p.mPid = 76;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         Package p = new Package(1, "DependencyMissingFromRelease", ".tim", "DependencyMissingFromRelease.tim", "1.TIM.WIP", "\\vob\\DependencyMissingFromRelease", 'M');
         p.mPid = 1011;
         p.mDirectlyPlanned = true;
         packageCollection.add(p);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = new Package(2, "CommonDependency", ".tim", "CommonDependency.tim", "2.TIM.WIP", "\\vob\\CommonDependency", 'M');
           p.mPid = 34;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = new Package(3, "SolarisCentricProduct", ".tim", "SolarisCentricProduct.tim", "3.TIM.WIP", "\\vob\\SolarisCentricProduct", 'N');
           p.mPid = 908;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = new Package(4, "GenericProduct", ".tim", "GenericProduct.tim", "4.TIM.WIP", "\\vob\\GenericProduct", 'P');
           p.mPid = 6;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = new Package(5, "Product", ".tim", "Product.tim", "5.TIM.WIP", "\\vob\\Product", 'M');
           p.mPid = 11;
           p.mDirectlyPlanned = true;
           packageCollection.add(p);
         }
        
         p = new Package(6, "UnfinishedProduct", ".tim", "UnfinishedProduct.tim", "6.TIM.WIP", "\\vob\\UnfinishedProduct", 'M');
         p.mPid = 113;
         p.mDirectlyPlanned = true;
         packageCollection.add(p);
         
        /* planned dependencies
         * pv_id pkg_name                     v_ext
         * 1     NotInTheRelease              .cots
         * 2     CotsWithFunnyVersion         .cots
         * 2     UncommonDependency           .tim
         * 3     CommonDependency             .tim
         * 4     CommonDependency             .tim
         * 5     UncommonDependency           .tim
         */
         p = findPackage(1, packageCollection);
         p.mDependencyCollection.add("NotInTheRelease.cots");
         p.mDependencyIDCollection.add(-1);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(2, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(-1);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(4, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(-1);
         }
         
        /* planned build info
         * pv_id bm_name bsa_name
         * 0     Linux   Java 1.6
         * 1     Linux   Debug
         * 2     Linux   Debug
         * 2     Solaris Production
         * 2     Win32   Production and Debug
         * 3     Solaris Java 1.4
         * 4     Generic Java 1.5
         * 5     Linux   Java 1.6
         * 5     Win32   Java 1.6
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(0, packageCollection);
           BuildStandard bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
         p = findPackage(1, packageCollection);
         BuildStandard bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(2, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setAll();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(4, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_5();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
        /* planned unit test info
         * pv_id test_type_name
         * 2     Manual Test
         * 2     Interactive Test
         * 2     Integration Test
         * 5     Autobuild UTF
         */
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.mHasAutomatedUnitTests = true;
         }
         
        /* planned build failure info
         * pv_id user_email
         * 3     jimmyfishcake@erggroup.com
         * 3     rayhaddock@erggroup.com
         * 5     timbutdim@erggroup.com
         */
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(3, packageCollection);
           p.mBuildFailureEmailCollection.add("jimmyfishcake@erggroup.com");
           p.mBuildFailureEmailCollection.add("rayhaddock@erggroup.com");
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0 )
         {
           p = findPackage(5, packageCollection);
           p.mBuildFailureEmailCollection.add("timbutdim@erggroup.com");
         }
         
        /* planned do not ripple info
         * pv_id
         * 6
         */
         p = findPackage(6, packageCollection);
         p.mDoNotRipple = true;
         
        /* planned advisory ripple info
         * pv_id
         * 0
         */
         if ( mConnectionString.compareTo("iteration1") == 0 )
         {
           p = findPackage(0, packageCollection);
           p.mAdvisoryRipple = true;
         }
         
        /* released info
         * pv_id pkg_id pkg_name                     pkg_version      v_ext pkg_label                           src_path                   ripple_field
         * 7     8      CotsWithFunnyVersion         hoopla2_x.cots   .cots CotsWithFunnyVersion_hoopla2_x.cots \vob\CotsWithFunnyVersion
         * 8     17     NotInAnyWayReproducible      1.0.0.tim        .tim  NA                                  NA
         * 9     34     CommonDependency             1.0.0000.tim     .tim  CommonDependency_1.0.0000.tim       \vob\CommonDependency
         * 10    908    SolarisCentricProduct        1.0.0000.tim     .tim  SolarisCentricProduct_1.0.0000.tim  \vob\SolarisCentricProduct m
         * 11    16     LinuxCentricProduct          1.0.0000.tim     .tim  LinuxCentricProduct_1.0.0000.tim    \vob\LinuxCentricProduct
         * 12    312    Win32CentricProduct          1.0.0000.tim     .tim  Win32CentricProduct_1.0.0000.tim    \vob\Win32CentricProduct
         * 13    6      GenericProduct               1.0.0000.tim     .tim  GenericProduct_1.0.0000.tim         \vob\ToBeMovedFromHere     M
         * 14    81     AdvisoryDependency           1.0.0000.tim     .tim  AdvisoryDependency_1.0.0000.tim     \vob\AdvisoryDependency
         * 15    1      MergedProduct                1.0.0000.tim     .tim  MergedProduct_1.0.0000.tim          \vob\MergedProduct         m
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = new Package(0, "UncommonDependency", "0.0.1000.tim", ".tim", "UncommonDependency.tim", "UncommonDependency_0.0.1000.tim", "\\vob\\UncommonDependency", 'x');
           p.mPid = 76;
           Integer pv_id = new Integer(0);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "0.0.1000";
           }
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = new Package(2, "CommonDependency", "2.0.0000.tim", ".tim", "CommonDependency.tim", "CommonDependency_2.0.0000.tim", "\\vob\\CommonDependency", 'x');
           p.mPid = 34;
           Integer pv_id = new Integer(2);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "2.0.0000";
           }
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = new Package(3, "SolarisCentricProduct", "1.1.0000.tim", ".tim", "SolarisCentricProduct.tim", "SolarisCentricProduct_1.1.0000.tim", "\\vob\\SolarisCentricProduct", 'm');
           p.mPid = 908;
           Integer pv_id = new Integer(3);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.1.0000";
           }
         }
        
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = new Package(4, "GenericProduct", "1.0.1000.tim", ".tim", "GenericProduct.tim", "GenericProduct_1.0.1000.tim", "\\vob\\GenericProduct", 'M');
           p.mPid = 6;
           Integer pv_id = new Integer(4);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.1000";
           }
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = new Package(5, "Product", "1.0.0000.tim", ".tim", "Product.tim", "Product_1.0.0000.tim", "\\vob\\Product", 'M');
           p.mPid = 11;
           Integer pv_id = new Integer(5);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           Package plannedPackage = findPackage(p.mAlias, packageCollection);
           
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         p = new Package(7, "CotsWithFunnyVersion", "hoopla2_x.cots", ".cots", "CotsWithFunnyVersion.cots", "CotsWithFunnyVersion_hoopla2_x", "\\vob\\CotsWithFunnyVersion", 'x');
         p.mPid = 8;
         Integer pv_id = new Integer(7);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         Package plannedPackage = findPackage(p.mAlias, packageCollection);
         
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "hoopla2_x";
         }
         
         p = new Package(8, "NotInAnyWayReproducible", "1.0.0.tim", ".tim", "NotInAnyWayReproducible.tim", "NA", "NA", 'x');
         p.mPid = 17;
         pv_id = new Integer(8);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0";
         }

         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = new Package(9, "CommonDependency", "1.0.0000.tim", ".tim", "CommonDependency.tim", "CommonDependency_1.0.0000.tim", "\\vob\\CommonDependency", 'x');
           p.mPid = 34;
           pv_id = new Integer(9);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = new Package(10, "SolarisCentricProduct", "1.0.0000.tim", ".tim", "SolarisCentricProduct.tim", "SolarisCentricProduct_1.0.0000.tim", "\\vob\\SolarisCentricProduct", 'm');
           p.mPid = 908;
           pv_id = new Integer(10);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
          
           if ( plannedPackage == NULL_PACKAGE )
           {
             packageCollection.add(p);
           }
           else
           {
             plannedPackage.mVersion = "1.0.0000";
           }
         }
        
         p = new Package(11, "LinuxCentricProduct", "1.0.0000.tim", ".tim", "LinuxCentricProduct.tim", "LinuxCentricProduct_1.0.0000.tim", "\\vob\\LinuxCentricProduct", 'x');
         p.mPid = 16;
         pv_id = new Integer(11);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         p = new Package(12, "Win32CentricProduct", "1.0.0000.tim", ".tim", "Win32CentricProduct.tim", "Win32CentricProduct_1.0.0000.tim", "\\vob\\Win32CentricProduct", 'x');
         p.mPid = 312;
         pv_id = new Integer(12);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = new Package(13, "GenericProduct", "1.0.0000.tim", ".tim", "GenericProduct.tim", "GenericProduct_1.0.0000.tim", "\\vob\\ToBeMovedFromHere", 'M');
           p.mPid = 6;
           pv_id = new Integer(13);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
        
         p = new Package(14, "AdvisoryDependency", "1.0.0000.tim", ".tim", "AdvisoryDependency.tim", "AdvisoryDependency_1.0.0000.tim", "\\vob\\AdvisoryDependency", 'x');
         p.mPid = 81;
         pv_id = new Integer(14);
         rippleEngine.mReleasedPvIDCollection.add(pv_id);
         plannedPackage = findPackage(p.mAlias, packageCollection);
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = new Package(15, "MergedProduct", "1.0.0000.tim", ".tim", "MergedProduct.tim", "MergedProduct_1.0.0000.tim", "\\vob\\MergedProduct", 'm');
           p.mPid = 1;
           pv_id = new Integer(15);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
         else
         {
           p = new Package(16, "MergedProduct", "1.0.0000.tim", ".tim", "MergedProduct.tim", "MergedProduct_1.0.0000.tim", "\\vob\\MergedProduct", 'm');
           p.mPid = 1;
           pv_id = new Integer(16);
           rippleEngine.mReleasedPvIDCollection.add(pv_id);
           plannedPackage = findPackage(p.mAlias, packageCollection);
         }
        
         if ( plannedPackage == NULL_PACKAGE )
         {
           packageCollection.add(p);
         }
         else
         {
           plannedPackage.mVersion = "1.0.0000";
         }
         
        /* released dependencies
         * pv_id dpv_id pkg_name                     v_ext
         * 8     9      CommonDependency             .tim
         * 9     7      CotsWithFunnyVersion         .cots
         * 10    9      CommonDependency             .tim
         * 11    44     AdvisoryDependency           .tim
         * 13    9      CommonDependency             .tim
         * 15    99     CommonDependency             .tim
         */
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = findPackage(2, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(7);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(0);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = findPackage(4, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.mDependencyCollection.add("UncommonDependency.tim");
           p.mDependencyIDCollection.add(0);
         }

         p = findPackage(8, packageCollection);
         p.mDependencyCollection.add("CommonDependency.tim");
         p.mDependencyIDCollection.add(9);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(9, packageCollection);
           p.mDependencyCollection.add("CotsWithFunnyVersion.cots");
           p.mDependencyIDCollection.add(7);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(9);
         }
         
         p = findPackage(11, packageCollection);
         p.mDependencyCollection.add("AdvisoryDependency.tim");
         p.mDependencyIDCollection.add(44);
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(13, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(9);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = findPackage(15, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(99);
         }
         else
         {
           p = findPackage(16, packageCollection);
           p.mDependencyCollection.add("CommonDependency.tim");
           p.mDependencyIDCollection.add(2);
         }
         
        /* released build info
         * pv_id bm_name bsa_name
         * 7     Solaris Debug
         * 9     Linux   Debug
         * 9     Solaris Debug
         * 9     Win32   Production
         * 10    Solaris Java 1.4
         * 11    Linux   Production and Debug
         * 12    Win32   Java 1.6
         * 13    Generic Java 1.4
         * 14    Linux   Debug
         * 15    Linux   Debug
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = findPackage(0, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 && mConnectionString.compareTo("iteration2") != 0 )
         {
           p = findPackage(2, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setAll();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0 )
         {
           p = findPackage(4, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_5();
           p.mBuildStandardCollection.add(bs);
         }
        
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.set1_6();
           p.mBuildStandardCollection.add(bs);
         }

         p = findPackage(7, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setSolaris();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 || mConnectionString.compareTo("iteration2") == 0 )
         {
           p = findPackage(9, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
           bs = new BuildStandard(rippleEngine);
           bs.setWin32();
           bs.setProduction();
           p.mBuildStandardCollection.add(bs);
         }
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setSolaris();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }
         
         p = findPackage(11, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setAll();
         p.mBuildStandardCollection.add(bs);

         p = findPackage(12, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setWin32();
         bs.set1_6();
         p.mBuildStandardCollection.add(bs);

         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0 )
         {
           p = findPackage(13, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setGeneric();
           bs.set1_4();
           p.mBuildStandardCollection.add(bs);
         }

         p = findPackage(14, packageCollection);
         bs = new BuildStandard(rippleEngine);
         bs.setLinux();
         bs.setDebug();
         p.mBuildStandardCollection.add(bs);
         
         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0
           || mConnectionString.compareTo("iteration4") == 0
           || mConnectionString.compareTo("iteration5") == 0
           || mConnectionString.compareTo("iteration6") == 0 )
         {
           p = findPackage(15, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
         }
         else
         {
           p = findPackage(16, packageCollection);
           bs = new BuildStandard(rippleEngine);
           bs.setLinux();
           bs.setDebug();
           p.mBuildStandardCollection.add(bs);
         }
        
        /* released package unit test info
         * pv_id tt.test_type_name
         * 9     Manual Test
         * 9     Interactive Test
         * 9     Integration Test
         * 11    Autobuild UTF
         */
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.mHasAutomatedUnitTests = true;
         }

         p = findPackage(11, packageCollection);
         p.mHasAutomatedUnitTests = true;
         
        /* released build failure email info
         * pv_id user_email
         * 10    jimmyfishcake@erggroup.com
         */
         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0 )
         {
           p = findPackage(3, packageCollection);
           p.mBuildFailureEmailCollection.add("jimmyfishcake@erggroup.com");
           p.mBuildFailureEmailCollection.add("rayhaddock@erggroup.com");
         }

         if ( mConnectionString.compareTo("iteration1") != 0 
           && mConnectionString.compareTo("iteration2") != 0
           && mConnectionString.compareTo("iteration3") != 0
           && mConnectionString.compareTo("iteration4") != 0
           && mConnectionString.compareTo("iteration5") != 0 )
         {
           p = findPackage(5, packageCollection);
           p.mBuildFailureEmailCollection.add("timbutdim@erggroup.com");
         }

         if ( mConnectionString.compareTo("iteration1") == 0 
           || mConnectionString.compareTo("iteration2") == 0
           || mConnectionString.compareTo("iteration3") == 0 )
         {
           p = findPackage(10, packageCollection);
           p.mBuildFailureEmailCollection.add("jimmyfishcake@erggroup.com");
         }
         
        /* released do not ripple info
         * pv_id
         * 11
         */
         p = findPackage(11, packageCollection);
         p.mDoNotRipple = true;
         
        /* released advisory ripple info
         * pv_id
         * 14
         */
         if ( mConnectionString.compareTo("iteration1") != 0 )
         {
           p = findPackage(0, packageCollection);
           p.mAdvisoryRipple = true;
         }

         p = findPackage(14, packageCollection);
         p.mAdvisoryRipple = true;
      }
      else
      {
        /* prod_id pkg_name                pkg_version  v_ext pkg_label                           src_path
         * 8       NotInAnyWayReproducible 1.0.0.tim    .tim  NA                                  NA
         * 10      SolarisCentricProduct   1.0.0000.tim .tim  SolarisCentricProduct_1.0.0000.tim  \vob\SolarisCentricProduct
         * 11      LinuxCentricProduct     1.0.0000.tim .tim  LinuxCentricProduct_1.0.0000.tim    \vob\LinuxCentricProduct
         * 12      Win32CentricProduct     1.0.0000.tim .tim  Win32CentricProduct_1.0.0000.tim    \vob\Win32CentricProduct
         * 13      GenericProduct          1.0.0000.tim .tim  GenericProduct_1.0.0000.tim         \vob\ToBeMovedFromHere
         */
         Package p = new Package(8, "NotInAnyWayReproducible", "1.0.0.tim", ".tim", "NotInAnyWayReproducible.1.0.0.tim", "NA", "NA", 'x');
         packageCollection.add(p);
         p = new Package(10, "SolarisCentricProduct", "1.0.0000.tim", ".tim", "SolarisCentricProduct.1.0.0000.tim", "SolarisCentricProduct_1.0.0000.tim", "\\vob\\SolarisCentricProduct", 'x');
         packageCollection.add(p);
         p = new Package(11, "LinuxCentricProduct", "1.0.0000.tim", ".tim", "LinuxCentricProduct.1.0.0000.tim", "LinuxCentricProduct_1.0.0000.tim", "\\vob\\LinuxCentricProduct", 'x');
         packageCollection.add(p);
         p = new Package(12, "Win32CentricProduct", "1.0.0000.tim", ".tim", "Win32CentricProduct.1.0.0000.tim", "Win32CentricProduct_1.0.0000.tim", "\\vob\\Win32CentricProduct", 'x');
         packageCollection.add(p);
         p = new Package(13, "GenericProduct", "1.0.0000.tim", ".tim", "GenericProduct.1.0.0000.tim", "GenericProduct_1.0.0000.tim", "\\vob\\ToBeMovedFromHere", 'x');
         packageCollection.add(p);

        /* the above products have the following dependencies which will be discovered in traverseDependencies
         * pv_id   pkg_name, dpv.pkg_version, dpv.v_ext, dpv.pkg_label, dpv.src_path
         * 7     CotsWithFunnyVersion         hoopla2_x.cots   .cots CotsWithFunnyVersion_hoopla2_x.cots \vob\CotsWithFunnyVersion
         * 9     CommonDependency             1.0.0000.tim     .tim  CommonDependency_1.0.0000.tim       \vob\CommonDependency
         * 14    AdvisoryDependency           1.0.0000.tim     .tim  AdvisoryDependency_1.0.0000.tim     \vob\AdvisoryDependency
         * the above packages have the following build info
         * pv_id bm_name bsa_name
         * 7     Solaris Debug
         * 9     Linux   Debug
         * 9     Solaris Debug
         * 9     Win32   Production
         * 10    Solaris Java 1.4
         * 11    Linux   Production and Debug
         * 12    Win32   Java 1.6
         * 13    Generic Java 1.4
         * 14    Linux   Debug
         */
      }
    }
    else
    {
      try
      {
        if (daemonMode)
        {
          // get planned package info
          CallableStatement stmt1 = mConnection.prepareCall(
          "select pl.pv_id, p.pkg_id, p.pkg_name, pv.v_ext, pv.pkg_label, pv.src_path, pv.change_type " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.packages p " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id=pl.pv_id and p.pkg_id=pv.pkg_id " +
          "order by pl.pv_id"
          );
          ResultSet rset1 = stmt1.executeQuery();
           
          while( rset1.next() )
          {
            int pv_id = rset1.getInt("pv_id");
            
            if ( rset1.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset1 null pv_id");
              // show stopper
              throw new Exception();
            }
            
            int pkg_id = rset1.getInt("pkg_id");
            
            if ( rset1.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset1 null pkg_id " + pv_id);
              // show stopper
              throw new Exception();
            }

            String pkg_name = rset1.getString("pkg_name");
             
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset1 null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }

            String v_ext = rset1.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }

            String pkg_label = rset1.getString("pkg_label");
             
            if ( pkg_label == null )
            {
              pkg_label = "NA";
            }
            
            String src_path = rset1.getString("src_path");
             
            if ( src_path == null )
            {
              src_path = "NA";
            }

            String change_type = rset1.getString("change_type");
             
            if ( change_type == null )
            {
              change_type = "P";
            }

            char ct = 'x';
            
            if ( change_type.compareTo("M") == 0 )
            {
              ct = 'M';
            }
            else if ( change_type.compareTo("N") == 0 )
            {
              ct = 'N';
            }
            else if ( change_type.compareTo("P") == 0 )
            {
              ct = 'P';
            }
            
            if ( ct != 'x' )
            {
              Package p = new Package(pv_id, pkg_name, v_ext, pkg_name + v_ext, pkg_label, src_path, ct);
              p.mPid = pkg_id;
              p.mDirectlyPlanned = true;
              packageCollection.add(p);
            }
          }

          // get planned package dependency info
          CallableStatement stmt2 = mConnection.prepareCall(
          "select pl.pv_id, p.pkg_name, dpv.v_ext " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and pd.pv_id=pl.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id " +
          "order by pl.pv_id"
          );
          ResultSet rset2 = stmt2.executeQuery();
            
          while( rset2.next() )
          {
            boolean ignore = false;
            
            int pv_id = rset2.getInt("pv_id");
            
            if ( rset2.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset2 null pv_id");
              // show stopper
              throw new Exception();
            }
            
            Package p = findPackage(pv_id, packageCollection);
            
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset2 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
            
            String pkg_name = rset2.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset2 null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String v_ext = rset2.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }

            if ( !ignore )
            {
              p.mDependencyCollection.add(pkg_name + v_ext);
              p.mDependencyIDCollection.add(-1);
            }
          }
          
          // get planned package build info
          CallableStatement stmt3 = mConnection.prepareCall(
          "select pl.pv_id, bm.bm_name, bsa.bsa_name " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id " +
          "order by pl.pv_id"
          );
          ResultSet rset3 = stmt3.executeQuery();
             
          while( rset3.next() )
          {
            boolean ignore = false;
            int pv_id = rset3.getInt("pv_id");
            
            if ( rset3.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset3 null pv_id");
              // show stopper
              throw new Exception();
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset3 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
             
            String bm_name = rset3.getString("bm_name");
             
            if ( bm_name == null )
            {
              mLogger.fatal("queryPackageVersions rset3 null bm_name " + pv_id);
              // show stopper
              throw new Exception();
            }
             
            String bsa_name = rset3.getString("bsa_name");
             
            if ( bsa_name == null )
            {
              mLogger.fatal("queryPackageVersions rset3 null bsa_name " + pv_id);
              // show stopper
              throw new Exception();
            }

            if ( !ignore )
            {
              boolean supportedBuildStandard = true;
              BuildStandard bs = new BuildStandard(rippleEngine);

              if ( bm_name.compareTo("Solaris") == 0 )
              {
                bs.setSolaris();
              }
              else if ( bm_name.compareTo("Win32") == 0 )
              {
                bs.setWin32();
              }
              else if ( bm_name.compareTo("Linux") == 0 )
              {
                bs.setLinux();
              }
              else if ( bm_name.compareTo("Generic") == 0 )
              {
                bs.setGeneric();
              }
              else
              {
                supportedBuildStandard = false;
              }
               
              if ( bsa_name.compareTo("Production") == 0 )
              {
                bs.setProduction();
              }
              else if ( bsa_name.compareTo("Debug") == 0 )
              {
                bs.setDebug();
              }
              else if ( bsa_name.compareTo("Production and Debug") == 0 )
              {
                bs.setAll();
              }
              else if ( bsa_name.compareTo("Java 1.4") == 0 )
              {
                bs.set1_4();
              }
              else if ( bsa_name.compareTo("Java 1.5") == 0 )
              {
                bs.set1_5();
              }
              else if ( bsa_name.compareTo("Java 1.6") == 0 )
              {
                bs.set1_6();
              }
              else
              {
                supportedBuildStandard = false;
              }
               
              if ( supportedBuildStandard )
              {
                p.mBuildStandardCollection.add(bs);
              }
            }
          }

          // get planned package unit test info
          CallableStatement stmt4 = mConnection.prepareCall(
          "select pl.pv_id, tt.test_type_name " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk " +
          "order by pl.pv_id"
          );
          ResultSet rset4 = stmt4.executeQuery();
             
          while( rset4.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset4.getInt("pv_id");
             
            if ( rset4.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset4 null pv_id");
              // show stopper
              throw new Exception();
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset4 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
             
            String test_type_name = rset4.getString("test_type_name");
             
            if ( test_type_name == null )
            {
              mLogger.fatal("queryPackageVersions rset4 null test_type_name " + pv_id);
              // show stopper
              throw new Exception();
            }
             
            if ( !ignore )
            {
              if ( test_type_name.compareTo("Autobuild UTF") == 0 )
              {
                p.mHasAutomatedUnitTests = true;
              }
            }
          }

          // get planned package build failure info
          CallableStatement stmt5 = mConnection.prepareCall(
          "select pl.pv_id, u.user_email " +
          "from release_manager.planned pl, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.autobuild_failure af, release_manager.members_group mg, release_manager.users u " +
          "where pl.rtag_id=" + baseline + " and rt.rtag_id=pl.rtag_id and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and af.view_id=pl.view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id " +
          "order by pl.pv_id"
          );
          ResultSet rset5 = stmt5.executeQuery();
              
          while( rset5.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset5.getInt("pv_id");
             
            if ( rset5.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset5 null pv_id");
              // show stopper
              throw new Exception();
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset5 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
              
            String user_email = rset5.getString("user_email");
              
            if ( user_email == null )
            {
              // this can be null!
              ignore = true;
            }
              
            if ( !ignore )
            {
              p.mBuildFailureEmailCollection.add(user_email);
            }
          }

          // get planned package do not ripple info
          CallableStatement stmt6 = mConnection.prepareCall(
          "select pl.pv_id " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.do_not_ripple dnr " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and dnr.rtag_id=pl.rtag_id and dnr.pv_id=pl.pv_id " +
          "order by pl.pv_id"
          );
          ResultSet rset6 = stmt6.executeQuery();
               
          while( rset6.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset6.getInt("pv_id");
              
            if ( rset6.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset6 null pv_id");
              // show stopper
              throw new Exception();
            }
               
            Package p = findPackage(pv_id, packageCollection);
               
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset6 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
               
            if ( !ignore )
            {
              p.mDoNotRipple = true;
            }
          }

          // get planned package advisory ripple info
          CallableStatement stmt7 = mConnection.prepareCall(
          "select pl.pv_id " +
          "from release_manager.planned pl, release_manager.package_versions pv, release_manager.advisory_ripple ar " +
          "where pl.rtag_id=" + baseline + " and pv.build_type='A' and pv.dlocked='A' " +
          "and pv.pv_id = pl.pv_id and ar.rtag_id=pl.rtag_id and ar.pv_id=pl.pv_id " +
          "order by pl.pv_id"
          );
          ResultSet rset7 = stmt7.executeQuery();
               
          while( rset7.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset7.getInt("pv_id");
              
            if ( rset7.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset7 null pv_id");
              // show stopper
              throw new Exception();
            }
               
            Package p = findPackage(pv_id, packageCollection);
               
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset7 highly unlikely " + pv_id);
              // highly unlikely but package may have been added in between queries
              ignore = true;
            }
               
            if ( !ignore )
            {
              p.mAdvisoryRipple = true;
            }
          }
          
          // get released package info
          CallableStatement stmt8 = mConnection.prepareCall(
          "select rc.pv_id, p.pkg_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_label, pv.src_path, pv.ripple_field " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.packages p " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and p.pkg_id = pv.pkg_id " +
          "order by rc.pv_id"
          );
          ResultSet rset8 = stmt8.executeQuery();
          
          while( rset8.next() )
          {
            int pv_id = rset8.getInt("pv_id");
            
            if ( rset8.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset8 null pv_id");
              // show stopper
              throw new Exception();
            }
            
            int pkg_id = rset8.getInt("pkg_id");
            
            if ( rset8.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_id " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String pkg_name = rset8.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String pkg_version = rset8.getString("pkg_version");
            
            if ( pkg_version == null )
            {
              mLogger.fatal("queryPackageVersions rset8 null pkg_version " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String v_ext = rset8.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }
            
            String pkg_label = rset8.getString("pkg_label");
            
            if ( pkg_label == null )
            {
              pkg_label = "NA";
            }
            
            String src_path = rset8.getString("src_path");
            
            if ( src_path == null )
            {
              src_path = "NA";
            }
            
            String ripple_field = rset8.getString("ripple_field");
            
            if ( ripple_field == null )
            {
              ripple_field = "x";
            }
            else if ( ripple_field.length() == 0 )
            {
              ripple_field = "x";
            }
            
            Package p = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + v_ext, pkg_label, src_path, ripple_field.charAt(0));
            p.mPid = pkg_id;
            Integer ipv_id = new Integer(pv_id);
            rippleEngine.mReleasedPvIDCollection.add(ipv_id);
            Package plannedPackage = findPackage(p.mAlias, packageCollection);
            
            if ( plannedPackage == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset8 no planned package " + pv_id);
              packageCollection.add(p);
            }
            else
            {
              int endindex = pkg_version.length() - v_ext.length();
              
              if ( endindex > 0 )
              {
                pkg_version = pkg_version.substring(0, endindex);
              }

              plannedPackage.mVersion = pkg_version;
            }
          }

          // get released package dependency info
          CallableStatement stmt9 = mConnection.prepareCall(
          "select rc.pv_id, dpv.pv_id, p.pkg_name, dpv.v_ext " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id " +
          "order by rc.pv_id"
          );
          ResultSet rset9 = stmt9.executeQuery();
             
          while( rset9.next() )
          {
            boolean ignore = false;
             
            int pv_id = rset9.getInt(1);
             
            if ( rset9.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset9 null pv_id");
              // show stopper
              throw new Exception();
            }
             
            int dpv_id = rset9.getInt(2);
             
            if ( rset9.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset9 null dpv_id " + pv_id);
              // show stopper
              throw new Exception();
            }
             
            Package p = findPackage(pv_id, packageCollection);
             
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset9 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
             
            String pkg_name = rset9.getString("pkg_name");
             
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset9 null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }
             
            String v_ext = rset9.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }

            if ( !ignore )
            {
              p.mDependencyCollection.add(pkg_name + v_ext);
              p.mDependencyIDCollection.add(dpv_id);
            }
          }
           
          // get released package build info
          CallableStatement stmt10 = mConnection.prepareCall(
          "select rc.pv_id, bm.bm_name, bsa.bsa_name " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id " +
          "order by rc.pv_id"
          );
          ResultSet rset10 = stmt10.executeQuery();
              
          while( rset10.next() )
          {
            boolean ignore = false;
            int pv_id = rset10.getInt("pv_id");
             
            if ( rset10.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset10 null pv_id");
              // show stopper
              throw new Exception();
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset10 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
              
            String bm_name = rset10.getString("bm_name");
              
            if ( bm_name == null )
            {
              mLogger.fatal("queryPackageVersions rset10 null bm_name " + pv_id);
              // show stopper
              throw new Exception();
            }
              
            String bsa_name = rset10.getString("bsa_name");
              
            if ( bsa_name == null )
            {
              mLogger.fatal("queryPackageVersions rset10 null bsa_name " + pv_id);
              // show stopper
              throw new Exception();
            }

            if ( !ignore )
            {
              boolean supportedBuildStandard = true;
              BuildStandard bs = new BuildStandard(rippleEngine);

              if ( bm_name.compareTo("Solaris") == 0 )
              {
                bs.setSolaris();
              }
              else if ( bm_name.compareTo("Win32") == 0 )
              {
                bs.setWin32();
              }
              else if ( bm_name.compareTo("Linux") == 0 )
              {
                bs.setLinux();
              }
              else if ( bm_name.compareTo("Generic") == 0 )
              {
                bs.setGeneric();
              }
              else
              {
                supportedBuildStandard = false;
              }
                
              if ( bsa_name.compareTo("Production") == 0 )
              {
                bs.setProduction();
              }
              else if ( bsa_name.compareTo("Debug") == 0 )
              {
                bs.setDebug();
              }
              else if ( bsa_name.compareTo("Production and Debug") == 0 )
              {
                bs.setAll();
              }
              else if ( bsa_name.compareTo("Java 1.4") == 0 )
              {
                bs.set1_4();
              }
              else if ( bsa_name.compareTo("Java 1.5") == 0 )
              {
                bs.set1_5();
              }
              else if ( bsa_name.compareTo("Java 1.6") == 0 )
              {
                bs.set1_6();
              }
              else
              {
                supportedBuildStandard = false;
              }
                
              if ( supportedBuildStandard )
              {
                p.mBuildStandardCollection.add(bs);
              }
            }
          }

          // get released package unit test info
          CallableStatement stmt11 = mConnection.prepareCall(
          "select rc.pv_id, tt.test_type_name " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.unit_tests ut, release_manager.test_types tt " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and ut.pv_id=pv.pv_id and tt.test_type_id=ut.test_types_fk " +
          "order by rc.pv_id"
          );
          ResultSet rset11 = stmt11.executeQuery();
              
          while( rset11.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset11.getInt("pv_id");
              
            if ( rset11.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset11 null pv_id");
              // show stopper
              throw new Exception();
            }
              
            Package p = findPackage(pv_id, packageCollection);
              
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset11 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
              
            String test_type_name = rset11.getString("test_type_name");
              
            if ( test_type_name == null )
            {
              mLogger.fatal("queryPackageVersions rset11 null test_type_name " + pv_id);
              // show stopper
              throw new Exception();
            }
              
            if ( !ignore )
            {
              if ( test_type_name.compareTo("Autobuild UTF") == 0 )
              {
                p.mHasAutomatedUnitTests = true;
              }
            }
          }

          // get released package build failure email info
          CallableStatement stmt12 = mConnection.prepareCall(
          "select rc.pv_id, u.user_email " +
          "from release_manager.release_content rc, release_manager.release_tags rt, release_manager.package_versions pv, release_manager.autobuild_failure af, release_manager.members_group mg, release_manager.users u " +
          "where rc.rtag_id=" + baseline + " and rt.rtag_id=rc.rtag_id " +
          "and pv.pv_id = rc.pv_id and af.view_id=rc.base_view_id and mg.group_email_id=af.group_email_id and u.user_id=mg.user_id and af.proj_id=rt.proj_id " +
          "order by rc.pv_id"
          );
          ResultSet rset12 = stmt12.executeQuery();
               
          while( rset12.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset12.getInt("pv_id");
              
            if ( rset12.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset12 null pv_id");
              // show stopper
              throw new Exception();
            }
               
            Package p = findPackage(pv_id, packageCollection);
               
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset12 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
               
            String user_email = rset12.getString("user_email");
               
            if ( user_email == null )
            {
              // this can be null
              ignore = true;
            }
               
            if ( !ignore )
            {
              p.mBuildFailureEmailCollection.add(user_email);
            }
          }

          // get released package do not ripple info
          CallableStatement stmt13 = mConnection.prepareCall(
          "select rc.pv_id " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.do_not_ripple dnr " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and dnr.rtag_id=rc.rtag_id and dnr.pv_id=rc.pv_id " +
          "order by rc.pv_id"
          );
          ResultSet rset13 = stmt13.executeQuery();
                
          while( rset13.next() )
          {
            boolean ignore = false;
               
            int pv_id = rset13.getInt("pv_id");
               
            if ( rset13.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset13 null pv_id");
              // show stopper
              throw new Exception();
            }
                
            Package p = findPackage(pv_id, packageCollection);
                
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset13 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
                
            if ( !ignore )
            {
              p.mDoNotRipple = true;
            }
          }

          // get released advisory ripple info
          CallableStatement stmt14 = mConnection.prepareCall(
          "select rc.pv_id " +
          "from release_manager.release_content rc, release_manager.package_versions pv, release_manager.advisory_ripple ar " +
          "where rc.rtag_id=" + baseline +
          " and pv.pv_id = rc.pv_id and ar.rtag_id=rc.rtag_id and ar.pv_id=rc.pv_id " +
          "order by rc.pv_id"
          );
          ResultSet rset14 = stmt14.executeQuery();
                
          while( rset14.next() )
          {
            boolean ignore = false;
              
            int pv_id = rset14.getInt("pv_id");
               
            if ( rset14.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset14 null pv_id");
              // show stopper
              throw new Exception();
            }
                
            Package p = findPackage(pv_id, packageCollection);
                
            if ( p == NULL_PACKAGE )
            {
              mLogger.info("queryPackageVersions rset14 package may have been superceded by planned " + pv_id);
              ignore = true;
            }
                
            if ( !ignore )
            {
              p.mAdvisoryRipple = true;
            }
          }
        }
        else
        {
          // get released product info
          CallableStatement stmt = mConnection.prepareCall(
          "select oc.prod_id, p.pkg_name, pv.pkg_version, pv.v_ext, pv.pkg_label, pv.src_path " +
          "from bom_contents bc, operating_systems os, os_contents oc, release_manager.package_versions pv, release_manager.packages p " +
          "where bc.bom_id=" + baseline + " and os.node_id=bc.node_id and oc.os_id=os.os_id and pv.pv_id=oc.prod_id and p.pkg_id=pv.pkg_id " +
          "order by oc.prod_id"
          );
          ResultSet rset = stmt.executeQuery();
            
          while( rset.next() )
          {
            int pv_id = rset.getInt("prod_id");
              
            if ( rset.wasNull() )
            {
              mLogger.fatal("queryPackageVersions rset null prod_id");
              // show stopper
              throw new Exception();
            }
              
            String pkg_name = rset.getString("pkg_name");
              
            if ( pkg_name == null )
            {
              mLogger.fatal("queryPackageVersions rset null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }
              
            String pkg_version = rset.getString("pkg_version");
              
            if ( pkg_version == null )
            {
              mLogger.fatal("queryPackageVersions rset null pkg_version " + pv_id);
              // show stopper
              throw new Exception();
            }
              
            String v_ext = rset.getString("v_ext");
             
            if ( v_ext == null )
            {
              v_ext = "";
            }
              
            String pkg_label = rset.getString("pkg_label");
              
            if ( pkg_label == null )
            {
              pkg_label = "NA";
            }
              
            String src_path = rset.getString("src_path");
              
            if ( src_path == null )
            {
              src_path = "NA";
            }
              
            Package p = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + "." + pkg_version, pkg_label, src_path, 'x');
            packageCollection.add(p);
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryPackageVersions database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryPackageVersions show stopper");
          throw new Exception();
        }
      }
    }
    
    if (!daemonMode)
    {
      // use a ListIterator as it allows traverseDependencies to modify the packageCollection
      for (ListIterator it = packageCollection.listIterator(); it.hasNext(); )
      {
        Package p = (Package) it.next();
        traverseDependencies(packageCollection, p, false, it);
      }

      for (Iterator it = packageCollection.iterator(); it.hasNext(); )
      {
        Package p = (Package) it.next();
        queryBuildInfo(rippleEngine, p);
      }
    }

  }

  /**only used in daemon mode
   *   select config from build_service_config where service='MAIL SERVER';
   * returns the configured service
   */
  String queryMailServer() throws SQLException, Exception
  {
    mLogger.debug("queryMailServer");
    String retVal = new String();
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryMailServer !mUseDatabase");
      // a highly likely mail server
      retVal = "aupera03.aupera.erggroup.com";
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select config from release_manager.build_service_config where service='MAIL SERVER'");
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String config = rset.getString("config");
          
          if ( config != null )
          {
            retVal += config;
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMailServer database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMailServer show stopper");
          throw new Exception();
        }
      }
    }
    
    mLogger.info("queryMailServer returned " + retVal);
    return retVal;
  }

  /**only used in daemon mode
   *   select config from build_service_config where service='BUILD FAILURE MAIL SENDER';
   * returns the configured service
   */
  String queryMailSender() throws SQLException, Exception
  {
    mLogger.debug("queryMailSender");
    String retVal = new String();

    if ( !mUseDatabase )
    {
      mLogger.info("queryMailSender !mUseDatabase");
      // a highly likely mail sender
      retVal = "buildadm@erggroup.com";
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select config from release_manager.build_service_config where service='BUILD FAILURE MAIL SENDER'");
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          String config = rset.getString("config");
          
          if ( config != null )
          {
            retVal += config;
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryMailSender database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryMailSender show stopper");
          throw new Exception();
        }
      }
    }

    mLogger.debug("queryMailSender returned " + retVal);
    return retVal;
  }

  /**called only in escrow mode
   * if checkCollection is true, checks the pv_id is in the packageCollection
   * if checkCollection is false, or the pv_id is not in the collection
   * 1 traverses the pv_id package dependencies
   *   select dpv.pv_id, p.pkg_name, dpv.pkg_version, dpv.v_ext, dpv.pkg_label, dpv.src_path
   *   from release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p
   *   where pv.pv_id = <pv_id> and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id
   *   order by pv.pv_id;
   * 2 for each dpv.pv_id in the resultset
   *     call traverseDependencies( packageCollection, dpv.pv_id, true )
   *     if the pv_id is not in the collection, add it
   *   
   */
  private void traverseDependencies(Vector packageCollection, Package pkg, 
                                     boolean checkCollection, 
                                     ListIterator listIterator) throws SQLException, Exception
  {
    mLogger.debug("traverseDependencies " + checkCollection);
    boolean pvIdInCollection = false;
    
    if ( checkCollection )
    {
      for (Iterator it = packageCollection.iterator(); it.hasNext(); )
      {
        Package p = (Package) it.next();
        
        if ( p.mId == pkg.mId )
        {
          pvIdInCollection = true;
          break;
        }
      }
    }
    
    if ( !pvIdInCollection )
    {
      Vector resultset = new Vector();

      if ( !mUseDatabase )
      {
        mLogger.info("traverseDependencies !mUseDatabase");
        
        if ( pkg.mId == 8 || pkg.mId == 10 || pkg.mId == 13 )
        {
          Package p = new Package(9, "CommonDependency", "1.0.0000.tim", ".tim", "CommonDependency.1.0.0000.tim", "CommonDependency_1.0.0000.tim", "\\vob\\CommonDependency", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
        else if ( pkg.mId == 9 )
        {
          Package p = new Package(7, "CotsWithFunnyVersion", "hoopla2_x.cots", ".cots", "CotsWithFunnyVersion.hoopla2_x.cots", "CotsWithFunnyVersion_hoopla2_x.cots", "\\vob\\CotsWithFunnyVersion", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
        else if ( pkg.mId == 11 )
        {
          Package p = new Package(14, "AdvisoryDependency", "1.0.0000.tim", ".tim", "AdvisoryDependency.1.0.0000.tim", "AdvisoryDependency_1.0.0000.tim", "\\vob\\AdvisoryDependency", 'x');
          resultset.add(p);
          pkg.mDependencyCollection.add(p.mAlias);
        }
      }
      else
      {
        try
        {
          CallableStatement stmt = mConnection.prepareCall(
          "select dpv.pv_id, p.pkg_name, dpv.pkg_version, dpv.v_ext, dpv.pkg_label, dpv.src_path " +
          "from release_manager.package_versions pv, release_manager.package_dependencies pd, release_manager.package_versions dpv, release_manager.packages p " +
          "where pv.pv_id=" + pkg.mId + " and pd.pv_id=pv.pv_id and dpv.pv_id=pd.dpv_id and p.pkg_id=dpv.pkg_id " +
          "order by pv.pv_id"
          );
          ResultSet rset = stmt.executeQuery();
          
          while( rset.next() )
          {
            int pv_id = rset.getInt("pv_id");
            
            if ( rset.wasNull() )
            {
              mLogger.fatal("traverseDependencies null pv_id");
              // show stopper
              throw new Exception();
            }
            
            String pkg_name = rset.getString("pkg_name");
            
            if ( pkg_name == null )
            {
              mLogger.fatal("traverseDependencies null pkg_name " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String pkg_version = rset.getString("pkg_version");
            
            if ( pkg_version == null )
            {
              mLogger.fatal("traverseDependencies null pkg_version " + pv_id);
              // show stopper
              throw new Exception();
            }
            
            String v_ext = rset.getString("v_ext");
            
            if ( v_ext == null )
            {
              v_ext = "";
            }
            
            String pkg_label = rset.getString("pkg_label");
            
            if ( pkg_label == null )
            {
              pkg_label = "NA";
            }
            
            String src_path = rset.getString("src_path");
            
            if ( src_path == null )
            {
              src_path = "NA";
            }
            
            Package p = new Package(pv_id, pkg_name, pkg_version, v_ext, pkg_name + "." + pkg_version, pkg_label, src_path, 'x');
            resultset.add(p);
            pkg.mDependencyCollection.add(p.mAlias);
          }
        }
        catch ( SQLException e )
        {
          if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
          {
            mLogger.fatal("traverseDependencies database access error only");
            throw new SQLException();
          }
          else
          {
            mLogger.fatal("traverseDependencies show stopper");
            throw new Exception();
          }
        }
      }
      
      for (Iterator it = resultset.iterator(); it.hasNext(); )
      {
        Package r = (Package) it.next();
        traverseDependencies(packageCollection, r, true, listIterator);
        
        pvIdInCollection = false;
        
        for (Iterator it2 = packageCollection.iterator(); it2.hasNext(); )
        {
          Package p = (Package) it2.next();
          
          if ( p.mId == r.mId )
          {
            pvIdInCollection = true;
            break;
          }
        }
        
        if (!pvIdInCollection)
        {
          // insert the Package immediately before the next Package returned by next
          // this does not change the next Package (if any) to be returned by next
          listIterator.add(r);
        }
       
      }
    }
  }

  /**returns the Package with the matching mID or NULL_PACKAGE if no package has the mID
   */
  private Package findPackage(int id, Vector packageCollection)
  {
    mLogger.debug("findPackage 1 id " + id);
    Package retVal = NULL_PACKAGE;

    for (Iterator it = packageCollection.iterator(); it.hasNext(); )
    {
      Package p = (Package) it.next();
      
      if ( p.mId == id )
      {
        retVal = p;
        break;
      }
    }
    
    mLogger.debug("findPackage 1 returned " + retVal.mName);
    return retVal;
  }

  /**called only in escrow mode to add build info to the Package
   * select bm.bm_name, bsa.bsa_name
   * from release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa
   * where pv.pv_id = <p.pv_id> and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id
   * order by pv.pv_id;
   */
  private void queryBuildInfo(RippleEngine rippleEngine, Package p) throws SQLException, Exception
  {
    mLogger.debug("queryBuildInfo");
    if ( !mUseDatabase )
    {
      mLogger.info("queryBuildInfo !mUseDatabase");
      
      if (p.mId == 7)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 9)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
        bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
        bs = new BuildStandard(rippleEngine);
        bs.setWin32();
        bs.setProduction();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 10)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setSolaris();
        bs.set1_4();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 11)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setAll();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 12)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setWin32();
        bs.set1_6();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 13)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setGeneric();
        bs.set1_4();
        p.mBuildStandardCollection.add(bs);
      }
      else if (p.mId == 14)
      {
        BuildStandard bs = new BuildStandard(rippleEngine);
        bs.setLinux();
        bs.setDebug();
        p.mBuildStandardCollection.add(bs);
      }
      
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall(
        "select bm.bm_name, bsa.bsa_name " +
        "from release_manager.package_versions pv, release_manager.package_build_info pbi, release_manager.build_machines bm, release_manager.build_standards_addendum bsa " +
        "where pv.pv_id=" + p.mId + " and pbi.pv_id=pv.pv_id and bm.bm_id=pbi.bm_id and bsa.bsa_id=pbi.bsa_id " +
        "order by pv.pv_id"
        );
        ResultSet rset = stmt.executeQuery();
         
        while( rset.next() )
        {
          boolean supportedBuildStandard = true;
          BuildStandard bs = new BuildStandard(rippleEngine);
          String bm_name = rset.getString("bm_name");
          
          if ( bm_name == null )
          {
            mLogger.fatal("queryBuildInfo null bm_name " + p.mId);
            // show stopper
            throw new Exception();
          }
          else if ( bm_name.compareTo("Solaris") == 0 )
          {
            bs.setSolaris();
          }
          else if ( bm_name.compareTo("Win32") == 0 )
          {
            bs.setWin32();
          }
          else if ( bm_name.compareTo("Linux") == 0 )
          {
            bs.setLinux();
          }
          else if ( bm_name.compareTo("Generic") == 0 )
          {
            bs.setGeneric();
          }
          else
          {
            supportedBuildStandard = false;
          }
           
          String bsa_name = rset.getString("bsa_name");
           
          if ( bsa_name == null )
          {
            mLogger.fatal("queryBuildInfo null bsa_name " + p.mId);
            // show stopper
            throw new Exception();
          }
          else if ( bsa_name.compareTo("Production") == 0 )
          {
            bs.setProduction();
          }
          else if ( bsa_name.compareTo("Debug") == 0 )
          {
            bs.setDebug();
          }
          else if ( bsa_name.compareTo("Production and Debug") == 0 )
          {
            bs.setAll();
          }
          else if ( bsa_name.compareTo("Java 1.4") == 0 )
          {
            bs.set1_4();
          }
          else if ( bsa_name.compareTo("Java 1.5") == 0 )
          {
            bs.set1_5();
          }
          else if ( bsa_name.compareTo("Java 1.6") == 0 )
          {
            bs.set1_6();
          }
          else
          {
            supportedBuildStandard = false;
          }
           
          if ( supportedBuildStandard )
          {
            p.mBuildStandardCollection.add(bs);
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryBuildInfo database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryBuildInfo show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**returns the Package with the matching mAlias or NULL_PACKAGE if no package has the mAlias
   */
  private Package findPackage(String alias, Vector packageCollection)
  {
    mLogger.debug("findPackage 2 alias " + alias);
    Package retVal = NULL_PACKAGE;

    for (Iterator it = packageCollection.iterator(); it.hasNext(); )
    {
      Package p = (Package) it.next();
      
      if ( p.mAlias.compareTo( alias ) == 0 )
      {
        retVal = p;
        break;
      }
    }
    
    mLogger.info("findPackage 2 returned " + retVal.mName);
    return retVal;
  }

  /**essentially locks the row in the BUILD_SERVICE_CONFIG table with a service of MUTEX
   * for the duration of the connection
   * this prevents other MasterThreads from generating build files in parallel
   * and hence prevents planned version numbering contention
   * select CONFIG from BUILD_SERVICE_CONFIG WHERE SERVICE='MUTEX' FOR UPDATE
   */
  public void claimMutex() throws SQLException, Exception
  {
    mLogger.debug("claimMutex");
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select CONFIG from release_manager.BUILD_SERVICE_CONFIG WHERE SERVICE='MUTEX' FOR UPDATE");
        stmt.executeUpdate();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("claimMutex database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("claimMutex show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**sets CURRENT_BUILD_FILES to NULL for the rcon_id
   * update run_level set current_build_files=null where rcon_id=<rcon_id>
   * returns true if successful
   */
  public boolean clearBuildFile(int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("clearBuildFile");
    boolean retVal = false;

    try
    {
      connect();
      CallableStatement stmt = mConnection.prepareCall("update release_manager.run_level set current_build_files=null where rcon_id=" + rcon_id);
      stmt.executeUpdate();
      mConnection.commit();
      disconnect();
      retVal = true;
    }
    catch ( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("clearBuildFile database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("clearBuildFile show stopper");
        throw new Exception();
      }
    }
         
    mLogger.info("clearBuildFile returned " + retVal);
    return retVal;
  }

  /**updates the CURRENT_BUILD_FILES for the rtag_id
   * update (
   * select current_build_files from run_level rl, release_config rc
   * where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id
   * ) set current_build_files=<buildFile>
   * returns true if successful
   */
  public boolean publishBuildFile(int rtag_id, String buildFile) throws SQLException, Exception
  {
    mLogger.debug("publishBuildFile publishing a build file of length " + buildFile.length());
    boolean retVal = false;
    
    try
    {
      connect();
      
      PreparedStatement stmt = mConnection.prepareStatement(
      "update (" +
      "select current_build_files from release_manager.run_level rl, release_manager.release_config rc " +
      "where rc.rtag_id=? and rl.rcon_id=rc.rcon_id" +
      ") set current_build_files=?");
      stmt.setInt(1, rtag_id);
      stmt.setString(2, buildFile);
      stmt.executeUpdate();
      mConnection.commit();
      disconnect();
      retVal = true;
    }
    catch ( SQLException e )
    {
      if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
      {
        mLogger.error("publishBuildFile database access error only");
        throw new SQLException();
      }
      else
      {
        mLogger.fatal("publishBuildFile show stopper");
        throw new Exception();
      }
    }
    catch ( Exception e )
    {
      // this catch and rethrow is historical
      // problems were found using CallableStatement when updating a CLOB column with data > 4000 bytes
      mLogger.fatal("publishBuildFile caught Exception " + e.getMessage());
      throw new Exception();
    }
    mLogger.info("publishBuildFile returned " + retVal);
    return retVal;
  }

  /**ensures a run_level_schedule row with a non null indefinite_pause column exists
   * this is aimed at stopping all daemons dead
   * it is raised when handling an unsupported exception case in either the main or slave daemons
   * typically an SQLException other than a database connection related one
   */
  public void indefinitePause() throws SQLException, Exception
  {
    mLogger.debug("indefinitePause");
    if ( mUseDatabase )
    {
      connect();
      CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_BUILDAPI.SET_INFINITE_PAUSE(); end;" );
      stmt.executeUpdate();
      mConnection.commit();
      disconnect();
    }
  }

  /**only used in daemon mode to determine version existence in the database
   *  1 select pkg_id from package_versions where pkg_id=<pkg_id> and pkg_version=<pkg_version>;
   *  2 select pkg_id from planned_versions where pkg_id=<pkg_id> and pkg_version=<pkg_version>;
   * returns true if either resultset contains one record to indicate it already exists
   */
  boolean queryPackageVersions(int pkg_id, String pkg_version) throws SQLException, Exception
  {
    mLogger.debug("queryPackageVersions");
    boolean retVal = false;
    
    if ( mUseDatabase )
    {
      try
      {
        mLogger.info("queryPackageVersions release_manager.package_versions");
        CallableStatement stmt1 = mConnection.prepareCall("select pkg_id from release_manager.package_versions where pkg_id=" + pkg_id + " and pkg_version='" + pkg_version + "'");
        ResultSet rset1 = stmt1.executeQuery();
        int rsetSize = 0;
        
        while( rset1.next() )
        {
          rsetSize++;
        }

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
          // show stopper
          throw new Exception();
        }
        
        if ( rsetSize == 1 )
        {
          retVal = true;
        }
        else
        {
          mLogger.info("queryPackageVersions release_manager.planned_versions");
          CallableStatement stmt2 = mConnection.prepareCall("select pkg_id from release_manager.planned_versions where pkg_id=" + pkg_id + " and pkg_version='" + pkg_version + "'");
          ResultSet rset2 = stmt2.executeQuery();
          rsetSize = 0;
          
          while( rset2.next() )
          {
            rsetSize++;
          }

          if ( rsetSize > 1 )
          {
            mLogger.fatal("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
            // show stopper
            throw new Exception();
          }
          
          if ( rsetSize == 1 )
          {
            retVal = true;
          }
          else
          {
            mLogger.info("queryPackageVersions archive_manager.package_versions");
            CallableStatement stmt3 = mConnection.prepareCall("select pkg_id from archive_manager.package_versions where pkg_id=" + pkg_id + " and pkg_version='" + pkg_version + "'");
            ResultSet rset3 = stmt3.executeQuery();
            rsetSize = 0;
            
            while( rset3.next() )
            {
              rsetSize++;
            }

            if ( rsetSize > 1 )
            {
              mLogger.fatal("queryPackageVersions rsetSize > 1 " + pkg_id + " " + pkg_version);
              // show stopper
              throw new Exception();
            }
            
            if ( rsetSize == 1 )
            {
              retVal = true;
            }
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryPackageVersions database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryPackageVersions show stopper");
          throw new Exception();
        }
      }
    }
    
    mLogger.info("queryPackageVersions returned " + retVal);
    return retVal;
  }

  /**only used in daemon mode
   *  insert into planned_versions (pkg_id, pkg_version) values (<pkg_id>, <pkg_version>);
   *  update
   *  (
   *  select current_pkg_id_being_built from run_level rl, release_config rc
   *  where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id
   *  )
   *  set current_pkg_id_being_built=<pkg_id>
   */
  void claimVersion(int pkg_id, String pkg_version, int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("claimVersion " + pkg_id + " " + pkg_version);
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt3 = mConnection.prepareCall("insert into release_manager.planned_versions (pkg_id, pkg_version) values (" + pkg_id + ", '" + pkg_version + "')");
        stmt3.executeUpdate();
        CallableStatement stmt4 = mConnection.prepareCall(
        "update " +
        "(" +
        "select current_pkg_id_being_built from release_manager.run_level rl, release_manager.release_config rc " +
        "where rc.rtag_id=" + rtag_id + " and rl.rcon_id=rc.rcon_id" +
        ")" +
        "set current_pkg_id_being_built=" + pkg_id);
        stmt4.executeUpdate();
        mConnection.commit();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("claimVersion database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("claimVersion show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**handles database connection/disconnection
   * executes the AutoMakeRelease stored procedure with the passed parameters
   */
  public void autoMakeRelease(String rtagId, String packageName, 
                              String packageExtension, 
                              String packageVersion, String packageLabel, 
                              String packageDepends, String isRipple) throws SQLException, Exception
  {
    mLogger.debug("autoMakeRelease " + packageName);
    if ( mUseDatabase )
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_RMAPI.AUTO_MAKE_RELEASE(?,?,?,?,?,?,?,?); end;" );
        stmt.registerOutParameter( 1, Types.INTEGER);
        stmt.setString( 2, rtagId );
        stmt.setString( 3, packageName );
        stmt.setString( 4, packageExtension );
        stmt.setString( 5, packageVersion );
        stmt.setString( 6, packageLabel );
        stmt.setString( 7, packageDepends );
        stmt.setString( 8, isRipple );
        stmt.setString( 9, "buildadm" );
        stmt.executeUpdate();
        int result = stmt.getInt( 1 );
        
        if ( result <= 0 && result != -2 )
        {
          // -2 if already released
          // flag build failure
          mLogger.fatal("autoMakeRelease show stopper PK_RMAPI.AUTO_MAKE_RELEASE failed, returned" + result);
          throw new Exception();
        }
        mConnection.commit();
        disconnect();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("autoMakeRelease database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("autoMakeRelease show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**handles database connection/disconnection
   * executes the ExcludeFromBuild stored procedure with the passed parameters
   */
  public void excludeFromBuild(String packageVersionId, 
                               String packageVersion, String rtagId) throws SQLException, Exception
  {
    mLogger.debug("excludeFromBuild " + packageVersionId);
    if ( mUseDatabase )
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall( "begin ? := PK_RMAPI.EXCLUDE_FROM_BUILD(?,?,?,?); end;" );
        stmt.registerOutParameter( 1, Types.INTEGER);
        stmt.setString( 2, packageVersionId );
        stmt.setString( 3, packageVersion );
        stmt.setString( 4, rtagId );
        stmt.setString( 5, "buildadm" );
        stmt.executeUpdate();
        int result = stmt.getInt( 1 );
      
        if ( result != 0 )
        {
          // flag build failure
          mLogger.fatal( "excludeFromBuild show stopper PK_RMAPI.EXCLUDE_FROM_BUILD failed, returned " + result );
          throw new Exception();
        }
        mConnection.commit();
        disconnect();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("excludeFromBuild database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("excludeFromBuild show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**Representation of a row in the RELEASE_CONFIG table
   */
  private class ReleaseConfig
  {
    /**rtag_id column value
     * @attribute
     */
    private int mRtag_id;

    /**rcon_id column value
     * @attribute
     */
    private int mRcon_id;

    /**daemon_mode column value
     * @attribute
     */
    private char mDaemon_mode;

    /**gbebuildfilter column value
     * @attribute
     */
    private String mGbebuildfilter;

    /**constructor
     */
    ReleaseConfig(int rtag_id, int rcon_id, char daemon_mode, 
                  String gbebuildfilter)
    {
      mLogger.debug("ReleaseConfig rtag_id " + rtag_id + " rcon_id " + rcon_id + " daemon_mode " + daemon_mode + " gbebuildfilter " + gbebuildfilter );
      mRtag_id = rtag_id;
      mRcon_id = rcon_id;
      mDaemon_mode = daemon_mode;
      mGbebuildfilter = gbebuildfilter;
    }

    /**accessor method
     */
    int get_rtag_id()
    {
      mLogger.debug("get_rtag_id");
      mLogger.info("get_rtag_id returned " + mRtag_id);
      return mRtag_id;
    }

    /**accessor method
     */
    int get_rcon_id()
    {
      mLogger.debug("get_rcon_id");
      mLogger.info("get_rcon_id returned " + mRcon_id);
      return mRcon_id;
    }

    /**accessor method
     */
    char get_daemon_mode()
    {
      mLogger.debug("get_daemon_mode");
      mLogger.info("get_daemon_mode returned " + mDaemon_mode);
      return mDaemon_mode;
    }

    /**accessor method
     */
    String get_gbebuildfilter()
    {
      mLogger.debug("get_gbebuildfilter");
      mLogger.info("get_gbebuildfilter returned " + mGbebuildfilter);
      return mGbebuildfilter;
    }
  }

  /**Representation of a row in the RUN_LEVEL table
   */
  private class RunLevel
  {
    /**rcon_id column value
     * @attribute
     */
    private int mRcon_id;

    /**current_build_files column value
     * @attribute
     */
    private String mCurrent_build_file;

    /**current_run_level column value
     * @attribute
     */
    private int mCurrent_run_level;

    /**pause column value
     * @attribute
     */
    private boolean mPause;

    /**constructor
     */
    RunLevel(int rcon_id, String current_build_file, int current_run_level, 
             boolean pause)
    {
      mLogger.debug("RunLevel");
      mRcon_id = rcon_id;
      mCurrent_build_file = current_build_file;
      mCurrent_run_level = current_run_level;
      mPause = pause;
    }

    /**accessor method
     */
    int get_rcon_id()
    {
      mLogger.debug("get_rcon_id");
      mLogger.info("get_rcon_id returned " + mRcon_id);
      return mRcon_id;
    }

    /**accessor method
     */
    String get_current_build_file()
    {
      mLogger.debug("get_current_build_file");
      mLogger.info("get_current_build_file returned " + mCurrent_build_file);
      return mCurrent_build_file;
    }

    /**accessor method
     */
    int get_current_run_level()
    {
      mLogger.debug("get_current_run_level");
      mLogger.info("get_current_run_level returned " + mCurrent_run_level);
      return mCurrent_run_level;
    }

    /**accessor method
     */
    boolean get_pause()
    {
      mLogger.debug("get_pause");
      mLogger.debug("get_pause returned " + mPause);      
      return mPause;
    }

  }

  /**constructor
   */
  public ReleaseManager(final String connectionString, final String username, 
                        final String password)
  {
    mLogger.debug("ReleaseManager " + connectionString);
    mConnectionString = connectionString;
    mUsername = username;
    mPassword = password;
  }

  /**constructor used when schema information is unknown eg location, username, password
   */
  public ReleaseManager()
  {
    // inherit mConnectionString, mUsername, mPassword
     mLogger.debug("ReleaseManager");
  }

  /**connect to oracle
   */
  public void connect() throws SQLException, Exception
  {
    mLogger.debug("connect");
    
    if ( !mUseDatabase )
    {
      mLogger.info("connect !mUseDatabase");
    }
    else
    {
      if ( !mRegistered )
      {
        try
        {
          // the JDBC driver is registered only once per database that needs to be accessed
          mLogger.debug("connect registering driver");
          DriverManager.registerDriver( new OracleDriver() );
          mRegistered = true;
        }
        catch(SQLException e)
        {
          mLogger.fatal("connect failed to register the oracle jdbc driver with the driver manager");
          throw new Exception();
        }
      }

      // let connect throw SQLException to indicate a database access error
      try
      {
        mConnection = DriverManager.getConnection(mConnectionString, mUsername, mPassword);
      }
      catch(SQLException e)
      {
        mLogger.error("connect getConnection failed");
        mConnection = null;
        throw new SQLException();
      }
    }
  }

  /**disconnect from oracle
   */
  public void disconnect()
  {
    mLogger.debug("disconnect");
    if ( mUseDatabase )
    {
      try
      {
        mConnection.close();
      }
      catch(SQLException e)
      {
        // special case do nothing
        mLogger.error("disconnect caught Exception");
      }
    }
  }

  /**returns true if the mReleaseConfigCollection is not empty and returns the rcon_id of the first element
   */
  public boolean getFirstReleaseConfig(MutableInt rcon_id)
  {
    mLogger.debug("getFirstReleaseConfig 1");
    boolean retVal = true;
    
    try
    {
      mReleaseConfigIndex = 0;
      ReleaseConfig rc = (ReleaseConfig)mReleaseConfigCollection.get( mReleaseConfigIndex );
      rcon_id.value = rc.get_rcon_id();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getFirstReleaseConfig 1 returning " + retVal);
    return retVal;
  }

  /**returns true if the mReleaseConfigCollection is not empty and returns the rcon_id, rtag_id, daemon_mode and gbebuildfilter of the first element
   */
  public boolean getFirstReleaseConfig(MutableInt rtag_id, 
                                       MutableInt rcon_id, 
                                       MutableChar daemon_mode, 
                                       MutableString gbebuildfilter)
  {
    mLogger.debug("getFirstReleaseConfig 2");
    boolean retVal = true;
    
    try
    {
      mReleaseConfigIndex = 0;
      ReleaseConfig rc = (ReleaseConfig)mReleaseConfigCollection.get( mReleaseConfigIndex );
      rtag_id.value = rc.get_rtag_id();
      rcon_id.value = rc.get_rcon_id();
      daemon_mode.value = rc.get_daemon_mode();
      gbebuildfilter.value = rc.get_gbebuildfilter();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getFirstReleaseConfig 2 returning " + retVal);
    return retVal;
  }

  /**returns true if the mRunLevelCollection is not empty and returns the rcon_id and current_run_level of the first element
   */
  public boolean getFirstRunLevel(MutableInt rcon_id, 
                                  MutableInt current_run_level)
  {
    mLogger.debug("getFirstRunLevel");
    boolean retVal = true;
    
    try
    {
      mRunLevelIndex = 0;
      RunLevel rl = (RunLevel)mRunLevelCollection.get( mRunLevelIndex );
      rcon_id.value = rl.get_rcon_id();
      current_run_level.value = rl.get_current_run_level();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getFirstRunLevel returning " + retVal);
    return retVal;
  }

  /**returns true if the mReleaseConfigCollection contains a next element and returns the rcon_id of the next element
   */
  public boolean getNextReleaseConfig(MutableInt rcon_id)
  {
    mLogger.debug("getNextReleaseConfig 1");
    boolean retVal = true;
    
    try
    {
      mReleaseConfigIndex++;
      ReleaseConfig rc = (ReleaseConfig)mReleaseConfigCollection.get( mReleaseConfigIndex );
      rcon_id.value = rc.get_rcon_id();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getNextReleaseConfig 1 returning " + retVal);
    return retVal;
  }

  /**returns true if the mReleaseConfigCollection contains a next element and returns the rcon_id, rtag_id, daemon_mode and gbebuildfilter of the next element
   */
  public boolean getNextReleaseConfig(MutableInt rtag_id, 
                                      MutableInt rcon_id, 
                                      MutableChar daemon_mode, 
                                      MutableString gbebuildfilter)
  {
    mLogger.debug("getNextReleaseConfig 2");
    boolean retVal = true;
    
    try
    {
      mReleaseConfigIndex++;
      ReleaseConfig rc = (ReleaseConfig)mReleaseConfigCollection.get( mReleaseConfigIndex );
      rtag_id.value = rc.get_rtag_id();
      rcon_id.value = rc.get_rcon_id();
      daemon_mode.value = rc.get_daemon_mode();
      gbebuildfilter.value = rc.get_gbebuildfilter();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getNextReleaseConfig 2 returning " + retVal);
    return retVal;
  }

  /**returns true if the mRunLevelCollection contains a next element and returns the rcon_id and current_run_level of the next element
   */
  public boolean getNextRunLevel(MutableInt rcon_id, 
                                 MutableInt current_run_level)
  {
    mLogger.debug("getNextRunLevel");
    boolean retVal = true;
    
    try
    {
      mRunLevelIndex++;
      RunLevel rl = (RunLevel)mRunLevelCollection.get( mRunLevelIndex );
      rcon_id.value = rl.get_rcon_id();
      current_run_level.value = rl.get_current_run_level();
    }
    catch( ArrayIndexOutOfBoundsException e )
    {
      retVal = false;
    }
    
    mLogger.info("getNextRunLevel returning " + retVal);
    return retVal;
  }

  /**queries the RUN_LEVEL table using the rcon_id primary key
   * returns false if the query returns a result set containing one row with a non NULL pause column
   * (indicating intent to pause the thread)
   * refer to sequence diagram allowed to proceed
   */
  public boolean queryDirectedRunLevel(final int rcon_id) throws SQLException, Exception
  {
    mLogger.debug("queryDirectedRunLevel " + rcon_id);
    boolean retVal = true;
    
    if ( mUseDatabase )
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select pause from release_manager.run_level where rcon_id=" + rcon_id);
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        
        while( rset.next() )
        {
          rsetSize++;
          rset.getInt("pause");
          
          if ( !rset.wasNull() )
          {
            retVal = false;
          }
        }

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryDirectedRunLevel rsetSize > 1");
          // show stopper
          throw new Exception();
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryDirectedRunLevel database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryDirectedRunLevel show stopper");
          throw new Exception();
        }
      }
    }
   
    mLogger.info("queryDirectedRunLevel returning " + retVal);
    return retVal;
  }

  /**queries the RELEASE_CONFIG table using the rcon_id primary key, rtag_id, daemon_hostname, daemon_mode, gbebuildfilter
   * return true if the query contains a result set containing one row
   * (indicating the rcon_id is still configured and its configuration is unchanged)
   * refer to sequence diagram allowed to proceed
   */
  public boolean queryReleaseConfig(final int rtag_id, final int rcon_id, 
                                    final String daemon_hostname, 
                                    final char daemon_mode, 
                                    final String gbebuildfilter) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 1");
    boolean retVal = false;
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryReleaseConfig 1 !mUseDatabase");
      
      if ( mConnectionString.compareTo("unit test exit") != 0 )
      {
        retVal = true;
      }
    }
    else
    {
      try
      {
        String sql = new String("select gbe_buildfilter from release_manager.release_config where rtag_id=" + rtag_id + " and rcon_id=" + rcon_id + " and daemon_hostname='" + daemon_hostname + "' and daemon_mode='" + daemon_mode + "'" );
        CallableStatement stmt = mConnection.prepareCall( sql );
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        
        while( rset.next() )
        {
          rsetSize++;
          String gbe_buildfilter = rset.getString("gbe_buildfilter");
          
          if ( gbe_buildfilter == null )
          {
            mLogger.info("queryReleaseConfig 1 gbe_buildfilter == null");
            if ( gbebuildfilter.length() == 0 )
            {
              retVal = true;
            }
          }
          else
          {
            if ( gbebuildfilter.compareTo( gbe_buildfilter ) == 0 )
            {
              retVal = true;
            }
          }
        }

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryReleaseConfig 1 rsetSize > 1");
          // show stopper
          throw new Exception();
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 1 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 1 show stopper");
          throw new Exception();
        }
      }
    }
    
    mLogger.info("queryReleaseConfig 1 returning " + retVal);
    return retVal;
  }

  /**removes all elements from the mReleaseConfigCollection
   * handles database connection and disconnection
   * queries the RELEASE_CONFIG table using the rtag_id
   * populates the mReleaseConfigCollection with the query result set
   * partially implements the sequence diagrams coordinate slave threads generate build files
   */
  public void queryReleaseConfig(final int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 2");
    mReleaseConfigCollection.removeAllElements();
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryReleaseConfig 2 !mUseDatabase");
      ReleaseConfig releaseConfig = new ReleaseConfig(1,1,'M',"unittestbuildfilter");
      mReleaseConfigCollection.add(releaseConfig);
      releaseConfig = new ReleaseConfig(1,2,'S',"anotherunittestbuildfilter");
      mReleaseConfigCollection.add(releaseConfig);
    }
    else
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall("select rcon_id, daemon_mode, gbe_buildfilter from release_manager.release_config where rtag_id=" + rtag_id );
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          int rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 2 null rcon_id " + rtag_id);
            // show stopper
            throw new Exception();
          }

          char dm = 'S';          
          String daemon_mode = rset.getString("daemon_mode");
          
          if ( daemon_mode != null )
          {
            mLogger.info("queryReleaseConfig 2 daemon_mode " + daemon_mode + ".");
            
            if ( daemon_mode.compareTo("M") == 0 )
            {
              dm = 'M';
            }
          }
          
          String gbe_buildfilter = rset.getString("gbe_buildfilter");
          
          if ( gbe_buildfilter == null )
          {
            gbe_buildfilter = new String("");
          }
          
          ReleaseConfig releaseConfig = new ReleaseConfig( rtag_id, rcon_id, dm, gbe_buildfilter );
          mReleaseConfigCollection.add(releaseConfig);
        }
        
        disconnect();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 2 daemon_mode database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 2 show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**removes all elements from the mReleaseConfigCollection
   * handles database connection and disconnection
   * queries the RELEASE_CONFIG table using the daemon_hostname
   * populates the mReleaseConfigCollection with the query result set
   * partially implements the sequence diagram spawn thread
   */
  public void queryReleaseConfig(final String hostname) throws SQLException, Exception
  {
    mLogger.debug("queryReleaseConfig 3 " + hostname);
    mReleaseConfigCollection.removeAllElements();
    
    if ( mConnectionString.compareTo("unit test spawn thread") == 0)
    {
      mLogger.info("queryReleaseConfig 3 unit test spawn thread");
      // specifying a gbebuildfilter of unit test is designed to invoke a benign thread for unit test purposes
      ReleaseConfig releaseConfig = new ReleaseConfig(1,1,'M',"unit test spawn thread");
      mReleaseConfigCollection.add(releaseConfig);
      releaseConfig = new ReleaseConfig(2,2,'S',"unit test spawn thread");
      mReleaseConfigCollection.add(releaseConfig);
    }
    else
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall("select rtag_id, rcon_id, daemon_mode, gbe_buildfilter from release_manager.release_config where daemon_hostname='" + hostname + "'" );
        ResultSet rset = stmt.executeQuery();
        
        while( rset.next() )
        {
          int rtag_id = rset.getInt("rtag_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 3 null rtag_id");
            // show stopper
            throw new Exception();
          }

          int rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryReleaseConfig 3 null rcon_id");
            // show stopper
            throw new Exception();
          }

          char dm = 'S';          
          String daemon_mode = rset.getString("daemon_mode");
          
          if ( daemon_mode != null )
          {
            mLogger.info("queryReleaseConfig 3 daemon_mode " + daemon_mode + ".");
          
            if ( daemon_mode.compareTo("M") == 0 )
            {
              dm = 'M';
            }
          }
          
          String gbe_buildfilter = rset.getString("gbe_buildfilter");
          
          if ( gbe_buildfilter == null )
          {
            gbe_buildfilter = new String("");
          }
          
          ReleaseConfig releaseConfig = new ReleaseConfig( rtag_id, rcon_id, dm, gbe_buildfilter );
          mReleaseConfigCollection.add(releaseConfig);
        }
        
        disconnect();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryReleaseConfig 3 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryReleaseConfig 3 show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**queries the RUN_LEVEL table using the rcon_id primary key
   * handles database connection and disconnection
   * polls indefinitely until CURRENT_BUILD_FILES column is non NULL
   * returns the current_build_files
   * implements the sequence diagram consume build files
   */
  public void queryRunLevel(int rcon_id, MutableString currentBuildFiles) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevel 1 rcon_id " + rcon_id);
    if ( !mUseDatabase )
    {
      mLogger.info("queryRunLevel 1 !mUseDatabase");
      currentBuildFiles.value = "unit test build file content";
    }
    else
    {
      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall("select current_build_files from release_manager.run_level where rcon_id=" + rcon_id);
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        
        while( rset.next() )
        {
          rsetSize++;
          currentBuildFiles.value = rset.getString("current_build_files");
          if (rset.wasNull())
          {
            currentBuildFiles.value = "";
          }
        }

        if ( rsetSize > 1 )
        {
          mLogger.fatal("queryRunLevel 1 rsetSize > 1");
          // show stopper
          throw new Exception();
        }
        
        disconnect();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevel 1 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevel 1 show stopper");
          throw new Exception();
        }
      }
    }
  }

  /**removes all elements from the mRunLevelCollection
   * handles database connection and disconnection
   *   select rl.rcon_id, rl.current_run_level from release_config rc, run_level rl
   *   where rc.rtag_id=<rtag_id> and rl.rcon_id=rc.rcon_id;
   * populates the mRunLevelCollection with the query result set
   * refer to sequence diagram coordinate slave threads
   */
  public void queryRunLevel(final int rtag_id) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevel 2 rtag_id " + rtag_id);
    if ( mConnectionString.compareTo("unit test coordinate slave threads") == 0)
    {
      mLogger.info("queryRunLevel 2 unit test coordinate slave threads");
      
      if ( mRunLevelCollection.size() == 0)
      {
        // first time not all slave threads are waiting
        RunLevel runLevel = new RunLevel(1, "", DB_WAITING, false);
        mRunLevelCollection.add(runLevel);
        runLevel = new RunLevel(2, "", DB_IDLE, false);
        mRunLevelCollection.add(runLevel);
      }
      else
      {
        // subsequent times all slave threads are waiting
        mRunLevelCollection.removeAllElements();
        RunLevel runLevel = new RunLevel(1, "", DB_WAITING, false);
        mRunLevelCollection.add(runLevel);
        runLevel = new RunLevel(2, "", DB_WAITING, false);
        mRunLevelCollection.add(runLevel);
      }
    }
    
    if ( mUseDatabase )
    {
      mRunLevelCollection.removeAllElements();

      try
      {
        connect();
        CallableStatement stmt = mConnection.prepareCall(
        "select rl.rcon_id, rl.current_run_level from release_config rc, run_level rl " +
        "where rc.rtag_id=" +rtag_id + " and rl.rcon_id=rc.rcon_id");
        ResultSet rset = stmt.executeQuery();
        int rsetSize = 0;
        int rcon_id = 0;
        int current_run_level = 0;
        
        while( rset.next() )
        {
          rsetSize++;
          rcon_id = rset.getInt("rcon_id");
          
          if ( rset.wasNull() )
          {
            mLogger.fatal("queryRunLevel 2 null rcon_id");
            // show stopper
            throw new Exception();
          }
          
          current_run_level = rset.getInt("current_run_level");

          if ( rset.wasNull() )
          {
            mLogger.fatal("queryRunLevel 2 null current_run_level");
            // show stopper
            throw new Exception();
          }
          
          RunLevel runLevel = new RunLevel(rcon_id, "", current_run_level, false);
          mRunLevelCollection.add(runLevel);
        }

        if ( rsetSize == 0 )
        {
          mLogger.fatal("queryRunLevel 2 rsetSize == 0");
          // show stopper
          throw new Exception();
        }
        
        disconnect();
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevel 2 database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevel 2 show stopper");
          throw new Exception();
        }
      }
      

    }
  }

  /**queries the RUN_LEVEL_SCHEDULE table
   * returns false if a row in the query result set indicates build service downtime is scheduled
   * returns false if a row in the query result set has a non NULL indefinite_pause
   * refer to the sequence diagram allowed to proceed
   */
  public boolean queryRunLevelSchedule(Date resumeTime) throws SQLException, Exception
  {
    mLogger.debug("queryRunLevelSchedule");
    boolean retVal = true;
    
    if ( !mUseDatabase )
    {
      mLogger.info("queryRunLevelSchedule !mUseDatabase");
      
      if ( mConnectionString.compareTo("unit test not allowed to proceed") == 0 )
      {
        // schedule a 100ms max wait
        resumeTime.setTime( resumeTime.getTime() + 100 );
        retVal = false;
      }
    }
    else
    {
      try
      {
        CallableStatement stmt = mConnection.prepareCall("select scheduled_pause, scheduled_resume, repeat, indefinite_pause from release_manager.run_level_schedule");
        ResultSet rset = stmt.executeQuery();
        Date now = new Date();
         
        while( rset.next() )
        {
          // retain date and time component
          Timestamp sp = rset.getTimestamp("scheduled_pause");
          
          if ( sp != null )
          {
            Date scheduled_pause = new Date( sp.getTime() );
            Timestamp sr = rset.getTimestamp("scheduled_resume");
            
            if ( sr != null )
            {
              Date scheduled_resume = new Date( sr.getTime() );
              int repeat = rset.getInt("repeat");
              mLogger.info("queryRunLevelSchedule repeat " + repeat);
              
              if ( !rset.wasNull() )
              {
                switch( repeat )
                {
                  case 0:
                  {
                    // one off
                    if ( scheduled_pause.before(now) && scheduled_resume.after(now) )
                    {
                      mLogger.warn("queryRunLevelSchedule one off scheduled downtime");
                      retVal = false;
                    }
                    break;
                  }
                  case 1:
                  {
                    // daily
                    GregorianCalendar startOfDowntime = new GregorianCalendar();
                    startOfDowntime.setTime(scheduled_pause);
                    GregorianCalendar endOfDowntime = new GregorianCalendar();
                    endOfDowntime.setTime(scheduled_resume);
                    GregorianCalendar clock = new GregorianCalendar();
                    clock.setTime(now);
                    // normalise
                    endOfDowntime.set( startOfDowntime.get(Calendar.YEAR), startOfDowntime.get(Calendar.MONTH), startOfDowntime.get(Calendar.DAY_OF_MONTH) );
                    clock.set( startOfDowntime.get(Calendar.YEAR), startOfDowntime.get(Calendar.MONTH), startOfDowntime.get(Calendar.DAY_OF_MONTH) );
                    
                    if ( startOfDowntime.before(clock) && endOfDowntime.after(clock) )
                    {
                      mLogger.warn("queryRunLevelSchedule daily scheduled downtime");
                      retVal = false;
                    }
                    break;
                  }
                  case 7:
                  {
                    // weekly
                    GregorianCalendar startOfDowntime = new GregorianCalendar();
                    startOfDowntime.setTime(scheduled_pause);
                    GregorianCalendar endOfDowntime = new GregorianCalendar();
                    endOfDowntime.setTime(scheduled_resume);
                    GregorianCalendar clock = new GregorianCalendar();
                    clock.setTime(now);
                    
                    if ( startOfDowntime.get(Calendar.DAY_OF_WEEK) == clock.get(Calendar.DAY_OF_WEEK) )
                    {
                      // normalise
                      endOfDowntime.set( startOfDowntime.get(Calendar.YEAR), startOfDowntime.get(Calendar.MONTH), startOfDowntime.get(Calendar.DAY_OF_MONTH) );
                      clock.set( startOfDowntime.get(Calendar.YEAR), startOfDowntime.get(Calendar.MONTH), startOfDowntime.get(Calendar.DAY_OF_MONTH) );
                       
                      if ( startOfDowntime.before(clock) && endOfDowntime.after(clock) )
                      {
                        mLogger.warn("queryRunLevelSchedule weekly scheduled downtime");
                        retVal = false;
                      }
                    }
                    break;
                  }
                }
              }
            }
          }

          int ip = rset.getInt("indefinite_pause");
          
          if ( !rset.wasNull() )
          {
            // indefinite pause is non null
            mLogger.warn("queryRunLevelSchedule indefinite pause");
            retVal = false;
          }
        }
      }
      catch ( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("queryRunLevelSchedule database access error only");
          throw new SQLException();
        }
        else
        {
          mLogger.fatal("queryRunLevelSchedule show stopper");
          throw new Exception();
        }
      }
    }
    
    mLogger.info("queryRunLevelSchedule returning " + retVal);
    return retVal;
  }

  /**persists the runLevel in the RUN_LEVEL table for the rcon_id primary key
   * refer to sequence diagrams generate build files, allowed to proceed, not allowed to proceed, exit, check environment
   */
  public void updateCurrentRunLevel(final int rcon_id, final int runLevel) throws SQLException, Exception
  {
    mLogger.debug("updateCurrentRunLevel");
    if ( !mUseDatabase )
    {
      mLogger.info("updateCurrentRunLevel !mUseDatabase");
      Integer i = new Integer(runLevel);
      mPersistedRunLevelCollection.add(i);
    }
    else
    {
      try
      {
        connect();
        boolean update = false;
        {
          // check if the rcon_id exists in the table
          CallableStatement stmt = mConnection.prepareCall("select rcon_id from release_manager.run_level where rcon_id=" + rcon_id);
          ResultSet rset = stmt.executeQuery();
          
          while( rset.next() )
          {
            update = true;
          }
        }
        
        if ( !update )
        {
          // check if the rcon_id is still configured
          boolean configured = false;
          {
            CallableStatement stmt = mConnection.prepareCall("select rcon_id from release_manager.release_config where rcon_id=" + rcon_id);
            ResultSet rset = stmt.executeQuery();
            
            while( rset.next() )
            {
              configured = true;
            }
          }
          CallableStatement stmt = mConnection.prepareCall("insert into release_manager.run_level (rcon_id) values (" + rcon_id + ")" );
          stmt.executeUpdate();
        }

        {
          CallableStatement stmt = mConnection.prepareCall("update release_manager.run_level set current_run_level=" + runLevel + " where rcon_id=" + rcon_id);
          stmt.executeUpdate();
        }
        mConnection.commit();
        disconnect();
      }
      catch( SQLException e )
      {
        if ( mConnection == null || ( mConnection != null && !mConnection.isValid(10) ) )
        {
          mLogger.error("updateCurrentRunLevel database access error only");
          throw new Exception();
        }
        else
        {
          mLogger.fatal("updateCurrentRunLevel show stopper");
          throw new Exception();
        }
      }
    }
  }

}