xref: /trunk/main/xml2cmp/source/finder/dependy.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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