Rev 4280 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.erggroup.buildtool.ripple;import java.io.File;import java.sql.SQLException;import java.util.Iterator;import java.util.ListIterator;import java.util.Vector;import java.lang.Exception;import org.apache.log4j.Logger;/**Plans release impact by generating a set of Strings containing build file content.*/public class RippleEngine{/**collection of gbemachtypes in String form associated with the baseline* limited to the following items "win32", "sparc", "solaris10_sparc32", "solaris10_x86", "linux_i386"* accessed by Package::isLinuxBuilt, isSolarisBuilt, isWin32Built* @attribute*/Vector<String> mGbeMachtypeCollection = new Vector<String>();/**configured mail server* @attribute*/public String mMailServer = new String();/**configured mail sender user* @attribute*/public String mMailSender = new String();/**configured global email target* @attribute*/public String mGlobalTarget = new String();/**name associated with the baseline* @attribute*/public String mBaselineName = new String();/**collection of released pv_ids associated with the release* @attribute*/Vector<Integer> mReleasedPvIDCollection = new Vector<Integer>();/**timestamp associated with build file generation* @attribute*/long mTimestamp = 0;/**set to "non generic", "generic" or "dummy" to indicate the nature of the package in the build file in daemon mode* @attribute*/String mAddendum = new String("dummy");/**collection of build exceptions associated with the baseline/* used to determine (and report) what change in build exceptions happens as part of planRelease* deamon centric* @aggregation shared* @attribute*/Vector<BuildExclusion> mBuildExclusionCollection = new Vector<BuildExclusion>();/**Logger* @attribute*/private static final Logger mLogger = Logger.getLogger(RippleEngine.class);/**collection of escrow support file content in String form, set_up* @attribute*/private Vector<String> mEscrowSupportCollection = new Vector<String>();/**package versions representing the baseline* escrow centric* @aggregation shared* @attribute*/private Vector<Package> mPackageCollection = new Vector<Package>();/**index to current String item* @attribute*/private int mBuildIndex;/**Database abstraction* @attribute*/private ReleaseManager mReleaseManager;/**Baseline identifier (rtag_id for a release manager baseline, bom_id for deployment manager baseline)* @attribute*/private int mBaseline;/**When true, mBuildCollection contains one item based on a release manager rtag_id and contains a daemon property* When false, mBuildCollection contains at least one item based on a deployment manager bom_id* Will be accessed by the Package class to calculate its mAlias* @attribute*/boolean mDaemon;/**collection of build file content in String form* @attribute*/private Vector<String> mBuildCollection = new Vector<String>();/**Warning message* @attribute*/private static final String mAnyBuildPlatforms = new String("Warning. The following package versions are not reproducible on any build platform: ");/**Flag to control output to standard out* @attribute*/private boolean mAnyBuildPlatformsFlag = true;/**Warning message* @attribute*/private static final String mAssocBuildPlatforms = new String("Warning. The following package versions are not reproducible on the build platforms associated with this baseline: ");/**Flag to control output to standard out* @attribute*/private boolean mAssocBuildPlatformsFlag = true;/**Warning message* @attribute*/private static final String mNotInBaseline = new String("Warning. The following package versions are not reproducible as they are directly dependent upon package versions not in the baseline: ");/**Flag to control output to standard out* @attribute*/private boolean mNotInBaselineFlag = true;/**Warning message* @attribute*/private static final String mDependent = new String("Warning. The following package versions are not reproducible as they are directly/indirectly dependent upon not reproducible package versions: ");/**Flag to control output to standard out* @attribute*/private boolean mDependentFlag = true;/**Warning message* @attribute*/private static final String mCircularDependency = new String("Warning. The following package versions are not reproducible as they have circular dependencies: ");/**Flag to control output to standard out* @attribute*/private boolean mCircularDependencyFlag = true;/**constructor*/public RippleEngine(ReleaseManager releaseManager, int rtag_id,boolean isDaemon){mLogger.debug("RippleEngine rtag_id " + rtag_id + " isDaemon " + isDaemon);mReleaseManager = releaseManager;mBaseline = rtag_id;mDaemon = isDaemon;}/**discards all build file content* plans new build file content*/public void planRelease() throws SQLException, Exception{mLogger.warn("planRelease mDaemon " + mDaemon);boolean highProbabilityBuildRequirement = true;if ( mAddendum.compareTo("dummy") == 0 ){// the last planning session had no build requirementhighProbabilityBuildRequirement = false;}mAddendum = "dummy";mBuildCollection.removeAllElements();mPackageCollection.removeAllElements();mReleasedPvIDCollection.removeAllElements();if ( !mDaemon ){mEscrowSupportCollection.removeAllElements();}// use finally block in planRelease to ensure releaseMutex is calledtry{mReleaseManager.connectForPlanning(highProbabilityBuildRequirement);if ( mDaemon ){// claim the mutexmLogger.warn("planRelease claimMutex");mReleaseManager.claimMutex();mBuildExclusionCollection.removeAllElements();Vector<BuildExclusion> tempBuildExclusionCollection = new Vector<BuildExclusion>();mLogger.warn("planRelease queryBuildExclusions");mReleaseManager.queryBuildExclusions(tempBuildExclusionCollection, mBaseline);// only populate mBuildExclusionCollection with tempBuildExclusionCollection entries which have a relevant root_pv_id// ie the root_pv_id is ONLY relevant if it is null (-1) or it points to a pv_id in the collection// the package with a pv_id which is a root_pv_id may be removed ie when fixing a build issuefor (Iterator<BuildExclusion> it = tempBuildExclusionCollection.iterator(); it.hasNext(); ){BuildExclusion buildExclusion = it.next();if ( buildExclusion.isRelevant(tempBuildExclusionCollection) ){mBuildExclusionCollection.add(buildExclusion);}else{// this is just a cosmetic step// it includes package versions which have been indirectly excluded// the build daemon ignores this information, but it serves to clarify this point to usersbuildExclusion.includeToBuild(mReleaseManager, mBaseline);}}}mLogger.warn("planRelease queryPackageVersions");mReleaseManager.queryPackageVersions(this, mPackageCollection, mDaemon, mBaseline);// must deal with test builds here as they may impact upon package attributes// eg dependency collection and build standard differences// this gives test builds preferential treatmentif ( mDaemon ){// process test buildsfor (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processedif ( p.mTestBuildInstruction > 0 ){mLogger.info("planRelease package test build " + p.mName);// force patch for test build numberingp.mDirectlyPlanned = true;p.mChangeType.setPatch();p.mRequiresSourceControlInteraction = false;rippleIndirectlyPlanned(p);// put the mTestBuildAttributes to workp.mVcsTag = p.mTestBuildVcsTag;p.setEmail();p.setDependencyCollection();p.setBuildStandardCollection();}}}}// set up mPackageDependencyCollectionmLogger.warn("planRelease setup mPackageDependencyCollection");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();for (Iterator<String> it2 = p.mDependencyCollection.iterator(); it2.hasNext(); ){String alias = it2.next();Package dependency = findPackage(alias);p.mPackageDependencyCollection.add(dependency);}}// DEVI 56479 detect and deal with circular dependenciesmLogger.warn("planRelease deal with circular dependencies");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.hasCircularDependency( this ) ){mLogger.info("planRelease circular dependency detected " + p.mAlias);// exclude all dependent packages// max 50 charsrippleBuildExclude(p, p.mId, "Package has circular dependency", null, null);// take the package out of the buildp.mBuildFile = -6;mLogger.info("planRelease set mBuildFile to -6 for package " + p.mAlias );standardOut(mCircularDependency, p.mAlias, mCircularDependencyFlag);}}// DEVI 55483 now use the fully built mPackageDependencyCollection (in rippleBuildExclude)mLogger.warn("planRelease use the fully built mPackageDependencyCollection");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();for (Iterator<String> it2 = p.mDependencyCollection.iterator(); it2.hasNext(); ){String alias = it2.next();Package dependency = findPackage(alias);if (dependency == ReleaseManager.NULL_PACKAGE){mLogger.info("planRelease dependency is not in the baseline " + alias);// exclude all dependent packages// max 50 charsrippleBuildExclude(p, p.mId, "Package build dependency not in the release", null, null);// take the package out of the buildp.mBuildFile = -4;mLogger.info("planRelease set mBuildFile to -4 for package " + p.mAlias );standardOut(mNotInBaseline, p.mAlias, mNotInBaselineFlag);break;}}}// process packages which are not reproducible, and all packages dependent upon themmLogger.warn("planRelease process packages which are not reproducible");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processedif (!p.isReproducible()){// for escrow build purposes, exclude all dependent package versionsmLogger.info("planRelease package not reproducible " + p.mName);// max 50 charsrippleBuildExclude(p, p.mId, "Package has no build environment", null, null);// package is not reproducible, discardp.mBuildFile = -1;mLogger.info("planRelease set mBuildFile to -1 for package " + p.mAlias );standardOut(mAnyBuildPlatforms, p.mAlias, mAnyBuildPlatformsFlag);}}}// process packages which are not reproducible on the build platforms configured for this baselinemLogger.warn("planRelease process packages which are not reproducible2");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processed// assume it does not need to be reproduced for this baselineboolean reproduce = false;for (Iterator<String> it2 = mGbeMachtypeCollection.iterator(); it2.hasNext(); ){String machtype = it2.next();if ( machtype.compareTo("linux_i386") == 0 ){if ( p.isLinuxBuilt() ){reproduce = true;mLogger.info("planRelease package built on linux " + p.mAlias );break;}}else if ( machtype.compareTo("win32") == 0 ){if ( p.isWin32Built() ){reproduce = true;mLogger.info("planRelease package built on win32 " + p.mAlias );break;}}else if ( machtype.compareTo("sparc") == 0|| machtype.compareTo("solaris10_x86") == 0|| machtype.compareTo("solaris10_sparc32") == 0 ){if ( p.isSolarisBuilt() ){reproduce = true;mLogger.info("planRelease package built on solaris " + p.mAlias );break;}}}if ( !reproduce ){mLogger.info("planRelease package not reproducible on the build platforms configured for this baseline " + p.mName);if (mDaemon){// DEVI 54816// for escrow build purposes, do not exclude all dependent package versions// max 50 charsrippleBuildExclude(p, p.mId, "Package not built for configured platforms", null, null);}// package is not reproducible on the build platforms configured for this baseline, discardp.mBuildFile = -2;mLogger.info("planRelease set mBuildFile to -2 for package " + p.mAlias );standardOut(mAssocBuildPlatforms, p.mAlias, mAssocBuildPlatformsFlag);}}}if (mDaemon){// process packages which are not ripple buildable, and all packages dependent upon themmLogger.warn("planRelease process packages which are not ripple buildable");for (ListIterator<BuildExclusion> it = mBuildExclusionCollection.listIterator(); it.hasNext(); ){BuildExclusion be = it.next();for (Iterator<Package> it1 = mPackageCollection.iterator(); it1.hasNext(); ){Package p = it1.next();// ensure only root cause, non test build, build exclusions are excluded// mBuildExclusionCollection is at this point based on// relevant (direct and indirect) excluded pv's in the databaseif ( be.compare(p.mId) && be.isARootCause() && p.mTestBuildInstruction == 0 ){// package is not reproducible, discardrippleBuildExclude( p, p.mId, null, it, be );p.mBuildFile = -3;mLogger.info("planRelease set mBuildFile to -3 for package " + p.mAlias );break;}}}// process packages which need to be ripple builtmLogger.warn("planRelease process packages which need to be ripple built");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processedif (p.mDirectlyPlanned){// a WIP exists on the package// exclude all dependent package versionsmLogger.info("planRelease package has WIP " + p.mName);rippleIndirectlyPlanned(p);}else{Iterator<Integer> it2 = p.mDependencyIDCollection.iterator();Iterator<Package> it3 = p.mPackageDependencyCollection.iterator();for ( ; it2.hasNext() && it3.hasNext(); ){Integer dpv_id = it2.next();Package dependency = it3.next();if ( !dependency.mAdvisoryRipple ){// not advisory, ie has ripple build impactboolean found = false;for ( Iterator<Integer> it4 = mReleasedPvIDCollection.iterator(); it4.hasNext(); ){Integer pv_id = it4.next();if ( pv_id.compareTo(dpv_id) == 0 ){found = true;break;}}if ( !found ){// the package is out of date// exclude all dependent package versionsmLogger.info("planRelease package out of date " + p.mName);rippleIndirectlyPlanned(p);break;}}}}}}// process packages which do not exist in the archivemLogger.warn("planRelease process packages which do not exist in the archive");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processed// for unit test purposes, assume all packages exist in the archive if releasedif ( ReleaseManager.mUseDatabase ){// only check existence outside the unit testif (!p.mDirectlyPlanned && !p.mIndirectlyPlanned){// check package version archive existenceif (!p.exists()){mLogger.info("planRelease package not found in archive " + p.mName);// DEVI 47395 the cause of this build is not WIP or ripple induced,// it simply does not exist in the archive (has been removed)// prevent source control interactionp.mRequiresSourceControlInteraction = false;rippleIndirectlyPlanned(p);}}}}}// process forced ripplesmLogger.warn("planRelease process forced ripples");for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == 0){// package has yet to be processedif ( p.mForcedRippleInstruction > 0 ){mLogger.info("planRelease package forced ripple " + p.mName);rippleIndirectlyPlanned(p);}}}}else{// escrow reporting onlyfor (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if (p.mBuildFile == -3){standardOut(mDependent, p.mAlias, mDependentFlag);}}}// process remaining packages which need to be reproduced for this baseline// determine the build file for each package// for daemon builds, determine the first package that can be built now, this means the first package not dependent upon packages also to be built// set its mBuildNumber to 1, all remaining reproducible packages to 2// for escrow builds, determine the package versions that can be built in the build iteration// set their mBuildNumber to the build iteration// increment the build iteration and repeat until all package versions that need to be reproduced have been assigned a build iterationboolean allProcessed = false;int buildFile = 1;// delete the file <rtagId>officialInteger rtag = new Integer(mBaseline);File rtagIdOfficial = new File(rtag + "official");mLogger.warn("planRelease process Remaining-1");if (rtagIdOfficial.exists()){boolean del = rtagIdOfficial.delete();if ( !del ){// the delete failed// some literature suggests a forced garbage collection may free up resources associated with file handles// nothing to lose since the file "must" be deletedSystem.gc();del = rtagIdOfficial.delete();if ( !del ){mLogger.fatal("rtagIdOfficial.delete() returned " + del);}}}String raw_data = new String("");String lf = new String( System.getProperty("line.separator") );mLogger.warn("planRelease process Remaining-2");do{boolean allDependenciesProcessed = true;do{// assume all dependencies have been processedallDependenciesProcessed = true;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( ( mDaemon && ( ( !p.mDirectlyPlanned && !p.mIndirectlyPlanned ) || p.mBuildFile < 0 ) ) ||( !mDaemon && p.mBuildFile == -2 ) ){// flag packages with no build requirement as processed in daemon mode// DEVI 54816 flag packages with a foreign build environment as processed in escrow modep.mProcessed = true;mLogger.info("planRelease package has no build requirement " + p.mName);}else if ( ( p.mBuildFile == 0 ) && ( (mDaemon && ( p.mDirectlyPlanned || p.mIndirectlyPlanned ) ) || ( !mDaemon ) ) ){// package yet to be processed and// in daemon mode has a build requirement or// in escrow modeboolean canBeBuiltNow = true;boolean allDependenciesForThisPackageProcessed = true;for ( Iterator<Package> it2 = p.mPackageDependencyCollection.iterator(); it2.hasNext(); ){Package dependency = it2.next();if ( !dependency.mProcessed ){// cannot determine canBeBuiltNow until this dependency has been processedallDependenciesForThisPackageProcessed = false;allDependenciesProcessed = false;}else if ( ( mDaemon && ( dependency.mDirectlyPlanned ) || ( dependency.mIndirectlyPlanned ) ) ||( !mDaemon &&( ( dependency.mBuildFile == 0 ) ||( dependency.mBuildFile == buildFile &&( ( p.isLinuxBuilt() && !dependency.isLinuxBuilt() ) ||( p.isWin32Built() && !dependency.isWin32Built() ) ||( p.isSolarisBuilt() && !dependency.isSolarisBuilt() ) ||( !p.isLinuxBuilt() && dependency.isLinuxBuilt() ) ||( !p.isWin32Built() && dependency.isWin32Built() ) ||( !p.isSolarisBuilt() && dependency.isSolarisBuilt() ) ) ) ) ) ){// in daemon mode this processed dependency has a build requirement or// in escrow mode...// this processed dependency has not been assigned to a build iteration or// this processed dependency has been assigned to this build iteration and does not build on this platformcanBeBuiltNow = false;mLogger.info("planRelease package cannot be built in this iteration " + p.mName);break;}}if (allDependenciesForThisPackageProcessed){p.mProcessed = true;if ( mDaemon ){if ( canBeBuiltNow ){// flag package with build requirement, may get downgraded to future build requirementp.mBuildFile = 1;mLogger.info("planRelease set mBuildFile to 1 for package " + p.mAlias );}else{// flag package with future build requirementp.mBuildFile = 2;mLogger.info("planRelease set mBuildFile to 2 for package " + p.mAlias );}}else{if ( canBeBuiltNow ){String isWin32Built = new String("");if ( p.isWin32Built() ){isWin32Built = "W";}String isLinuxBuilt = new String("");if ( p.isLinuxBuilt() ){isLinuxBuilt = "L";}String isSolarisBuilt = new String("");if ( p.isSolarisBuilt() ){isSolarisBuilt = "S";}String isGeneric = new String("");if ( p.isGeneric() ){isGeneric = "G";}raw_data += p.mAlias + "," +isWin32Built + "," +isLinuxBuilt + "," +isSolarisBuilt + "," +isGeneric + "," +buildFile +lf;// not daemonp.mBuildFile = buildFile;mLogger.info("planRelease set mBuildFile to " + buildFile + " for package " + p.mAlias );}}}}}} while( !allDependenciesProcessed );if ( mDaemon ){for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mProcessed && p.mBuildFile == 1 ){p.mBuildFile = buildFile;mLogger.info("planRelease 2 set mBuildFile to " + buildFile + " for package " + p.mAlias );if ( buildFile == 1 ){int pvApplied = p.applyPV(mReleaseManager, mBaseline);if ( pvApplied == 1 ){// max 50 charsrippleBuildExclude(p, p.mId, "Package has non standard versioning", null, null);}else if ( pvApplied == 2 ){// max 50 charsrippleBuildExclude(p, p.mId, "Package has reached ripple field limitations", null, null);}else if ( pvApplied == 3 ){// max 50 charsrippleBuildExclude(p, p.mId, "Package has invalid change type", null, null);}else{buildFile = 2;if ( p.mForcedRippleInstruction > 0 ){mReleaseManager.markDaemonInstCompleted( p.mForcedRippleInstruction );}if ( p.mTestBuildInstruction > 0 ){mReleaseManager.markDaemonInstInProgress( p.mTestBuildInstruction );}}}else{mLogger.info("planRelease package has future (downgraded) build requirement " + p.mName + " " + buildFile);}}}}// are more build files requiredallProcessed = true;if (mDaemon){for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile < 0 || ( !p.mDirectlyPlanned && !p.mIndirectlyPlanned ) ){// at this point...// only 1 package with a build requirement has a mBuildFile of 1,// all other packages with a build requirement have an mBuildFile of 2// give packages with no build requirement, reproducible or not, an mBuildFile of 3p.mBuildFile = 3;mLogger.info("planRelease 1 set mBuildFile to 3 for package " + p.mAlias );}}}else{// this is escrow mode centricfor (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == 0 ){// more build files are requiredallProcessed = false;mLogger.info("planRelease more build files are required for " + p.mName);break;}}buildFile++;}} while( !allProcessed );// persist the build filesallProcessed = false;buildFile = 1;mLogger.warn("planRelease process Remaining-3");if ( mDaemon ){// all interesting packages in daemon mode match the following filterbuildFile = 3;}mTimestamp = System.currentTimeMillis();if ( !ReleaseManager.mUseDatabase ){mTimestamp = 123456789;}//-----------------------------------------------------------------------// Generate the build filedo{String buildFileContent = new String( generateBuildFileHeader() );for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();// DEVI 54816// now set a packages mBuildFile to -2 in escrow mode, but do not ripple this through// its consumers need dependency package property infoif ( ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) ) || ( !mDaemon && p.mBuildFile == -2 ) ){buildFileContent += generatePackageProperty(p);}}buildFileContent += generateTaskdef();String set_up = new String("");boolean daemonHasTarget = false;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile > 0 && p.mBuildFile <= buildFile ){buildFileContent += generateTarget(p, buildFile);if ( p.mBuildFile == 1 ){daemonHasTarget = true;}}if ( !mDaemon && buildFile == 1 ){set_up += "jats jats_vcsrelease -extractfiles"+ " \"-label=" + p.mVcsTag + "\""+ " \"-view=" + p.mAlias + "\""+ " -root=. -noprefix"+ lf;}}if ( mDaemon && !daemonHasTarget ){// must have AbtSetUp, AbtTearDown, and AbtPublish targetsbuildFileContent += "<target name=\"AbtSetUp\"/>" + lf +"<target name=\"AbtTearDown\"/>" + lf +"<target name=\"AbtPublish\"/>" + lf;}if ( !mDaemon && buildFile == 1 ){mEscrowSupportCollection.add(set_up);mEscrowSupportCollection.add(raw_data);}buildFileContent += generateDefaultTarget( buildFile);buildFileContent += generateBuildFileFooter();mBuildCollection.add(buildFileContent);// are more build files requiredallProcessed = true;if (!mDaemon){// this is escrow mode centricfor (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile > buildFile ){// more build files are requiredallProcessed = false;mLogger.info("planRelease reiterating package has no build requirement " + p.mName + " " + p.mBuildFile + " " + buildFile);break;}}buildFile++;}} while( !allProcessed );}finally{mLogger.warn("planRelease finally");// this block is executed regardless of what happens in the try block// even if an exception is thrown// ensure the SELECT FOR UPDATE is releasedif ( mDaemon ){// attempt to release the SELECT FOR UPDATE through a commit// a commit must be done in the normal case// a commit may as well be done in the Exception case// in the case of a SQLException indicating database connectivity has been lost// having a go at the commit is superfluous// as the SELECT FOR UPDATE will have been released upon disconnectionmReleaseManager.releaseMutex();mLogger.warn("planRelease finally-1");}// ensure disconnectmReleaseManager.disconnectForPlanning(highProbabilityBuildRequirement);mLogger.warn("planRelease finally-2");}mLogger.warn("planRelease mDaemon " + mDaemon + " returned");}/**reports what change in build exceptions happens as part of planRelease*/public void reportChange() throws SQLException, Exception{for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); ){BuildExclusion buildExclusion = it.next();if ( !buildExclusion.isProcessed() ){// notifybuildExclusion.excludeFromBuild(mReleaseManager, mBaseline);buildExclusion.email(mPackageCollection, mMailServer, mMailSender, mBaselineName, mReleaseManager);}}}/**returns first build file content* returns false if no build file content exists*/public boolean getFirstBuildFileContent(MutableString content){mLogger.debug("getFirstBuildFileContent");boolean retVal = true;try{mBuildIndex = 0;content.value = (String)mBuildCollection.get( mBuildIndex );}catch( ArrayIndexOutOfBoundsException e ){retVal = false;}mLogger.info("getFirstBuildFileContent returned " + retVal);return retVal;}/**returns next build file content* returns false if no next build file content exists*/public boolean getNextBuildFileContent(MutableString content){mLogger.debug("getNextBuildFileContent");boolean retVal = true;try{mBuildIndex++;content.value = (String)mBuildCollection.get( mBuildIndex );}catch( ArrayIndexOutOfBoundsException e ){retVal = false;}mLogger.debug("getNextBuildFileContent returned " + retVal);return retVal;}/**collects meta data associated with the baseline* this is sufficient to send an indefinite pause email notification*/public void collectMetaData() throws SQLException, Exception{mLogger.debug("collectMetaData mDaemon " + mDaemon);mGbeMachtypeCollection.removeAllElements();try{mReleaseManager.connect();mReleaseManager.queryMachtypes(mGbeMachtypeCollection, mDaemon, mBaseline);if (mDaemon){mMailServer = mReleaseManager.queryMailServer();mMailSender = mReleaseManager.queryMailSender();mGlobalTarget = mReleaseManager.queryGlobalAddresses();}mBaselineName = mReleaseManager.queryBaselineName(mDaemon, mBaseline);}finally{// this block is executed regardless of what happens in the try block// even if an exception is thrown// ensure disconnectmReleaseManager.disconnect();}}/**returns the Package with the matching mAlias or NULL_PACKAGE if no package has the mID*/public Package findPackage(String alias){mLogger.debug("findPackage");Package retVal = ReleaseManager.NULL_PACKAGE;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mAlias.compareTo( alias ) == 0 ){retVal = p;break;}}mLogger.info("findPackage returned " + retVal.mName);return retVal;}/**sets the mBuildFile to -5 for the package and all dependent packages*/private void rippleBuildExclude(Package p, int root_pv_id, String root_cause, ListIterator<BuildExclusion> list, BuildExclusion be ){mLogger.debug("rippleBuildExclude");if ( p.mBuildFile == 0 || p.mBuildFile == 1 ){p.mBuildFile = -5;mLogger.info("rippleBuildExclude set mBuildFile to -5 for package " + p.mAlias );if ( be != null ){be.process();}else{// if found, process it, else add it (unprocessed)boolean found = false;for (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); ){BuildExclusion buildExclusion = it.next();if ( buildExclusion.compare(p.mId, root_pv_id, root_cause)){found = true;buildExclusion.process();break;}}if (!found){// process all occurrences for this package// these will be superceded by a new build exclusion entryfor (Iterator<BuildExclusion> it = mBuildExclusionCollection.iterator(); it.hasNext(); ){BuildExclusion buildExclusion = it.next();if ( buildExclusion.compare(p.mId)){buildExclusion.process();}}BuildExclusion buildExclusion = new BuildExclusion(p.mId, root_pv_id, root_cause, p.mTestBuildInstruction);if ( list == null ){mBuildExclusionCollection.add(buildExclusion);}else{// must use the ListIterator interface to add to the collection whilst iterating through itlist.add(buildExclusion);}}}// only ripple a test build failure through for non test buildsif ( p.mTestBuildInstruction == 0 ){// non test buildfor (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package pkg = it.next();if ( pkg != p ){for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); ){Package dependency = it2.next();if ( dependency == p ){rippleBuildExclude( pkg, root_pv_id, null, list, null );break;}}}}}}mLogger.info("rippleBuildExclude set " + p.mName + " " + p.mBuildFile);}public String escapeXml( String xml ){xml = xml.replaceAll("&", "&");xml = xml.replaceAll("<", "<");xml = xml.replaceAll(">", ">");xml = xml.replaceAll("\"",""");xml = xml.replaceAll("'", "'");xml = xml.replaceAll("\\$", "\\$\\$");return xml;}/**returns a build file header for the mBaseline*/private String generateBuildFileHeader(){mLogger.debug("generateBuildFileHeader");String lf = new String( System.getProperty("line.separator") );String retVal = new String("");retVal +="<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>" + lf +"<project name=\"mass\" default=\"full\" basedir=\".\">" + lf;if ( mDaemon ){retVal +="<property name=\"abt_mail_server\" value=\"" + mMailServer + "\"/>" + lf +"<property name=\"abt_mail_sender\" value=\"" + mMailSender + "\"/>" + lf +"<property name=\"abt_rtag_id\" value=\"" + mBaseline + "\"/>" + lf +"<property name=\"abt_daemon\" value=\"" + mTimestamp + "\"/>" + lf;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == 1 ){retVal +="<property name=\"abt_package_name\" value=\"" + p.mName + "\"/>" + lf +"<property name=\"abt_package_version\" value=\"" + p.mVersion + p.mExtension + "\"/>" + lf +"<property name=\"abt_package_extension\" value=\"" + p.mExtension + "\"/>" + lf +loc(p, "abt_package_location", lf) +"<property name=\"abt_package_depends\" value=\"";// depends in the form 'cs','25.1.0000.cr';'Dinkumware_STL','1.0.0.cots'String depends = new String();for (Iterator<Package> it3 = p.mPackageDependencyCollection.iterator(); it3.hasNext(); ){Package depend = it3.next();if ( depends.compareTo( "" ) != 0 ){depends += ";";}depends += "\'" + depend.mName + "\'";depends += ",";String dependsExtension = depend.mExtension;String dependsVersion = depend.mVersion;if ( dependsExtension.length() > 0 ){dependsVersion += dependsExtension;}else{dependsExtension = ".";}depends += "\'" + dependsVersion + "\'";}retVal += depends + "\"/>" + lf +"<property name=\"abt_is_ripple\" value=\"";if ( p.mDirectlyPlanned ){retVal += "0";}else{retVal += "1";}retVal += "\"/>" + lf +"<property name=\"abt_package_version_id\" value=\"" + p.mId + "\"/>" + lf +"<property name=\"abt_does_not_require_source_control_interaction\" value=\"";if ( ! p.mRequiresSourceControlInteraction ){retVal += "true";}else{retVal += "false";}retVal += "\"/>" + lf +"<property name=\"abt_test_build_instruction\" value=\"" + p.mTestBuildInstruction + "\"/>" + lf;}}}else{retVal +="<property name=\"abt_rtag_id\" value=\"-1\"/>" + lf;}String majorVersionNumber = this.getClass().getPackage().getSpecificationVersion();if ( !ReleaseManager.mUseDatabase ){// hard code 11 for unit test purposesmajorVersionNumber = "11";}retVal +="<property name=\"abt_release\" value=\"" + escapeXml(mBaselineName) + "\"/>" + lf +"<property name=\"abt_buildtool_version\" value=\""+ majorVersionNumber + "\"/>" + lf +"<condition property=\"abt_family\" value=\"windows\">" + lf +" <os family=\"windows\"/>" + lf +"</condition>" + lf +"<property name=\"abt_family\" value=\"unix\"/>" + lf;mLogger.info("generateBuildFileHeader returned " + retVal);return retVal;}/**returns an ant property for the passed Package*/private String generatePackageProperty(Package p){mLogger.debug("generatePackageProperty");String lf = new String( System.getProperty("line.separator") );String retVal = new String("");retVal +=" <property name=\"" + p.mAlias + "\" value=\"" + p.mName + " " + p.mVersion + p.mExtension + "\"/>" + lf;mLogger.info("generatePackageProperty returned " + retVal);return retVal;}/**returns an ant taskdef for the abt ant task*/private String generateTaskdef(){mLogger.debug("generateTaskdef");String lf = new String( System.getProperty("line.separator") );String retVal = new String("");retVal += "<taskdef name=\"abt\" classname=\"com.erggroup.buildtool.abt.ABT\"/>" + lf;// The ABTData class is only used in Daemon Modeif ( mDaemon ) {retVal += "<taskdef name=\"abtdata\" classname=\"com.erggroup.buildtool.abt.ABTData\"/>" + lf;}return retVal;}/** returns the command abtdata items* Common machine information* Common email address*/private String generateMachineInfo(Package p, String lf){String retVal = new String("");retVal += "<abtdata>" + lf;//// Iterate over all the machines and create a nice entry//for (Iterator<ReleaseConfig> it = mReleaseManager.mReleaseConfigCollection.iterator(); it.hasNext(); ){ReleaseConfig rc = it.next();retVal += " " + rc.getMachineEntry() + lf;}//// Now the email information//retVal += p.emailInfo( lf );// End of this elementretVal += "</abtdata>" + lf;return retVal;}/**returns an ant target for the passed Package* in daemon mode:* packages are categorised with one of three mBuildFile values:* 1 the package to be built by this buildfile* 2 the packages with a future build requirement* 3 the packages with no build requirement* the returned target depends on this categorisation and will have* 1 full abt info* 2 full dependency info to determine future build ordering but no abt info (will not build this package)* 3 only a name attribute (will not build this package)* in escrow mode:* if the passed Package's mBuildFile is different (less than) the passed build file,* the returned target have only a name attribute (will not build this package)*/private String generateTarget(Package p, int buildFile){mLogger.debug("generateTarget");String lf = new String( System.getProperty("line.separator") );String retVal = new String("");//-------------------------------------------------------------------------// Generate a collection of 'BuildStandard's//if ( ( mDaemon && p.mBuildFile == 1 ) || ( !mDaemon && !p.isGeneric() ) ){// populate 'missing' BuildStandardsboolean solaris = false;boolean linux = false;boolean win32 = false;boolean jats = false;boolean determinedBuildStandard = false;for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); ){BuildStandard bs = it.next();if ( bs.getSolaris() ){solaris = true;}else if ( bs.getLinux() ){linux = true;}else if ( bs.getWin32() ){win32 = true;}if ( !determinedBuildStandard && bs.getBuildStandard(!ReleaseManager.mUseDatabase, true).contains("<jats") ){jats = true;determinedBuildStandard = true;}}if ( !solaris ){BuildStandard bs = new BuildStandard(this);bs.setSolaris();if ( jats ){bs.setJatsNone();}else{bs.setAntNone();}p.mBuildStandardCollection.add(bs);}if ( !linux ){BuildStandard bs = new BuildStandard(this);bs.setLinux();if ( jats ){bs.setJatsNone();}else{bs.setAntNone();}p.mBuildStandardCollection.add(bs);}if ( !win32 ){BuildStandard bs = new BuildStandard(this);bs.setWin32();if ( jats ){bs.setJatsNone();}else{bs.setAntNone();}p.mBuildStandardCollection.add(bs);}}//---------------------------------------------------------------------// Generate the AbtData - common machine and email information// Only used by the daemon builds//if ( mDaemon && p.mBuildFile == 1 ){retVal += generateMachineInfo(p, lf);}//-------------------------------------------------------------------------// Generate the <target name=... /> construct// There are two types// 1) Simple dummy place holder. Just has the PackageName.PackageExt// 2) Full target. Has all information to build the package including// AbtSetUp, AbtTearDown and AbtPublish targets//if ( ( mDaemon && p.mBuildFile == 3 ) ||( !mDaemon && ( p.mBuildFile < buildFile ) ) ){retVal +="<target name=\"" + p.mAlias + "\"/>" + lf;}else{retVal +="<target name=\"" + p.mAlias + ".wrap\"";if ( p.mPackageDependencyCollection.size() > 0 ){retVal +=" depends=\"";boolean comma = false;for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); ){Package dependency = it.next();// DEVI 54816if ( !mDaemon && dependency.mBuildFile == -2 ){// ignore targets which build in foreign environments in escrow modecontinue;}if (comma){retVal += ",";}comma = true;retVal += dependency.mAlias;}retVal += "\"";}retVal += ">" + lf;if ( !mDaemon ){boolean hasDependenciesBuiltInThisIteration = false;if ( ( p.mPackageDependencyCollection.size() > 0 ) ){for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); ){Package dependency = it.next();if ( dependency.mBuildFile == buildFile ){hasDependenciesBuiltInThisIteration = true;break;}}}if ( hasDependenciesBuiltInThisIteration ){retVal +=" <condition property=\"" + p.mAlias + ".build\">" + lf +" <and>" + lf;for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); ){Package dependency = it.next();if ( dependency.mBuildFile == buildFile ){retVal +=" <or>" + lf +" <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"0\"/>" + lf +" <equals arg1=\"${" + dependency.mAlias + ".res}\" arg2=\"257\"/>" + lf +" </or>" + lf;}}retVal +=" </and>" + lf +" </condition>" + lf;}else{retVal += " <property name=\"" + p.mAlias + ".build\" value=\"\"/>" + lf;}}retVal +="</target>" + lf +"<target name=\"" + p.mAlias + "\" depends=\"" + p.mAlias + ".wrap\"";if ( !mDaemon ){retVal += " if=\"" + p.mAlias + ".build\"";}retVal += ">" + lf;if ( mDaemon && p.mBuildFile == 1 ){retVal +=" <property name=\"" + p.mAlias + "pkg_id\" value=\"" + p.mPid + "\"/>" + lf +" <property name=\"" + p.mAlias + "pv_id\" value=\"" + p.mId + "\"/>" + lf;}if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon ){retVal +=" <property name=\"" + p.mAlias + "packagename\" value=\"" + p.mName + "\"/>" + lf +" <property name=\"" + p.mAlias + "packageversion\" value=\"" + p.mVersion + "\"/>" + lf +" <property name=\"" + p.mAlias + "packageextension\" value=\"" + p.mExtension + "\"/>" + lf +" <property name=\"" + p.mAlias + "packagevcstag\" value=\"" + p.mVcsTag + "\"/>" + lf;if ( p.mDirectlyPlanned ){retVal += " <property name=\"" + p.mAlias + "directchange\" value=\"\"/>" + lf;}if ( ! p.mRequiresSourceControlInteraction ){retVal += " <property name=\"" + p.mAlias + "doesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;}mAddendum = "non generic";if ( p.isGeneric() ){mAddendum = "generic";retVal += " <property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;}retVal += " " + loc(p, p.mAlias + "loc", lf);if ( p.mHasAutomatedUnitTests && mDaemon ){retVal +=" <property name=\"" + p.mAlias + "unittests\" value=\"\"/>" + lf;}}// Add our own task and associated information//retVal += " <abt>" + lf;if ( ( mDaemon && p.mBuildFile == 1 ) || !mDaemon ){for (Iterator<Package> it = p.mPackageDependencyCollection.iterator(); it.hasNext(); ){Package dependency = it.next();retVal +=" <depend package_alias=\"${" + dependency.mAlias + "}\"/>" + lf;}retVal += buildInfo(p, lf, false);}retVal += " </abt>" + lf +"</target>" + lf;if ( mDaemon && p.mBuildFile == 1 ){// AbtSetUpretVal +="<target name=\"AbtSetUp\">" + lf +" <property name=\"AbtSetUppackagevcstag\" value=\"" + p.mVcsTag + "\"/>" + lf +" <property name=\"AbtSetUppackagename\" value=\"" + p.mName + "\"/>" + lf;retVal +=" <abt>" + lf +" </abt>" + lf +" </target>" + lf;// AbtTearDownretVal +="<target name=\"AbtTearDown\">" + lf +" <property name=\"AbtTearDownpackagevcstag\" value=\"" + p.mVcsTag + "\"/>" + lf +" <property name=\"AbtTearDownpackagename\" value=\"" + p.mName + "\"/>" + lf +" <property name=\"AbtTearDownpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +" <property name=\"AbtTearDownpackageextension\" value=\"" + p.mExtension + "\"/>" + lf;if ( p.isGeneric() ){retVal += " <property name=\"" + p.mAlias + "generic\" value=\"\"/>" + lf;}retVal +=" <abt>" + lf +buildInfo(p, lf, false) +" </abt>" + lf +"</target>" + lf;// AbtPublishretVal +="<target name=\"AbtPublish\">" + lf +" <property name=\"AbtPublishpackagevcstag\" value=\"" + p.mVcsTag + "\"/>" + lf +" <property name=\"AbtPublishpackagename\" value=\"" + p.mName + "\"/>" + lf +" <property name=\"AbtPublishpackageversion\" value=\"" + p.mVersion + "\"/>" + lf +" <property name=\"AbtPublishpackageextension\" value=\"" + p.mExtension + "\"/>" + lf;if ( p.mDirectlyPlanned ){retVal += " <property name=\"AbtPublishdirectchange\" value=\"\"/>" + lf;}if ( ! p.mRequiresSourceControlInteraction ){retVal += " <property name=\"AbtPublishdoesnotrequiresourcecontrolinteraction\" value=\"\"/>" + lf;}if ( p.isGeneric() ){retVal += " <property name=\"AbtPublishgeneric\" value=\"\"/>" + lf;}retVal += " " + loc(p, "AbtPublishloc", lf);retVal +=" <abt>" + lf +buildInfo(p, lf, true) +" </abt>" + lf +"</target>" + lf;}}mLogger.info("generateTarget returned " + retVal);return retVal;}/**returns an ant default target for the current build iteration*/private String generateDefaultTarget(int buildFile){mLogger.debug("generateDefaultTarget");String lf = new String( System.getProperty("line.separator") );String retVal = new String("");retVal +="<target name=\"fullstart\">" + lf;if (buildFile == 1){retVal +="<echo message=\"${line.separator}" + mAnyBuildPlatforms + "${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == -1 ){retVal +="<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}}retVal +="<echo message=\"${line.separator}" + mAssocBuildPlatforms + "${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == -2 ){retVal +="<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}}retVal +="<echo message=\"${line.separator}" + mNotInBaseline + "${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == -4 ){retVal +="<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}}retVal +="<echo message=\"${line.separator}" + mDependent + "${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( p.mBuildFile == -5 ){retVal +="<echo message=\"${line.separator}" + p.mAlias + "${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}}}if ( !mDaemon ){retVal +="<echo message=\"${line.separator}Build Started:${line.separator}${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}retVal +="</target>" + lf +"<target name=\"full\" depends=\"fullstart";for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package p = it.next();if ( ( p.mBuildFile > 0 ) && ( p.mBuildFile <= buildFile ) ){retVal += "," + p.mAlias;}}retVal +="\">" + lf;if ( !mDaemon ){retVal +="<echo message=\"${line.separator}Build Finished${line.separator}\" file=\"publish.log\" append=\"true\"/>" + lf;}retVal +="</target>" + lf;return retVal;}/**returns a build file footer*/private String generateBuildFileFooter(){mLogger.debug("generateBuildFileFooter");String retVal = new String("</project>");return retVal;}/**sets the mIndirectlyPlanned true for the package and all dependent packages*/private void rippleIndirectlyPlanned(Package p){mLogger.debug("rippleIndirectlyPlanned");if ( !p.mIndirectlyPlanned && p.mBuildFile == 0 ){p.mIndirectlyPlanned = true;for (Iterator<Package> it = mPackageCollection.iterator(); it.hasNext(); ){Package pkg = it.next();if ( pkg != p ){for (Iterator<Package> it2 = pkg.mPackageDependencyCollection.iterator(); it2.hasNext(); ){Package dependency = it2.next();if ( dependency == p ){rippleIndirectlyPlanned( pkg );break;}}}}}mLogger.info("rippleIndirectlyPlanned set " + p.mName + " " + p.mIndirectlyPlanned);}/**accessor method*/public String getESCROWSetUp(){mLogger.debug("getESCROWSetUp");String retVal = new String("");try{if ( mEscrowSupportCollection.size() >= 1 ){retVal = (String)mEscrowSupportCollection.get(0);}}catch( ArrayIndexOutOfBoundsException e ){}mLogger.info("getESCROWSetUp returned " + retVal);return retVal;}/**accessor method*/public String getRawData(){mLogger.debug("getRawData");String retVal = new String("");try{if ( mEscrowSupportCollection.size() >= 2 ){retVal = (String)mEscrowSupportCollection.get(1);}}catch( ArrayIndexOutOfBoundsException e ){}mLogger.info("getRawData returned " + retVal);return retVal;}/**returns first build file content and addendum* the addendum value is one of "non generic", "generic" or "dummy"*/public void getFirstBuildFileContent(MutableString content,MutableString addendum){mLogger.debug("getFirstBuildFileContent");try{mBuildIndex = 0;content.value = (String)mBuildCollection.get( mBuildIndex );addendum.value = mAddendum;}catch( ArrayIndexOutOfBoundsException e ){}mLogger.info("getFirstBuildFileContent passed " + content.value + addendum.value);}/**returns the build loc*/private String loc(Package p, String target, String lf){mLogger.debug("loc");String retVal = new String();String loc = new String("/");if (mDaemon){// Daemon: Start in root of view/workspaceloc += mBaseline;}else{// mAlias used with jats -extractfiles -viewloc += p.mAlias;}//// Always use '/' as a path seperator - even if user has specified '\'// Ant can handle it.//loc = loc.replace('\\', '/');retVal +="<property name=\"" + target + "\" value=\"" + loc + "\"/>" + lf;mLogger.info("loc returned " + retVal);return retVal;}/**returns the buildInfo* p - Package to process* lf - End of Line terminator* filter - False: Include all build standards* True: Only include build standards relevent to the package*/private String buildInfo(Package p, String lf, boolean filter){mLogger.debug("buildInfo");String platforms = new String();String standards = new String();//// Create two (related) xlm sequences// platforms - <platform gbe_machtype="linux_i386"/>// standards - <jats target="all"/>//for (Iterator<BuildStandard> it = p.mBuildStandardCollection.iterator(); it.hasNext(); ){BuildStandard bs = it.next();if ( !filter || !bs.getBuildStandard(!ReleaseManager.mUseDatabase, true).contains("\"none\"") ){String platform = bs.getPlatform(!ReleaseManager.mUseDatabase, true);if ( platform.length() > 0 ){platforms += platform + lf;}String standard = bs.getBuildStandard(!ReleaseManager.mUseDatabase, true);if ( standard.length() > 0 ){standards += standard + lf;}}}mLogger.info("buildInfo returned " + platforms + standards);return platforms + standards;}/**prints to standard out in escrow mode only*/private void standardOut(final String message, final String alias, boolean printMessage){mLogger.debug("standardOut");if (!mDaemon){if ( printMessage ){System.out.println(message);// switch the message offprintMessage = false;}System.out.println(alias);}}}