--- /dev/null
+/** @file\r
+ToolChainMap class\r
+\r
+ToolChainMap class is used for storing tool chain configurations.\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+package org.tianocore.build.toolchain;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+/**\r
+ ToolChainMap is a wrapper class for a generic Map class which uses ToolChainKey\r
+ class as its key. It's used to store and retrieve tool chain configuration \r
+ information.\r
+ **/\r
+public class ToolChainMap {\r
+ //\r
+ // From which part of key can be used to match "*"\r
+ // \r
+ private int matchLevel = ToolChainKey.keyLength - 2;\r
+\r
+ //\r
+ // A Map object in which tool chain configuration information will be stored\r
+ // \r
+ private Map<ToolChainKey, String> map = null;\r
+\r
+ /**\r
+ Public constructor. It just initializes the private Map object.\r
+ **/\r
+ public ToolChainMap() {\r
+ this.map = new HashMap<ToolChainKey, String>();\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.put(). It's used when default delimiter of\r
+ ToolChainKey is not wanted and will be overrided by "delimiter" parameter.\r
+\r
+ @param key Key string which is concatenated with "delimiter"\r
+ @param delimiter The delimiter string in the key string\r
+ @param value Value string associated with the "key"\r
+ \r
+ @retval String The "value" string if the "key" is valid.\r
+ @retval null if the "key" is invalid\r
+ **/\r
+ public String put(String key, String delimiter, String value) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key, delimiter);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return (String)map.put(toolChainKey, value);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.put().\r
+\r
+ @param key Key string which is concatenated with default "delimiter"\r
+ @param value Value string associated with the "key"\r
+ \r
+ @retval String The "value" string if the "key" is valid.\r
+ @retval null if the "key" is invalid\r
+ **/\r
+ public String put(String key, String value) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return (String)map.put(toolChainKey, value);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.put(). The key is given in the form of string\r
+ array.\r
+\r
+ @param key Key string array\r
+ @param value Value string associated with the "key"\r
+ \r
+ @retval String The "value" string if the "key" is valid.\r
+ @retval null if the "key" is invalid\r
+ **/\r
+ public String put(String[] key, String value) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return (String)map.put(toolChainKey, value);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.put(). The key is given in ToolChainKey class.\r
+\r
+ @param key ToolChainKey class\r
+ @param value Value string associated with the "key"\r
+ \r
+ @retval String The "value" string if the "key" is valid.\r
+ @retval null if the "key" is invalid\r
+ **/\r
+ public String put(ToolChainKey key, String value) {\r
+ return (String)map.put(key, value);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.get().\r
+\r
+ @param key Key string which is concatenated with default "delimiter"\r
+ \r
+ @return String\r
+ **/\r
+ public String get(String key) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return get(toolChainKey);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.get(). It's used when default delimiter of\r
+ ToolChainKey is not wanted and will be overrided by "delimiter" parameter.\r
+\r
+ @param key Key string which is concatenated with "delimiter"\r
+ @param delimiter The delimiter string in the key string\r
+ \r
+ @return String\r
+ **/\r
+ public String get(String key, String delimiter) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key, delimiter);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return get(toolChainKey);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.get(). The key is given in the form of string\r
+ array.\r
+\r
+ @param key Key string array\r
+ \r
+ @return String\r
+ **/\r
+ public String get(String[] key) {\r
+ ToolChainKey toolChainKey;\r
+\r
+ try {\r
+ toolChainKey = new ToolChainKey(key);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+ return get(toolChainKey);\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.get(). The key is given in ToolChainKey class.\r
+ All other form of get() method will eventually call this form of get. It\r
+ will do real job of finding the value associated with the given key. Most\r
+ of the job is to try to match the key with "wildcard".\r
+\r
+ @param key ToolChainKey class\r
+ \r
+ @return String The value associated with the key\r
+ **/\r
+ public String get(ToolChainKey key) {\r
+ ///\r
+ /// First, we'll try to get the value through the exact given key\r
+ /// \r
+ String result = map.get(key);\r
+ if (result != null || map.containsKey(key)) {\r
+ return result;\r
+ }\r
+\r
+ ///\r
+ /// If nothing is found, then, we'll try all possible keys combined with\r
+ /// wildcard "*". In order not to change the original key value, we have\r
+ /// to clone one for later use. \r
+ /// \r
+ String[] keySet = key.getKeySet();\r
+ ToolChainKey tmpKey;\r
+ try {\r
+ tmpKey = new ToolChainKey(keySet);\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+\r
+ ///\r
+ /// In the current tool chain definition format (in name/value pair), \r
+ /// there're five parts in the "name". The last part of the "name" must\r
+ /// not be "wildcard". So we should start combining "*" from the fourth part.\r
+ /// We'll try all the possible combinations until the value can be fetched.\r
+ /// \r
+ /// The following code implements the logic which will try to use, for example,\r
+ /// following key parts combinations sequentially to get the value.\r
+ /// \r
+ /// TARGET_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE\r
+ /// TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE\r
+ /// TARGET_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE\r
+ /// TARGET_TOOLCHAIN_*_*_ATTRIBUTE\r
+ /// TARGET_*_ARCH_TOOLCODE_ATTRIBUTE\r
+ /// TARGET_*_ARCH_*_ATTRIBUTE\r
+ /// TARGET_*_*_TOOLCODE_ATTRIBUTE\r
+ /// TARGET_*_*_*_ATTRIBUTE\r
+ /// *_TOOLCHAIN_ARCH_TOOLCODE_ATTRIBUTE\r
+ /// *_TOOLCHAIN_ARCH_*_ATTRIBUTE\r
+ /// *_TOOLCHAIN_*_TOOLCODE_ATTRIBUTE\r
+ /// *_TOOLCHAIN_*_*_ATTRIBUTE\r
+ /// *_*_ARCH_TOOLCODE_ATTRIBUTE\r
+ /// *_*_ARCH_*_ATTRIBUTE\r
+ /// *_*_*_TOOLCODE_ATTRIBUTE\r
+ /// *_*_*_*_ATTRIBUTE\r
+ /// \r
+\r
+ //\r
+ // level is used to control if all parts of "name" have been "wildcarded"\r
+ // \r
+ int level = matchLevel;\r
+ while (level >= 0) {\r
+ //\r
+ // tmplevel is used to control if all parts of "name" between first\r
+ // "*" and fourth name part have been "wildcarded".\r
+ // \r
+ int tmpLevel = level;\r
+ while (tmpLevel >= level) {\r
+ String[] tmpKeySet = tmpKey.getKeySet();\r
+ try {\r
+ if (!tmpKeySet[tmpLevel].equals("*")) {\r
+ //\r
+ // If "tmplevel" part is not "*", set it to "*".\r
+ // For example, at first loop, the key will become\r
+ // TARGET_TOOLCHAIN_ARCH_*_ATTRIBUTE, and at next loop,\r
+ // become TARGET_TOOLCHAIN_*_ARCH_ATTRIBUTE\r
+ // \r
+ tmpKey.setKey("*", tmpLevel);\r
+ //\r
+ // We'll try all possible combinations between current\r
+ // part and the fourth part.\r
+ // \r
+ tmpLevel = matchLevel;\r
+ } else {\r
+ //\r
+ // Restore original value of key if "*" at "tmplevel"\r
+ // part of "name" has been checked\r
+ // \r
+ tmpKey.setKey(keySet[tmpLevel], tmpLevel);\r
+ //\r
+ // Try "*" at part left to "tmplevel" part of "name"\r
+ // \r
+ --tmpLevel;\r
+ continue;\r
+ }\r
+ } catch (Exception e) {\r
+ return null;\r
+ }\r
+\r
+ //\r
+ // Try get the value from the map\r
+ // \r
+ result = map.get(tmpKey);\r
+ if (result != null) {\r
+ //\r
+ // The map actually has no exact key as the given "key", \r
+ // putting it back into map can speed up the get() next time\r
+ // \r
+ map.put(key, result);\r
+ return result;\r
+ }\r
+ }\r
+ ///\r
+ /// If all possible combinations of "wildcard" between "level" and \r
+ /// the fourth part of "name" have been tried, try the left part\r
+ /// \r
+ --level;\r
+ }\r
+\r
+ //\r
+ // The map actually has no exact key as the given "key", putting it back\r
+ // into map can speed up the get() next time even we got nothing.\r
+ // \r
+ map.put(key, result);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.size().\r
+\r
+ @return int The size of map\r
+ **/\r
+ public int size() {\r
+ return map.size();\r
+ }\r
+\r
+ /**\r
+ Wrapper function for Map.keySet().\r
+\r
+ @return Set<ToolChainKey> A set of ToolChainKey objects\r
+ */\r
+ public Set<ToolChainKey> keySet() {\r
+ return (Set<ToolChainKey>)map.keySet();\r
+ }\r
+}\r
+\r