xref: /aoo4110/main/soldep/bootstrp/prodmap.cxx (revision b1cdbd2c)
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 /*****************************************************************************/
ProductMapper()40 ProductMapper::ProductMapper()
41 /*****************************************************************************/
42 				: pVersionList( NULL ),
43 				pProductList( NULL )
44 {
45 }
46 
47 /*****************************************************************************/
ProductMapper(GenericInformationList * pVerList)48 ProductMapper::ProductMapper( GenericInformationList *pVerList )
49 /*****************************************************************************/
50 				: pVersionList( pVerList ),
51 				pProductList( NULL )
52 {
53 	if ( pVerList )
54 		CreateProductList( pVerList );
55 }
56 
57 /*****************************************************************************/
~ProductMapper()58 ProductMapper::~ProductMapper()
59 /*****************************************************************************/
60 {
61 	delete pProductList;
62 }
63 
64 /*****************************************************************************/
CreateProductList(GenericInformationList * pVerList)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 /*****************************************************************************/
GetProductInformation(const ByteString & rProduct,GenericInformation * & pProductInfo)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 /*****************************************************************************/
PrintDependentTargets(const ByteString & rProduct,sal_uInt16 nLevel)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 /*****************************************************************************/
PrintAndDeleteBaseList()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 /*****************************************************************************/
PrintDependencies(const ByteString & rProduct)233 sal_uInt16 ProductMapper::PrintDependencies( const ByteString &rProduct )
234 /*****************************************************************************/
235 {
236 	sal_uInt16 nResult = PrintDependentTargets( rProduct );
237 	PrintAndDeleteBaseList();
238 	return nResult;
239 }
240 
241 /*****************************************************************************/
PrintProductList()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 /*****************************************************************************/
GetMinorList(const ByteString & rVersion,const ByteString & rEnvironment)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 /*****************************************************************************/
GetVersionRoot(GenericInformationList * pList,const ByteString & rVersion)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 /*****************************************************************************/
GetBases(GenericInformation * pProductInfo,sal_uInt16 nLevel,BaseProductList * pBases)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 /*****************************************************************************/
PrintMinorList(const ByteString rProduct,const ByteString rEnvironment)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 /*****************************************************************************/
PrintSingleMinorList(GenericInformation * pProductInfo,BaseProductList * pBases,const ByteString rEnvironment)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