]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PlatformPcdPreprocessActionForBuilding.java
Refine the code for PCD tools.
[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.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
30import org.tianocore.PcdBuildDefinitionDocument;\r
31import org.tianocore.PlatformSurfaceAreaDocument;\r
32import org.tianocore.build.exception.PlatformPcdPreprocessBuildException;\r
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
37import org.tianocore.pcd.action.PlatformPcdPreprocessAction;\r
38import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
39import org.tianocore.pcd.entity.ModulePcdInfoFromFpd;\r
40import org.tianocore.pcd.entity.Token;\r
41import org.tianocore.pcd.entity.UsageIdentification;\r
42import org.tianocore.pcd.exception.EntityException;\r
43import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
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
51 ///\r
52 /// FPD file path.\r
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
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
90 @param fpdFilePath The fpd file path of current build or processing.\r
91 @param messageLevel The message level for this Action.\r
92\r
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
96\r
97 **/\r
98 public void perform(String fpdFilePath, int messageLevel) \r
99 throws PlatformPcdPreprocessBuildException {\r
100 this.fpdFilePath = fpdFilePath;\r
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
122 public void execute() throws PlatformPcdPreprocessBuildException {\r
123 String errorMessageHeader = "Failed to initialize the Pcd memory database because: ";\r
124 String errorsForPreprocess = null;\r
125\r
126 //\r
127 // Get memoryDatabaseManager instance from GlobalData.\r
128 // The memoryDatabaseManager should be initialized as static variable\r
129 // in some Pre-process class.\r
130 //\r
131 setPcdDbManager(GlobalData.getPCDMemoryDBManager());\r
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
138 try {\r
139 initPcdMemoryDbWithPlatformInfo();\r
140 } catch (PlatformPcdPreprocessException exp) {\r
141 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + exp.getMessage());\r
142 }\r
143 errorsForPreprocess = this.getErrorString();\r
144 if (errorsForPreprocess != null) {\r
145 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + errorsForPreprocess);\r
146 }\r
147\r
148 //\r
149 // Generate for PEI, DXE PCD DATABASE's definition and initialization.\r
150 //\r
151 try {\r
152 genPcdDatabaseSourceCode ();\r
153 } catch (EntityException exp) {\r
154 throw new PlatformPcdPreprocessBuildException(errorMessageHeader + "\r\n" + exp.getMessage());\r
155 }\r
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
163 @return String Guid information from SPD file.\r
164 @throws PlatformPcdPreprocessException\r
165 Fail to get Guid information from SPD file.\r
166 **/\r
167 public String getGuidInfoFromSpd(String guidCName) throws PlatformPcdPreprocessException {\r
168 String tokenSpaceStrRet = null;\r
169 try {\r
170 tokenSpaceStrRet = GlobalData.getGuidInfoFromCname(guidCName);\r
171 } catch ( Exception e ) {\r
172 throw new PlatformPcdPreprocessException ("Failed to get Guid CName " + guidCName + " from the SPD file!");\r
173 }\r
174 return tokenSpaceStrRet;\r
175 }\r
176\r
177 /**\r
178 This function generates source code for PCD Database.\r
179\r
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
209 @return List<ModuleInfo> the component array.\r
210 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.\r
211\r
212 **/\r
213 public List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
214 throws PlatformPcdPreprocessException {\r
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
237 allModules.add(\r
238 new ModulePcdInfoFromFpd(\r
239 usageId, \r
240 ((PcdBuildDefinitionDocument)pcdBuildDefinitions.get(id)).getPcdBuildDefinition()));\r
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
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
254\r
255 @return String exception strings.\r
256 */\r
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
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
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
281 throws PlatformPcdPreprocessException {\r
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
287 String tokenSpaceStrRet = null;\r
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
297 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
298 } catch(XmlException xmlE) {\r
299 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
300 }\r
301 }\r
302\r
303 dynamicPcdBuildDefinitions = fpdDocInstance.getPlatformSurfaceArea().getDynamicPcdBuildDefinitions();\r
304 if (dynamicPcdBuildDefinitions == null) {\r
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
307 token.cName,\r
308 moduleName);\r
309 putError(exceptionString);\r
310 return null;\r
311 }\r
312\r
313 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();\r
314 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {\r
315 tokenSpaceStrRet = getGuidInfoFromSpd(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuidCName());\r
316\r
317 if (tokenSpaceStrRet == null) {\r
318 exceptionString = "Fail to get token space guid for token " + dynamicPcdBuildDataArray.get(index).getCName();\r
319 putError(exceptionString);\r
320 continue;\r
321 }\r
322\r
323 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),\r
324 tokenSpaceStrRet);\r
325 if (dynamicPrimaryKey.equals(token.getPrimaryKeyString())) {\r
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
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
339 **/\r
340 public List<DynamicPcdBuildDefinitions.PcdBuildData>\r
341 getAllDynamicPcdInfoFromFpd()\r
342 throws PlatformPcdPreprocessException {\r
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
353 throw new PlatformPcdPreprocessException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());\r
354 } catch(XmlException xmlE) {\r
355 throw new PlatformPcdPreprocessException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());\r
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
370 @throws PlatformPcdPreprocessBuildException Bad parameter.\r
371 **/\r
372 private void checkParameter() throws PlatformPcdPreprocessBuildException {\r
373 File file = null;\r
374\r
375 if (fpdFilePath == null) {\r
376 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");\r
377 }\r
378\r
379 if (fpdFilePath.length() == 0) {\r
380 throw new PlatformPcdPreprocessBuildException("FPDFileName should be empty for CollectPCDAtion!");\r
381 }\r
382\r
383 file = new File(fpdFilePath);\r
384\r
385 if(!file.exists()) {\r
386 throw new PlatformPcdPreprocessBuildException("FPD File " + fpdFilePath + " does not exist!");\r
387 }\r
388 }\r
389}\r