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