]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java
1. Fix the problem of adding PCD for different Arch.
[mirror_edk2.git] / Tools / Source / FrameworkWizard / src / org / tianocore / frameworkwizard / platform / ui / global / GlobalData.java
1 /** @file
2 GlobalData class.
3
4 GlobalData provide initializing, instoring, querying and update global data.
5 It is a bridge to intercommunicate between multiple component, such as AutoGen,
6 PCD and so on.
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 package org.tianocore.frameworkwizard.platform.ui.global;
18
19 import org.apache.xmlbeans.XmlObject;
20 import org.tianocore.DbPathAndFilename;
21 import org.tianocore.FrameworkDatabaseDocument;
22 import org.tianocore.ModuleSurfaceAreaDocument;
23 import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
24 import org.tianocore.frameworkwizard.platform.ui.id.FpdModuleIdentification;
25 import org.tianocore.frameworkwizard.platform.ui.id.ModuleIdentification;
26 import org.tianocore.frameworkwizard.platform.ui.id.PackageIdentification;
27 import org.tianocore.frameworkwizard.platform.ui.id.PlatformIdentification;
28
29 import java.io.File;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.ListIterator;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.Vector;
39 import java.util.logging.Logger;
40
41 /**
42 GlobalData provide initializing, instoring, querying and update global data.
43 It is a bridge to intercommunicate between multiple component, such as AutoGen,
44 PCD and so on.
45
46 <p>Note that all global information are initialized incrementally. All data will
47 parse and record only of necessary during build time. </p>
48
49 @since GenBuild 1.0
50 **/
51 public class GlobalData {
52
53
54 public static Logger log = Logger.getAnonymousLogger();
55 public static KeyComparator comparator = new KeyComparator();
56 ///
57 /// Record current WORKSPACE Directory
58 ///
59 private static String workspaceDir = "";
60
61 ///
62 /// Be used to ensure Global data will be initialized only once.
63 ///
64 // private static boolean globalFlag = false;
65
66 ///
67 /// Framework Database information: package list and platform list
68 ///
69 private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();
70
71 private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
72
73 ///
74 /// Every detail SPD informations: Module list, Library class definition,
75 /// Package header file, GUID/PPI/Protocol definitions
76 ///
77 private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
78
79 ///
80 /// Build informations are divided into three parts:
81 /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
82 ///
83 private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
84
85 private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
86
87 private static XmlObject fpdBuildOptions;
88
89 private static XmlObject fpdDynamicPcds;
90
91 ///
92 /// Parsed modules list
93 ///
94 private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
95
96 ///
97 /// built modules list with ARCH, TARGET, TOOLCHAIN
98 ///
99 private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
100
101 /**
102 Parse framework database (DB) and all SPD files listed in DB to initialize
103 the environment for next build. This method will only be executed only once
104 in the whole build process.
105
106 @param workspaceDatabaseFile the file name of framework database
107 @param workspaceDir current workspace directory path
108 @throws Exception
109 Framework Dababase or SPD or MSA file is not valid
110 **/
111 public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws Exception {
112
113 //
114 // Backup workspace directory. It will be used by other method
115 //
116 GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
117 File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
118 try {
119 FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
120 //
121 // validate FrameworkDatabaseFile
122 //
123 // if (! db.validate()) {
124 // throw new Exception("Framework Database file [" + dbFile.getPath() + "] is invalid.");
125 // }
126 //
127 // Get package list
128 //
129 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
130
131 Iterator iter = packages.iterator();
132 while (iter.hasNext()) {
133 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();
134 String fileName = dbPath.getStringValue();
135 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
136 if (!packageList.contains(spd.getPackageId())) {
137 packageList.add(spd.getPackageId());
138 }
139 spdTable.put(spd.getPackageId(), spd);
140 }
141
142
143 } catch (Exception e) {
144 e.printStackTrace();
145 throw new Exception("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
146 }
147 }
148
149 /**
150 Get the current WORKSPACE Directory.
151
152 @return current workspace directory
153 **/
154 public synchronized static String getWorkspacePath() {
155 return workspaceDir;
156 }
157
158
159 /**
160 Get the MSA file name with absolute path
161 */
162 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws Exception {
163 File msaFile = null;
164 //
165 // TBD. Do only when package is null.
166 //
167 Iterator iter = packageList.iterator();
168 while (iter.hasNext()) {
169 PackageIdentification packageId = (PackageIdentification)iter.next();
170 Spd spd = spdTable.get(packageId);
171 msaFile = spd.getModuleFile(moduleId);
172 if (msaFile != null ) {
173 break ;
174 }
175 }
176 if (msaFile == null){
177 throw new Exception("Can't find Module [" + moduleId.getName() + "] in all packages. ");
178 }
179 else {
180 return msaFile;
181 }
182 }
183
184 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {
185 //
186 // If package already defined in module
187 //
188 if (moduleId.getPackage() != null) {
189 return moduleId.getPackage();
190 }
191
192 PackageIdentification packageId = null;
193 Iterator iter = packageList.iterator();
194 while (iter.hasNext()) {
195 packageId = (PackageIdentification)iter.next();
196
197 Spd spd = spdTable.get(packageId);
198 if (spd.getModuleFile(moduleId) != null ) {
199 moduleId.setPackage(packageId);
200 break ;
201 }
202 }
203 if (packageId == null){
204 return null;
205 }
206 else {
207 return packageId;
208 }
209 }
210
211 /**
212 Difference between build and parse: ToolChain and Target
213 **/
214 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
215 return builtModules.contains(moduleId);
216 }
217
218 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
219 builtModules.add(fpdModuleId);
220 }
221
222
223 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws Exception{
224 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
225 Set keySet = doc.keySet();
226 Iterator iter = keySet.iterator();
227 while (iter.hasNext()){
228 String key = (String)iter.next();
229 XmlObject item = cloneXmlObject(doc.get(key), true);
230 result.put(key, item);
231 }
232 fpdModuleSA.put(fpdModuleId, result);
233 }
234
235 /**
236 Query overrided module surface area information. If current is Package
237 or Platform build, also include the information from FPD file.
238
239 <p>Note that surface area parsing is incremental. That means the method will
240 only parse the MSA and MBD files if necessary. </p>
241
242 @param moduleName the base name of the module
243 @return the overrided module surface area information
244 @throws Exception
245 MSA or MBD is not valid
246 **/
247 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws Exception {
248 if (parsedModules.containsKey(fpdModuleId)) {
249 return parsedModules.get(fpdModuleId);
250 }
251 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
252 ModuleIdentification moduleId = fpdModuleId.getModule();
253 //
254 // First part: get the MSA files info
255 //
256 doc = getNativeMsa(moduleId);
257
258 //
259 // Second part: put build options
260 //
261 doc.put("BuildOptions", fpdBuildOptions);
262
263 //
264 // Third part: get Module info from FPD, such as Library instances, PCDs
265 //
266 if (fpdModuleSA.containsKey(fpdModuleId)){
267 //
268 // merge module info in FPD to final Doc
269 // For Library Module, do nothing here
270 //
271 doc.putAll(fpdModuleSA.get(fpdModuleId));
272 }
273 parsedModules.put(fpdModuleId, doc);
274 return doc;
275 }
276
277 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws Exception {
278 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
279 return getDoc(fpdModuleId);
280 }
281 /**
282 Query the native MSA information with module base name.
283
284 <p>Note that MSA parsing is incremental. That means the method will
285 only to parse the MSA files when never parsed before. </p>
286
287 @param moduleName the base name of the module
288 @return the native MSA information
289 @throws Exception
290 MSA file is not valid
291 **/
292 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws Exception {
293 if (nativeMsa.containsKey(moduleId)) {
294 return nativeMsa.get(moduleId);
295 }
296 File msaFile = getMsaFile(moduleId);
297 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
298 nativeMsa.put(moduleId, msaMap);
299 return msaMap;
300 }
301
302 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {
303
304 try {
305 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
306 //
307 // Validate File if they accord with XML Schema
308 //
309 // if ( ! doc.validate()){
310 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
311 // }
312 //
313 // parse MSA file
314 //
315 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
316 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
317 msaMap.put("ModuleSurfaceArea", msa);
318 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
319 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
320 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
321 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
322 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
323 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
324 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
325 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
326 return msaMap;
327 }
328 catch (Exception ex){
329 throw new Exception(ex.getMessage());
330 }
331 }
332
333 public static Map<String, XmlObject> getFpdBuildOptions() {
334 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
335 map.put("BuildOptions", fpdBuildOptions);
336 return map;
337 }
338
339 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws Exception{
340 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
341 }
342
343 public static XmlObject getFpdDynamicPcds() {
344 return fpdDynamicPcds;
345 }
346
347 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
348 GlobalData.fpdDynamicPcds = fpdDynamicPcds;
349 }
350
351 //////////////////////////////////////////////
352 //////////////////////////////////////////////
353
354 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
355 Spd spd = spdTable.get(packageId);
356 if (spd == null ) {
357 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
358 return dummy;
359 }
360 else {
361 return spd.getModules();
362 }
363 }
364
365 public synchronized static PlatformIdentification getPlatform(String name) throws Exception {
366 Iterator iter = platformList.iterator();
367 while(iter.hasNext()){
368 PlatformIdentification platformId = (PlatformIdentification)iter.next();
369 if (platformId.getName().equalsIgnoreCase(name)) {
370 GlobalData.log.info("Platform: " + platformId + platformId.getFpdFile());
371 return platformId;
372 }
373 }
374 throw new Exception("Can't find platform [" + name + "] in current workspace. ");
375 }
376
377 public synchronized static File getPackageFile(PackageIdentification packageId) throws Exception {
378 Iterator iter = packageList.iterator();
379 while(iter.hasNext()){
380 PackageIdentification packageItem = (PackageIdentification)iter.next();
381 if (packageItem.equals(packageId)) {
382 packageId.setName(packageItem.getName());
383 return packageItem.getSpdFile();
384 }
385 }
386 throw new Exception("Can't find " + packageId + " in current workspace. ");
387 }
388
389 public synchronized static File getModuleFile(ModuleIdentification moduleId) throws Exception {
390 PackageIdentification packageId = getPackageForModule(moduleId);
391 moduleId.setPackage(packageId);
392 Spd spd = spdTable.get(packageId);
393 return spd.getModuleFile(moduleId);
394 }
395 //
396 // expanded by FrameworkWizard
397 //
398 public synchronized static XmlObject getModuleXmlObject(ModuleIdentification moduleId) throws Exception {
399 PackageIdentification packageId = getPackageForModule(moduleId);
400 moduleId.setPackage(packageId);
401 Spd spd = spdTable.get(packageId);
402 return spd.msaDocMap.get(moduleId);
403 }
404
405 public synchronized static XmlObject getPackageXmlObject(PackageIdentification packageId) {
406 Spd spd = spdTable.get(packageId);
407 if (spd != null){
408 return spd.spdDocMap.get("PackageSurfaceArea");
409 }
410 return null;
411 }
412
413 public synchronized static Set<PackageIdentification> getPackageList(){
414 return packageList;
415 }
416 ///// remove!!
417 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws Exception {
418 if ( object == null) {
419 return null;
420 }
421 XmlObject result = null;
422 try {
423 result = XmlObject.Factory.parse(object.getDomNode()
424 .cloneNode(deep));
425 } catch (Exception ex) {
426 throw new Exception(ex.getMessage());
427 }
428 return result;
429 }
430
431 public static ModuleIdentification getModuleId(String key){
432 //
433 // Get ModuleGuid, ModuleVersion, PackageGuid, PackageVersion, Arch into string array.
434 //
435 String[] keyPart = key.split(" ");
436 Set<PackageIdentification> spi = GlobalData.getPackageList();
437 Iterator ispi = spi.iterator();
438
439 while(ispi.hasNext()) {
440 PackageIdentification pi = (PackageIdentification)ispi.next();
441 if ( !pi.getGuid().equalsIgnoreCase(keyPart[2])){
442
443 continue;
444 }
445 if (keyPart[3] != null && keyPart[3].length() > 0 && !keyPart[3].equals("null")){
446 if(!pi.getVersion().equals(keyPart[3])){
447 continue;
448 }
449 }
450 Set<ModuleIdentification> smi = GlobalData.getModules(pi);
451 Iterator ismi = smi.iterator();
452 while(ismi.hasNext()) {
453 ModuleIdentification mi = (ModuleIdentification)ismi.next();
454 if (mi.getGuid().equalsIgnoreCase(keyPart[0])){
455 if (keyPart[1] != null && keyPart[1].length() > 0 && !keyPart[1].equals("null")){
456 if(!mi.getVersion().equals(keyPart[1])){
457 continue;
458 }
459 }
460
461 return mi;
462 }
463 }
464 }
465 return null;
466 }
467
468 public static Vector<String> getModuleSupArchs(ModuleIdentification mi) throws Exception{
469 Vector<String> vArchs = null;
470 ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = (ModuleSurfaceAreaDocument.ModuleSurfaceArea)getModuleXmlObject(mi);
471 if (msa.getModuleDefinitions() == null || msa.getModuleDefinitions().getSupportedArchitectures() == null) {
472 return vArchs;
473 }
474 ListIterator li = msa.getModuleDefinitions().getSupportedArchitectures().listIterator();
475 while (li.hasNext()) {
476 if (vArchs == null) {
477 vArchs = new Vector<String>();
478 }
479 vArchs.add((String)li.next());
480 }
481
482 return vArchs;
483 }
484
485 }
486
487 final class KeyComparator implements Comparator<String> {
488 public int compare(String x, String y) {
489 return x.compareToIgnoreCase(y);
490 }
491
492 }
493