]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/Merge/src/org/tianocore/Merge/CombineMsa.java
Adding merge command line program that merges multiple MSA modules into a single...
[mirror_edk2.git] / Tools / Source / Merge / src / org / tianocore / Merge / CombineMsa.java
CommitLineData
0e771cd3 1// @file\r
2// This Class processes multiple MSA files and merges them into a single, \r
3// merged MSA file. It will optionally add the merged MSA file into a package.\r
4//\r
5//\r
6// Copyright (c) 2006, Intel Corporation All rights reserved.\r
7//\r
8// This program and the accompanying materials are licensed and made\r
9// available under the terms and conditions of the BSD License which\r
10// accompanies this distribution. The full text of the license may \r
11// be found at http://opensource.org/licenses/bsd-license.php\r
12//\r
13// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15//\r
16//\r
17\r
18package org.tianocore.Merge;\r
19\r
20import java.io.*;\r
21import java.util.*;\r
22// import java.lang.*;\r
23// import java.lang.ExceptionInInitializerError;\r
24\r
25// import org.apache.xmlbeans.*;\r
26import org.apache.xmlbeans.XmlCursor;\r
27// import org.apache.xmlbeans.XmlObject;\r
28import org.apache.xmlbeans.XmlOptions;\r
29import org.apache.xmlbeans.XmlException;\r
30import org.tianocore.*;\r
31\r
32// import org.tianocore.*;\r
33import org.tianocore.ModuleSurfaceAreaDocument.*;\r
34import org.tianocore.MsaHeaderDocument.*;\r
35import org.tianocore.LicenseDocument.*;\r
36import org.tianocore.ModuleDefinitionsDocument.*;\r
37import org.tianocore.LibraryClassDefinitionsDocument.*;\r
38import org.tianocore.SourceFilesDocument.*;\r
39import org.tianocore.PackageDependenciesDocument.*;\r
40import org.tianocore.ProtocolsDocument.*;\r
41import org.tianocore.EventsDocument.*;\r
42import org.tianocore.HobsDocument.*;\r
43import org.tianocore.PPIsDocument.*;\r
44import org.tianocore.VariablesDocument.*;\r
45import org.tianocore.BootModesDocument.*;\r
46import org.tianocore.SystemTablesDocument.*;\r
47import org.tianocore.DataHubsDocument.*;\r
48import org.tianocore.HiiPackagesDocument.*;\r
49import org.tianocore.GuidsDocument.*;\r
50import org.tianocore.ExternsDocument.*;\r
51import org.tianocore.PcdCodedDocument.*;\r
52import org.tianocore.ModuleBuildOptionsDocument.*;\r
53import org.tianocore.UserExtensionsDocument.*;\r
54\r
55import org.tianocore.PackageSurfaceAreaDocument.*;\r
56import org.tianocore.MsaFilesDocument.*;\r
57\r
58public class CombineMsa {\r
59\r
60 private final int DEBUG = 0;\r
61\r
62 private final int PASS = 0;\r
63\r
64 private final int FAIL = 1;\r
65\r
66 private final int FOUND = 0;\r
67\r
68 private final int NOTFOUND = 1;\r
69\r
70 private int result = PASS;\r
71\r
72 private String licenseTxt = "";\r
73\r
74 private ArrayList<String> aLicenses = new ArrayList<String>();\r
75\r
76 private String Copyright = "";\r
77\r
78 private ArrayList<String> aCopyright = new ArrayList<String>();\r
79\r
80 private String Abstract = "\n Merged Modules: \n";\r
81\r
82 private String Description = "\n Merging Modules: \n";\r
83\r
84 private String sArchitectures = "";\r
85\r
86 private MsaHeader header = null;\r
87\r
88 private final String Specification = "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052";\r
89\r
90 private ModuleSurfaceArea mergeMsaFile = null;\r
91\r
92 private ModuleSurfaceArea leafMsa = null;\r
93\r
94 private ModuleDefinitions moduleDefs = null;\r
95\r
96 private LibraryClassDefinitions libClassDefs = null;\r
97\r
98 private ArrayList<String> aLibClassDefs = new ArrayList<String>();\r
99\r
100 private int libraryClassIndex = 0;\r
101\r
102 private SourceFiles mergeSourceFiles = null;\r
103\r
104 private int sourceFileIndex = 0;\r
105\r
106 private PackageDependencies mergePackageDependencies = null;\r
107\r
108 private ArrayList<String> aPackageList = new ArrayList<String>();\r
109\r
110 private int packageDependenciesIndex = 0;\r
111\r
112 private Protocols mergeProtocols = null;\r
113\r
114 private ArrayList<String> aProtocolList = new ArrayList<String>();\r
115\r
116 private ArrayList<String> aProtocolNotifyList = new ArrayList<String>();\r
117\r
118 private int protocolIndex = 0;\r
119\r
120 private int protocolNotifyIndex = 0;\r
121\r
122 private Events mergeEvents = null;\r
123\r
124 private Events.CreateEvents mergeCreateEvents = null;\r
125\r
126 private Events.SignalEvents mergeSignalEvents = null;\r
127\r
128 private ArrayList<String> aCreateEventsList = new ArrayList<String>();\r
129\r
130 private ArrayList<String> aSignalEventsList = new ArrayList<String>();\r
131\r
132 private int createEventIndex = 0;\r
133\r
134 private int signalEventIndex = 0;\r
135\r
136 private Hobs mergeHobs = null;\r
137\r
138 private ArrayList<String> aHobsList = new ArrayList<String>();\r
139\r
140 private int hobsIndex = 0;\r
141\r
142 private PPIs mergePpis = null;\r
143\r
144 private ArrayList<String> aPpiList = new ArrayList<String>();\r
145\r
146 private ArrayList<String> aPpiNotifyList = new ArrayList<String>();\r
147\r
148 private int ppiIndex = 0;\r
149\r
150 private int ppiNotifyIndex = 0;\r
151\r
152 private Variables mergeVariables = null;\r
153\r
154 private ArrayList<String> aVariablesList = new ArrayList<String>();\r
155\r
156 private int variablesIndex = 0;\r
157\r
158 private BootModes mergeBootModes = null;\r
159\r
160 private ArrayList<String> aBootModesList = new ArrayList<String>();\r
161\r
162 private int bootModesIndex = 0;\r
163\r
164 private SystemTables mergeSystemTables = null;\r
165\r
166 private ArrayList<String> aSystemTablesList = new ArrayList<String>();\r
167\r
168 private int systemTableIndex = 0;\r
169\r
170 private DataHubs mergeDataHubs = null;\r
171\r
172 private ArrayList<String> aDataHubsList = new ArrayList<String>();\r
173\r
174 private int dataHubsIndex = 0;\r
175\r
176 private HiiPackages mergeHiiPackages = null;\r
177\r
178 private ArrayList<String> aHiiPackagesList = new ArrayList<String>();\r
179\r
180 private int hiiPackageIndex = 0;\r
181\r
182 private Guids mergeGuids = null;\r
183\r
184 private ArrayList<String> aGuidsList = new ArrayList<String>();\r
185\r
186 private int guidsIndex = 0;\r
187\r
188 private Externs mergeExterns = null;\r
189\r
190 private ArrayList<String> aEntryPointList = new ArrayList<String>();\r
191\r
192 private ArrayList<String> aUnloadImageList = new ArrayList<String>();\r
193\r
194 private ArrayList<String> aDriverBindingList = new ArrayList<String>();\r
195\r
196 private ArrayList<String> aConstructorList = new ArrayList<String>();\r
197\r
198 private ArrayList<String> aDestructorList = new ArrayList<String>();\r
199\r
200 private ArrayList<String> aVirtualAddressMapList = new ArrayList<String>();\r
201\r
202 private ArrayList<String> aExitBootServicesList = new ArrayList<String>();\r
203\r
204 private int externsIndex = 0;\r
205\r
206 private ArrayList<String> aSpecArray = new ArrayList<String>();\r
207\r
208 private int specIndex = 0;\r
209\r
210 private PcdCoded mergePcdCoded = null;\r
211\r
212 private ArrayList<String> aPcdCNameList = new ArrayList<String>();\r
213\r
214 private ArrayList<String> aPcdItemTypeList = new ArrayList<String>();\r
215\r
216 private int pcdIndex = 0;\r
217\r
218 private ModuleBuildOptions mergeBuildOptions = null;\r
219\r
220 private UserExtensions mergeUserExtensions = null;\r
221\r
222 private XmlCursor cursor = null;\r
223\r
224 private String mergeUsage = "";\r
225\r
226 private String leafUsage = "";\r
227\r
228 private int VERBOSE = 0;\r
229\r
230 // The combineMsaFiles routine is the primary routine for creating a \r
231 // Merged MSA file.\r
232\r
233 public int combineMsaFiles(String msaFilename, ArrayList<String> msaFiles, String uiName, String spdFilename,\r
234 String baseName, int Flags) {\r
235 // msaFile has been verified to either not exist, or, if it does exist, \r
236 // it will be over written.\r
237 // All files in the msaFiles ArrayList have been verifed to exist.\r
238 // If the uiName is not null, we will have a new UI Name for the merged \r
239 // module.\r
240 // If the uiName is null, we will use the module name from the first \r
241 // Leaf module.\r
242 // If the spdFile is not null, the Package (SPD) file has been verified \r
243 // to exist.\r
244 // If the spdFile is null, don't attempt to add the new msa file.\r
245\r
246 if (Flags > 0)\r
247 VERBOSE = 1;\r
248 if (mergeMsaFile == null) {\r
249 //\r
250 // create the data structure for the merged Module\r
251 //\r
252 mergeMsaFile = ModuleSurfaceArea.Factory.newInstance();\r
253\r
254 System.out.println("Merging " + msaFiles.size() + " Modules");\r
255 //\r
256 // we always require a Header and a Module Definition section.\r
257 // These will be added to the mergeMsaFile after we have completed \r
258 // all processing of the Leaf MSA files.\r
259 //\r
260 header = MsaHeaderDocument.Factory.newInstance().addNewMsaHeader();\r
261 moduleDefs = ModuleDefinitionsDocument.Factory.newInstance().addNewModuleDefinitions();\r
262 //\r
263 // A merged module cannot be created from binary modules - we force \r
264 // the new module to be source here, however we will test every \r
265 // module to make sure that none are binary; exiting the program if\r
266 // a module is binary\r
267 //\r
268 moduleDefs.setBinaryModule(false);\r
269\r
270 for (int i = 0; i < msaFiles.size(); i++) {\r
271 String leafFilename = msaFiles.get(i).toString();\r
272 leafMsa = getLeafFile(leafFilename);\r
273 if (leafMsa == null) {\r
274 System.out.println("Could not read Leaf MSA file: " + leafFilename);\r
275 System.exit(FAIL);\r
276 }\r
277 if (i == 0) {\r
278 //\r
279 // Special code for first file, since this file is used \r
280 // to initialize some of the data in the mergeMsaFile. \r
281 // Set the Merge module's ModuleName to the name in the \r
282 // first Leaf Module. If a new module name is given, \r
283 // over write it later, just before writing the Merge \r
284 // Module MSA file.\r
285 header.setModuleName(leafMsa.getMsaHeader().getModuleName().toString());\r
286 //\r
287 // All modules must be of the same module type, we set it \r
288 // here, and test the other Leaf modules' type later.\r
289 header.setModuleType(leafMsa.getMsaHeader().getModuleType());\r
290 //\r
291 // This is a new Module, so we need a new GUID\r
292 header.setGuidValue(UUID.randomUUID().toString());\r
293 //\r
294 // Use the version from the first Leaf module as the \r
295 // Merge Module version number.\r
296 header.setVersion(leafMsa.getMsaHeader().getVersion().toString());\r
297 //\r
298 // There is no special requirement for processing the \r
299 // following, so we just fall through on these elements \r
300 // of the header.\r
301 // Abstract will be added after parsing all leaf MSA files.\r
302 // Description will be added after parsing all leaf MSA files.\r
303 // Copyright will be added after parsing all leaf MSA files.\r
304 // License will be added after parsing all leaf MSA files.\r
305 //\r
306 // Force the specification to match this tool's spec version.\r
307 header.setSpecification(Specification);\r
308 //\r
309 // Set the Merged Module's Output Basename to match the first \r
310 // leaf module\r
311 String OutputFileName = leafMsa.getModuleDefinitions().getOutputFileBasename().toString();\r
312 //\r
313 // Just in case someone put a space character in the first\r
314 // leaf module's output filename, replace the spaces with\r
315 // an underscore.\r
316 OutputFileName.replace(" ", "_");\r
317 moduleDefs.setOutputFileBasename(OutputFileName);\r
318 //\r
319 // We start with the first module's list of supported \r
320 // architectures. As we process the additional leaf modules,\r
321 // we may have to remove some supported architectures from \r
322 // the list, as we can only build for the "least common \r
323 // denominator" subset of architectures.\r
324 sArchitectures = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
325 if ((DEBUG > 5) || (VERBOSE > 5))\r
326 System.out.println("New Header: \"" + header.getModuleName().toString() + "\"");\r
327 }\r
328 //\r
329 // We test the license in each leaf module, and will only print\r
330 // licenses that are may be different in wording (white spaces \r
331 // and line feeds are ignored in this test.)\r
332 if (leafMsa.getMsaHeader().getLicense() != null)\r
333 licenseTxt += checkDuplicateStrings(leafMsa.getMsaHeader().getLicense().getStringValue().trim(),\r
334 aLicenses);\r
335 if ((DEBUG > 10) || (VERBOSE > 10))\r
336 System.out.println("License: " + licenseTxt);\r
337 //\r
338 // We test the copyright line from each leaf module, and will \r
339 // add additional copyright lines only if they are different \r
340 // in wording (white spaces and line feeds are ignored in this\r
341 // test.)\r
342 if (leafMsa.getMsaHeader().getCopyright() != null)\r
343 Copyright += checkDuplicateStrings(leafMsa.getMsaHeader().getCopyright().toString().trim(),\r
344 aCopyright);\r
345 if ((DEBUG > 10) || (VERBOSE > 10))\r
346 System.out.println("Copyright: " + Copyright);\r
347 //\r
348 // ALL leaf modules must be of the same Module Type, if not, \r
349 // print an error and exit.\r
350 if (header.getModuleType() != leafMsa.getMsaHeader().getModuleType()) {\r
351 System.out.println("ERROR: Module Types different!");\r
352 System.out.println(" Expected: " + header.getModuleType());\r
353 System.out.println(" " + leafFilename + " ModuleType: " + leafMsa.getMsaHeader().getModuleType());\r
354 System.out.println("Merge ABORTED!");\r
355 System.exit(FAIL);\r
356 }\r
357 //\r
358 // Combine the Abstract and Descriptions into a single \r
359 // description entry, prefixing each with the Leaf MSA filename,\r
360 // so you know which description is from which Leaf module.\r
361 Description += " -- " + leafFilename + " -- \n Abstract: "\r
362 + leafMsa.getMsaHeader().getAbstract().toString() + "\n Description: "\r
363 + leafMsa.getMsaHeader().getDescription().toString() + "\n";\r
364 //\r
365 // Use the Abstract of the Merged Module to list the Leaf \r
366 // Module's MSA files.\r
367 Abstract += " -- " + leafFilename + " -- \n";\r
368 //\r
369 // Ignore ClonedFrom right now\r
370 //\r
371\r
372 // Process Supported Architectures\r
373 // A merged module supports the lowest common set of \r
374 // architectures\r
375 String testArch = "";\r
376 if (leafMsa.getModuleDefinitions().getSupportedArchitectures() == null) {\r
377 System.out\r
378 .println("Module " + leafFilename + " does not have the Supported Architectures defined!");\r
379 System.out.println("Supported Architectures is a required element!");\r
380 System.out.println("Merge ABORTED!");\r
381 System.exit(FAIL);\r
382 }\r
383 testArch = leafMsa.getModuleDefinitions().getSupportedArchitectures().toString();\r
384 String aArch[] = sArchitectures.split(" ");\r
385 for (int ictr = 0; ictr < aArch.length; ictr++) {\r
386 if (!testArch.contains(aArch[ictr])) {\r
387 sArchitectures = sArchitectures.replace(aArch[ictr], "");\r
388 }\r
389 }\r
390 if (sArchitectures.length() < 2) {\r
391 System.out.println("ERROR: The Leaf Modules' Supported Architectures are mutually exclusive.");\r
392 System.out.println("At least one architecture must be common to all Leaf Modules!");\r
393 System.out.println("Merge Aborting!");\r
394 System.exit(FAIL);\r
395 }\r
396 //\r
397 // Now start to process the rest of the Leaf Module's MSA files.\r
398 // We will only test a Leaf module's section if it has data, skipping\r
399 // empty sections\r
400 // As part of this process, we will only create a Library Class Definition\r
401 // if one was defined, and we will only do it one time.\r
402 if (leafMsa.isSetLibraryClassDefinitions()) {\r
403 // \r
404 // If libClassDefs == null, create a new libClassDefs and add\r
405 // this module's libClassDefs to the merge Module's\r
406 // If libClassDefs != null, check that we have only unique LibraryClass entries\r
407 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
408 // Mark the LibraryClass as ALWAYS_PRODUCED\r
409 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
410 // Mark the LibraryClass as ALWAYS_CONSUMED\r
411 // It is permissable to have one PRODUCED and one CONSUMED entry\r
412 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
413 // and another Leaf uses BY_START, create two entries, one for each.\r
414 //\r
415 // The RecommendedInstance attributes can be ignored!\r
416 //\r
417 // First PASS of the TOOL \r
418 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
419 // this as an error!\r
420 // Probable Enhancement\r
421 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
422 //\r
423 // First PASS of the TOOL\r
424 // The SupModuleList must be identical for all Leaf Modules!\r
425 // Probable Enhancement\r
426 // The SupModuleList should be combined to include all possible supported module types.\r
427 //\r
428 // First PASS of the TOOL\r
429 // Ignore the FeatureFlag - we are not using it now.\r
430 // Probable Enhancement\r
431 // FeatureFlags must be identical for each LibraryClass, otherwize fail the Merge\r
432 //\r
433 // Create the working copy if one does not exist!\r
434 if (libClassDefs == null)\r
435 libClassDefs = LibraryClassDefinitionsDocument.Factory.newInstance()\r
436 .addNewLibraryClassDefinitions();\r
437 //\r
438 // Get the Leaf LibraryClassDefinitions Section\r
439 LibraryClassDefinitions leafLibClassDef = leafMsa.getLibraryClassDefinitions();\r
440 //\r
441 // We only need to test there are entries in the Leaf LibraryClassDefinitions section!\r
442 if (leafLibClassDef.getLibraryClassList().size() > 0) {\r
443 for (int index = 0; index < leafLibClassDef.getLibraryClassList().size(); index++) {\r
444 //\r
445 // We can use the Keyword to search to see if the Leaf's Library Class was already\r
446 // added to the Merge Module.\r
447 String test = "";\r
448 String leafKeyword = leafLibClassDef.getLibraryClassList().get(index).getKeyword()\r
449 .toString().trim();\r
450\r
451 leafUsage = "";\r
452 if (leafLibClassDef.getLibraryClassList().get(index).getUsage() != null)\r
453 leafUsage = leafLibClassDef.getLibraryClassList().get(index).getUsage().toString()\r
454 .trim();\r
455\r
456 String leafSupArchList = "";\r
457 if (leafLibClassDef.getLibraryClassList().get(index).getSupArchList() != null)\r
458 leafSupArchList = leafLibClassDef.getLibraryClassList().get(index).getSupArchList()\r
459 .toString().trim();\r
460\r
461 String leafSupModuleList = "";\r
462 if (leafLibClassDef.getLibraryClassList().get(index).getSupModuleList() != null)\r
463 leafSupModuleList = leafLibClassDef.getLibraryClassList().get(index).getSupModuleList()\r
464 .toString().trim();\r
465\r
466 test = checkDuplicateStrings(leafKeyword, aLibClassDefs);\r
467 if (test.length() > 0) {\r
468 // The checkDuplicateStrings returns "" if a duplicate was found.\r
469 // Here, the Leaf LibraryClass gets entered because the Keyword was not found.\r
470 // No more testing is required, since this is the first instance of the LibraryClass\r
471 libClassDefs.addNewLibraryClass();\r
472 libClassDefs.setLibraryClassArray(libraryClassIndex++,\r
473 leafLibClassDef.getLibraryClassList().get(index));\r
474 } else {\r
475 // The Merged Module has already specified the Library Class\r
476 // Check ATTRIBUTES, following the rules above.\r
477 // Since we cannot get the LibraryClass entry using the Keyword, we have to search\r
478 // all of the Merged Module's LibraryClass statements until we find a match.\r
479 // Also, we may have more than one LibraryClass with the same Keyword, but different\r
480 // Usage, SupArchList, FeatureFlag or SupModuleList\r
481 for (int nidx = 0; nidx < libraryClassIndex; nidx++) {\r
482 String mergeKeyword = libClassDefs.getLibraryClassList().get(nidx).getKeyword()\r
483 .trim();\r
484\r
485 if (leafKeyword.contentEquals(mergeKeyword)) {\r
486 // We have the FIRST match, let's check usage, remember, we can have more than one LibraryClass Keyword.\r
487 mergeUsage = libClassDefs.getLibraryClassList().get(nidx).getUsage().toString()\r
488 .trim();\r
489 // If the usage is identical, check the SupArchList next\r
490 if (!leafUsage.contentEquals(mergeUsage)) {\r
491 if (checkUsage().trim().contains("DIFFERENT")) {\r
492 // See if there is another entry for PRODUCED or CONSUME\r
493 int anotherLC = NOTFOUND;\r
494 for (int iidx = nidx + 1; iidx < libraryClassIndex; iidx++) {\r
495 String innerTestKeyword = libClassDefs.getLibraryClassList()\r
496 .get(iidx).getKeyword()\r
497 .toString().trim();\r
498 if (leafKeyword.contentEquals(innerTestKeyword)) {\r
499 anotherLC = FOUND;\r
500 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
501 .getUsage().toString().trim();\r
502 if (checkProduced()) {\r
503 libClassDefs\r
504 .getLibraryClassList()\r
505 .get(iidx)\r
506 .setUsage(\r
507 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
508 }\r
509 // Both Usage types are CONSUMED\r
510 if (checkConsumed()) {\r
511 libClassDefs\r
512 .getLibraryClassList()\r
513 .get(iidx)\r
514 .setUsage(\r
515 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
516 }\r
517 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
518 .contains("TO_START"))))\r
519 anotherLC = FOUND;\r
520 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
521 .contains("BY_START"))))\r
522 anotherLC = FOUND;\r
523 }\r
524 }\r
525 if (anotherLC == NOTFOUND) {\r
526 // we need to add the leaf Library Class\r
527 libClassDefs.addNewLibraryClass();\r
528 libClassDefs\r
529 .setLibraryClassArray(\r
530 libraryClassIndex++,\r
531 leafLibClassDef\r
532 .getLibraryClassList()\r
533 .get(index));\r
534 }\r
535 }\r
536\r
537 // Both Usage types are PRODUCED\r
538 if (checkUsage().trim().contains("PRODUCED")) {\r
539 libClassDefs.getLibraryClassList().get(nidx)\r
540 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
541 }\r
542 // Both Usage types are CONSUMED\r
543 if (checkUsage().trim().contains("CONSUMED")) {\r
544 libClassDefs.getLibraryClassList().get(nidx)\r
545 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
546 }\r
547 }\r
548 // Usage testing completed\r
549 // Check SupArchList\r
550 String mergeSupArchList = "";\r
551 if (libClassDefs.getLibraryClassList().get(nidx).getSupArchList() != null)\r
552 mergeSupArchList = libClassDefs.getLibraryClassList().get(nidx)\r
553 .getSupArchList().toString().trim();\r
554 if (!mergeSupArchList.equalsIgnoreCase(leafSupArchList)) {\r
555 System.out\r
556 .println("ERROR: Library Class, keyword: " + leafKeyword\r
557 + " defines a different set of supported architectures.");\r
558 System.out\r
559 .println("Version 0.1 of the merge tool requires that they must be identical!");\r
560 System.out.println("First instance of the Library used: "\r
561 + mergeSupArchList);\r
562 System.out.println("While this module, " + leafFilename + " uses: "\r
563 + leafSupArchList);\r
564 System.out.println("Merge ABORTED!");\r
565 System.exit(FAIL);\r
566 }\r
567 // Architecture Testing completed\r
568 // Check SupModuleType\r
569 String mergeSupModuleList = "";\r
570 if (libClassDefs.getLibraryClassList().get(nidx).getSupModuleList() != null)\r
571 mergeSupModuleList = libClassDefs.getLibraryClassList().get(nidx)\r
572 .getSupModuleList().toString().trim();\r
573 if (!mergeSupModuleList.equalsIgnoreCase(leafSupModuleList)) {\r
574 System.out.println("ERROR: Library Class, keyword: " + leafKeyword\r
575 + " defines a different set of supported modules.");\r
576 System.out\r
577 .println("Version 0.1 of the merge tool requires that they must be identical!");\r
578 System.out.println("First instance of the Library used: "\r
579 + mergeSupModuleList);\r
580 System.out.println("While this module, " + leafFilename + " uses: "\r
581 + leafSupModuleList);\r
582 System.out.println("Merge ABORTED!");\r
583 System.exit(FAIL);\r
584 }\r
585 // Supported Module Testing completed\r
586 // Check FeatureFlage\r
587 // Next version, not this one.\r
588 }\r
589 } // end of processing of duplicate Library Class entries\r
590 } // end duplicate entry\r
591 } // end of test loop for duplicates \r
592 } // endif Merge Module LibraryModuleDefinitions existed\r
593 } // endif of LibraryModuleDefinition Tests\r
594\r
595 if (leafMsa.isSetSourceFiles()) {\r
596 // TODO: test for NULL settings\r
597 // Add Sourcefiles to the Merge Module. NOTE: ONLY MODIFY THE Filename, prepending the path to the MSA file.\r
598 // First get the path portion of the leafMSA file, which will be prepended to the filename\r
599 // everything else stays intact.\r
600 if (mergeSourceFiles == null)\r
601 mergeSourceFiles = SourceFilesDocument.Factory.newInstance().addNewSourceFiles();\r
602\r
603 String pathToMsa = getPathPartOfLeafMsa(leafFilename);\r
604 if (DEBUG > 10)\r
605 System.out.println("PATH TO SOURCE FILES: " + pathToMsa);\r
606 if (leafMsa.getSourceFiles().getFilenameList() != null) {\r
607 List<FilenameDocument.Filename> leafSourceFiles = leafMsa.getSourceFiles().getFilenameList();\r
608 for (int index = 0; index < leafSourceFiles.size(); index++) {\r
609 String leafFile = leafSourceFiles.get(index).getStringValue().toString();\r
610 leafFile = pathToMsa + leafFile;\r
611 leafSourceFiles.get(index).setStringValue(leafFile);\r
612 mergeSourceFiles.addNewFilename();\r
613 mergeSourceFiles.setFilenameArray(sourceFileIndex++, leafSourceFiles.get(index));\r
614 }\r
615 }\r
616 }\r
617\r
618 if (leafMsa.isSetPackageDependencies()) {\r
619 //\r
620 // If mergePackageDependencies == null, create a new mergePackageDependencies and\r
621 // add the leaf module's Package Dependencies section to the merge Module's\r
622 // If mergePackageDependencies != null, test the leaf Package entries against\r
623 // what has already been added to the mergePackageDependencies data structure.\r
624 //\r
625 // Add Unique Package entries.\r
626 // For this Merge Tool a Package is defined as PackageGuid\r
627 //\r
628 // ABORT THE MERGE WITH FAIL if the PACKAGE VERSION NUMBERS ARE DIFFERENT\r
629 // between Leaf modules\r
630 //\r
631 // Version 0.1 of the tool\r
632 // SupArchList, if it exists, must be identical for all Leaf Modules\r
633 // Probable Enhancement\r
634 // Just specify the lowest common denominator\r
635 //\r
636 // Create the working copy if one does not exist!\r
637 // TODO: CODE GOES HERE\r
638 if (mergePackageDependencies == null)\r
639 mergePackageDependencies = PackageDependenciesDocument.Factory.newInstance()\r
640 .addNewPackageDependencies();\r
641\r
642 PackageDependencies leafPackageDependencies = leafMsa.getPackageDependencies();\r
643 if (leafPackageDependencies.sizeOfPackageArray() > 0) {\r
644 for (int index = 0; index < leafPackageDependencies.sizeOfPackageArray(); index++) {\r
645 String packageGuid = leafPackageDependencies.getPackageArray(index).getPackageGuid();\r
646 String test = checkDuplicateStrings(packageGuid, aPackageList);\r
647 if (test.length() > 0) {\r
648 mergePackageDependencies.addNewPackage();\r
649 mergePackageDependencies\r
650 .setPackageArray(packageDependenciesIndex++,\r
651 leafPackageDependencies.getPackageArray(index));\r
652 }\r
653 }\r
654 }\r
655 } // endif PackageDependencies\r
656\r
657 if (leafMsa.isSetProtocols()) {\r
658 // TODO: \r
659 // TEST FOR NULL SETTINGS so we don't get an error!\r
660 // Add Usage Merging routines\r
661 // \r
662 // If mergeProtocols == null, create a new mergeProtocols and add\r
663 // leaf module's Protocols section to the merge Module's\r
664 //\r
665 // Keep ALL Protocol entries before ProtocolNotify entries!\r
666 //\r
667 // If mergeProtocols != null, check that we have only unique Protocol and ProtocolNotify entries\r
668 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
669 // Mark the Protocol or ProtocolNotify as ALWAYS_PRODUCED\r
670 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
671 // Mark the Protocol or ProtocolNotify as ALWAYS_CONSUMED\r
672 // It is permissable to have one PRODUCED and one CONSUMED entry\r
673 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
674 // and another Leaf uses BY_START, create two entries, one for each.\r
675 //\r
676 // First PASS of the TOOL \r
677 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
678 // this as an error!\r
679 // Probable Enhancement\r
680 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
681 //\r
682 // First PASS of the TOOL\r
683 // Ignore the FeatureFlag - we are not using it now.\r
684 // Probable Enhancement\r
685 // FeatureFlags must be identical for each unique Protocol or ProtocolNotify Entry, otherwise fail the Merge\r
686 //\r
687 // HelpText RULE:\r
688 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
689 // is the leaf Module's path and filename to the MSA file!\r
690 //\r
691 // Create the working copy if one does not exist!\r
692\r
693 if (mergeProtocols == null)\r
694 mergeProtocols = ProtocolsDocument.Factory.newInstance().addNewProtocols();\r
695\r
696 Protocols leafProtocols = leafMsa.getProtocols();\r
697 // Handle Protocol Entries First\r
698 if (leafProtocols.sizeOfProtocolArray() > 0) {\r
699 for (int index = 0; index < leafProtocols.sizeOfProtocolArray(); index++) {\r
700 String protocolCName = leafProtocols.getProtocolArray(index).getProtocolCName();\r
701 String test = checkDuplicateStrings(protocolCName, aProtocolList);\r
702 if (test.length() > 0) {\r
703 // new Protocol\r
704 mergeProtocols.addNewProtocol();\r
705 mergeProtocols.setProtocolArray(protocolIndex++, leafProtocols.getProtocolArray(index));\r
706 } else {\r
707 // Found an existing protocol\r
708 leafUsage = leafProtocols.getProtocolArray(index).getUsage().toString().trim();\r
709 for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
710 if (mergeProtocols.getProtocolArray(nidx).getProtocolCName()\r
711 .contains(protocolCName)) {\r
712 // Found one entry that matches.\r
713 mergeUsage = mergeProtocols.getProtocolArray(nidx).getUsage().toString().trim();\r
714 if (!mergeUsage.contentEquals(leafUsage)) {\r
715 // Usages are different\r
716 if (checkUsage().trim().contains("DIFFERENT")) {\r
717 // We need to check to see if there's another entry\r
718 int anotherProtocol = NOTFOUND;\r
719 for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
720\r
721 if (mergeProtocols.getProtocolArray(iidx).getUsage().toString()\r
722 .trim().contains(protocolCName)) {\r
723 anotherProtocol = FOUND;\r
724 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
725 .getUsage().toString().trim();\r
726 if (checkProduced()) {\r
727 mergeProtocols\r
728 .getProtocolArray(nidx)\r
729 .setUsage(\r
730 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
731 anotherProtocol = FOUND;\r
732 }\r
733 // Both Usage types are CONSUMED\r
734 if (checkConsumed()) {\r
735 mergeProtocols\r
736 .getProtocolArray(nidx)\r
737 .setUsage(\r
738 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
739 anotherProtocol = FOUND;\r
740 }\r
741 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
742 .contains("TO_START"))))\r
743 anotherProtocol = FOUND;\r
744 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
745 .contains("BY_START"))))\r
746 anotherProtocol = FOUND;\r
747 }\r
748 }\r
749 if (anotherProtocol == NOTFOUND) {\r
750 mergeProtocols.addNewProtocol();\r
751 mergeProtocols\r
752 .setProtocolArray(\r
753 protocolIndex++,\r
754 leafProtocols\r
755 .getProtocolArray(index));\r
756 }\r
757 } else {\r
758 // usage types are either both PRODUCED or CONSUMED\r
759 if (checkProduced())\r
760 mergeProtocols.getProtocolArray(nidx)\r
761 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
762 if (checkConsumed())\r
763 mergeProtocols.getProtocolArray(nidx)\r
764 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
765 }\r
766 }\r
767 }\r
768 } // end of Usage Test\r
769 }\r
770 }\r
771 }\r
772\r
773 // Handle ProtocolNotify Entries Second\r
774 if (leafProtocols.sizeOfProtocolNotifyArray() > 0) {\r
775 for (int index = 0; index < leafProtocols.sizeOfProtocolNotifyArray(); index++) {\r
776 String protocolNotifyCName = leafProtocols.getProtocolNotifyArray(index)\r
777 .getProtocolNotifyCName();\r
778 String test = checkDuplicateStrings(protocolNotifyCName, aProtocolNotifyList);\r
779 if (test.length() > 0) {\r
780 mergeProtocols.addNewProtocolNotify();\r
781 mergeProtocols.setProtocolNotifyArray(protocolNotifyIndex++,\r
782 leafProtocols.getProtocolNotifyArray(index));\r
783 } else {\r
784 // We have an existing ProtocolNotify Entry\r
785 leafUsage = leafProtocols.getProtocolNotifyArray(index).getUsage().toString().trim();\r
786 for (int nidx = 0; nidx < protocolIndex; nidx++) {\r
787 if (mergeProtocols.getProtocolNotifyArray(nidx).getProtocolNotifyCName()\r
788 .contains(protocolNotifyCName)) {\r
789 // Found one entry that matches.\r
790 mergeUsage = mergeProtocols.getProtocolNotifyArray(nidx).getUsage().toString().trim();\r
791 if (!mergeUsage.contentEquals(leafUsage)) {\r
792 // Usages are different\r
793 if (checkUsage().trim().contains("DIFFERENT")) {\r
794 // We need to check to see if there's another entry\r
795 int anotherProtocol = NOTFOUND;\r
796 for (int iidx = nidx + 1; iidx < protocolIndex; iidx++) {\r
797\r
798 if (mergeProtocols.getProtocolNotifyArray(iidx).getUsage().toString()\r
799 .trim().contains(protocolNotifyCName)) {\r
800 anotherProtocol = FOUND;\r
801 mergeUsage = libClassDefs.getLibraryClassList().get(iidx)\r
802 .getUsage().toString().trim();\r
803 if (checkProduced()) {\r
804 mergeProtocols\r
805 .getProtocolNotifyArray(nidx)\r
806 .setUsage(\r
807 org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
808 anotherProtocol = FOUND;\r
809 }\r
810 // Both Usage types are CONSUMED\r
811 if (checkConsumed()) {\r
812 mergeProtocols\r
813 .getProtocolNotifyArray(nidx)\r
814 .setUsage(\r
815 org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
816 anotherProtocol = FOUND;\r
817 }\r
818 if (((mergeUsage.contains("TO_START")) && (leafUsage\r
819 .contains("TO_START"))))\r
820 anotherProtocol = FOUND;\r
821 if (((mergeUsage.contains("BY_START")) && (leafUsage\r
822 .contains("BY_START"))))\r
823 anotherProtocol = FOUND;\r
824 }\r
825 }\r
826 if (anotherProtocol == NOTFOUND) {\r
827 mergeProtocols.addNewProtocolNotify();\r
828 mergeProtocols\r
829 .setProtocolNotifyArray(\r
830 protocolNotifyIndex++,\r
831 leafProtocols\r
832 .getProtocolNotifyArray(index));\r
833 }\r
834 } else {\r
835 // usage types are either both PRODUCED or CONSUMED\r
836 if (checkProduced())\r
837 mergeProtocols.getProtocolNotifyArray(nidx)\r
838 .setUsage(org.tianocore.UsageTypes.ALWAYS_PRODUCED);\r
839 if (checkConsumed())\r
840 mergeProtocols.getProtocolNotifyArray(nidx)\r
841 .setUsage(org.tianocore.UsageTypes.ALWAYS_CONSUMED);\r
842 }\r
843 }\r
844 }\r
845 } // end of Usage Test\r
846 } // end of Usage test\r
847 }\r
848 }\r
849\r
850 } // endif Protocols\r
851\r
852 if (leafMsa.isSetEvents()) {\r
853 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
854 //\r
855 // "Unique" Entries are based on EventsTypes:EventGuidCName attributes\r
856 // NOTE: The EventGuidCName can appear once and only once in a CreateEvents Section\r
857 // The SAME EventGuidCName can appear once and only once in the SignalEvents Section\r
858 // Two EventGuidCName entries, one in CreateEvents the other in SignalEvents IS PERMITTED!\r
859 //\r
860 // If mergeEvents == null, create a new mergeEvents and add\r
861 // leaf module's Events section to the merge Module's\r
862 //\r
863 // Keep ALL CreateEvents entries before SignalEvents entries!\r
864 //\r
865 // If mergeEvents != null, check that we have only unique CreateEvents and SignalEvents entries\r
866 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
867 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_PRODUCED\r
868 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
869 // Mark the CreateEvents.EventTypes or SignalEvents.EventTypes as ALWAYS_CONSUMED\r
870 // It is permissable to have one PRODUCED and one CONSUMED entry\r
871 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
872 // and another Leaf uses BY_START, create two entries, one for each.\r
873 //\r
874 // First PASS of the TOOL \r
875 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
876 // this as an error!\r
877 // Probable Enhancement\r
878 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
879 //\r
880 // First PASS of the TOOL\r
881 // Ignore the FeatureFlag - we are not using it now.\r
882 // Probable Enhancement\r
883 // FeatureFlags must be identical for each unique EventTypes, otherwise fail the Merge\r
884 //\r
885 // The EventTypes.EventType elements must be identical for all instances of\r
886 // the EventGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
887 // was different.\r
888 //\r
889 //\r
890 // HelpText RULE:\r
891 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
892 // is the leaf Module's path and filename to the MSA file!\r
893 //\r
894 // Create the working copy if one does not exist!\r
895 // TODO: Code goes here\r
896\r
897 if (mergeCreateEvents == null)\r
898 mergeCreateEvents = EventsDocument.Events.CreateEvents.Factory.newInstance();\r
899\r
900 Events leafEvents = leafMsa.getEvents();\r
901 if (leafEvents.getCreateEvents() != null) {\r
902 Events.CreateEvents leafCreateEvents = leafEvents.getCreateEvents();\r
903 if (leafCreateEvents.sizeOfEventTypesArray() > 0) {\r
904 for (int index = 0; index < leafCreateEvents.sizeOfEventTypesArray(); index++) {\r
905 String EventGuidCName = leafCreateEvents.getEventTypesArray(index).getEventGuidCName();\r
906 String test = checkDuplicateStrings(EventGuidCName, aCreateEventsList);\r
907 if (test.length() > 0) {\r
908 mergeCreateEvents.addNewEventTypes();\r
909 mergeCreateEvents.setEventTypesArray(createEventIndex++,\r
910 leafEvents.getCreateEvents()\r
911 .getEventTypesArray(index));\r
912\r
913 }\r
914 }\r
915 }\r
916 }\r
917\r
918 if (mergeSignalEvents == null)\r
919 mergeSignalEvents = EventsDocument.Events.SignalEvents.Factory.newInstance();\r
920\r
921 if (leafEvents.getSignalEvents() != null) {\r
922 Events.SignalEvents leafSignalEvents = leafEvents.getSignalEvents();\r
923 if (leafSignalEvents.sizeOfEventTypesArray() > 0) {\r
924 for (int index = 0; index < leafSignalEvents.sizeOfEventTypesArray(); index++) {\r
925 String EventGuidCName = leafSignalEvents.getEventTypesArray(index).getEventGuidCName();\r
926 String test = checkDuplicateStrings(EventGuidCName, aSignalEventsList);\r
927 if (test.length() > 0) {\r
928 mergeSignalEvents.addNewEventTypes();\r
929 mergeSignalEvents.setEventTypesArray(signalEventIndex++,\r
930 leafEvents.getSignalEvents()\r
931 .getEventTypesArray(index));\r
932 }\r
933 }\r
934 }\r
935 }\r
936 } // endif Events \r
937\r
938 if (leafMsa.isSetHobs()) {\r
939 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
940 //\r
941 // "Unique" Entries are based on Hobs.HobTypes:HobGuidCName attribute\r
942 //\r
943 // If mergeHobs == null, create a new mergeHobs and add\r
944 // leaf module's Hobs section to the merge Module's\r
945 //\r
946 // \r
947 // If mergeHobs != null, check that we have only unique Hobs.HobTypes entries\r
948 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
949 // Mark the Hobs.HobTypes as ALWAYS_PRODUCED\r
950 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
951 // Mark the Hobs.HobTypes as ALWAYS_CONSUMED\r
952 // It is permissable to have one PRODUCED and one CONSUMED entry\r
953 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
954 // and another Leaf uses BY_START, create two entries, one for each.\r
955 //\r
956 // First PASS of the TOOL \r
957 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
958 // this as an error!\r
959 // Probable Enhancement\r
960 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
961 //\r
962 // First PASS of the TOOL\r
963 // Ignore the FeatureFlag - we are not using it now.\r
964 // Probable Enhancement\r
965 // FeatureFlags must be identical for each unique HobTypes element, otherwise fail the Merge\r
966 //\r
967 // The HobTypes.HobType elements must be identical for all instances of\r
968 // the HobGuidCName FAIL THE MERGE WITH ERROR indicating the Leaf file name that \r
969 // was different.\r
970 //\r
971 //\r
972 // HelpText RULE:\r
973 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
974 // is the leaf Module's path and filename to the MSA file!\r
975 //\r
976 // Create the working copy if one does not exist!\r
977 // TODO: Code goes here\r
978 if (mergeHobs == null)\r
979 mergeHobs = HobsDocument.Factory.newInstance().addNewHobs();\r
980\r
981 Hobs leafHobs = leafMsa.getHobs();\r
982 if (leafHobs.sizeOfHobTypesArray() > 0) {\r
983 for (int index = 0; index < leafHobs.sizeOfHobTypesArray(); index++) {\r
984 String hobGuidCName = leafHobs.getHobTypesArray(index).getHobType().toString();\r
985 String test = checkDuplicateStrings(hobGuidCName, aHobsList);\r
986 if (test.length() > 0) {\r
987 mergeHobs.addNewHobTypes();\r
988 mergeHobs.setHobTypesArray(hobsIndex++, leafHobs.getHobTypesArray(index));\r
989 }\r
990 }\r
991 }\r
992 } // endif Hobs \r
993\r
994 if (leafMsa.isSetPPIs()) {\r
995 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
996 //\r
997 // Keep only Unique Ppi or PpiNotify elements, based on the PpiCName and PpiNotifyCName respectively.\r
998\r
999 // If mergePpi == null, create a new mergePpi and add\r
1000 // leaf module's PPIs section to the merge Module's\r
1001 //\r
1002 // Keep ALL Ppi entries before PpiNotify entries!\r
1003 //\r
1004 // If mergePpi != null, check that we have only unique Ppi and PpiNotify entries\r
1005 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1006 // Mark the Ppi or PpiNotify as ALWAYS_PRODUCED\r
1007 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1008 // Mark the Ppi or PpiNotify as ALWAYS_CONSUMED\r
1009 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1010 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1011 // and another Leaf uses BY_START, create two entries, one for each.\r
1012 //\r
1013 // First PASS of the TOOL \r
1014 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1015 // this as an error!\r
1016 // Probable Enhancement\r
1017 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1018 //\r
1019 // First PASS of the TOOL\r
1020 // Ignore the FeatureFlag - we are not using it now.\r
1021 // Probable Enhancement\r
1022 // FeatureFlags must be identical for each unique Ppi or PpiNotify Entry, otherwise fail the Merge\r
1023 //\r
1024 // HelpText RULE:\r
1025 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1026 // is the leaf Module's path and filename to the MSA file!\r
1027 //\r
1028 // Create the working copy if one does not exist!\r
1029 // TODO: Code Goes Here!\r
1030 if (mergePpis == null)\r
1031 mergePpis = PPIsDocument.Factory.newInstance().addNewPPIs();\r
1032\r
1033 PPIs leafPPIs = leafMsa.getPPIs();\r
1034 // Handle the PPI Entries First\r
1035 if (leafPPIs.sizeOfPpiArray() > 0) {\r
1036 for (int index = 0; index < leafPPIs.sizeOfPpiArray(); index++) {\r
1037 String ppiCName = leafPPIs.getPpiArray(index).getPpiCName();\r
1038 String test = checkDuplicateStrings(ppiCName, aPpiList);\r
1039 if (test.length() > 0) {\r
1040 mergePpis.addNewPpi();\r
1041 mergePpis.setPpiArray(ppiIndex++, leafPPIs.getPpiArray(index));\r
1042 }\r
1043 }\r
1044 }\r
1045\r
1046 // Handle the PpiNotify Second\r
1047 if (leafPPIs.sizeOfPpiNotifyArray() > 0) {\r
1048 for (int index = 0; index < leafPPIs.sizeOfPpiNotifyArray(); index++) {\r
1049 String ppiNotifyCName = leafPPIs.getPpiNotifyArray(index).getPpiNotifyCName();\r
1050 String test = checkDuplicateStrings(ppiNotifyCName, aPpiNotifyList);\r
1051 if (test.length() > 0) {\r
1052 mergePpis.addNewPpiNotify();\r
1053 mergePpis.setPpiNotifyArray(ppiNotifyIndex++, leafPPIs.getPpiNotifyArray(index));\r
1054 }\r
1055 }\r
1056 }\r
1057\r
1058 } // endif Ppis\r
1059\r
1060 if (leafMsa.isSetVariables()) {\r
1061 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1062 //\r
1063 // Keep only Unique Variable elements, based on the VariableName element.\r
1064 //\r
1065 // If mergeVariables == null, create a new mergeVariables and add\r
1066 // leaf module's Variables section to the merge Module's\r
1067 //\r
1068 // If mergeVariables != null, check that we have only unique Variable entries\r
1069 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1070 // Mark the Variable as ALWAYS_PRODUCED\r
1071 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1072 // Mark the Variable as ALWAYS_CONSUMED\r
1073 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1074 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1075 // and another Leaf uses BY_START, create two entries, one for each.\r
1076 //\r
1077 // First PASS of the TOOL \r
1078 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1079 // this as an error!\r
1080 // Probable Enhancement\r
1081 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1082 //\r
1083 // First PASS of the TOOL\r
1084 // Ignore the FeatureFlag - we are not using it now.\r
1085 // Probable Enhancement\r
1086 // FeatureFlags must be identical for each unique Variable entry, otherwise fail the Merge\r
1087 //\r
1088 // HelpText RULE:\r
1089 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1090 // is the leaf Module's path and filename to the MSA file!\r
1091 //\r
1092 // Create the working copy if one does not exist!\r
1093 // TODO: Code Goes Here!\r
1094 if (mergeVariables == null)\r
1095 mergeVariables = VariablesDocument.Factory.newInstance().addNewVariables();\r
1096\r
1097 Variables leafVariables = leafMsa.getVariables();\r
1098 if (leafVariables.sizeOfVariableArray() > 0) {\r
1099 for (int index = 0; index < leafVariables.sizeOfVariableArray(); index++) {\r
1100 String variableGuidCName = leafVariables.getVariableArray(index).getGuidCName();\r
1101 String test = checkDuplicateStrings(variableGuidCName, aVariablesList);\r
1102 if (test.length() > 0) {\r
1103 mergeVariables.addNewVariable();\r
1104 mergeVariables\r
1105 .setVariableArray(variablesIndex++, leafVariables.getVariableArray(index));\r
1106 }\r
1107 }\r
1108 }\r
1109\r
1110 }// endif Variables\r
1111\r
1112 if (leafMsa.isSetBootModes()) {\r
1113 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1114 //\r
1115 // Keep only Unique BootMode elements, based on the BootModeName Attribute.\r
1116 //\r
1117 // If mergeBootModes == null, create a new mergeBootModes and add\r
1118 // leaf module's BootModes section to the merge Module's\r
1119 //\r
1120 // If mergeBootModes != null, check that we have only unique BootMode entries\r
1121 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1122 // Mark the BootMode as ALWAYS_PRODUCED\r
1123 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1124 // Mark the BootMode as ALWAYS_CONSUMED\r
1125 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1126 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1127 // and another Leaf uses BY_START, create two entries, one for each.\r
1128 //\r
1129 // First PASS of the TOOL \r
1130 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1131 // this as an error!\r
1132 // Probable Enhancement\r
1133 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1134 //\r
1135 // First PASS of the TOOL\r
1136 // Ignore the FeatureFlag - we are not using it now.\r
1137 // Probable Enhancement\r
1138 // FeatureFlags must be identical for each unique BootMode entry, otherwise fail the Merge\r
1139 //\r
1140 // HelpText RULE:\r
1141 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1142 // is the leaf Module's path and filename to the MSA file!\r
1143 //\r
1144 // Create the working copy if one does not exist!\r
1145 // TODO: Code Goes Here!\r
1146 if (mergeBootModes == null)\r
1147 mergeBootModes = BootModesDocument.Factory.newInstance().addNewBootModes();\r
1148\r
1149 BootModes leafBootModes = leafMsa.getBootModes();\r
1150 if (leafBootModes.sizeOfBootModeArray() > 0) {\r
1151 for (int index = 0; index < leafBootModes.sizeOfBootModeArray(); index++) {\r
1152 String bootModeName = leafBootModes.getBootModeArray(index).getBootModeName().toString();\r
1153 String test = checkDuplicateStrings(bootModeName, aBootModesList);\r
1154 if (test.length() > 0) {\r
1155 mergeBootModes.addNewBootMode();\r
1156 mergeBootModes\r
1157 .setBootModeArray(bootModesIndex++, leafBootModes.getBootModeArray(index));\r
1158 }\r
1159 }\r
1160 }\r
1161\r
1162 }// endif BootMode\r
1163\r
1164 if (leafMsa.isSetSystemTables()) {\r
1165 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1166 //\r
1167 // Keep only Unique SystemTableCNames elements, based on the SystemTableCName element.\r
1168 //\r
1169 // If mergeSystemTables == null, create a new mergeSystemTables and add\r
1170 // leaf module's Variables section to the merge Module's\r
1171 //\r
1172 // If mergeSystemTables != null, check that we have only unique SystemTableCNames entries\r
1173 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1174 // Mark the SystemTableCName as ALWAYS_PRODUCED\r
1175 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1176 // Mark the SystemTableCName as ALWAYS_CONSUMED\r
1177 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1178 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1179 // and another Leaf uses BY_START, create two entries, one for each.\r
1180 //\r
1181 // First PASS of the TOOL \r
1182 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1183 // this as an error!\r
1184 // Probable Enhancement\r
1185 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1186 //\r
1187 // First PASS of the TOOL\r
1188 // Ignore the FeatureFlag - we are not using it now.\r
1189 // Probable Enhancement\r
1190 // FeatureFlags must be identical for each unique SystemTableCNames entry, otherwise fail the Merge\r
1191 //\r
1192 // HelpText RULE:\r
1193 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1194 // is the leaf Module's path and filename to the MSA file!\r
1195 //\r
1196 // Create the working copy if one does not exist!\r
1197 // TODO: Code Goes Here!\r
1198 if (mergeSystemTables == null)\r
1199 mergeSystemTables = SystemTablesDocument.Factory.newInstance().addNewSystemTables();\r
1200\r
1201 SystemTables leafSystemTables = leafMsa.getSystemTables();\r
1202 if (leafSystemTables.sizeOfSystemTableCNamesArray() > 0) {\r
1203 for (int index = 0; index < leafSystemTables.sizeOfSystemTableCNamesArray(); index++) {\r
1204 String systemTableCName = leafSystemTables.getSystemTableCNamesArray(index)\r
1205 .getSystemTableCName();\r
1206 String test = checkDuplicateStrings(systemTableCName, aSystemTablesList);\r
1207 if (test.length() > 0) {\r
1208 mergeSystemTables.addNewSystemTableCNames();\r
1209 mergeSystemTables\r
1210 .setSystemTableCNamesArray(\r
1211 systemTableIndex++,\r
1212 leafSystemTables\r
1213 .getSystemTableCNamesArray(index));\r
1214 }\r
1215 }\r
1216 }\r
1217\r
1218 }// endif SystemTables\r
1219\r
1220 if (leafMsa.isSetDataHubs()) {\r
1221 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1222 //\r
1223 // Keep only Unique DataHubs elements, based on the DataHubRecord.DataHubCName element.\r
1224 //\r
1225 // If mergeDataHubs == null, create a new mergeDataHubs and add\r
1226 // leaf module's DataHubs section to the merge Module's\r
1227 //\r
1228 // If mergeDataHubs != null, check that we have only unique DataHubRecord entries\r
1229 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1230 // Mark the DataHubCName as ALWAYS_PRODUCED\r
1231 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1232 // Mark the DataHubCName as ALWAYS_CONSUMED\r
1233 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1234 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1235 // and another Leaf uses BY_START, create two entries, one for each.\r
1236 //\r
1237 // First PASS of the TOOL \r
1238 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1239 // this as an error!\r
1240 // Probable Enhancement\r
1241 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1242 //\r
1243 // First PASS of the TOOL\r
1244 // Ignore the FeatureFlag - we are not using it now.\r
1245 // Probable Enhancement\r
1246 // FeatureFlags must be identical for each unique DataHubRecord entry, otherwise fail the Merge\r
1247 //\r
1248 // HelpText RULE:\r
1249 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1250 // is the leaf Module's path and filename to the MSA file!\r
1251 //\r
1252 // Create the working copy if one does not exist!\r
1253 // TODO: Code Goes Here!\r
1254 if (mergeDataHubs == null)\r
1255 mergeDataHubs = DataHubsDocument.Factory.newInstance().addNewDataHubs();\r
1256\r
1257 DataHubs leafDataHubs = leafMsa.getDataHubs();\r
1258 if (leafDataHubs.sizeOfDataHubRecordArray() > 0) {\r
1259 for (int index = 0; index < leafDataHubs.sizeOfDataHubRecordArray(); index++) {\r
1260 String dataHubCName = leafDataHubs.getDataHubRecordArray(index).getDataHubCName();\r
1261 String test = checkDuplicateStrings(dataHubCName, aDataHubsList);\r
1262 if (test.length() > 0) {\r
1263 mergeDataHubs.addNewDataHubRecord();\r
1264 mergeDataHubs.setDataHubRecordArray(dataHubsIndex++,\r
1265 leafDataHubs.getDataHubRecordArray(index));\r
1266 }\r
1267 }\r
1268 }\r
1269\r
1270 }// endif DataHubs\r
1271\r
1272 if (leafMsa.isSetHiiPackages()) {\r
1273 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1274 //\r
1275 // Keep only Unique HiiPackage elements, based on the HiiPackage.HiiCName element.\r
1276 //\r
1277 // If mergeHiiPackages == null, create a new mergeHiiPackages and add\r
1278 // leaf module's DataHubs section to the merge Module's\r
1279 //\r
1280 // If mergeHiiPackages != null, check that we have only unique HiiPackage entries\r
1281 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1282 // Mark the HiiPackage as ALWAYS_PRODUCED\r
1283 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1284 // Mark the HiiPackage as ALWAYS_CONSUMED\r
1285 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1286 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1287 // and another Leaf uses BY_START, create two entries, one for each.\r
1288 //\r
1289 // First PASS of the TOOL \r
1290 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1291 // this as an error!\r
1292 // Probable Enhancement\r
1293 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1294 //\r
1295 // First PASS of the TOOL\r
1296 // Ignore the FeatureFlag - we are not using it now.\r
1297 // Probable Enhancement\r
1298 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
1299 //\r
1300 // HelpText RULE:\r
1301 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1302 // is the leaf Module's path and filename to the MSA file!\r
1303 //\r
1304 // Create the working copy if one does not exist!\r
1305 // TODO: Code Goes Here!\r
1306 if (mergeHiiPackages == null)\r
1307 mergeHiiPackages = HiiPackagesDocument.Factory.newInstance().addNewHiiPackages();\r
1308\r
1309 HiiPackages leafHiiPackages = leafMsa.getHiiPackages();\r
1310 if (leafHiiPackages.sizeOfHiiPackageArray() > 0) {\r
1311 for (int index = 0; index < leafHiiPackages.sizeOfHiiPackageArray(); index++) {\r
1312 String hiiCName = leafHiiPackages.getHiiPackageArray(index).getHiiCName();\r
1313 String test = checkDuplicateStrings(hiiCName, aHiiPackagesList);\r
1314 if (test.length() > 0) {\r
1315 mergeHiiPackages.addNewHiiPackage();\r
1316 mergeHiiPackages.setHiiPackageArray(hiiPackageIndex++,\r
1317 leafHiiPackages.getHiiPackageArray(index));\r
1318 }\r
1319 }\r
1320 }\r
1321\r
1322 }// endif HiiPackage\r
1323\r
1324 if (leafMsa.isSetGuids()) {\r
1325 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1326 //\r
1327 // Keep only Unique Guids elements, based on the GuidCNames.GuidCName element.\r
1328 //\r
1329 // If mergeGuids == null, create a new mergeGuids and add\r
1330 // leaf module's Guids section to the merge Module's\r
1331 //\r
1332 // If mergeGuids != null, check that we have only unique GuidCNames entries\r
1333 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1334 // Mark the GuidCNames as ALWAYS_PRODUCED\r
1335 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1336 // Mark the GuidCNames as ALWAYS_CONSUMED\r
1337 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1338 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1339 // and another Leaf uses BY_START, create two entries, one for each.\r
1340 //\r
1341 // First PASS of the TOOL \r
1342 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1343 // this as an error!\r
1344 // Probable Enhancement\r
1345 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1346 //\r
1347 // First PASS of the TOOL\r
1348 // Ignore the FeatureFlag - we are not using it now.\r
1349 // Probable Enhancement\r
1350 // FeatureFlags must be identical for each unique GuidCNames entry, otherwise fail the Merge\r
1351 //\r
1352 // HelpText RULE:\r
1353 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1354 // is the leaf Module's path and filename to the MSA file!\r
1355 //\r
1356 // Create the working copy if one does not exist!\r
1357 // TODO: Code Goes Here!\r
1358 if (mergeGuids == null)\r
1359 mergeGuids = GuidsDocument.Factory.newInstance().addNewGuids();\r
1360\r
1361 Guids leafGuids = leafMsa.getGuids();\r
1362 if (leafGuids.sizeOfGuidCNamesArray() > 0) {\r
1363 for (int index = 0; index < leafGuids.sizeOfGuidCNamesArray(); index++) {\r
1364 String hiiCName = leafGuids.getGuidCNamesArray(index).getGuidCName();\r
1365 String test = checkDuplicateStrings(hiiCName, aGuidsList);\r
1366 if (test.length() > 0) {\r
1367 mergeGuids.addNewGuidCNames();\r
1368 mergeGuids.setGuidCNamesArray(guidsIndex++, leafGuids.getGuidCNamesArray(index));\r
1369 }\r
1370 }\r
1371 }\r
1372\r
1373 }// endif GuidCNames\r
1374\r
1375 if (leafMsa.isSetExterns()) {\r
1376 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1377 //\r
1378 // FAIL THE MERGE if Externs.PcdIsDriver is present\r
1379 // FAIL THE MERGE if Externs.TianoR8FlashMap_h is TRUE\r
1380 //\r
1381 // Keep only Unique Extern elements, based on the Extern.* elements.\r
1382 //\r
1383 // If mergeExterns == null, create a new mergeExterns and add\r
1384 // leaf module's Extern section to the merge Module's\r
1385 //\r
1386 // If mergeExterns != null, check that we have only unique Extern.* entries\r
1387 //\r
1388 // After storing the initial LEAF MODULE'S SPECIFICATION SECTION\r
1389 // ALL other Leaf Modules must declare the exact same specifications\r
1390 // If they do not, FAIL the MERGE with an error message, printing the\r
1391 // name of the leaf MSA that did not match, along with\r
1392 // Expected: from the merge module's specification list\r
1393 // Got: from the leaf file that fails!\r
1394 //\r
1395 // For Each <Extern>\r
1396 // For each pair of <ModuleEntryPoint> and/or <ModuleUnloadImage>\r
1397 // The ModuleUnloadImage value must be identical for an identical pair of ModuleEntryPoint values\r
1398 // If not, FAIL THE MERGE, giving the current leaf MSA filename as the failure, along with the\r
1399 // additional error information as follows:\r
1400 // -- leafFilename --\r
1401 // ModuleEntryPoint: \r
1402 // Expected ModuleUnloadImage: fromMergeModule\r
1403 // Got ModuleUnloadImage: fromLeaf\r
1404 // Merge Aborted!\r
1405 // More than one <Extern> Section with a pair of <ModuleEntryPoint><ModuleUnloadImage> is allowed\r
1406 //\r
1407 // For each pair of one <Constructor> and/or one <Destructor> elements\r
1408 // The <Extern> section containing the <Constructor> <Destructor> pairs \r
1409 // The Destructor value in all leaf modules must be identical for all Constructor elements that are identical.\r
1410 // More than one <Extern> Section with Constructor/Destructor pair is permitted.\r
1411 //\r
1412 // For each Set four elements, DriverBinding, ComponentName, DriverConfig and DriverDiag,\r
1413 // 1 DriverBinding and\r
1414 // 0 or 1 ComponentName and/or\r
1415 // 0 or 1 DriverConfig and/or\r
1416 // 0 or 1 DriverDiag \r
1417 // elements must appear in 1 <Extern> Section.\r
1418 //\r
1419 // A ComponentName cannot be used without a DriverBinding element.\r
1420 // A DriverConfig element cannot appear without a DriverBinding element. \r
1421 // A DriverDiag element cannot appear without a DriverBinding element\r
1422 // These elements are matched within a single <Extern> Section uniquely defined by the DriverBinding element. \r
1423 // Multiple <Extern> sections of this type are permitted.\r
1424 //\r
1425 // Each pair of SetVirtualAddressMapCallBack and ExitBootServiceCallBack elements MUST \r
1426 // BE in one Extern Section. ONE AND ONLY ONE of this section is permitted.\r
1427 //\r
1428 // First PASS of the TOOL \r
1429 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1430 // this as an error!\r
1431 // Probable Enhancement\r
1432 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1433 //\r
1434 // First PASS of the TOOL\r
1435 // Ignore the FeatureFlag - we are not using it now.\r
1436 // Probable Enhancement\r
1437 // FeatureFlags must be identical for each unique Extern entry, otherwise fail the Merge\r
1438 //\r
1439 // Create the working copy if one does not exist!\r
1440 // TODO: Code Goes Here!\r
1441 if (mergeExterns == null)\r
1442 mergeExterns = ExternsDocument.Factory.newInstance().addNewExterns();\r
1443\r
1444 Externs leafExterns = leafMsa.getExterns();\r
1445 // PCD IS DRIVER NOT ALLOWED IN A MERGED Module\r
1446 if (leafExterns.isSetPcdIsDriver()) {\r
1447 System.out.println("The Module: " + leafFilename + " is a PCD Driver and CANNOT BE MERGED!");\r
1448 System.out.println("Merge Aborted");\r
1449 System.err.flush();\r
1450 System.exit(FAIL);\r
1451 }\r
1452\r
1453 // TIANO R8 FLASHMAP.H NOT ALLOWED IN A MERGED Module\r
1454 if (leafExterns.isSetTianoR8FlashMapH()) {\r
1455 System.out.println("The Module: " + leafFilename\r
1456 + " set the Tiano R8 FlashMap.h Flag and CANNOT BE MERGED!");\r
1457 System.out.println("Merge Aborted");\r
1458 System.err.flush();\r
1459 System.exit(FAIL);\r
1460 }\r
1461\r
1462 // Add the Specification Array, one time only.\r
1463 if (leafExterns.sizeOfSpecificationArray() > 0) {\r
1464 for (int index = 0; index < leafExterns.sizeOfSpecificationArray(); index++) {\r
1465 String spec = leafExterns.getSpecificationArray(index);\r
1466 String test = checkSpecs(spec, leafFilename, aSpecArray);\r
1467 if (test.length() > 0) {\r
1468 mergeExterns.addNewSpecification();\r
1469 mergeExterns.setSpecificationArray(specIndex++, test);\r
1470 }\r
1471 }\r
1472 }\r
1473\r
1474 if (leafExterns.sizeOfExternArray() > 0) {\r
1475 for (int index = 0; index < leafExterns.sizeOfExternArray(); index++) {\r
1476 String test = "";\r
1477 if (leafExterns.getExternArray(index).isSetModuleEntryPoint()) {\r
1478 // ModuleEntryPoint, if an Unload Image is paired with\r
1479 // the Module Entry point, it will piggy back on the\r
1480 // Module Entry Point Extern\r
1481 String moduleEntryPoint = leafExterns.getExternArray(index).getModuleEntryPoint();\r
1482 test = checkDuplicateStrings(moduleEntryPoint, aEntryPointList);\r
1483\r
1484 } else if (leafExterns.getExternArray(index).isSetModuleUnloadImage()) {\r
1485 // Module Unload Image is here in case there is no\r
1486 // Entry Point - not very typical\r
1487 String moduleUnloadImage = leafExterns.getExternArray(index).getModuleUnloadImage();\r
1488 test = checkDuplicateStrings(moduleUnloadImage, aUnloadImageList);\r
1489\r
1490 } else if (leafExterns.getExternArray(index).isSetConstructor()) {\r
1491 // Constructors must be unique, if a Destructor is\r
1492 // paired with a constructor, it will pigback on\r
1493 // the constructor\r
1494 String constructor = leafExterns.getExternArray(index).getConstructor();\r
1495 test = checkDuplicateStrings(constructor, aConstructorList);\r
1496\r
1497 } else if (leafExterns.getExternArray(index).isSetDestructor()) {\r
1498 // Destructors must be unique\r
1499 String destructor = leafExterns.getExternArray(index).getDestructor();\r
1500 test = checkDuplicateStrings(destructor, aDestructorList);\r
1501\r
1502 } else if (leafExterns.getExternArray(index).isSetDriverBinding()) {\r
1503 // Driver Bindings must be unique\r
1504 // Fixed the MSA files - ComponentName, Driver Config and\r
1505 // Driver Diag statments must be inside of an Extern that \r
1506 // has a Driver Binding\r
1507 String driverBinding = leafExterns.getExternArray(index).getDriverBinding();\r
1508 test = checkDuplicateStrings(driverBinding, aDriverBindingList);\r
1509\r
1510 } else if (leafExterns.getExternArray(index).isSetSetVirtualAddressMapCallBack()) {\r
1511 // Handle Virtual Address Map and Exit Boot Services Call Backs\r
1512 // in a single Extern if they are present\r
1513 String virtualAddressMap = leafExterns.getExternArray(index)\r
1514 .getSetVirtualAddressMapCallBack();\r
1515 test = checkDuplicateStrings(virtualAddressMap, aVirtualAddressMapList);\r
1516\r
1517 } else if (leafExterns.getExternArray(index).isSetExitBootServicesCallBack()) {\r
1518 // Handle a stand alone Exit Boot Services Call Back\r
1519 String exitBootServices = leafExterns.getExternArray(index)\r
1520 .getExitBootServicesCallBack();\r
1521 test = checkDuplicateStrings(exitBootServices, aExitBootServicesList);\r
1522 } else {\r
1523 // Unknown Extern FAIL - May be an invalid Component Name in it's own Extern Statement\r
1524 System.out.println("Unknown EXTERN defined in Module: " + leafFilename);\r
1525 System.out.println("Value: " + leafExterns.getExternArray(index).toString());\r
1526 System.out.println("Merge Aborted!");\r
1527 System.err.flush();\r
1528 System.exit(FAIL);\r
1529 }\r
1530\r
1531 if (test.length() > 0) {\r
1532 mergeExterns.addNewExtern();\r
1533 mergeExterns.setExternArray(externsIndex++, leafExterns.getExternArray(index));\r
1534 }\r
1535 }\r
1536 }\r
1537 }// endif mergeExterns\r
1538\r
1539 if (leafMsa.isSetPcdCoded()) {\r
1540 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1541 //\r
1542 // Keep only Unique PcdCoded elements, based on the PcdCoded.PcdEntry.C_Name element.\r
1543 //\r
1544 // If mergePcdCoded == null, create a new mergePcdCoded and add\r
1545 // leaf module's PcdCoded section to the merge Module's\r
1546 //\r
1547 // If mergePcdCoded != null, check that we have only unique PcdEntry entries\r
1548 // IF one Leaf usage is SOMETIMES_PRODUCED, and another Leaf usage is ALWAYS_PRODUCED,\r
1549 // Mark the PcdEntry as ALWAYS_PRODUCED\r
1550 // IF one Leaf usage is SOMETIMES_CONSUMED, and another Leaf usage is ALWAYS_CONSUMED,\r
1551 // Mark the PcdEntry as ALWAYS_CONSUMED\r
1552 // It is permissable to have one PRODUCED and one CONSUMED entry\r
1553 // TO_START and BY_START cannot be combined in any fashion, if one Leaf uses TO_START\r
1554 // and another Leaf uses BY_START, create two entries, one for each.\r
1555 //\r
1556 // First PASS of the TOOL \r
1557 // SupArchList must be identical for all Leaf Modules! Fail the Merge if not, reporting\r
1558 // this as an error!\r
1559 // Probable Enhancement\r
1560 // The SupArchList, if set, must be for the "Lowest Common Denominator"\r
1561 //\r
1562 // First PASS of the TOOL\r
1563 // Ignore the FeatureFlag - we are not using it now.\r
1564 // Probable Enhancement\r
1565 // FeatureFlags must be identical for each unique HiiPackage entry, otherwise fail the Merge\r
1566 //\r
1567 // First PASS of the TOOL\r
1568 // Ignore the PcdEntry:Usage Attribute\r
1569 // Probable Enhancment\r
1570 // Have Usage Combined like was done for the Library Class\r
1571 //\r
1572 // First PASS of the TOOL\r
1573 // If Different PcdItemTypes, Abort The MERGE\r
1574 //\r
1575 // Probably Enhancement\r
1576 // The PcdItemType Should be checked using the following rules\r
1577 // Feature Flag MUST ALWAYS BE A FEATURE FLAG\r
1578 // If different Item Types occur, mark the PCD as DYNAMIC\r
1579 //\r
1580 // HelpText RULE:\r
1581 // HelpText should be concatenated with a line -- leafFilename -- separator, where leafFilename\r
1582 // is the leaf Module's path and filename to the MSA file!\r
1583 //\r
1584 // Create the working copy if one does not exist!\r
1585 // TODO: Code Goes Here!\r
1586 if (mergePcdCoded == null)\r
1587 mergePcdCoded = PcdCodedDocument.Factory.newInstance().addNewPcdCoded();\r
1588\r
1589 PcdCoded leafPcdCoded = leafMsa.getPcdCoded();\r
1590 if (leafPcdCoded.sizeOfPcdEntryArray() > 0) {\r
1591 for (int index = 0; index < leafPcdCoded.sizeOfPcdEntryArray(); index++) {\r
1592 String pcdCName = leafPcdCoded.getPcdEntryArray(index).getCName();\r
1593 String pcdItemType = leafPcdCoded.getPcdEntryArray(index).getPcdItemType().toString();\r
1594 String test = checkPcd(pcdCName, pcdItemType, leafFilename, aPcdCNameList);\r
1595 if (test.length() > 0) {\r
1596 mergePcdCoded.addNewPcdEntry();\r
1597 mergePcdCoded.setPcdEntryArray(pcdIndex++, leafPcdCoded.getPcdEntryArray(index));\r
1598 }\r
1599 }\r
1600 }\r
1601\r
1602 }// endif PcdCoded\r
1603\r
1604 if (leafMsa.isSetModuleBuildOptions()) {\r
1605 // TODO: TEST FOR NULL SETTINGS so we don't get an error!\r
1606 //\r
1607 // Any element that appear within a leaf's ModuleBuildOptions should be appended to\r
1608 // the Merge Module's BuildOptions section.\r
1609 //\r
1610 // NO ATTEMPT IS MADE TO VERIFY UNIQUENESS ON ANYTHING WITHIN THIS SECTION!\r
1611 //\r
1612 // Create the working copy if one does not exist!\r
1613 // if (mergeBuildOptions == null)\r
1614 // mergeBuildOptions = ModuleBuildOptionsDocument.Factory.newInstance().addNewModuleBuildOptions();\r
1615\r
1616 // ModuleBuildOptions leafModuleBuildOptions = leafMsa.getModuleBuildOptions();\r
1617\r
1618 // mergeBuildOptions.addNewModuleBuildOptions();\r
1619 // mergeBuildOptions.setModuleBuildOptions(leafModuleBuildOptions);\r
1620\r
1621 //\r
1622 // TODO: Code Goes Here!\r
1623 } // endif ModuleBuildOptions\r
1624\r
1625 // Need to process any UserExtensions here too.\r
1626 if (leafMsa.getUserExtensionsList() != null) {\r
1627\r
1628 if (mergeUserExtensions == null)\r
1629 mergeUserExtensions = UserExtensionsDocument.Factory.newInstance().addNewUserExtensions();\r
1630\r
1631 // for (int index = 0; index < leafMsa.getUserExtensionsList().size(); index++)\r
1632\r
1633 }\r
1634\r
1635 } // Completed parsing all leaf files.\r
1636\r
1637 header.setAbstract(Abstract);\r
1638 header.setCopyright(Copyright);\r
1639 header.setDescription(Description);\r
1640 License mLicense = License.Factory.newInstance();\r
1641 mLicense.setStringValue(licenseTxt);\r
1642 header.setLicense(mLicense);\r
1643 if ((DEBUG > 0) || (VERBOSE > 0))\r
1644 System.out.println("Merged Module supports: " + sArchitectures + " architectures.");\r
1645 List<String> lArchitectures = new ArrayList<String>();\r
1646 String s[] = sArchitectures.replace(" ", " ").trim().split(" ");\r
1647 for (int idx = 0; idx < s.length; idx++) {\r
1648 lArchitectures.add(s[idx]);\r
1649 if (DEBUG > 7)\r
1650 System.out.println("Adding architecture: " + s[idx]);\r
1651 }\r
1652 moduleDefs.setSupportedArchitectures(lArchitectures);\r
1653\r
1654 } // endif mergeMsaFile == null\r
1655\r
1656 if ((uiName != null) && (uiName.length() > 0) && (result == PASS)) {\r
1657 // TODO: Stub for replacing the msaFile UiName\r
1658 if ((DEBUG > 0) || (VERBOSE > 0))\r
1659 System.out.println("Updating the uiName: " + uiName);\r
1660 header.setModuleName(uiName);\r
1661 }\r
1662\r
1663 if ((baseName != null) && (baseName.length() > 0) && (result == PASS)) {\r
1664 if ((DEBUG > 0) || (VERBOSE > 0))\r
1665 System.out.println("Setting the Output Filename:" + baseName);\r
1666 moduleDefs.setOutputFileBasename(baseName);\r
1667 }\r
1668\r
1669 if (result == PASS) {\r
1670 // TODO: Stub to write out the new MSA file\r
1671 File outMsa = new File(msaFilename);\r
1672 try {\r
1673 if (DEBUG > 2)\r
1674 System.out.println("SAVING new MSA FILE: " + msaFilename);\r
1675\r
1676 mergeMsaFile.setMsaHeader(header);\r
1677 mergeMsaFile.setModuleDefinitions(moduleDefs);\r
1678 // ALL THE REST OF THE SECTIONS ARE OPTIONAL\r
1679 // SO check that they are not null before adding them to the merged MSA file!\r
1680 if (libClassDefs != null)\r
1681 mergeMsaFile.setLibraryClassDefinitions(libClassDefs);\r
1682 if (mergeSourceFiles != null)\r
1683 mergeMsaFile.setSourceFiles(mergeSourceFiles);\r
1684 if (mergePackageDependencies != null)\r
1685 mergeMsaFile.setPackageDependencies(mergePackageDependencies);\r
1686 if (mergeProtocols != null)\r
1687 mergeMsaFile.setProtocols(mergeProtocols);\r
1688\r
1689 if ((mergeCreateEvents != null) || (mergeSignalEvents != null)) {\r
1690 if (mergeEvents == null)\r
1691 mergeEvents = EventsDocument.Factory.newInstance().addNewEvents();\r
1692\r
1693 if (mergeCreateEvents.getEventTypesList().size() > 0) {\r
1694 mergeEvents.addNewCreateEvents();\r
1695 mergeEvents.setCreateEvents(mergeCreateEvents);\r
1696 }\r
1697 if (mergeSignalEvents.getEventTypesList().size() > 0) {\r
1698 mergeEvents.addNewSignalEvents();\r
1699 mergeEvents.setSignalEvents(mergeSignalEvents);\r
1700 }\r
1701\r
1702 mergeMsaFile.setEvents(mergeEvents);\r
1703 }\r
1704\r
1705 if (mergeHobs != null)\r
1706 mergeMsaFile.setHobs(mergeHobs);\r
1707\r
1708 if (mergePpis != null)\r
1709 mergeMsaFile.setPPIs(mergePpis);\r
1710\r
1711 if (mergeVariables != null)\r
1712 mergeMsaFile.setVariables(mergeVariables);\r
1713\r
1714 if (mergeBootModes != null)\r
1715 mergeMsaFile.setBootModes(mergeBootModes);\r
1716\r
1717 if (mergeSystemTables != null)\r
1718 mergeMsaFile.setSystemTables(mergeSystemTables);\r
1719\r
1720 if (mergeDataHubs != null)\r
1721 mergeMsaFile.setDataHubs(mergeDataHubs);\r
1722\r
1723 if (mergeHiiPackages != null)\r
1724 mergeMsaFile.setHiiPackages(mergeHiiPackages);\r
1725\r
1726 if (mergeGuids != null)\r
1727 mergeMsaFile.setGuids(mergeGuids);\r
1728\r
1729 if (mergeExterns != null)\r
1730 mergeMsaFile.setExterns(mergeExterns);\r
1731\r
1732 if (mergePcdCoded != null)\r
1733 mergeMsaFile.setPcdCoded(mergePcdCoded);\r
1734\r
1735 XmlCursor cursor = XmlConfig.setupXmlCursor(mergeMsaFile.newCursor());\r
1736 XmlOptions options = XmlConfig.setupXmlOptions();\r
1737 ModuleSurfaceAreaDocument msaDoc = ModuleSurfaceAreaDocument.Factory.newInstance();\r
1738 msaDoc.addNewModuleSurfaceArea();\r
1739 msaDoc.setModuleSurfaceArea(mergeMsaFile);\r
1740 msaDoc.save(outMsa, options);\r
1741 System.out.println("The Merged MSA file: " + msaFilename + ", has been created!");\r
1742 } catch (IOException e) {\r
1743 System.out.println("Problem writing the output file: " + msaFilename + " " + e);\r
1744 result = FAIL;\r
1745 }\r
1746 }\r
1747\r
1748 if ((spdFilename != null) && (result == PASS)) {\r
1749 // TODO: Stub for adding the msaFile to the <MsaFiles><Filename> in the spdFile\r
1750 String msaLine = getPathFromSpd(spdFilename, msaFilename);\r
1751 System.out.println("Updating the SPD file (" + spdFilename + ") with: " + msaLine);\r
1752 try {\r
1753 File spdFile = new File(spdFilename);\r
1754 PackageSurfaceAreaDocument spdDoc = PackageSurfaceAreaDocument.Factory.parse(spdFile);\r
1755 PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();\r
1756\r
1757 // MsaFiles mergeMsaFilesForSpd = MsaFilesDocument.Factory.newInstance().addNewMsaFiles();\r
1758 List<String> msaFilenames = spd.getMsaFiles().getFilenameList();\r
1759 msaFilenames.add(msaLine);\r
1760 XmlCursor cursor = XmlConfig.setupXmlCursor(spd.newCursor());\r
1761 XmlOptions options = XmlConfig.setupXmlOptions();\r
1762 spdDoc.save(spdFile, options);\r
1763 } catch (IOException e) {\r
1764 System.out.println("I/O Exception on spd file: " + spdFilename + " " + e);\r
1765 } catch (XmlException x) {\r
1766 System.out.println("XML Exception on SPD file: " + spdFilename + " " + x);\r
1767 }\r
1768 } else if ((spdFilename == null) && (result == PASS)) {\r
1769\r
1770 System.out.println("The file: " + msaFilename + ", must be added to a package file before it can be used!");\r
1771 }\r
1772 return result;\r
1773 }\r
1774\r
1775 public ModuleSurfaceArea getLeafFile(String filename) {\r
1776 File leafMsaFile = new File(filename);\r
1777 if ((DEBUG > 1) || (VERBOSE > 1))\r
1778 System.out.println("Processing MSA File: " + filename);\r
1779 try {\r
1780 leafMsa = ModuleSurfaceAreaDocument.Factory.parse(leafMsaFile).getModuleSurfaceArea();\r
1781 if ((DEBUG > 4) || (VERBOSE > 4))\r
1782 System.out.println("Binary: " + leafMsa.getModuleDefinitions().getBinaryModule());\r
1783 if (leafMsa.getModuleDefinitions().getBinaryModule()) {\r
1784 System.out.println("ERROR: Binary Module was specified in MSA: " + filename);\r
1785 System.out.println("Merge Aborted!");\r
1786 System.err.flush();\r
1787 return null;\r
1788 }\r
1789 } catch (IOException e) {\r
1790 System.out.println("I/O Exception on filename: " + filename + " " + e);\r
1791 System.out.println("Merge Aborted!");\r
1792 System.err.flush();\r
1793 System.exit(FAIL);\r
1794 } catch (XmlException x) {\r
1795 System.out.println("XML Exception reading file: " + filename + " " + x);\r
1796 System.out.println("Merge Aborted!");\r
1797 System.err.flush();\r
1798 System.exit(FAIL);\r
1799 }\r
1800 return leafMsa;\r
1801 }\r
1802\r
1803 private String getPathFromSpd(String spdFn, String msaFn) {\r
1804 String path2Msa = null;\r
1805\r
1806 spdFn = spdFn.replace("\\", "/").trim();\r
1807 String s[] = spdFn.split("/");\r
1808 String justSpdFilename = s[s.length - 1];\r
1809\r
1810 String Cwd = System.getProperty("user.dir");\r
1811 Cwd = Cwd.replace("\\", "/").trim();\r
1812 if ((DEBUG > 10) || (VERBOSE > 10)) {\r
1813 System.out.println("Current directory = " + Cwd);\r
1814 }\r
1815 String sp[] = Cwd.split("/");\r
1816 int theDirectory = sp.length - (s.length - 1);\r
1817 if (DEBUG > 10)\r
1818 System.out.println("The Directory length: " + theDirectory + " s.length: " + s.length + " sp.length: "\r
1819 + (sp.length - 1));\r
1820\r
1821 String path2Spd = "";\r
1822 for (int ictr = 0; ictr < theDirectory; ictr++) {\r
1823 path2Spd += sp[ictr] + "/";\r
1824 if (DEBUG > 10)\r
1825 System.out.println("Creating path to SPD file: " + path2Spd);\r
1826 }\r
1827\r
1828 String testPath2Spd = path2Spd + justSpdFilename;\r
1829\r
1830 File tFile = new File(testPath2Spd);\r
1831 if (!tFile.exists()) {\r
1832 System.out.println("The specified SPD file, " + spdFn + " does not exist at: " + testPath2Spd);\r
1833 System.out.println("Please use the FrameworkWizard to add this MSA file to the package.");\r
1834 System.exit(FAIL);\r
1835 }\r
1836 path2Msa = Cwd.replace(path2Spd, "");\r
1837 path2Msa = path2Msa + "/" + msaFn;\r
1838 return path2Msa;\r
1839 }\r
1840\r
1841 private String checkDuplicateStrings(String aString, ArrayList<String> aList) {\r
1842\r
1843 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1844 if (DEBUG > 8)\r
1845 System.out.println("Comparing: \n" + aString.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1846 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1847 if (aString.replace(" ", "").replace("\n", "").contains(\r
1848 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1849 .toString().trim())) {\r
1850 if ((DEBUG > 3) || (VERBOSE > 3))\r
1851 System.out.println("Found a duplicate String, skipping!");\r
1852 return "";\r
1853 }\r
1854 }\r
1855 if ((DEBUG > 3) || (VERBOSE > 3))\r
1856 System.out.println("Returning UNIQUE String!\n " + aString);\r
1857 aList.add(aString);\r
1858 return aString;\r
1859 }\r
1860\r
1861 private String checkSpecs(String specName, String filename, ArrayList<String> aList) {\r
1862 // Check Specifications\r
1863 // Skip of Specs are identical\r
1864 String spec[] = new String[2];\r
1865 spec = specName.replace(" ", " ").trim().split(" ");\r
1866 String specInMem[] = new String[2];\r
1867 if ((DEBUG > 10) || (VERBOSE > 10))\r
1868 System.out.println("Specification: " + specName);\r
1869\r
1870 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1871 if (DEBUG > 8)\r
1872 System.out.println("Comparing: \n" + specName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1873 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1874 if (specName.replace(" ", "").replace("\n", "").contains(\r
1875 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1876 .toString().trim())) {\r
1877 if ((DEBUG > 3) || (VERBOSE > 3))\r
1878 System.out.println("Found a duplicate String, skipping!");\r
1879 return "";\r
1880 }\r
1881 specInMem = aList.get(lctr).replace(" ", " ").trim().split(" ");\r
1882 if (spec[0].contentEquals(specInMem[0])) {\r
1883 if (!spec[1].contains(specInMem[1])) {\r
1884 System.out.println("Module: " + filename + " is coded to " + specName);\r
1885 System.out.println("Merge needs to be coded to: " + aList.get(lctr));\r
1886 System.out.println("Merge Aborted!");\r
1887 System.err.flush();\r
1888 System.exit(FAIL);\r
1889 }\r
1890 }\r
1891\r
1892 }\r
1893 if ((DEBUG > 3) || (VERBOSE > 3))\r
1894 System.out.println("Returning Specification: " + specName);\r
1895 aList.add(specName);\r
1896 return specName;\r
1897 }\r
1898\r
1899 private String checkPcd(String pcdName, String itemType, String filename, ArrayList<String> aList) {\r
1900\r
1901 for (int lctr = 0; lctr < aList.size(); lctr++) {\r
1902 if (DEBUG > 8)\r
1903 System.out.println("Comparing: \n" + pcdName.replace(" ", "").replace("\n", "") + "\nTo: \n"\r
1904 + aList.get(lctr).replace(" ", "").replace("\n", "").toString().trim());\r
1905 if (pcdName.replace(" ", "").replace("\n", "").contains(\r
1906 aList.get(lctr).replace(" ", "").replace("\n", "")\r
1907 .toString().trim())) {\r
1908 if (!aPcdItemTypeList.get(lctr).contains(itemType)) {\r
1909 System.out\r
1910 .println("The Pcd Item Type for " + pcdName + " in file: " + filename + "does not match!");\r
1911 System.out.println("Expected: " + aPcdItemTypeList.get(lctr));\r
1912 System.out.println("Was set to: " + itemType);\r
1913 System.out.println("Merge Aborted!");\r
1914 System.err.flush();\r
1915 System.exit(FAIL);\r
1916 }\r
1917 if ((DEBUG > 3) || (VERBOSE > 3))\r
1918 System.out.println("Found a duplicate String, skipping!");\r
1919 return "";\r
1920 }\r
1921 }\r
1922 if ((DEBUG > 3) || (VERBOSE > 3))\r
1923 System.out.println("Returning UNIQUE String!\n " + pcdName);\r
1924 aPcdItemTypeList.add(itemType);\r
1925 aList.add(pcdName);\r
1926 return pcdName;\r
1927 }\r
1928\r
1929 private String checkUsage() {\r
1930 String result = "";\r
1931 // Usage types are different\r
1932 if (((mergeUsage.contains("CONSUMED")) && (leafUsage.contains("PRODUCED")))\r
1933 || ((mergeUsage.contains("PRODUCED")) && (leafUsage.contains("CONSUMED")))\r
1934 || ((mergeUsage.contains("TO_START")) && (leafUsage.contains("BY_START")))\r
1935 || ((mergeUsage.contains("BY_START")) && (leafUsage.contains("TO_START")))) {\r
1936 result = "DIFFERENT";\r
1937 }\r
1938 // Both Usage types are PRODUCED\r
1939 if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
1940 || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
1941 result = "PRODUCED";\r
1942 }\r
1943\r
1944 // Both Usage types are CONSUMED\r
1945 if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
1946 || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
1947 result = "CONSUMED";\r
1948 }\r
1949 return result;\r
1950 }\r
1951\r
1952 private boolean checkProduced() {\r
1953 boolean result = false;\r
1954\r
1955 if (((mergeUsage.contains("ALWAYS_PRODUCED")) && (leafUsage.contains("SOMETIMES_PRODUCED")))\r
1956 || ((mergeUsage.contains("SOMETIMES_PRODUCED")) && (leafUsage.contains("ALWAYS_PRODUCED")))) {\r
1957 result = true;\r
1958 }\r
1959 return result;\r
1960 }\r
1961\r
1962 private boolean checkConsumed() {\r
1963 boolean result = false;\r
1964\r
1965 if (((mergeUsage.contains("ALWAYS_CONSUMED")) && (leafUsage.contains("SOMETIMES_CONSUMED")))\r
1966 || ((mergeUsage.contains("SOMETIMES_CONSUMED")) && (leafUsage.contains("ALWAYS_CONSUMED")))) {\r
1967 result = true;\r
1968 }\r
1969 return result;\r
1970 }\r
1971\r
1972 private String getPathPartOfLeafMsa(String sFilename) {\r
1973 String pathName = "";\r
1974 String s[] = sFilename.replace("\\", "/").trim().split("/");\r
1975 for (int j = 0; j < (s.length - 1); j++) {\r
1976 pathName += s[j] + "/";\r
1977 }\r
1978 return pathName;\r
1979 }\r
1980\r
1981 private static class XmlConfig {\r
1982 public static XmlCursor setupXmlCursor(XmlCursor cursor) {\r
1983 String uri = "http://www.TianoCore.org/2006/Edk2.0";\r
1984 cursor.push();\r
1985 cursor.toNextToken();\r
1986 cursor.insertNamespace("", uri);\r
1987 cursor.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");\r
1988 cursor.pop();\r
1989 return cursor;\r
1990\r
1991 }\r
1992\r
1993 public static XmlOptions setupXmlOptions() {\r
1994 XmlOptions options = new XmlOptions();\r
1995 options.setCharacterEncoding("UTF-8");\r
1996 options.setSavePrettyPrint();\r
1997 options.setSavePrettyPrintIndent(2);\r
1998 return options;\r
1999 }\r
2000\r
2001 }\r
2002}\r