]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java
Fix the bug for not add error reporting in getAllDynamicPcdInfoFromFpd(), it block...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PlatformPcdPreprocessActionForBuilding.java
... / ...
CommitLineData
1/** @file\r
2 PlatformPcdPreprocessActionForBuilding class.\r
3\r
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
5 This class will be used for wizard and build tools, So it can *not* inherit\r
6 from buildAction or wizardAction.\r
7\r
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18package org.tianocore.build.pcd.action;\r
19\r
20import java.io.File;\r
21import java.io.IOException;\r
22import java.math.BigInteger;\r
23import java.util.ArrayList;\r
24import java.util.Iterator;\r
25import java.util.List;\r
26import java.util.Map;\r
27\r
28import org.apache.xmlbeans.XmlException;\r
29import org.apache.xmlbeans.XmlObject;\r
30import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
31import org.tianocore.PcdBuildDefinitionDocument;\r
32import org.tianocore.PlatformSurfaceAreaDocument;\r
33import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;\r
34import org.tianocore.build.fpd.FpdParserTask;\r
35import org.tianocore.build.global.GlobalData;\r
36import org.tianocore.build.id.FpdModuleIdentification;\r
37import org.tianocore.pcd.action.ActionMessage;\r
38import org.tianocore.pcd.action.PlatformPcdPreprocessAction;\r
39import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
40import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;\r
41import org.tianocore.pcd.entity.Token;\r
42import org.tianocore.pcd.entity.UsageIdentification;\r
43import org.tianocore.pcd.exception.EntityException;\r
44import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
45\r
46/**\r
47 This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
48 This class will be used for wizard and build tools, So it can *not* inherit\r
49 from buildAction or UIAction.\r
50**/\r
51public class PlatformPcdPreprocessActionForBuilding extends PlatformPcdPreprocessAction {\r
52 ///\r
53 /// FPD file is the root file.\r
54 ///\r
55 private String fpdFilePath;\r
56\r
57 ///\r
58 /// Message level for CollectPCDAction.\r
59 ///\r
60 private int originalMessageLevel;\r
61\r
62 ///\r
63 /// Cache the fpd docment instance for private usage.\r
64 ///\r
65 private PlatformSurfaceAreaDocument fpdDocInstance;\r
66\r
67 /**\r
68 Set action message level for CollectPcdAction tool.\r
69\r
70 The message should be restored when this action exit.\r
71\r
72 @param actionMessageLevel parameter for this action\r
73 **/\r
74 public void setActionMessageLevel(int actionMessageLevel) {\r
75 originalMessageLevel = ActionMessage.messageLevel;\r
76 ActionMessage.messageLevel = actionMessageLevel;\r
77 }\r
78\r
79 /**\r
80 Set FPDFileName parameter for this action class.\r
81\r
82 @param fpdFilePath fpd file path\r
83 **/\r
84 public void setFPDFilePath(String fpdFilePath) {\r
85 this.fpdFilePath = fpdFilePath;\r
86 }\r
87\r
88 /**\r
89 Common function interface for outer.\r
90\r
91 @param fpdFilePath The fpd file path of current build or analysis.\r
92 @param messageLevel The message level for this Action.\r
93\r
94 @throws PlatformPreprocessBuildException \r
95 The exception of this function. Because it can *not* be predict\r
96 where the action class will be used. So only Exception can be throw.\r
97\r
98 **/\r
99 public void perform(String fpdFilePath, int messageLevel) \r
100 throws PlatformPcdPreprocessBuildException {\r
101 setFPDFilePath(fpdFilePath);\r
102 setActionMessageLevel(messageLevel);\r
103 checkParameter();\r
104 execute();\r
105 ActionMessage.messageLevel = originalMessageLevel;\r
106 }\r
107\r
108 /**\r
109 Core execution function for this action class.\r
110\r
111 This function work flows will be:\r
112 1) Collect and prepocess PCD information from FPD file, all PCD\r
113 information will be stored into memory database.\r
114 2) Generate 3 strings for\r
115 a) All modules using Dynamic(Ex) PCD entry.(Token Number)\r
116 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.\r
117 c) DXE PCD Database (C structure) for PCD Service DXE.\r
118\r
119\r
120 @throws EntityException Exception indicate failed to execute this action.\r
121\r
122 **/\r
123 public void execute() throws PlatformPcdPreprocessBuildException {\r
124 String errorMessageHeader = "Fail to initialize Pcd memory database for building. Because:";\r
125 String errorsForPreprocess = null;\r
126\r
127 //\r
128 // Get memoryDatabaseManager instance from GlobalData.\r
129 // The memoryDatabaseManager should be initialized as static variable\r
130 // in some Pre-process class.\r
131 //\r
132 setPcdDbManager(GlobalData.getPCDMemoryDBManager());\r
133\r
134 //\r
135 // Collect all PCD information defined in FPD file.\r
136 // Evenry token defind in FPD will be created as an token into\r
137 // memory database.\r
138 //\r
139 try {\r
140 initPcdMemoryDbWithPlatformInfo();\r
141 } catch (PlatformPcdPreprocessException exp) {\r
142 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
143 }\r
144 errorsForPreprocess = this.getErrorString();\r
145 if (errorsForPreprocess != null) {\r
146 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);\r
147 }\r
148\r
149 //\r
150 // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
151 //\r
152 try {\r
153 genPcdDatabaseSourceCode ();\r
154 } catch (EntityException exp) {\r
155 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
156 }\r
157 }\r
158\r
159 /**\r
160 Override function: implementate the method of get Guid string information from SPD file.\r
161\r
162 @param guidCName Guid CName string.\r
163\r
164 @return String Guid information from SPD file.\r
165 @throws PlatformPcdPreprocessException\r
166 Fail to get Guid information from SPD file.\r
167 **/\r
168 public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {\r
169 String tokenSpaceStrRet = null;\r
170 try {\r
171 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);\r
172 } catch ( Exception e ) {\r
173 throw new PlatformPcdPreprocessException ("Failed get Guid CName " + guidCName + "from SPD file!");\r
174 }\r
175 return tokenSpaceStrRet;\r
176 }\r
177\r
178 /**\r
179 This function generates source code for PCD Database.\r
180\r
181 @throws EntityException If the token does *not* exist in memory database.\r
182\r
183 **/\r
184 private void genPcdDatabaseSourceCode()\r
185 throws EntityException {\r
186 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions();\r
187\r
188 ArrayList<Token> alPei = new ArrayList<Token> ();\r
189 ArrayList<Token> alDxe = new ArrayList<Token> ();\r
190\r
191 getPcdDbManager().getTwoPhaseDynamicRecordArray(alPei, alDxe);\r
192 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);\r
193 pcdPeiDatabase.genCode();\r
194 MemoryDatabaseManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString() +\r
195 PcdDatabase.getPcdPeiDatabaseDefinitions();\r
196 MemoryDatabaseManager.PcdPeimCString = pcdPeiDatabase.getCString();\r
197\r
198 PcdDatabase pcdDxeDatabase = new PcdDatabase(alDxe, "DXE", alPei.size());\r
199 pcdDxeDatabase.genCode();\r
200 MemoryDatabaseManager.PcdDxeHString = MemoryDatabaseManager.PcdPeimHString + pcdDxeDatabase.getHString() +\r
201 PcdDatabase.getPcdDxeDatabaseDefinitions();\r
202 MemoryDatabaseManager.PcdDxeCString = pcdDxeDatabase.getCString();\r
203 }\r
204\r
205 /**\r
206 Override function: Get component array from FPD.\r
207\r
208 This function maybe provided by some Global class.\r
209\r
210 @return List<ModuleInfo> the component array.\r
211 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.\r
212\r
213 **/\r
214 public List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
215 throws PlatformPcdPreprocessException {\r
216 List<ModulePcdInfoFromFpd> allModules = new ArrayList<ModulePcdInfoFromFpd>();\r
217 Map<FpdModuleIdentification, XmlObject> pcdBuildDefinitions = null;\r
218 UsageIdentification usageId = null;\r
219\r
220 pcdBuildDefinitions = GlobalData.getFpdPcdBuildDefinitions();\r
221 if (pcdBuildDefinitions == null) {\r
222 return null;\r
223 }\r
224\r
225 //\r
226 // Loop map to retrieve all PCD build definition and Module id\r
227 //\r
228 Iterator item = pcdBuildDefinitions.keySet().iterator();\r
229 while (item.hasNext()){\r
230 FpdModuleIdentification id = (FpdModuleIdentification) item.next();\r
231 usageId = new UsageIdentification(id.getModule().getName(),\r
232 id.getModule().getGuid(),\r
233 id.getModule().getPackage().getName(),\r
234 id.getModule().getPackage().getGuid(),\r
235 id.getArch(),\r
236 id.getModule().getVersion(),\r
237 id.getModule().getModuleType());\r
238 allModules.add(\r
239 new ModulePcdInfoFromFpd(\r
240 usageId, \r
241 ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));\r
242 }\r
243 return allModules;\r
244 }\r
245\r
246 /**\r
247 Override function: Verify the datum value according its datum size and datum type, this\r
248 function maybe moved to FPD verification tools in future.\r
249\r
250 @param cName The token name\r
251 @param moduleName The module who use this PCD token\r
252 @param datum The PCD's datum\r
253 @param datumType The PCD's datum type\r
254 @param maxDatumSize The max size for PCD's Datum.\r
255\r
256 @return String exception strings.\r
257 */\r
258 public String verifyDatum(String cName,\r
259 String moduleName,\r
260 String datum,\r
261 Token.DATUM_TYPE datumType,\r
262 int maxDatumSize) {\r
263 //\r
264 // In building system, datum should not be checked, the checking work\r
265 // should be done by wizard tools or PCD verification tools.\r
266 // \r
267 return null;\r
268 }\r
269\r
270 /**\r
271 Override function: Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.\r
272\r
273 This function should be implemented in GlobalData in future.\r
274\r
275 @param token The token instance which has hold module's PCD information\r
276 @param moduleName The name of module who will use this Dynamic PCD.\r
277\r
278 @return DynamicPcdBuildDefinitions.PcdBuildData\r
279 **/\r
280 public DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFpd(Token token,\r
281 String moduleName)\r
282 throws PlatformPcdPreprocessException {\r
283 int index = 0;\r
284 String exceptionString = null;\r
285 String dynamicPrimaryKey = null;\r
286 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
287 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
288 String tokenSpaceStrRet = null;\r
289\r
290 //\r
291 // If FPD document is not be opened, open and initialize it.\r
292 // BUGBUG: The code should be moved into GlobalData in future.\r
293 //\r
294 if (fpdDocInstance == null) {\r
295 try {\r
296 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
297 } catch(IOException ioE) {\r
298 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
299 } catch(XmlException xmlE) {\r
300 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
301 }\r
302 }\r
303\r
304 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
305 if (dynamicPcdBuildDefinitions == null) {\r
306 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+\r
307 "PCD entry %s in module %s!",\r
308 token.cName,\r
309 moduleName);\r
310 putError(exceptionString);\r
311 return null;\r
312 }\r
313\r
314 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
315 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
316 tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
317\r
318 if (tokenSpaceStrRet == null) {\r
319 exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();\r
320 putError(exceptionString);\r
321 continue;\r
322 }\r
323\r
324 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
325 tokenSpaceStrRet);\r
326 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {\r
327 return dynamicPcdBuildDataArray.get(index);\r
328 }\r
329 }\r
330\r
331 return null;\r
332 }\r
333\r
334 /**\r
335 Override function: get all <DynamicPcdBuildDefinition> from FPD file.\r
336\r
337 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.\r
338 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.\r
339\r
340 **/\r
341 public List<DynamicPcdBuildDefinitions.PcdBuildData>\r
342 getAllDynamicPcdInfoFromFpd()\r
343 throws PlatformPcdPreprocessException {\r
344 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;\r
345\r
346 //\r
347 // Open fpd document to get <DynamicPcdBuildDefinition> Section.\r
348 // BUGBUG: the function should be move GlobalData in furture.\r
349 //\r
350 if (fpdDocInstance == null) {\r
351 try {\r
352 fpdDocInstance = (PlatformSurfaceAreaDocument)XmlObject.Factory.parse(new File(fpdFilePath));\r
353 } catch(IOException ioE) {\r
354 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
355 } catch(XmlException xmlE) {\r
356 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
357 }\r
358 }\r
359\r
360 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
361 if (dynamicPcdBuildDefinitions == null) {\r
362 return null;\r
363 }\r
364\r
365 return dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
366 }\r
367\r
368 /**\r
369 check parameter for this action.\r
370\r
371 @throws PlatformPcdPreprocessBuildException Bad parameter.\r
372 **/\r
373 private void checkParameter() throws PlatformPcdPreprocessBuildException {\r
374 File file = null;\r
375\r
376 if (fpdFilePath == null) {\r
377 throw new PlatformPcdPreprocessBuildException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
378 }\r
379\r
380 if (fpdFilePath.length() == 0) {\r
381 throw new PlatformPcdPreprocessBuildException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
382 }\r
383\r
384 file = new File(fpdFilePath);\r
385\r
386 if(!file.exists()) {\r
387 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");\r
388 }\r
389 }\r
390\r
391 /**\r
392 Test case function\r
393\r
394 @param argv parameter from command line\r
395 **/\r
396 public static void main(String argv[]) throws PlatformPcdPreprocessBuildException {\r
397 PlatformPcdPreprocessActionForBuilding ca = new PlatformPcdPreprocessActionForBuilding();\r
398 String projectDir = "x:/edk2";\r
399 ca.setFPDFilePath(projectDir + "/EdkNt32Pkg/Nt32.fpd");\r
400 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
401 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
402 projectDir,\r
403 "tools_def.txt");\r
404 System.out.println("After initInfo!");\r
405 FpdParserTask fpt = new FpdParserTask();\r
406 fpt.parseFpdFile(new File(projectDir + "/EdkNt32Pkg/Nt32.fpd"));\r
407 ca.execute();\r
408 }\r
409}\r