]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java
[EDKT169]Add feature of sorting modules in FPD file.
[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 packageList.clear();
130 List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
131
132 Iterator iter = packages.iterator();
133 while (iter.hasNext()) {
134 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();
135 String fileName = dbPath.getStringValue();
136 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
137 packageList.add(spd.getPackageId());
138 spdTable.put(spd.getPackageId(), spd);
139 }
140
141
142 } catch (Exception e) {
143 e.printStackTrace();
144 throw new Exception("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
145 }
146 }
147
148 /**
149 Get the current WORKSPACE Directory.
150
151 @return current workspace directory
152 **/
153 public synchronized static String getWorkspacePath() {
154 return workspaceDir;
155 }
156
157
158 /**
159 Get the MSA file name with absolute path
160 */
161 public synchronized static File getMsaFile(ModuleIdentification moduleId) throws Exception {
162 File msaFile = null;
163 //
164 // TBD. Do only when package is null.
165 //
166 Iterator iter = packageList.iterator();
167 while (iter.hasNext()) {
168 PackageIdentification packageId = (PackageIdentification)iter.next();
169 Spd spd = spdTable.get(packageId);
170 msaFile = spd.getModuleFile(moduleId);
171 if (msaFile != null ) {
172 break ;
173 }
174 }
175 if (msaFile == null){
176 throw new Exception("Can't find Module [" + moduleId.getName() + "] in all packages. ");
177 }
178 else {
179 return msaFile;
180 }
181 }
182
183 public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {
184 //
185 // If package already defined in module
186 //
187 if (moduleId.getPackage() != null) {
188 return moduleId.getPackage();
189 }
190
191 PackageIdentification packageId = null;
192 Iterator iter = packageList.iterator();
193 while (iter.hasNext()) {
194 packageId = (PackageIdentification)iter.next();
195
196 Spd spd = spdTable.get(packageId);
197 if (spd.getModuleFile(moduleId) != null ) {
198 moduleId.setPackage(packageId);
199 break ;
200 }
201 }
202 if (packageId == null){
203 return null;
204 }
205 else {
206 return packageId;
207 }
208 }
209
210 /**
211 Difference between build and parse: ToolChain and Target
212 **/
213 public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
214 return builtModules.contains(moduleId);
215 }
216
217 public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
218 builtModules.add(fpdModuleId);
219 }
220
221
222 public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) throws Exception{
223 Map<String, XmlObject> result = new HashMap<String, XmlObject>();
224 Set keySet = doc.keySet();
225 Iterator iter = keySet.iterator();
226 while (iter.hasNext()){
227 String key = (String)iter.next();
228 XmlObject item = cloneXmlObject(doc.get(key), true);
229 result.put(key, item);
230 }
231 fpdModuleSA.put(fpdModuleId, result);
232 }
233
234 /**
235 Query overrided module surface area information. If current is Package
236 or Platform build, also include the information from FPD file.
237
238 <p>Note that surface area parsing is incremental. That means the method will
239 only parse the MSA and MBD files if necessary. </p>
240
241 @param moduleName the base name of the module
242 @return the overrided module surface area information
243 @throws Exception
244 MSA or MBD is not valid
245 **/
246 public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws Exception {
247 if (parsedModules.containsKey(fpdModuleId)) {
248 return parsedModules.get(fpdModuleId);
249 }
250 Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
251 ModuleIdentification moduleId = fpdModuleId.getModule();
252 //
253 // First part: get the MSA files info
254 //
255 doc = getNativeMsa(moduleId);
256
257 //
258 // Second part: put build options
259 //
260 doc.put("BuildOptions", fpdBuildOptions);
261
262 //
263 // Third part: get Module info from FPD, such as Library instances, PCDs
264 //
265 if (fpdModuleSA.containsKey(fpdModuleId)){
266 //
267 // merge module info in FPD to final Doc
268 // For Library Module, do nothing here
269 //
270 doc.putAll(fpdModuleSA.get(fpdModuleId));
271 }
272 parsedModules.put(fpdModuleId, doc);
273 return doc;
274 }
275
276 public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws Exception {
277 FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
278 return getDoc(fpdModuleId);
279 }
280 /**
281 Query the native MSA information with module base name.
282
283 <p>Note that MSA parsing is incremental. That means the method will
284 only to parse the MSA files when never parsed before. </p>
285
286 @param moduleName the base name of the module
287 @return the native MSA information
288 @throws Exception
289 MSA file is not valid
290 **/
291 public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws Exception {
292 if (nativeMsa.containsKey(moduleId)) {
293 return nativeMsa.get(moduleId);
294 }
295 File msaFile = getMsaFile(moduleId);
296 Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
297 nativeMsa.put(moduleId, msaMap);
298 return msaMap;
299 }
300
301 public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {
302
303 try {
304 ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
305 //
306 // Validate File if they accord with XML Schema
307 //
308 // if ( ! doc.validate()){
309 // throw new Exception("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
310 // }
311 //
312 // parse MSA file
313 //
314 ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
315 Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
316 msaMap.put("ModuleSurfaceArea", msa);
317 msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
318 msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
319 msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
320 msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
321 msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
322 msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
323 msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
324 msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
325 return msaMap;
326 }
327 catch (Exception ex){
328 throw new Exception(ex.getMessage());
329 }
330 }
331
332 public static Map<String, XmlObject> getFpdBuildOptions() {
333 Map<String, XmlObject> map = new HashMap<String, XmlObject>();
334 map.put("BuildOptions", fpdBuildOptions);
335 return map;
336 }
337
338 public static void setFpdBuildOptions(XmlObject fpdBuildOptions) throws Exception{
339 GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
340 }
341
342 public static XmlObject getFpdDynamicPcds() {
343 return fpdDynamicPcds;
344 }
345
346 public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
347 GlobalData.fpdDynamicPcds = fpdDynamicPcds;
348 }
349
350 //////////////////////////////////////////////
351 //////////////////////////////////////////////
352
353 public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
354 Spd spd = spdTable.get(packageId);
355 if (spd == null ) {
356 Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
357 return dummy;
358 }
359 else {
360 return spd.getModules();
361 }
362 }
363
364 public synchronized static PlatformIdentification getPlatform(String name) throws Exception {
365 Iterator iter = platformList.iterator();
366 while(iter.hasNext()){
367 PlatformIdentification platformId = (PlatformIdentification)iter.next();
368 if (platformId.getName().equalsIgnoreCase(name)) {
369 GlobalData.log.info("Platform: " + platformId + platformId.getFpdFile());
370 return platformId;
371 }
372 }
373 throw new Exception("Can't find platform [" + name + "] in current workspace. ");
374 }
375
376 public synchronized static File getPackageFile(PackageIdentification packageId) throws Exception {
377 Iterator iter = packageList.iterator();
378 while(iter.hasNext()){
379 PackageIdentification packageItem = (PackageIdentification)iter.next();
380 if (packageItem.equals(packageId)) {
381 packageId.setName(packageItem.getName());
382 return packageItem.getSpdFile();
383 }
384 }
385 throw new Exception("Can't find " + packageId + " in current workspace. ");
386 }
387
388 public synchronized static File getModuleFile(ModuleIdentification moduleId) throws Exception {
389 PackageIdentification packageId = getPackageForModule(moduleId);
390 moduleId.setPackage(packageId);
391 Spd spd = spdTable.get(packageId);
392 return spd.getModuleFile(moduleId);
393 }
394 //
395 // expanded by FrameworkWizard
396 //
397 public synchronized static XmlObject getModuleXmlObject(ModuleIdentification moduleId) throws Exception {
398 PackageIdentification packageId = getPackageForModule(moduleId);
399 moduleId.setPackage(packageId);
400 Spd spd = spdTable.get(packageId);
401 return spd.msaDocMap.get(moduleId);
402 }
403
404 public synchronized static XmlObject getPackageXmlObject(PackageIdentification packageId) {
405 Spd spd = spdTable.get(packageId);
406 if (spd != null){
407 return spd.spdDocMap.get("PackageSurfaceArea");
408 }
409 return null;
410 }
411
412 public synchronized static Set<PackageIdentification> getPackageList(){
413 return packageList;
414 }
415 ///// remove!!
416 private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws Exception {
417 if ( object == null) {
418 return null;
419 }
420 XmlObject result = null;
421 try {
422 result = XmlObject.Factory.parse(object.getDomNode()
423 .cloneNode(deep));
424 } catch (Exception ex) {
425 throw new Exception(ex.getMessage());
426 }
427 return result;
428 }
429
430 public static ModuleIdentification getModuleId(String key){
431 //
432 // Get ModuleGuid, ModuleVersion, PackageGuid, PackageVersion, Arch into string array.
433 //
434 String[] keyPart = key.split(" ");
435 Set<PackageIdentification> spi = GlobalData.getPackageList();
436 Iterator ispi = spi.iterator();
437
438 while(ispi.hasNext()) {
439 PackageIdentification pi = (PackageIdentification)ispi.next();
440 if ( !pi.getGuid().equalsIgnoreCase(keyPart[2])){
441
442 continue;
443 }
444 if (keyPart[3] != null && keyPart[3].length() > 0 && !keyPart[3].equals("null")){
445 if(!pi.getVersion().equals(keyPart[3])){
446 continue;
447 }
448 }
449 Set<ModuleIdentification> smi = GlobalData.getModules(pi);
450 Iterator ismi = smi.iterator();
451 while(ismi.hasNext()) {
452 ModuleIdentification mi = (ModuleIdentification)ismi.next();
453 if (mi.getGuid().equalsIgnoreCase(keyPart[0])){
454 if (keyPart[1] != null && keyPart[1].length() > 0 && !keyPart[1].equals("null")){
455 if(!mi.getVersion().equals(keyPart[1])){
456 continue;
457 }
458 }
459
460 return mi;
461 }
462 }
463 }
464 return null;
465 }
466
467 public static Vector<String> getModuleSupArchs(ModuleIdentification mi) throws Exception{
468 Vector<String> vArchs = null;
469 ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = (ModuleSurfaceAreaDocument.ModuleSurfaceArea)getModuleXmlObject(mi);
470 if (msa.getModuleDefinitions() == null || msa.getModuleDefinitions().getSupportedArchitectures() == null) {
471 return vArchs;
472 }
473 ListIterator li = msa.getModuleDefinitions().getSupportedArchitectures().listIterator();
474 while (li.hasNext()) {
475 if (vArchs == null) {
476 vArchs = new Vector<String>();
477 }
478 vArchs.add((String)li.next());
479 }
480
481 return vArchs;
482 }
483
484 }
485
486 final class KeyComparator implements Comparator<String> {
487 public int compare(String x, String y) {
488 return x.compareToIgnoreCase(y);
489 }
490
491 }
492