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