It is legal that same base name exist in one FPD file. In future, we should use ...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
CommitLineData
878ddf1f 1/** @file\r
2 CollectPCDAction 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.util.ArrayList;\r
23import java.util.HashMap;\r
24import java.util.List;\r
25import java.util.Map;\r
26import java.util.UUID;\r
27\r
28import org.apache.xmlbeans.XmlException;\r
29import org.apache.xmlbeans.XmlObject;\r
30import org.tianocore.FrameworkPlatformDescriptionDocument;\r
31import org.tianocore.ModuleSADocument;\r
32import org.tianocore.PackageSurfaceAreaDocument;\r
33import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;\r
34import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;\r
35import org.tianocore.build.autogen.CommonDefinition;\r
36import org.tianocore.build.global.GlobalData;\r
37import org.tianocore.build.global.SurfaceAreaQuery;\r
38import org.tianocore.build.pcd.action.ActionMessage;\r
39import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
40import org.tianocore.build.pcd.entity.SkuInstance;\r
41import org.tianocore.build.pcd.entity.Token;\r
42import org.tianocore.build.pcd.entity.UsageInstance;\r
43import org.tianocore.build.pcd.exception.EntityException;\r
44\r
45/** This action class is to collect PCD information from MSA, SPD, FPD xml file.\r
46 This class will be used for wizard and build tools, So it can *not* inherit\r
47 from buildAction or UIAction.\r
48**/\r
49public class CollectPCDAction {\r
50 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.\r
51 private MemoryDatabaseManager dbManager;\r
52\r
53 /// Workspacepath hold the workspace information.\r
54 private String workspacePath;\r
55\r
56 /// FPD file is the root file. \r
57 private String fpdFilePath;\r
58\r
59 /// Message level for CollectPCDAction.\r
60 private int originalMessageLevel;\r
61\r
62 /**\r
63 Set WorkspacePath parameter for this action class.\r
64\r
65 @param workspacePath parameter for this action\r
66 **/\r
67 public void setWorkspacePath(String workspacePath) {\r
68 this.workspacePath = workspacePath;\r
69 }\r
70\r
71 /**\r
72 Set action message level for CollectPcdAction tool.\r
73\r
74 The message should be restored when this action exit.\r
75\r
76 @param actionMessageLevel parameter for this action\r
77 **/\r
78 public void setActionMessageLevel(int actionMessageLevel) {\r
79 originalMessageLevel = ActionMessage.messageLevel;\r
80 ActionMessage.messageLevel = actionMessageLevel;\r
81 }\r
82\r
83 /**\r
84 Set FPDFileName parameter for this action class.\r
85\r
86 @param fpdFilePath fpd file path\r
87 **/\r
88 public void setFPDFilePath(String fpdFilePath) {\r
89 this.fpdFilePath = fpdFilePath;\r
90 }\r
91\r
92 /**\r
93 Common function interface for outer.\r
94 \r
95 @param workspacePath The path of workspace of current build or analysis.\r
96 @param fpdFilePath The fpd file path of current build or analysis.\r
97 @param messageLevel The message level for this Action.\r
98 \r
99 @throws Exception The exception of this function. Because it can *not* be predict\r
100 where the action class will be used. So only Exception can be throw.\r
101 \r
102 **/\r
103 public void perform(String workspacePath, String fpdFilePath, \r
104 int messageLevel) throws Exception {\r
105 setWorkspacePath(workspacePath);\r
106 setFPDFilePath(fpdFilePath);\r
107 setActionMessageLevel(messageLevel);\r
108 checkParameter();\r
109 execute();\r
110 ActionMessage.messageLevel = originalMessageLevel;\r
111 }\r
112\r
113 /**\r
114 Core execution function for this action class.\r
115 \r
116 This function work flows will be:\r
117 1) Get all token's platform information from FPD, and create token object into memory database.\r
118 2) Get all token's module information from MSA, and create usage instance for every module's PCD entry.\r
119 3) Get all token's inherited information from MSA's library, and create usage instance \r
120 for module who consume this library and create usage instance for library for building.\r
121 4) Collect token's package information from SPD, update these information for token in memory\r
122 database.\r
123 \r
124 @throws EntityException Exception indicate failed to execute this action.\r
125 \r
126 **/\r
127 private void execute() throws EntityException {\r
128 FrameworkPlatformDescriptionDocument fpdDoc = null;\r
129 Object[][] modulePCDArray = null;\r
130 Map<String, XmlObject> docMap = null;\r
131 ModuleSADocument.ModuleSA[] moduleSAs = null;\r
132 UsageInstance usageInstance = null;\r
133 String packageName = null;\r
134 String packageFullPath = null;\r
135 int index = 0;\r
136 int libraryIndex = 0;\r
137 int pcdArrayIndex = 0;\r
138 List<String> listLibraryInstance = null;\r
139 String componentTypeStr = null;\r
140\r
141 //\r
142 // Collect all PCD information defined in FPD file.\r
143 // Evenry token defind in FPD will be created as an token into \r
144 // memory database.\r
145 //\r
146 fpdDoc = createTokenInDBFromFPD();\r
147\r
148 //\r
149 // Searching MSA and SPD document. \r
150 // The information of MSA will be used to create usage instance into database.\r
151 // The information of SPD will be used to update the token information in database.\r
152 //\r
153\r
154 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();\r
155 map.put("FrameworkPlatformDescription", fpdDoc);\r
156 SurfaceAreaQuery.setDoc(map); \r
157\r
158 moduleSAs = SurfaceAreaQuery.getFpdModules();\r
159 for(index = 0; index < moduleSAs.length; index ++) {\r
160 //\r
161 // Get module document and use SurfaceAreaQuery to get PCD information\r
162 //\r
163 docMap = GlobalData.getDoc(moduleSAs[index].getModuleName());\r
164 SurfaceAreaQuery.setDoc(docMap);\r
165 modulePCDArray = SurfaceAreaQuery.getModulePCDTokenArray();\r
166 componentTypeStr = SurfaceAreaQuery.getComponentType();\r
167 packageName = \r
168 GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName());\r
169 packageFullPath = this.workspacePath + File.separator +\r
170 GlobalData.getPackagePath(packageName) +\r
171 packageName + ".spd";\r
172\r
173 if(modulePCDArray != null) {\r
174 //\r
175 // If current MSA contains <PCDs> information, then create usage\r
176 // instance for PCD information from MSA\r
177 //\r
178 for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length; \r
179 pcdArrayIndex ++) {\r
180 usageInstance = \r
181 createUsageInstanceFromMSA(moduleSAs[index].getModuleName(),\r
182 modulePCDArray[pcdArrayIndex]);\r
183\r
184 if(usageInstance == null) {\r
185 continue;\r
186 }\r
187 //\r
188 // Get remaining PCD information from the package which this module belongs to\r
189 //\r
190 updateTokenBySPD(usageInstance, packageFullPath);\r
191 }\r
192 }\r
193\r
194 //\r
195 // Get inherit PCD information which inherit from library instance of this module.\r
196 //\r
197 listLibraryInstance = \r
198 SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(),\r
199 CommonDefinition.AlwaysConsumed);\r
200 if(listLibraryInstance != null) {\r
201 for(libraryIndex = 0; libraryIndex < listLibraryInstance.size(); \r
202 libraryIndex ++) {\r
203 inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex),\r
204 moduleSAs[index].getModuleName(),\r
205 packageName,\r
206 componentTypeStr);\r
207 }\r
208 }\r
209 }\r
210 }\r
211\r
212 /**\r
213 This function will collect inherit PCD information from library for a module.\r
214 \r
215 This function will create two usage instance for inherited PCD token, one is \r
216 for module and another is for library.\r
217 For module, if it inherited a PCD token from library, this PCD token's value \r
218 should be instanced in module level, and belongs to module.\r
219 For library, it also need a usage instance for build.\r
220 \r
221 @param libraryName The name of library instance.\r
222 @param moduleName The name of module.\r
223 @param packageName The name of package while module belongs to.\r
224 @param parentcomponentType The component type of module.\r
225 \r
226 @throws EntityException If the token does *not* exist in memory database.\r
227 \r
228 **/\r
229 private void inheritPCDFromLibraryInstance(String libraryName,\r
230 String moduleName,\r
231 String packageName,\r
232 String parentcomponentType) \r
233 throws EntityException {\r
234 Map<String, XmlObject> docMap = null;\r
235 String primaryKeyString = null;\r
236 Object[][] libPcdDataArray = null;\r
237 UUID nullUUID = new UUID(0,0);\r
238 UUID platformUUID = nullUUID;\r
239 UUID tokenSpaceGuid = null;\r
240 int tokenIndex = 0;\r
241 Token token = null;\r
242 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
243 UsageInstance usageInstance = null;\r
244 String packageFullPath = null;\r
245\r
246 //\r
247 // Query PCD information from library's document.\r
248 //\r
249 docMap = GlobalData.getDoc(libraryName);\r
250 SurfaceAreaQuery.setDoc(docMap);\r
251 libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray();\r
252\r
253 if(libPcdDataArray == null) {\r
254 return;\r
255 }\r
256\r
257 for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) {\r
258 tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ? \r
259 nullUUID :(UUID)libPcdDataArray[tokenIndex][2];\r
260\r
261 //\r
262 // Get token from memory database. The token must be created from FPD already.\r
263 //\r
264 primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0],\r
265 tokenSpaceGuid,\r
266 platformUUID\r
267 );\r
268\r
269 if(dbManager.isTokenInDatabase(primaryKeyString)) {\r
270 token = dbManager.getTokenByKey(primaryKeyString);\r
271 } else {\r
272 throw new EntityException("The PCD token " + primaryKeyString + \r
273 " defined in module " + moduleName + \r
274 " does not exist in FPD file!");\r
275 } \r
276\r
277 //\r
278 // Create usage instance for module.\r
279 //\r
280 pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]);\r
281 usageInstance = new UsageInstance(token,\r
282 Token.PCD_USAGE.ALWAYS_CONSUMED,\r
283 pcdType,\r
284 CommonDefinition.getComponentType(parentcomponentType),\r
285 libPcdDataArray[tokenIndex][3],\r
286 null,\r
287 (String) libPcdDataArray[tokenIndex][5],\r
288 "",\r
289 moduleName,\r
290 packageName,\r
291 true);\r
292 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) {\r
293 token.addUsageInstance(usageInstance);\r
294\r
295 packageFullPath = this.workspacePath + File.separator +\r
296 GlobalData.getPackagePath(packageName) +\r
297 packageName + ".spd";\r
298 updateTokenBySPD(usageInstance, packageFullPath);\r
299 }\r
300\r
301 //\r
302 // We need create second usage instance for inherited case, which\r
303 // add library as an usage instance, because when build a module, and \r
304 // if module inherited from base library, then build process will build\r
305 // library at first. \r
306 //\r
307 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) {\r
308 packageName = GlobalData.getPackageNameForModule(libraryName);\r
309 usageInstance = new UsageInstance(token,\r
310 Token.PCD_USAGE.ALWAYS_CONSUMED,\r
311 pcdType,\r
312 CommonDefinition.ComponentTypeLibrary,\r
313 libPcdDataArray[tokenIndex][3],\r
314 null,\r
315 (String)libPcdDataArray[tokenIndex][5],\r
316 "",\r
317 libraryName,\r
318 packageName,\r
319 false);\r
320 token.addUsageInstance(usageInstance);\r
321 }\r
322 }\r
323 }\r
324\r
325 /**\r
326 Create usage instance for PCD token defined in MSA document\r
327\r
328 A PCD token maybe used by many modules, and every module is one of usage\r
329 instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is \r
330 consumer type usage instance of this token, and for ALWAYS_PRODUCED, \r
331 SOMETIMES_PRODUCED, it is produce type usage instance.\r
332 \r
333 @param moduleName The name of module \r
334 @param tokenInfoInMsa The PCD token information array retrieved from MSA.\r
335 \r
336 @return UsageInstance The usage instance created in memroy database.\r
337 \r
338 @throws EntityException If token did not exist in database yet.\r
339 \r
340 **/\r
341 private UsageInstance createUsageInstanceFromMSA(String moduleName,\r
342 Object[] tokenInfoInMsa) \r
343 throws EntityException {\r
344 String packageName = null;\r
345 UsageInstance usageInstance = null;\r
346 UUID tokenSpaceGuid = null;\r
347 UUID nullUUID = new UUID(0,0);\r
348 String primaryKeyString = null;\r
349 UUID platformTokenSpace = nullUUID;\r
350 Token token = null;\r
351 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
352 Token.PCD_USAGE pcdUsage = Token.PCD_USAGE.UNKNOWN;\r
353\r
354 tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2];\r
355\r
356 primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0],\r
357 tokenSpaceGuid,\r
358 platformTokenSpace);\r
359\r
360 //\r
361 // Get token object from memory database firstly.\r
362 //\r
363 if(dbManager.isTokenInDatabase(primaryKeyString)) {\r
364 token = dbManager.getTokenByKey(primaryKeyString);\r
365 } else {\r
366 throw new EntityException("The PCD token " + primaryKeyString + " defined in module " + \r
367 moduleName + " does not exist in FPD file!" );\r
368 }\r
369 pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]);\r
370 pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]);\r
371\r
372 packageName = GlobalData.getPackageNameForModule(moduleName);\r
373\r
374 if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) {\r
375 //\r
19ce77c3 376 // BUGBUG: It is legal that same base name exist in one FPD file. In furture\r
377 // we should use "Guid, Version, Package" and "Arch" to differ a module.\r
378 // So currently, warning should be disabled.\r
878ddf1f 379 //\r
19ce77c3 380 //ActionMessage.warning(this,\r
381 // "In module " + moduleName + " exist more than one PCD token " + token.cName\r
382 // );\r
878ddf1f 383 return null;\r
384 }\r
385\r
386 //\r
387 // BUGBUG: following code could be enabled at current schema. Because \r
388 // current schema does not provide usage information.\r
389 // \r
390 // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his \r
391 // usage is always ALWAYS_CONSUMED\r
392 //\r
393 //if((pcdType != Token.PCD_TYPE.DYNAMIC) &&\r
394 // (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) {\r
395 pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED;\r
396 //}\r
397\r
398 usageInstance = new UsageInstance(token,\r
399 pcdUsage,\r
400 pcdType,\r
401 CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()),\r
402 tokenInfoInMsa[3],\r
403 null,\r
404 (String) tokenInfoInMsa[5],\r
405 "",\r
406 moduleName,\r
407 packageName,\r
408 false);\r
409\r
410 //\r
411 // Use default value defined in MSA to update datum of token,\r
412 // if datum of token does not defined in FPD file.\r
413 //\r
414 if((token.datum == null) &&(tokenInfoInMsa[3] != null)) {\r
415 token.datum = tokenInfoInMsa[3];\r
416 }\r
417\r
418 token.addUsageInstance(usageInstance);\r
419\r
420 return usageInstance;\r
421 }\r
422\r
423 /**\r
424 Create token instance object into memory database, the token information\r
425 comes for FPD file. Normally, FPD file will contain all token platform \r
426 informations.\r
427 \r
428 This fucntion should be executed at firsly before others collection work\r
429 such as searching token information from MSA, SPD.\r
430 \r
431 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.\r
432 \r
433 @throws EntityException Failed to parse FPD xml file.\r
434 \r
435 **/\r
436 private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD() \r
437 throws EntityException {\r
438 XmlObject doc = null;\r
439 FrameworkPlatformDescriptionDocument fpdDoc = null;\r
440 int index = 0;\r
441 List<PcdBuildData> pcdBuildDataArray = new ArrayList<PcdBuildData>();\r
442 PcdBuildData pcdBuildData = null;\r
443 Token token = null;\r
444 UUID nullUUID = new UUID(0,0);\r
445 UUID platformTokenSpace= nullUUID;\r
446 List skuDataArray = new ArrayList();\r
447 SkuInstance skuInstance = null;\r
448 int skuIndex = 0;\r
449\r
450 //\r
451 // Get all tokens from FPD file and create token into database.\r
452 // \r
453\r
454 try {\r
455 doc = XmlObject.Factory.parse(new File(fpdFilePath));\r
456 } catch(IOException ioE) {\r
457 throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath);\r
458 } catch(XmlException xmlE) {\r
459 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath);\r
460 }\r
461\r
462 //\r
463 // Get memoryDatabaseManager instance from GlobalData.\r
464 //\r
465 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {\r
466 throw new EntityException("The instance of PCD memory database manager is null");\r
467 }\r
468\r
469 dbManager = new MemoryDatabaseManager();\r
470\r
471 if(!(doc instanceof FrameworkPlatformDescriptionDocument)) {\r
472 throw new EntityException("File " + fpdFilePath + \r
473 " is not a FrameworkPlatformDescriptionDocument");\r
474 }\r
475\r
476 fpdDoc =(FrameworkPlatformDescriptionDocument)doc;\r
477\r
478 //\r
479 // Add all tokens in FPD into Memory Database.\r
480 //\r
481 pcdBuildDataArray = \r
482 fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList();\r
483 for(index = 0; \r
484 index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray(); \r
485 index ++) {\r
486 pcdBuildData = pcdBuildDataArray.get(index);\r
487 token = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0));\r
488 //\r
489 // BUGBUG: in FPD, <defaultValue> should be defined as <Value>\r
490 //\r
491 token.datum = pcdBuildData.getDefaultValue();\r
492 token.hiiEnabled = pcdBuildData.getHiiEnable();\r
493 token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid());\r
494 token.variableName = pcdBuildData.getVariableName();\r
495 token.variableOffset = Integer.decode(pcdBuildData.getDataOffset());\r
496 token.skuEnabled = pcdBuildData.getSkuEnable();\r
497 token.maxSkuCount = Integer.decode(pcdBuildData.getMaxSku());\r
498 token.skuId = Integer.decode(pcdBuildData.getSkuId());\r
499 token.skuDataArrayEnabled = pcdBuildData.getSkuDataArrayEnable();\r
500 token.assignedtokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());\r
501 skuDataArray = pcdBuildData.getSkuDataArray1();\r
3d52de13 502 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
503\r
878ddf1f 504 if(skuDataArray != null) {\r
505 for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) {\r
506 //\r
507 // BUGBUG: Now in current schema, The value is defined as String type, \r
508 // it is not correct, the type should be same as the datumType\r
509 //\r
510 skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(),\r
511 ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue());\r
512 token.skuData.add(skuInstance);\r
513 }\r
514 }\r
515\r
516 if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName, \r
517 token.tokenSpaceName, \r
518 platformTokenSpace))) {\r
519 //\r
520 // If found duplicate token, Should tool be hold?\r
521 //\r
522 ActionMessage.warning(this, \r
523 "Token " + token.cName + " exists in token database");\r
524 continue;\r
525 }\r
526 token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());\r
527 dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName, \r
528 token.tokenSpaceName, \r
529 platformTokenSpace), \r
530 token);\r
531 }\r
532\r
533 return fpdDoc;\r
534 }\r
535\r
536 /**\r
537 Update PCD token in memory database by help information in SPD.\r
538\r
539 After create token from FPD and create usage instance from MSA, we should collect\r
540 PCD package level information from SPD and update token information in memory \r
541 database.\r
542 \r
543 @param usageInstance The usage instance defined in MSA and want to search in SPD.\r
544 @param packageFullPath The SPD file path.\r
545 \r
546 @throws EntityException Failed to parse SPD xml file.\r
547 \r
548 **/\r
549 private void updateTokenBySPD(UsageInstance usageInstance,\r
550 String packageFullPath) \r
551 throws EntityException {\r
3d52de13 552 PackageSurfaceAreaDocument pkgDoc = null;\r
553 PcdDefinitions pcdDefinitions = null;\r
554 List<PcdDefinitions.PcdEntry> pcdEntryArray = new ArrayList<PcdDefinitions.PcdEntry>();\r
555 int index = 0;\r
556 boolean isFoundInSpd = false;\r
557 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
878ddf1f 558\r
559 try {\r
560 pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath));\r
561 } catch(IOException ioE) {\r
562 throw new EntityException("Can't find the FPD xml fle:" + packageFullPath);\r
563 } catch(XmlException xmlE) {\r
564 throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath);\r
565 }\r
3d52de13 566 pcdDefinitions = pkgDoc.getPackageSurfaceArea().getPcdDefinitions();\r
567 //\r
568 // It is illege for SPD file does not contains any PCD information.\r
569 //\r
570 if (pcdDefinitions == null) {\r
571 return;\r
572 }\r
878ddf1f 573\r
3d52de13 574 pcdEntryArray = pcdDefinitions.getPcdEntryList();\r
575 if (pcdEntryArray == null) {\r
576 return;\r
577 }\r
878ddf1f 578 for(index = 0; index < pcdEntryArray.size(); index ++) {\r
579 if(pcdEntryArray.get(index).getCName().equalsIgnoreCase(\r
580 usageInstance.parentToken.cName)) {\r
581 isFoundInSpd = true;\r
582 //\r
583 // From SPD file , we can get following information.\r
584 // Token: Token number defined in package level.\r
585 // PcdItemType: This item does not single one. It means all supported item type.\r
586 // datumType: UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN \r
587 // datumSize: The size of default value or maxmine size.\r
588 // defaultValue: This value is defined in package level.\r
589 // HelpText: The help text is provided in package level.\r
590 //\r
591\r
592 usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken());\r
593\r
594 if(pcdEntryArray.get(index).getDatumType() != null) {\r
595 datumType = Token.getdatumTypeFromString(\r
596 pcdEntryArray.get(index).getDatumType().toString());\r
597 if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) {\r
598 usageInstance.parentToken.datumType = datumType;\r
599 } else {\r
600 if(datumType != usageInstance.parentToken.datumType) {\r
601 throw new EntityException("Different datum types are defined for Token :" + \r
602 usageInstance.parentToken.cName);\r
603 }\r
604 }\r
605\r
606 } else {\r
607 throw new EntityException("The datum type for token " + usageInstance.parentToken.cName + \r
608 " is not defind in SPD file " + packageFullPath);\r
609 }\r
610\r
611 usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue();\r
612 usageInstance.helpTextInSPD = "Help Text in SPD";\r
613\r
614 //\r
615 // If token's datum is not valid, it indicate that datum is not provided\r
616 // in FPD and defaultValue is not provided in MSA, then use defaultValue\r
617 // in SPD as the datum of token.\r
618 //\r
619 if(usageInstance.parentToken.datum == null) {\r
620 if(pcdEntryArray.get(index).getDefaultValue() != null) {\r
621 usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue();\r
622 } else {\r
623 throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName +\r
624 ", MSA and SPD also does not provide <defaultValue> for this token!");\r
625 }\r
626 }\r
627 }\r
628 }\r
878ddf1f 629 }\r
630\r
631 /**\r
632 check parameter for this action.\r
633 \r
634 @throws EntityException Bad parameter.\r
635 **/\r
636 private void checkParameter() throws EntityException {\r
637 File file = null;\r
638\r
639 if((fpdFilePath == null) ||(workspacePath == null)) {\r
640 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
641 }\r
642\r
643 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {\r
644 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");\r
645 }\r
646\r
647 file = new File(workspacePath);\r
648 if(!file.exists()) {\r
649 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");\r
650 }\r
651\r
652 file = new File(fpdFilePath);\r
653\r
654 if(!file.exists()) {\r
655 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");\r
656 }\r
657 }\r
658\r
659 /**\r
660 Test case function\r
661\r
662 @param argv parameter from command line\r
663 **/\r
664 public static void main(String argv[]) throws EntityException {\r
665 CollectPCDAction ca = new CollectPCDAction();\r
666 ca.setWorkspacePath("G:/mdk");\r
667 ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/Nt32.fpd");\r
668 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);\r
669 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
670 "G:/mdk");\r
671 ca.execute();\r
672 }\r
673}\r