xref: /aoo41x/main/soldep/bootstrp/prodmap.cxx (revision cdf0e10c)
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