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