]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/FrameworkWizard/src/org/tianocore/frameworkwizard/platform/ui/global/GlobalData.java
1. only show ModuleName, version, PackageName, version, supported Arch, path in table...
[mirror_edk2.git] / Tools / Source / FrameworkWizard / src / org / tianocore / frameworkwizard / platform / ui / global / GlobalData.java
index e74644fa75a630b7075359e1fee20418822c1c5a..4a325c21ffbf6111fd234e789ce88be91c4a8aa8 100644 (file)
@@ -31,16 +31,12 @@ import java.util.Comparator;
 import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
-import java.util.LinkedHashSet;\r
 import java.util.List;\r
+import java.util.ListIterator;\r
 import java.util.Map;\r
 import java.util.Set;\r
-import java.util.Stack;\r
-import java.util.TreeMap;\r
-import java.util.TreeSet;\r
+import java.util.Vector;\r
 import java.util.logging.Logger;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
 \r
 /**\r
   GlobalData provide initializing, instoring, querying and update global data.\r
@@ -65,7 +61,7 @@ public class GlobalData {
     ///\r
     /// Be used to ensure Global data will be initialized only once.\r
     ///\r
-    private static boolean globalFlag = false;\r
+//    private static boolean globalFlag = false;\r
     \r
     ///\r
     /// Framework Database information: package list and platform list\r
@@ -102,47 +98,6 @@ public class GlobalData {
     ///\r
     private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();\r
     \r
-    ///\r
-    /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.\r
-    ///\r
-//    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();\r
-\r
-    ///\r
-    /// build target + tool chain family/tag name + arch + command types + command options\r
-    ///\r
-    private static Map<String, Object> toolChainOptions;\r
-    private static Map<String, Object> toolChainFamilyOptions;\r
-    private static Map<String, String> toolChainDefinitions;\r
-    private static Map<FpdModuleIdentification, Map<String, Object>> moduleToolChainOptions = new HashMap<FpdModuleIdentification, Map<String, Object>>();;\r
-    private static Map<FpdModuleIdentification, Map<String, Object>> moduleToolChainFamilyOptions = new HashMap<FpdModuleIdentification, Map<String, Object>>();;\r
-    ///\r
-    ///\r
-    ///\r
-    private static Set<String> targets;\r
-    ///\r
-    ///\r
-    ///\r
-    private static Set<String> toolChainFamilies;\r
-    ///\r
-    ///\r
-    ///\r
-    private static Set<String> toolChains;\r
-    ///\r
-    /// keep track which toolchain family a toolchain tag belongs to\r
-    ///\r
-    private static Map<String, Set<String>> toolChainFamilyMap;\r
-    private static Map<String, Set<String>> toolChainCommandMap;\r
-    \r
-    ///\r
-    /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC\r
-    ///\r
-    private static Set<String> archs;\r
-\r
-    ///\r
-    /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP\r
-    ///\r
-    private static Set<String> commandTypes;\r
-    \r
     /**\r
       Parse framework database (DB) and all SPD files listed in DB to initialize\r
       the environment for next build. This method will only be executed only once\r
@@ -154,13 +109,6 @@ public class GlobalData {
             Framework Dababase or SPD or MSA file is not valid\r
     **/\r
     public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws Exception {\r
-        //\r
-        // ensure this method will be revoked only once\r
-        //\r
-        if (globalFlag) {\r
-            return;\r
-        }\r
-        globalFlag = true;\r
         \r
         //\r
         // Backup workspace directory. It will be used by other method\r
@@ -185,7 +133,9 @@ public class GlobalData {
                 DbPathAndFilename dbPath = (DbPathAndFilename)iter.next();\r
                 String fileName = dbPath.getStringValue();\r
                 Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));\r
-                packageList.add(spd.getPackageId());\r
+                if (!packageList.contains(spd.getPackageId())) {\r
+                    packageList.add(spd.getPackageId());\r
+                }\r
                 spdTable.put(spd.getPackageId(), spd);\r
             }\r
 \r
@@ -350,9 +300,7 @@ public class GlobalData {
     }\r
     \r
     public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws Exception {\r
-        if (! msaFile.exists()) {\r
-            throw new Exception("Surface Area file [" + msaFile.getPath() + "] can't found.");\r
-        }\r
+        \r
         try {\r
             ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);\r
             //\r
@@ -414,120 +362,6 @@ public class GlobalData {
         }\r
     }\r
 \r
-    /**\r
-      The header file path is relative to workspace dir\r
-    **/\r
-    public static String[] getLibraryClassHeaderFiles(PackageIdentification[] packages, String name) {\r
-        if (packages == null ){\r
-            // throw Exception or not????\r
-            return new String[0];\r
-        }\r
-        String[] result = null;\r
-        for (int i = 0; i < packages.length; i++){\r
-            Spd spd = spdTable.get(packages[i]);\r
-            //\r
-            // If find one package defined the library class\r
-            //\r
-            if( (result = spd.getLibClassIncluder(name)) != null){\r
-                return result;\r
-            } \r
-        }\r
-        return null;\r
-        \r
-    }\r
-    \r
-    /**\r
-      The header file path is relative to workspace dir\r
-    **/    \r
-    public static String getPackageHeaderFiles(PackageIdentification packages, String moduleType) throws Exception {\r
-        if (packages == null ){\r
-            return new String("");\r
-        }\r
-        Spd spd = spdTable.get(packages);\r
-        //\r
-        // If can't find package header file, skip it\r
-        //\r
-        String temp = null;\r
-        if (spd != null){\r
-               if( (temp = spd.getPackageIncluder(moduleType)) != null){\r
-                return temp;\r
-            }else {\r
-               temp = "";\r
-               return temp;\r
-            }\r
-        }else {\r
-               return null;\r
-        }\r
-    }   \r
-    \r
-    /**\r
-      return two values: {cName, GuidValue}\r
-    **/\r
-    public static String[] getGuid(PackageIdentification[] packages, String name) throws Exception {\r
-        if (packages == null ){\r
-            // throw Exception or not????\r
-            return new String[0];\r
-        }\r
-        String[] result = null;\r
-        for (int i = 0; i < packages.length; i++){\r
-            Spd spd = spdTable.get(packages[i]);\r
-            //\r
-            // If find one package defined the GUID\r
-            //\r
-            if( (result = spd.getGuid(name)) != null){\r
-                return result;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-    \r
-    /**\r
-      return two values: {cName, GuidValue}\r
-    **/    \r
-    public static String[] getPpiGuid(PackageIdentification[] packages, String name) throws Exception {\r
-        if (packages == null ){\r
-            return new String[0];\r
-        }\r
-        String[] result = null;\r
-        for (int i = 0; i < packages.length; i++){\r
-            Spd spd = spdTable.get(packages[i]);\r
-            //\r
-            // If find one package defined the Ppi GUID\r
-            //\r
-            if( (result = spd.getPpi(name)) != null){\r
-                return result;\r
-            }\r
-        }\r
-        return null;\r
-        \r
-    }\r
-    \r
-    /**\r
-      return two values: {cName, GuidValue}\r
-    **/   \r
-    public static String[] getProtocolGuid(PackageIdentification[] packages, String name) throws Exception {\r
-        if (packages == null ){\r
-            return new String[0];\r
-        }\r
-        String[] result = null;\r
-        for (int i = 0; i < packages.length; i++){\r
-            Spd spd = spdTable.get(packages[i]);\r
-            //\r
-            // If find one package defined the protocol GUID\r
-            //\r
-            if( (result = spd.getProtocol(name)) != null){\r
-                return result;\r
-            }\r
-        }\r
-        return null;\r
-        \r
-    }\r
-    \r
-    /////////////////////////// Update!! Update!! Update!!\r
-//    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {\r
-//        return pcdDbManager;\r
-//    }\r
-    ///////////////////////////\r
     public synchronized static PlatformIdentification getPlatform(String name) throws Exception {\r
         Iterator iter = platformList.iterator();\r
         while(iter.hasNext()){\r
@@ -594,426 +428,24 @@ public class GlobalData {
         return result;\r
     }\r
 \r
-    ////// Tool Chain Related, try to refine and put some logic process to ToolChainFactory\r
-    public static void setBuildToolChainFamilyOptions(Map<String, Object> map) {\r
-        toolChainFamilyOptions = map;\r
-    }\r
-\r
-    public static Map<String, Object> getToolChainFamilyOptions() {\r
-        return toolChainFamilyOptions;\r
-    }\r
-\r
-    public static void setBuildToolChainOptions(Map<String, Object> map) {\r
-        toolChainOptions = map;\r
-    }\r
-\r
-    public static Map<String, Object> getToolChainOptions() {\r
-        return toolChainOptions;\r
-    }\r
-\r
-    public static void setTargets(Set<String> targetSet) {\r
-        GlobalData.log.info("TargetSet: " + targetSet);\r
-        targets = targetSet;\r
-    }\r
-\r
-    public static String[] getTargets() {\r
-        return (String[])targets.toArray(new String[targets.size()]);\r
-    }\r
-\r
-    public static void setToolChains(Set<String> toolChainSet) {\r
-        toolChains = toolChainSet;\r
-    }\r
-\r
-    public static String[] getToolChains() {\r
-        String[] toolChainList = new String[toolChains.size()];\r
-        return (String[])toolChains.toArray(toolChainList);\r
-    }\r
-\r
-    public static void setToolChainFamilies(Set<String> toolChainFamilySet) {\r
-        toolChainFamilies = toolChainFamilySet;\r
-    }\r
-\r
-    public static void setToolChainFamiliyMap(Map<String, Set<String>> map) {\r
-        /*\r
-        Set<String> keys = map.keySet();\r
-        Iterator it = keys.iterator();\r
-        while (it.hasNext()) {\r
-            String toolchain = (String)it.next();\r
-            Set<String> familyMap = (Set<String>)map.get(toolchain);\r
-            Iterator fit = familyMap.iterator();\r
-            System.out.print(toolchain + ": ");\r
-            while (fit.hasNext()) {\r
-                System.out.print((String)fit.next() + " ");\r
-            }\r
-            System.out.println("");\r
-        }\r
-        */\r
-        toolChainFamilyMap = map;\r
-    }\r
-\r
-    public static String[] getToolChainFamilies() {\r
-        String[] toolChainFamilyList = new String[toolChainFamilies.size()];\r
-        return (String[])toolChainFamilies.toArray(toolChainFamilyList);\r
-    }\r
-\r
-    public static String[] getToolChainFamilies(String toolChain) {\r
-        Set<String> familySet = (Set<String>)toolChainFamilyMap.get(toolChain);\r
-        String[] toolChainFamilyList = new String[familySet.size()];\r
-        return (String[])familySet.toArray(toolChainFamilyList);\r
-    }\r
-\r
-    public static Set<String> getToolChainFamilySet(String toolChain) {\r
-        return (Set<String>)toolChainFamilyMap.get(toolChain);\r
-    }\r
-\r
-    public static void setArchs(Set<String> archSet) {\r
-        archs = archSet;\r
-    }\r
-\r
-    public static String[] getArchs() {\r
-        String[] archList = new String[archs.size()];\r
-        return (String[])archs.toArray(archList);\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static void SetCommandTypes(Set<String> commandTypeSet) {\r
-        commandTypes = commandTypeSet;\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static void SetCommandTypes(Map<String, Set<String>> commandTypeMap) {\r
-        toolChainCommandMap = commandTypeMap;\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String[] getCommandTypes() {\r
-        String[] commandList = new String[commandTypes.size()];\r
-        return (String[])commandTypes.toArray(commandList);\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String[] getCommandTypes(String toolChain) {\r
-        Set<String> commands = (Set<String>)toolChainCommandMap.get(toolChain);\r
-        if (commands == null) {\r
-            return new String[0];\r
-        }\r
-\r
-        String[] commandList = new String[commands.size()];\r
-        return (String[])commands.toArray(commandList);\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String getCommandSetting(String target, String toolChain, \r
-        String arch, String command, String attribute, FpdModuleIdentification fpdModuleId) {\r
-        String[] commandDescription = new String[] {target, toolChain, arch, command, attribute};\r
-        return getCommandSetting(commandDescription, fpdModuleId);\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) {\r
-        if (commandDescription[4].equals("FLAGS")) {\r
-            return getCommandFlags(commandDescription, fpdModuleId);\r
-        }\r
-\r
-        StringBuffer commandDescString = new StringBuffer(32);\r
-\r
-        int i = 0;\r
-        while (true) {\r
-            commandDescString.append(commandDescription[i++]);\r
-            if (i >= commandDescription.length) {\r
-                break;\r
+    \r
+    public static Vector<String> getModuleSupArchs(ModuleIdentification mi) throws Exception{\r
+        Vector<String> vArchs = null;\r
+        ModuleSurfaceAreaDocument.ModuleSurfaceArea msa = (ModuleSurfaceAreaDocument.ModuleSurfaceArea)getModuleXmlObject(mi);\r
+        if (msa.getModuleDefinitions() == null || msa.getModuleDefinitions().getSupportedArchitectures() == null) {\r
+            return vArchs;\r
+        }\r
+        ListIterator li = msa.getModuleDefinitions().getSupportedArchitectures().listIterator();\r
+        while (li.hasNext()) {\r
+            if (vArchs == null) {\r
+                vArchs = new Vector<String>();\r
             }\r
-            commandDescString.append("_");\r
-        }\r
-\r
-        return getCommandSetting(commandDescString.toString());\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String getCommandSetting(String commandDescString) {\r
-        return (String)toolChainDefinitions.get(commandDescString);\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static String getCommandFlags(String[] commandDescription, FpdModuleIdentification fpdModuleId) {\r
-        String setting = getSetting(toolChainOptions, commandDescription, fpdModuleId, false);\r
-\r
-        if (setting == null) {\r
-            String commandDesc = commandDescription[4];\r
-            commandDescription[4] = "FAMILY";\r
-            String toolChainFamily = getCommandSetting(commandDescription, fpdModuleId);\r
-            commandDescription[4] = commandDesc;\r
-\r
-            commandDesc = commandDescription[1];\r
-            commandDescription[1] = toolChainFamily;\r
-            setting = getSetting(toolChainFamilyOptions, commandDescription, fpdModuleId, true);\r
-            commandDescription[1] = commandDesc;\r
-        }\r
-\r
-        if (setting == null) {\r
-            setting = "";\r
+            vArchs.add((String)li.next());\r
         }\r
         \r
-        \r
-        Set<String> addFlagsSet = new LinkedHashSet<String>();\r
-        Set<String> subFlagsSet = new LinkedHashSet<String>();\r
-        putFlagsToSet(addFlagsSet, setting);\r
-\r
-        return getFlags(addFlagsSet, subFlagsSet);\r
-    }\r
-    /*\r
-\r
-     */\r
-    private static String getSetting(Map<String, Object> optionMap, String[] commandDescription, \r
-        FpdModuleIdentification fpdModuleId, boolean toolChainFamilyFlag) {\r
-\r
-        String setting = (String)getOption(optionMap, commandDescription);\r
-        if (fpdModuleId == null) {\r
-            return setting;\r
-        }\r
-        //\r
-        // module overrides\r
-        //\r
-        //\r
-        // get module xml doc\r
-        //\r
-        Map<String, XmlObject> fpdModule = (Map<String, XmlObject>)fpdModuleSA.get(fpdModuleId);\r
-        if (fpdModuleId == null) {\r
-            return setting;\r
-        }\r
-        SurfaceAreaQuery.push(fpdModule);\r
-        //\r
-        // check if the module has been parsed\r
-        //\r
-        Map<String, Object> moduleOptions = (Map<String, Object>)moduleToolChainOptions.get(fpdModuleId);\r
-        if (moduleOptions == null) {\r
-            //\r
-            // get all the build options of this module\r
-            //\r
-            moduleOptions = new TreeMap<String, Object>(comparator);\r
-            parseBuildOptions(moduleOptions, SurfaceAreaQuery.getOptions(toolChainFamilyFlag));\r
-        }\r
-        //\r
-        // get setting for current qualified command\r
-        //\r
-        Set<String> addSet = new TreeSet<String>();\r
-        Set<String> subSet = new TreeSet<String>();\r
-        putFlagsToSet(addSet, setting);\r
-        String moduleSetting = getOption(moduleOptions, commandDescription);\r
-        if (moduleSetting != null) {\r
-            moduleSetting = parseOptionString(moduleSetting, addSet, subSet);\r
-        }\r
-        //\r
-        // do necessary setting override\r
-        //\r
-        if (moduleSetting == null) {\r
-            setting = getRawFlags(addSet, subSet);\r
-        } else {\r
-            setting = moduleSetting;\r
-        }\r
-\r
-        SurfaceAreaQuery.pop();\r
-        return setting;\r
-    }\r
-    /*\r
-\r
-     */\r
-    public static void setToolChainDefinitions(Map<String, String> def) {\r
-        toolChainDefinitions = def;\r
-    }\r
-\r
-    public static Map<String, String> getToolChainDefinitions() {\r
-        return toolChainDefinitions;\r
-    }\r
-\r
-    /**\r
-      Separate the string and instore in set.\r
-       \r
-      <p> String is separated by Java Regulation Expression \r
-      "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
-      \r
-      <p>For example: </p>\r
-      \r
-      <pre>\r
-        "/nologo", "/W3", "/WX"\r
-        "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
-      </pre>\r
-      \r
-      @param set store the separated string\r
-      @param str string to separate\r
-    **/\r
-    private static void putFlagsToSet(Set<String> set, String str) {\r
-        if (str == null || str.length() == 0) {\r
-            return;\r
-        }\r
-\r
-        Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");\r
-        Matcher matcher = myPattern.matcher(str + " ");\r
-        while (matcher.find()) {\r
-            String item = str.substring(matcher.start(1), matcher.end(1));\r
-            set.add(item);\r
-        }\r
+        return vArchs;\r
     }\r
     \r
-    /**\r
-      Generate the final flags string will be used by compile command. \r
-      \r
-      @param add the add flags set\r
-      @param sub the sub flags set\r
-      @return final flags after add set substract sub set\r
-    **/\r
-    private static String getFlags(Set<String> add, Set<String> sub) {\r
-        String result = "";\r
-        add.removeAll(sub);\r
-        Iterator iter = add.iterator();\r
-        while (iter.hasNext()) {\r
-            String str = (String) iter.next();\r
-            result += str.substring(1, str.length() - 1) + " ";\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-      Generate the flags string with original format. The format is defined by \r
-      Java Regulation Expression "[^\\\\]?(\".*?[^\\\\]\")[ \t,]+". </p>\r
-      \r
-      <p>For example: </p>\r
-      \r
-      <pre>\r
-        "/nologo", "/W3", "/WX"\r
-        "/C", "/DSTRING_DEFINES_FILE=\"BdsStrDefs.h\""\r
-      </pre>\r
-      \r
-      @param add the add flags set\r
-      @param sub the sub flags set\r
-      @return flags with original format\r
-    **/\r
-    private static String getRawFlags(Set<String> add, Set<String> sub) {\r
-        String result = null;\r
-        add.removeAll(sub);\r
-        Iterator iter = add.iterator();\r
-        while (iter.hasNext()) {\r
-            String str = (String) iter.next();\r
-            result += "\"" + str.substring(1, str.length() - 1) + "\", ";\r
-        }\r
-        return result;\r
-    }\r
-\r
-    private static String parseOptionString(String optionString, Set<String> addSet, Set<String> subSet) {\r
-        boolean overrideOption = false;\r
-        Pattern pattern = Pattern.compile("ADD\\.\\[(.+)\\]");\r
-        Matcher matcher = pattern.matcher(optionString);\r
-\r
-        while (matcher.find()) {\r
-            overrideOption = true;\r
-            String addOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
-            putFlagsToSet(addSet, addOption);\r
-            \r
-        }\r
-\r
-        pattern = Pattern.compile("SUB\\.\\[(.+)\\]");\r
-        matcher = pattern.matcher(optionString);\r
-\r
-        while (matcher.find()) {\r
-            overrideOption = true;\r
-            String subOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();\r
-            putFlagsToSet(subSet, subOption);\r
-        }\r
-\r
-        if (overrideOption == true) {\r
-            return null;\r
-        }\r
-\r
-        return optionString;\r
-    }\r
-\r
-    public static String getOption(Map<String, Object> options, String[] toolDefString) {\r
-        Stack<Map<String, Object>> stack = new Stack<Map<String, Object>>();\r
-        Map<String, Object> map = options;\r
-        Map<String, Object> lastMap;\r
-        String option = null;\r
-        int length = toolDefString.length - 2;\r
-\r
-        int i = 0;\r
-        String key = null;\r
-        boolean backtrack = false;\r
-        while (true) {\r
-            if (map == null) {\r
-                if (stack.empty()) {\r
-                    break;\r
-                }\r
-                map = (Map<String, Object>)stack.pop();\r
-                if (backtrack) {\r
-                    --i;\r
-                }\r
-                key = "*";\r
-                backtrack = true;\r
-            } else {\r
-                if (i >= length) {\r
-                    break;\r
-                }\r
-                key = toolDefString[i];\r
-                stack.push(map);\r
-                ++i;\r
-                backtrack = false;\r
-            }\r
-            lastMap = map;\r
-            map = (Map<String, Object>)lastMap.get(key);\r
-        }\r
-\r
-        if (map != null) {\r
-            option = (String)map.get(toolDefString[i]);\r
-        }\r
-\r
-        return option;\r
-    }\r
-\r
-    private static void parseBuildOptions(Map<String, Object> optionMap, String[][] options) {\r
-        Map<String, Object> map;\r
-        Map<String, Object> nextMap;\r
-\r
-        for (int i = 0; i < options.length; ++i) {\r
-            map = optionMap;\r
-\r
-            int flagIndex = options[i].length - 1;\r
-            int cmdIndex = flagIndex - 1;\r
-            int archIndex = cmdIndex - 1;\r
-            for (int j = 0; j < cmdIndex; ++j) {\r
-                String s = options[i][j];\r
-                if (s == null || s.trim().length() == 0) {\r
-                    s = "*";\r
-                }\r
-                s = s.trim().toUpperCase();\r
-\r
-                nextMap = (Map<String, Object>)map.get(s);\r
-                if (nextMap == null) {\r
-                    nextMap = new HashMap<String, Object>();\r
-                    map.put(s, nextMap);\r
-                }\r
-\r
-                map = nextMap;\r
-            }\r
-\r
-            String cmd = options[i][cmdIndex];\r
-            String flag = options[i][flagIndex];\r
-            if (cmd == null || cmd.trim().length() == 0) {\r
-                cmd = "*";\r
-            }\r
-            if (flag == null) {\r
-                flag = "";\r
-            }\r
-            map.put(cmd.trim().toUpperCase(), flag.trim().toUpperCase());\r
-        }\r
-    }\r
-\r
 }\r
 \r
 final class KeyComparator implements Comparator<String> {\r