1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "prodmap.hxx" 29 #include <tools/geninfo.hxx> 30 #include <tools/fsys.hxx> 31 #include "minormk.hxx" 32 33 #include <stdio.h> 34 35 #define PRODUCT_KEY "TARGETDESCRIPTION/PRODUCTS" 36 #define DEPENDS_ON_KEY "TARGETDESCRIPTION/DEPENDSON" 37 #define BASED_ON_KEY "TARGETDESCRIPTION/BASEDON" 38 39 // 40 // class ProductMapper 41 // 42 43 /*****************************************************************************/ 44 ProductMapper::ProductMapper() 45 /*****************************************************************************/ 46 : pVersionList( NULL ), 47 pProductList( NULL ) 48 { 49 } 50 51 /*****************************************************************************/ 52 ProductMapper::ProductMapper( GenericInformationList *pVerList ) 53 /*****************************************************************************/ 54 : pVersionList( pVerList ), 55 pProductList( NULL ) 56 { 57 if ( pVerList ) 58 CreateProductList( pVerList ); 59 } 60 61 /*****************************************************************************/ 62 ProductMapper::~ProductMapper() 63 /*****************************************************************************/ 64 { 65 delete pProductList; 66 } 67 68 /*****************************************************************************/ 69 void ProductMapper::CreateProductList( GenericInformationList *pVerList ) 70 /*****************************************************************************/ 71 { 72 /* 73 creates a list of the following format: 74 75 ProductName Workspace // 6.0 Final SRC641 76 { // { 77 DependsOn // DependsOn 78 { // { 79 product1 // 80 product2 // 81 ... // 82 } // 83 BasedOn // 84 { // 85 productX // 86 productY // 87 ... // 88 } // 89 } // 90 */ 91 92 delete pProductList; 93 pProductList = NULL; 94 95 pVersionList = pVerList; 96 97 if ( pVersionList ) { 98 ByteString sProductKey( PRODUCT_KEY ); 99 ByteString sDependsOnKey( DEPENDS_ON_KEY ); 100 ByteString sBasedOnKey( BASED_ON_KEY ); 101 102 for ( sal_uIntPtr i = 0; i < pVersionList->Count(); i++ ) { 103 GenericInformation *pVersion = pVersionList->GetObject( i ); 104 105 GenericInformation *pProducts = pVersion->GetSubInfo( sProductKey, sal_True ); 106 if ( pProducts ) { 107 ByteString sProducts = pProducts->GetValue(); 108 109 ByteString sDependsOn; 110 GenericInformation *pDependsOn = pVersion->GetSubInfo( sDependsOnKey, sal_True ); 111 if ( pDependsOn ) 112 sDependsOn = pDependsOn->GetValue(); 113 114 ByteString sBasedOn; 115 GenericInformation *pBasedOn = pVersion->GetSubInfo( sBasedOnKey, sal_True ); 116 if ( pBasedOn ) 117 sBasedOn = pBasedOn->GetValue(); 118 119 for ( sal_uInt16 x = 0; x < sProducts.GetTokenCount( ';' ); x++ ) { 120 ByteString sProduct( sProducts.GetToken( x, ';' )); 121 if( sProduct.Len()) { 122 if ( !pProductList ) 123 pProductList = new GenericInformationList(); 124 125 pProductList->InsertInfo( sProduct, *pVersion, sal_True, sal_True ); 126 127 for ( sal_uInt16 y = 0; y < sDependsOn.GetTokenCount( ';' ); y++ ) { 128 ByteString sDependsOnKey_l = sProduct; 129 sDependsOnKey_l += "/DependsOn/"; 130 sDependsOnKey_l += sDependsOn.GetToken( y, ';' ); 131 132 pProductList->InsertInfo( sDependsOnKey_l, "", sal_True, sal_True ); 133 } 134 for ( sal_uInt16 z = 0; z < sBasedOn.GetTokenCount( ';' ); z++ ) { 135 ByteString sBasedOnKey_l = sProduct; 136 sBasedOnKey_l += "/BasedOn/"; 137 sBasedOnKey_l += sBasedOn.GetToken( z, ';' ); 138 139 pProductList->InsertInfo( sBasedOnKey_l, "", sal_True, sal_True ); 140 } 141 } 142 } 143 } 144 } 145 } 146 } 147 148 /*****************************************************************************/ 149 sal_uInt16 ProductMapper::GetProductInformation( 150 const ByteString &rProduct, GenericInformation *& pProductInfo ) 151 /*****************************************************************************/ 152 { 153 pProductInfo = NULL; 154 155 if ( !pVersionList ) 156 return PRODUCT_MAPPER_NO_VERSION_INFORMATION; 157 158 if ( !pProductList ) 159 return PRODUCT_MAPPER_NO_PRODUCT; 160 161 ByteString sProductKey( rProduct ); 162 pProductInfo = pProductList->GetInfo( sProductKey, sal_True ); 163 164 if ( !pProductInfo ) 165 return PRODUCT_MAPPER_NO_PRODUCT; 166 167 return PRODUCT_MAPPER_OK; 168 } 169 170 /*****************************************************************************/ 171 sal_uInt16 ProductMapper::PrintDependentTargets( 172 const ByteString &rProduct, sal_uInt16 nLevel ) 173 /*****************************************************************************/ 174 { 175 GenericInformation *pProductInfo; 176 177 sal_uInt16 nReturn = GetProductInformation( rProduct, pProductInfo ); 178 179 if ( nReturn == PRODUCT_MAPPER_OK ) { 180 for ( sal_uInt16 i = 0; i < nLevel; i++ ) 181 fprintf( stdout, " " ); 182 fprintf( stdout, "%s (%s)\n", pProductInfo->GetBuffer(), 183 pProductInfo->GetValue().GetBuffer()); 184 aPrintedList.PutString( new ByteString( *pProductInfo )); 185 186 for ( sal_uIntPtr j = 0; j < pProductList->Count(); j++ ) { 187 GenericInformation *pCandidate = pProductList->GetObject( j ); 188 ByteString sKey( "DEPENDSON/" ); 189 sKey += rProduct; 190 GenericInformation *pDependsOn = pCandidate->GetSubInfo( sKey, sal_True ); 191 if ( pDependsOn ) 192 PrintDependentTargets( *pCandidate, nLevel + 1 ); 193 } 194 if ( !nLevel ) { 195 ByteString sKey( "BASEDON" ); 196 GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey ); 197 if ( pBasedOn ) { 198 GenericInformationList *pBases = pBasedOn->GetSubList(); 199 if ( pBases ) { 200 for ( sal_uIntPtr k = 0; k < pBases->Count(); k++ ) { 201 aBaseList.PutString( new ByteString( *pBases->GetObject( k ))); 202 } 203 } 204 } 205 } 206 } 207 208 return nReturn; 209 } 210 211 /*****************************************************************************/ 212 sal_uInt16 ProductMapper::PrintAndDeleteBaseList() 213 /*****************************************************************************/ 214 { 215 if ( aBaseList.Count()) { 216 fprintf( stdout, "\nbased on\n" ); 217 while ( aBaseList.Count()) { 218 ByteString sProduct( *aBaseList.GetObject(( sal_uIntPtr ) 0 )); 219 if ( aPrintedList.IsString( aBaseList.GetObject(( sal_uIntPtr ) 0 )) == NOT_THERE ) { 220 aPrintedList.PutString( aBaseList.GetObject(( sal_uIntPtr ) 0 )); 221 PrintDependentTargets( sProduct ); 222 } 223 else 224 delete aBaseList.GetObject(( sal_uIntPtr ) 0 ); 225 226 aBaseList.Remove(( sal_uIntPtr ) 0 ); 227 } 228 while ( aPrintedList.Count()) 229 delete aPrintedList.Remove(( sal_uIntPtr ) 0 ); 230 231 fprintf( stdout, "\n" ); 232 } 233 return PRODUCT_MAPPER_OK; 234 } 235 236 /*****************************************************************************/ 237 sal_uInt16 ProductMapper::PrintDependencies( const ByteString &rProduct ) 238 /*****************************************************************************/ 239 { 240 sal_uInt16 nResult = PrintDependentTargets( rProduct ); 241 PrintAndDeleteBaseList(); 242 return nResult; 243 } 244 245 /*****************************************************************************/ 246 sal_uInt16 ProductMapper::PrintProductList() 247 /*****************************************************************************/ 248 { 249 if ( !pVersionList ) 250 return PRODUCT_MAPPER_NO_VERSION_INFORMATION; 251 252 if ( !pProductList || !pProductList->Count()) 253 return PRODUCT_MAPPER_NO_PRODUCT; 254 255 if ( pProductList->Count()) { 256 for ( sal_uIntPtr i = 0; i < pProductList->Count(); i++ ) 257 fprintf( stdout, "%s (%s)\n", 258 pProductList->GetObject( i )->GetBuffer(), 259 pProductList->GetObject( i )->GetValue().GetBuffer()); 260 fprintf( stdout, "\n" ); 261 } 262 263 return PRODUCT_MAPPER_OK; 264 } 265 266 /*****************************************************************************/ 267 SByteStringList *ProductMapper::GetMinorList( 268 const ByteString &rVersion, const ByteString &rEnvironment ) 269 /*****************************************************************************/ 270 { 271 SByteStringList *pList = NULL; 272 273 if ( pVersionList ) { 274 String sRoot( GetVersionRoot( pVersionList, rVersion )); 275 if ( sRoot.Len()) { 276 DirEntry aEntry( sRoot ); 277 aEntry += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US )); 278 String sWildcard( String::CreateFromAscii( "inc.*" )); 279 aEntry += DirEntry( sWildcard ); 280 281 Dir aDir( aEntry, FSYS_KIND_DIR ); 282 for ( sal_uInt16 i = 0; i < aDir.Count(); i++ ) { 283 ByteString sInc( aDir[ i ].GetName(), RTL_TEXTENCODING_ASCII_US ); 284 if ( sInc.GetTokenCount( '.' ) > 1 ) { 285 if ( !pList ) 286 pList = new SByteStringList(); 287 pList->PutString( new ByteString( sInc.GetToken( 1, '.' ))); 288 } 289 } 290 } 291 } 292 return pList; 293 } 294 295 /*****************************************************************************/ 296 String ProductMapper::GetVersionRoot( 297 GenericInformationList *pList, const ByteString &rVersion ) 298 /*****************************************************************************/ 299 { 300 ByteString sKey( rVersion ); 301 GenericInformation *pVersion = pList->GetInfo( sKey ); 302 if ( pVersion ) { 303 #ifdef UNX 304 sKey = "drives/o:/unixvolume"; 305 GenericInformation *pUnixVolume = pVersion->GetSubInfo( sKey, sal_True ); 306 ByteString sPath; 307 if ( pUnixVolume ) 308 sPath = pUnixVolume->GetValue(); 309 sPath += "/"; 310 #else 311 ByteString sPath( "o:\\" ); 312 #endif 313 sKey = "settings/path"; 314 GenericInformation *pPath = pVersion->GetSubInfo( sKey, sal_True ); 315 if ( pPath ) { 316 sPath += pPath->GetValue().GetToken( 0, '\\' ); 317 sPath += "/"; 318 } 319 #ifdef UNX 320 sPath.SearchAndReplaceAll( "\\", "/" ); 321 while( sPath.SearchAndReplace( "//", "/" ) != STRING_NOTFOUND ) {}; 322 #else 323 sPath.SearchAndReplaceAll( "/", "\\" ); 324 while( sPath.SearchAndReplace( "\\\\", "\\" ) != STRING_NOTFOUND ) {}; 325 #endif 326 327 return String( sPath, RTL_TEXTENCODING_ASCII_US ); 328 } 329 return String(); 330 } 331 332 /*****************************************************************************/ 333 BaseProductList *ProductMapper::GetBases( 334 GenericInformation *pProductInfo, sal_uInt16 nLevel, 335 BaseProductList *pBases ) 336 /*****************************************************************************/ 337 { 338 if ( !pBases ) 339 pBases = new BaseProductList(); 340 341 if ( pProductInfo ) { 342 ByteString sCandidate( *pProductInfo ); 343 sCandidate += " ("; 344 sCandidate += pProductInfo->GetValue(); 345 sCandidate += ")"; 346 347 ByteString sKey( "BASEDON" ); 348 GenericInformation *pBasedOn = pProductInfo->GetSubInfo( sKey ); 349 if ( pBasedOn ) { 350 GenericInformationList *pBasesInfo = pBasedOn->GetSubList(); 351 if ( pBasesInfo ) { 352 for ( sal_uIntPtr k = 0; k < pBasesInfo->Count(); k++ ) { 353 GenericInformation *pBaseProduct; 354 if ( GetProductInformation( *pBasesInfo->GetObject( k ), pBaseProduct ) == PRODUCT_MAPPER_OK ) 355 GetBases( pBaseProduct, ++ nLevel, pBases ); 356 } 357 } 358 } 359 sal_Bool bFound = sal_False; 360 ByteString sUpperCandidate( sCandidate ); 361 sUpperCandidate.ToUpperAscii(); 362 for ( sal_uInt16 i = 0; i < pBases->Count() && !bFound; i++ ) { 363 ByteString sTest( *pBases->GetObject( i )); 364 if ( sTest.ToUpperAscii() == sUpperCandidate ) 365 bFound = sal_True; 366 } 367 if ( !bFound ) 368 pBases->Insert( new ByteString( sCandidate ), ( sal_uIntPtr ) 0 ); 369 } 370 return pBases; 371 } 372 373 /*****************************************************************************/ 374 sal_uInt16 ProductMapper::PrintMinorList( 375 const ByteString rProduct, const ByteString rEnvironment ) 376 /*****************************************************************************/ 377 { 378 if ( !pVersionList ) 379 return PRODUCT_MAPPER_NO_VERSION_INFORMATION; 380 381 if ( !pProductList || !pProductList->Count()) 382 return PRODUCT_MAPPER_NO_PRODUCT; 383 384 GenericInformation *pProductInfo; 385 GetProductInformation( rProduct, pProductInfo ); 386 if ( !pProductInfo ) 387 return PRODUCT_MAPPER_NO_PRODUCT; 388 389 BaseProductList *pBases = GetBases( pProductInfo ); 390 if ( pBases->Count()) { 391 if ( pBases->Count() > 1 ) 392 fprintf( stdout, "Product \"%s\" based on ", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer()); 393 else 394 fprintf( stdout, "Product \"%s\" based on no other products", pBases->GetObject(( sal_uIntPtr ) 0 )->GetBuffer()); 395 396 for ( sal_uIntPtr i = 1; i < pBases->Count(); i++ ) { 397 fprintf( stdout, "\"%s\"", pBases->GetObject( i )->GetBuffer()); 398 if ( i < pBases->Count() - 1 ) 399 fprintf( stdout, ", " ); 400 } 401 fprintf( stdout, "\n\n" ); 402 } 403 sal_uInt16 nResult = PRODUCT_MAPPER_OK; 404 405 if ( rEnvironment.Len()) 406 nResult = PrintSingleMinorList( pProductInfo, pBases, rEnvironment ); 407 else { 408 ByteString sEnvKey( pProductInfo->GetValue()); 409 sEnvKey += "/Environments"; 410 411 GenericInformation *pEnvironmentInfo = pVersionList->GetInfo( sEnvKey, sal_True ); 412 if ( pEnvironmentInfo ) { 413 GenericInformationList *pEnvironmentList = pEnvironmentInfo->GetSubList(); 414 if ( pEnvironmentList ) { 415 for ( sal_uIntPtr i = 0; i < pEnvironmentList->Count(); i++ ) { 416 sal_uInt16 nTmp = PrintSingleMinorList( pProductInfo, pBases, *pEnvironmentList->GetObject( i )); 417 if ( nTmp != PRODUCT_MAPPER_OK ) 418 nResult = nTmp; 419 } 420 } 421 } 422 } 423 424 for ( sal_uIntPtr m = 0; m < pBases->Count(); m++ ) 425 delete pBases->GetObject( m ); 426 delete pBases; 427 428 return nResult; 429 } 430 431 /*****************************************************************************/ 432 sal_uInt16 ProductMapper::PrintSingleMinorList( 433 GenericInformation *pProductInfo, BaseProductList *pBases, 434 const ByteString rEnvironment ) 435 /*****************************************************************************/ 436 { 437 DirEntry aRoot( GetVersionRoot( pVersionList, pProductInfo->GetValue())); 438 aRoot += DirEntry( String( rEnvironment, RTL_TEXTENCODING_ASCII_US )); 439 if ( !aRoot.Exists()) 440 return PRODUCT_MAPPER_OK; 441 442 SByteStringList *pMinors = GetMinorList( pProductInfo->GetValue(), rEnvironment ); 443 if ( !pMinors ) 444 pMinors = new SByteStringList(); 445 pMinors->Insert( new ByteString( "" ), LIST_APPEND ); 446 447 SByteStringList aOutputList; 448 sal_Bool bUnknownMinor = sal_False; 449 for ( sal_uIntPtr i = 0; i < pMinors->Count(); i++ ) { 450 ByteString sOutput; 451 ByteString sProductVersion; 452 453 for ( sal_uIntPtr j = 0; j < pBases->Count(); j++ ) { 454 ByteString sCurProduct( *pBases->GetObject( j )); 455 ByteString sVersion( sCurProduct.GetToken( sCurProduct.GetTokenCount( '(' ) - 1, '(' ).GetToken( 0, ')' )); 456 if ( !j ) 457 sProductVersion = sVersion; 458 459 MinorMk *pMinorMk = new MinorMk( 460 pVersionList, sProductVersion, sVersion, rEnvironment, *pMinors->GetObject( i )); 461 462 ByteString sMinor( pMinorMk->GetLastMinor().GetBuffer()); 463 if ( !sMinor.Len()) { 464 sMinor = "!"; 465 bUnknownMinor = sal_True; 466 } 467 if ( j == 0 ) { 468 sOutput += pMinorMk->GetBuildNr(); 469 sOutput += " "; 470 471 if ( i == pMinors->Count() - 1 ) 472 sOutput += "flat: "; 473 else 474 sOutput += " "; 475 } 476 sOutput += sVersion; 477 sOutput += "."; 478 sOutput += sMinor; 479 sOutput += "("; 480 sOutput += pMinorMk->GetBuildNr(); 481 sOutput += ") "; 482 } 483 aOutputList.PutString( new ByteString( sOutput )); 484 } 485 ByteString sOldMinor; 486 487 if ( aOutputList.Count()) 488 fprintf( stdout, "Available builds on %s:\n", rEnvironment.GetBuffer()); 489 490 for ( sal_uIntPtr o = 0; o < aOutputList.Count(); o++ ) { 491 ByteString sOutput( *aOutputList.GetObject( o )); 492 sOutput = sOutput.Copy( sOutput.GetToken( 0, ' ' ).Len() + 1 ); 493 494 ByteString sCurMinor( sOutput.GetToken( 1, '.' ).GetToken( 0, '(' )); 495 if ( sOldMinor.Len() && sCurMinor < sOldMinor ) { 496 fprintf( stdout, " ----------\n" ); 497 } 498 sOldMinor = sCurMinor; 499 500 fprintf( stdout, "%s\n", sOutput.GetBuffer()); 501 delete aOutputList.GetObject( o ); 502 } 503 if ( bUnknownMinor ) 504 fprintf( stdout, "Symbol ! indcates that at least one minor could not be found\n\n" ); 505 else if ( aOutputList.Count()) 506 fprintf( stdout, "\n" ); 507 508 for ( sal_uIntPtr l = 0; l < pMinors->Count(); l++ ) 509 delete pMinors->GetObject( l ); 510 delete pMinors; 511 512 return PRODUCT_MAPPER_OK; 513 } 514 515 516 517 518