xref: /trunk/main/xml2cmp/source/finder/dependy.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 
29 #include "dependy.hxx"
30 #include <iostream>
31 #include "../support/syshelp.hxx"
32 #include "../support/list.hxx"
33 #include "../xcd/xmltree.hxx"
34 #include "../xcd/parse.hxx"
35 
36 
37 
38 Simstr 				ShortName(const Simstr & i_rService);
39 
40 
41 
42 Service::Service( const char * i_sName )
43 	:	sName(i_sName)
44 		// aImplementations
45 {
46 }
47 
48 ServiceInfo &
49 Service::AddImplementation( const char * i_sLibrary )
50 {
51 	ServiceInfo * ret = new ServiceInfo(i_sLibrary);
52 	aImplementations.push_back(ret);
53 	return *ret;
54 }
55 
56 ServiceInfo::ServiceInfo( const char * i_sLibrary )
57 	:	sImplementingLibrary(i_sLibrary)
58 		// aNeededServices
59 {
60 }
61 
62 void
63 ServiceInfo::AddDependency( const char * i_sNeededService )
64 {
65 	aNeededServices.push_back(i_sNeededService);
66 }
67 
68 DependencyFinder::DependencyFinder()
69 {
70 }
71 
72 DependencyFinder::~DependencyFinder()
73 {
74 }
75 
76 void
77 DependencyFinder::GatherData( const char * i_sSearchDirectory )
78 {
79 	List<Simstr> aFiles;
80 	GatherFileNames( aFiles, i_sSearchDirectory );
81 
82 	for ( unsigned i = 0; i < aFiles.size(); ++i )
83 	{
84 		ReadFile( aFiles[i].str() );
85 	}
86 }
87 
88 void
89 DependencyFinder::FindNeededServices( StringVector &		o_rLibraries,
90 									  StringVector &		o_rServices,
91 									  const Simstr &		i_rService )
92 {
93 	Map_Services::const_iterator itService = aServices.find(i_rService);
94 	if ( itService == aServices.end() )
95 	{
96 		std::cerr << "Error: Service \""
97 				  << i_rService.str()
98 				  << "\" not found."
99 				  << std::endl;
100 		return ;
101 	}
102 
103 	aResult_Libraries.erase( aResult_Libraries.begin(), aResult_Libraries.end() );
104 	aResult_Services.erase( aResult_Services.begin(), aResult_Services.end() );
105 
106 //	const ServiceInfo & rSInfo = (*itService).second->FirstImplementation();
107 	Add2Result( *(*itService).second );
108 
109 	for ( std::set< Simstr >::const_iterator il = aResult_Libraries.begin();
110 		  il != aResult_Libraries.end();
111 		  ++il )
112 	{
113 		o_rLibraries.push_back(*il);
114 	}
115 
116 	for ( std::set< Simstr >::const_iterator is = aResult_Services.begin();
117 		  is != aResult_Services.end();
118 		  ++is )
119 	{
120 		o_rServices.push_back(*is);
121 	}
122 }
123 
124 void
125 DependencyFinder::ReadFile(  const char * i_sFilename )
126 {
127 	ModuleDescription	aModule;
128 	X2CParser			aParser(aModule);
129 
130 	if ( !aParser.Parse(i_sFilename) )
131 	{
132 		std::cerr << "Error: File \""
133 			 << i_sFilename
134 			 << "\" could not be parsed."
135 			 << std::endl;
136 		return;
137 	}
138 
139 	// GetResults:
140 	Simstr sModule = aModule.ModuleName();
141 
142 	List < const MultipleTextElement* > aImplServices;
143 	List < const MultipleTextElement* > aNeededServices;
144 
145 	aModule.Get_SupportedServices(aImplServices);
146 	aModule.Get_ServiceDependencies(aNeededServices);
147 
148 	unsigned nImplServicesSize = aImplServices.size();
149 	unsigned nNeededServicesSize = aNeededServices.size();
150 
151 	for ( unsigned i = 0; i < nImplServicesSize; ++i )
152 	{
153 		const MultipleTextElement & rImpl = *aImplServices[i];
154 
155 		unsigned nImplDataSize = rImpl.Size();
156 		for ( unsigned di = 0; di < nImplDataSize; ++di )
157 		{
158 			Simstr sService = ShortName(rImpl.Data(di));
159 			Service * pService = aServices[sService];
160 			if (pService == 0)
161 			{
162 				pService = new Service(rImpl.Data(di));
163                 aServices[sService] = pService;
164 			}
165 			ServiceInfo & rSInfo = pService->AddImplementation(sModule);
166 
167 			for ( unsigned n = 0; n < nNeededServicesSize; ++n )
168 			{
169 				unsigned nNeededDataSize = aNeededServices[n]->Size();
170 				for ( unsigned dn = 0; dn < nNeededDataSize; ++dn )
171 				{
172 					if (! aNeededServices[n]->Data(dn).is_no_text())
173 						rSInfo.AddDependency( ShortName(aNeededServices[n]->Data(dn)) );
174 				}	// end for dn
175 			}	// end for n
176 		}	//	end for di
177 	}	// end for i
178 }
179 
180 void
181 DependencyFinder::Add2Result( const Service & i_rService )
182 {
183 	const ServiceInfo & rSInfo = i_rService.FirstImplementation();
184 	aResult_Libraries.insert(rSInfo.Library());
185 
186 	const ServiceInfo::List_NeededServices & rNeededs
187 			= rSInfo.NeededServices();
188 	for ( StringVector::const_iterator it = rNeededs.begin();
189 		  it != rNeededs.end();
190 		  ++it )
191 	{
192 		std::pair< std::set< Simstr >::iterator, bool > aInsertResult
193 				= aResult_Services.insert(*it);
194 		if (aInsertResult.second)
195 		{	// Needed service not yet known
196 			Map_Services::const_iterator itFound = aServices.find(*it);
197 			if ( itFound == aServices.end() )
198 			{
199 				std::cerr << "Needed service \""
200 						  << (*it).str()
201 						  << "\" not found,"
202 						  << std::endl;
203 			}
204 			else
205 			{
206 				Add2Result( *(*itFound).second );
207 			}
208 		} 	// endif (! aInsertResult.second)
209 	} 	// end for (it)
210 }
211 
212 
213 
214 Simstr
215 ShortName(const Simstr & i_rService)
216 {
217 	const char * pStart = i_rService.str();
218 	const char * pEnd = strchr(pStart,' ');
219 	if (pEnd != 0)
220 		return Simstr(pStart, 0, int(pEnd-pStart));
221 	else
222 		return i_rService;
223 }
224 
225