blob: 5294b127ec6163298447c8ac5e05dc329714904f [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "prodmap.hxx"
#include <tools/geninfo.hxx>
#include <tools/fsys.hxx>
#include "minormk.hxx"
#include <stdio.h>
#define PRODUCT_KEY "TARGETDESCRIPTION/PRODUCTS"
#define DEPENDS_ON_KEY "TARGETDESCRIPTION/DEPENDSON"
#define BASED_ON_KEY "TARGETDESCRIPTION/BASEDON"
//
// class ProductMapper
//
/*****************************************************************************/
ProductMapper::ProductMapper()
/*****************************************************************************/
: pVersionList( NULL ),
pProductList( NULL )
{
}
/*****************************************************************************/
ProductMapper::ProductMapper( GenericInformationList *pVerList )
/*****************************************************************************/
: pVersionList( pVerList ),
pProductList( NULL )
{
if ( pVerList )
CreateProductList( pVerList );
}
/*****************************************************************************/
ProductMapper::~ProductMapper()
/*****************************************************************************/
{
delete pProductList;
}
/*****************************************************************************/
void ProductMapper::CreateProductList( GenericInformationList *pVerList )
/*****************************************************************************/
{
/*
creates a list of the following format:
ProductName Workspace // 6.0 Final SRC641
{ // {
DependsOn // DependsOn
{ // {
product1 //
product2 //
... //
} //
BasedOn //
{ //
productX //
productY //
... //
} //
} //
*/
delete pProductList;
pProductList = NULL;
pVersionList = pVerList;
if ( pVersionList ) {
ByteString sProductKey( PRODUCT_KEY );
ByteString sDependsOnKey( DEPENDS_ON_KEY );
ByteString sBasedOnKey( BASED_ON_KEY );
for ( sal_uIntPtr i = 0; i < pVersionList->Count(); i++ ) {
GenericInformation *pVersion = pVersionList->GetObject( i );
GenericInformation *pProducts = pVersion->GetSubInfo( sProductKey, sal_True );
if ( pProducts ) {
ByteString sProducts = pProducts->GetValue();
ByteString sDependsOn;
GenericInformation *pDependsOn = pVersion->GetSubInfo( sDependsOnKey, sal_True );
if ( pDependsOn )
sDependsOn = pDependsOn->GetValue();
ByteString sBasedOn;
GenericInformation *pBasedOn = pVersion->GetSubInfo( sBasedOnKey, sal_True );
if ( pBasedOn )
sBasedOn = pBasedOn->GetValue();
for ( sal_uInt16 x = 0; x < sProducts.GetTokenCount( ';' ); x++ ) {
ByteString sProduct( sProducts.GetToken( x, ';' ));
if( sProduct.Len()) {
if ( !pProductList )
pProductList = new GenericInformationList();
pProductList->InsertInfo( sProduct, *pVersion, sal_True, sal_True );
for ( sal_uInt16 y = 0; y < sDependsOn.GetTokenCount( ';' ); y++ ) {
ByteString sDependsOnKey_l = sProduct;
sDependsOnKey_l += "/DependsOn/";
sDependsOnKey_l += sDependsOn.GetToken( y, ';' );
pProductList->InsertInfo( sDependsOnKey_l, "", sal_True, sal_True );
}
for ( sal_uInt16 z = 0; z < sBasedOn.GetTokenCount( ';' ); z++ ) {
ByteString sBasedOnKey_l = sProduct;
sBasedOnKey_l += "/BasedOn/";
sBasedOnKey_l += sBasedOn.GetToken( z, ';' );
pProductList->InsertInfo( sBasedOnKey_l, "", sal_True, sal_True );
}
}
}
}
}
}
}
/*****************************************************************************/
sal_uInt16 ProductMapper::GetProductInformation(
const ByteString &rProduct, GenericInformation *& pProductInfo )
/*****************************************************************************/
{
pProductInfo = NULL;
if ( !pVersionList )
return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
if ( !pProductList )
return PRODUCT_MAPPER_NO_PRODUCT;
ByteString sProductKey( rProduct );
pProductInfo = pProductList->GetInfo( sProductKey, sal_True );
if ( !pProductInfo )
return PRODUCT_MAPPER_NO_PRODUCT;
return PRODUCT_MAPPER_OK;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintDependentTargets(
const ByteString &rProduct, sal_uInt16 nLevel )
/*****************************************************************************/
{
GenericInformation *pProductInfo;
sal_uInt16 nReturn = GetProductInformation( rProduct, pProductInfo );
if ( nReturn == PRODUCT_MAPPER_OK ) {
for ( sal_uInt16 i = 0; i < nLevel; i++ )
fprintf( stdout, " " );
fprintf( stdout, "%s (%s)\n", pProductInfo->GetBuffer(),
pProductInfo->GetValue().GetBuffer());
aPrintedList.PutString( new ByteString( *pProductInfo ));
for ( sal_uIntPtr j = 0; j < pProductList->Count(); j++ ) {
GenericInformation *pCandidate = pProductList->GetObject( j );
ByteString sKey( "DEPENDSON/" );
sKey += rProduct;
GenericInformation *pDependsOn = pCandidate->GetSubInfo( sKey, sal_True );
if ( pDependsOn )
PrintDependentTargets( *pCandidate, nLevel + 1 );
}
if ( !nLevel ) {
ByteString sKey( "BASEDON" );
GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey );
if ( pBasedOn ) {
GenericInformationList *pBases = pBasedOn->GetSubList();
if ( pBases ) {
for ( sal_uIntPtr k = 0; k < pBases->Count(); k++ ) {
aBaseList.PutString( new ByteString( *pBases->GetObject( k )));
}
}
}
}
}
return nReturn;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintAndDeleteBaseList()
/*****************************************************************************/
{
if ( aBaseList.Count()) {
fprintf( stdout, "\nbased on\n" );
while ( aBaseList.Count()) {
ByteString sProduct( *aBaseList.GetObject(( sal_uIntPtr ) 0 ));
if ( aPrintedList.IsString( aBaseList.GetObject(( sal_uIntPtr ) 0 )) == NOT_THERE ) {
aPrintedList.PutString( aBaseList.GetObject(( sal_uIntPtr ) 0 ));
PrintDependentTargets( sProduct );
}
else
delete aBaseList.GetObject(( sal_uIntPtr ) 0 );
aBaseList.Remove(( sal_uIntPtr ) 0 );
}
while ( aPrintedList.Count())
delete aPrintedList.Remove(( sal_uIntPtr ) 0 );
fprintf( stdout, "\n" );
}
return PRODUCT_MAPPER_OK;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintDependencies( const ByteString &rProduct )
/*****************************************************************************/
{
sal_uInt16 nResult = PrintDependentTargets( rProduct );
PrintAndDeleteBaseList();
return nResult;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintProductList()
/*****************************************************************************/
{
if ( !pVersionList )
return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
if ( !pProductList || !pProductList->Count())
return PRODUCT_MAPPER_NO_PRODUCT;
if ( pProductList->Count()) {
for ( sal_uIntPtr i = 0; i < pProductList->Count(); i++ )
fprintf( stdout, "%s (%s)\n",
pProductList->GetObject( i )->GetBuffer(),
pProductList->GetObject( i )->GetValue().GetBuffer());
fprintf( stdout, "\n" );
}
return PRODUCT_MAPPER_OK;
}
/*****************************************************************************/
SByteStringList *ProductMapper::GetMinorList(
const ByteString &rVersion, const ByteString &rEnvironment )
/*****************************************************************************/
{
SByteStringList *pList = NULL;
if ( pVersionList ) {
String sRoot( GetVersionRoot( pVersionList, rVersion ));
if ( sRoot.Len()) {
DirEntry aEntry( sRoot );
aEntry += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US ));
String sWildcard( String::CreateFromAscii( "inc.*" ));
aEntry += DirEntry( sWildcard );
Dir aDir( aEntry, FSYS_KIND_DIR );
for ( sal_uInt16 i = 0; i < aDir.Count(); i++ ) {
ByteString sInc( aDir[ i ].GetName(), RTL_TEXTENCODING_ASCII_US );
if ( sInc.GetTokenCount( '.' ) > 1 ) {
if ( !pList )
pList = new SByteStringList();
pList->PutString( new ByteString( sInc.GetToken( 1, '.' )));
}
}
}
}
return pList;
}
/*****************************************************************************/
String ProductMapper::GetVersionRoot(
GenericInformationList *pList, const ByteString &rVersion )
/*****************************************************************************/
{
ByteString sKey( rVersion );
GenericInformation *pVersion = pList->GetInfo( sKey );
if ( pVersion ) {
#ifdef UNX
sKey = "drives/o:/unixvolume";
GenericInformation *pUnixVolume = pVersion->GetSubInfo( sKey, sal_True );
ByteString sPath;
if ( pUnixVolume )
sPath = pUnixVolume->GetValue();
sPath += "/";
#else
ByteString sPath( "o:\\" );
#endif
sKey = "settings/path";
GenericInformation *pPath = pVersion->GetSubInfo( sKey, sal_True );
if ( pPath ) {
sPath += pPath->GetValue().GetToken( 0, '\\' );
sPath += "/";
}
#ifdef UNX
sPath.SearchAndReplaceAll( "\\", "/" );
while( sPath.SearchAndReplace( "//", "/" ) != STRING_NOTFOUND ) {};
#else
sPath.SearchAndReplaceAll( "/", "\\" );
while( sPath.SearchAndReplace( "\\\\", "\\" ) != STRING_NOTFOUND ) {};
#endif
return String( sPath, RTL_TEXTENCODING_ASCII_US );
}
return String();
}
/*****************************************************************************/
BaseProductList *ProductMapper::GetBases(
GenericInformation *pProductInfo, sal_uInt16 nLevel,
BaseProductList *pBases )
/*****************************************************************************/
{
if ( !pBases )
pBases = new BaseProductList();
if ( pProductInfo ) {
ByteString sCandidate( *pProductInfo );
sCandidate += " (";
sCandidate += pProductInfo->GetValue();
sCandidate += ")";
ByteString sKey( "BASEDON" );
GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey );
if ( pBasedOn ) {
GenericInformationList *pBasesInfo = pBasedOn->GetSubList();
if ( pBasesInfo ) {
for ( sal_uIntPtr k = 0; k < pBasesInfo->Count(); k++ ) {
GenericInformation *pBaseProduct;
if ( GetProductInformation( *pBasesInfo->GetObject( k ), pBaseProduct ) == PRODUCT_MAPPER_OK )
GetBases( pBaseProduct, ++ nLevel, pBases );
}
}
}
sal_Bool bFound = sal_False;
ByteString sUpperCandidate( sCandidate );
sUpperCandidate.ToUpperAscii();
for ( sal_uInt16 i = 0; i < pBases->Count() && !bFound; i++ ) {
ByteString sTest( *pBases->GetObject( i ));
if ( sTest.ToUpperAscii() == sUpperCandidate )
bFound = sal_True;
}
if ( !bFound )
pBases->Insert( new ByteString( sCandidate ), ( sal_uIntPtr ) 0 );
}
return pBases;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintMinorList(
const ByteString rProduct, const ByteString rEnvironment )
/*****************************************************************************/
{
if ( !pVersionList )
return PRODUCT_MAPPER_NO_VERSION_INFORMATION;
if ( !pProductList || !pProductList->Count())
return PRODUCT_MAPPER_NO_PRODUCT;
GenericInformation *pProductInfo;
GetProductInformation( rProduct, pProductInfo );
if ( !pProductInfo )
return PRODUCT_MAPPER_NO_PRODUCT;
BaseProductList *pBases = GetBases( pProductInfo );
if ( pBases->Count()) {
if ( pBases->Count() > 1 )
fprintf( stdout, "Product \"%s\" based on ", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer());
else
fprintf( stdout, "Product \"%s\" based on no other products", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer());
for ( sal_uIntPtr i = 1; i < pBases->Count(); i++ ) {
fprintf( stdout, "\"%s\"", pBases->GetObject( i )->GetBuffer());
if ( i < pBases->Count() - 1 )
fprintf( stdout, ", " );
}
fprintf( stdout, "\n\n" );
}
sal_uInt16 nResult = PRODUCT_MAPPER_OK;
if ( rEnvironment.Len())
nResult = PrintSingleMinorList( pProductInfo, pBases, rEnvironment );
else {
ByteString sEnvKey( pProductInfo->GetValue());
sEnvKey += "/Environments";
GenericInformation *pEnvironmentInfo = pVersionList->GetInfo( sEnvKey, sal_True );
if ( pEnvironmentInfo ) {
GenericInformationList *pEnvironmentList = pEnvironmentInfo->GetSubList();
if ( pEnvironmentList ) {
for ( sal_uIntPtr i = 0; i < pEnvironmentList->Count(); i++ ) {
sal_uInt16 nTmp = PrintSingleMinorList( pProductInfo, pBases, *pEnvironmentList->GetObject( i ));
if ( nTmp != PRODUCT_MAPPER_OK )
nResult = nTmp;
}
}
}
}
for ( sal_uIntPtr m = 0; m < pBases->Count(); m++ )
delete pBases->GetObject( m );
delete pBases;
return nResult;
}
/*****************************************************************************/
sal_uInt16 ProductMapper::PrintSingleMinorList(
GenericInformation *pProductInfo, BaseProductList *pBases,
const ByteString rEnvironment )
/*****************************************************************************/
{
DirEntry aRoot( GetVersionRoot( pVersionList, pProductInfo->GetValue()));
aRoot += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US ));
if ( !aRoot.Exists())
return PRODUCT_MAPPER_OK;
SByteStringList *pMinors = GetMinorList( pProductInfo->GetValue(), rEnvironment );
if ( !pMinors )
pMinors = new SByteStringList();
pMinors->Insert( new ByteString( "" ), LIST_APPEND );
SByteStringList aOutputList;
sal_Bool bUnknownMinor = sal_False;
for ( sal_uIntPtr i = 0; i < pMinors->Count(); i++ ) {
ByteString sOutput;
ByteString sProductVersion;
for ( sal_uIntPtr j = 0; j < pBases->Count(); j++ ) {
ByteString sCurProduct( *pBases->GetObject( j ));
ByteString sVersion( sCurProduct.GetToken( sCurProduct.GetTokenCount( '(' ) - 1, '(' ).GetToken( 0, ')' ));
if ( !j )
sProductVersion = sVersion;
MinorMk *pMinorMk = new MinorMk(
pVersionList, sProductVersion, sVersion, rEnvironment, *pMinors->GetObject( i ));
ByteString sMinor( pMinorMk->GetLastMinor().GetBuffer());
if ( !sMinor.Len()) {
sMinor = "!";
bUnknownMinor = sal_True;
}
if ( j == 0 ) {
sOutput += pMinorMk->GetBuildNr();
sOutput += " ";
if ( i == pMinors->Count() - 1 )
sOutput += "flat: ";
else
sOutput += " ";
}
sOutput += sVersion;
sOutput += ".";
sOutput += sMinor;
sOutput += "(";
sOutput += pMinorMk->GetBuildNr();
sOutput += ") ";
}
aOutputList.PutString( new ByteString( sOutput ));
}
ByteString sOldMinor;
if ( aOutputList.Count())
fprintf( stdout, "Available builds on %s:\n", rEnvironment.GetBuffer());
for ( sal_uIntPtr o = 0; o < aOutputList.Count(); o++ ) {
ByteString sOutput( *aOutputList.GetObject( o ));
sOutput = sOutput.Copy( sOutput.GetToken( 0, ' ' ).Len() + 1 );
ByteString sCurMinor( sOutput.GetToken( 1, '.' ).GetToken( 0, '(' ));
if ( sOldMinor.Len() && sCurMinor < sOldMinor ) {
fprintf( stdout, " ----------\n" );
}
sOldMinor = sCurMinor;
fprintf( stdout, "%s\n", sOutput.GetBuffer());
delete aOutputList.GetObject( o );
}
if ( bUnknownMinor )
fprintf( stdout, "Symbol ! indcates that at least one minor could not be found\n\n" );
else if ( aOutputList.Count())
fprintf( stdout, "\n" );
for ( sal_uIntPtr l = 0; l < pMinors->Count(); l++ )
delete pMinors->GetObject( l );
delete pMinors;
return PRODUCT_MAPPER_OK;
}