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