Updated mcollective.init according to OSCI-658
[packages/precise/mcollective.git] / lib / mcollective / vendor / i18n / lib / i18n / backend / flatten.rb
diff --git a/lib/mcollective/vendor/i18n/lib/i18n/backend/flatten.rb b/lib/mcollective/vendor/i18n/lib/i18n/backend/flatten.rb
new file mode 100644 (file)
index 0000000..c23f7c1
--- /dev/null
@@ -0,0 +1,113 @@
+module I18n
+  module Backend
+    # This module contains several helpers to assist flattening translations.
+    # You may want to flatten translations for:
+    #
+    #   1) speed up lookups, as in the Memoize backend;
+    #   2) In case you want to store translations in a data store, as in ActiveRecord backend;
+    #
+    # You can check both backends above for some examples.
+    # This module also keeps all links in a hash so they can be properly resolved when flattened.
+    module Flatten
+      SEPARATOR_ESCAPE_CHAR = "\001"
+      FLATTEN_SEPARATOR = "."
+
+      # normalize_keys the flatten way. This method is significantly faster
+      # and creates way less objects than the one at I18n.normalize_keys.
+      # It also handles escaping the translation keys.
+      def self.normalize_flat_keys(locale, key, scope, separator)
+        keys = [scope, key].flatten.compact
+        separator ||= I18n.default_separator
+
+        if separator != FLATTEN_SEPARATOR
+          keys.map! do |k|
+            k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}",
+              "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}")
+          end
+        end
+
+        keys.join(".")
+      end
+
+      # Receives a string and escape the default separator.
+      def self.escape_default_separator(key) #:nodoc:
+        key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR)
+      end
+
+      # Shortcut to I18n::Backend::Flatten.normalize_flat_keys
+      # and then resolve_links.
+      def normalize_flat_keys(locale, key, scope, separator)
+        key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator)
+        resolve_link(locale, key)
+      end
+
+      # Store flattened links.
+      def links
+        @links ||= Hash.new { |h,k| h[k] = {} }
+      end
+
+      # Flatten keys for nested Hashes by chaining up keys:
+      #
+      #   >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
+      #   => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
+      #
+      def flatten_keys(hash, escape, prev_key=nil, &block)
+        hash.each_pair do |key, value|
+          key = escape_default_separator(key) if escape
+          curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym
+          yield curr_key, value
+          flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash)
+        end
+      end
+
+      # Receives a hash of translations (where the key is a locale and
+      # the value is another hash) and return a hash with all
+      # translations flattened.
+      #
+      # Nested hashes are included in the flattened hash just if subtree
+      # is true and Symbols are automatically stored as links.
+      def flatten_translations(locale, data, escape, subtree)
+        hash = {}
+        flatten_keys(data, escape) do |key, value|
+          if value.is_a?(Hash)
+            hash[key] = value if subtree
+          else
+            store_link(locale, key, value) if value.is_a?(Symbol)
+            hash[key] = value
+          end
+        end
+        hash
+      end
+
+      protected
+
+        def store_link(locale, key, link)
+          links[locale.to_sym][key.to_s] = link.to_s
+        end
+
+        def resolve_link(locale, key)
+          key, locale = key.to_s, locale.to_sym
+          links = self.links[locale]
+
+          if links.key?(key)
+            links[key]
+          elsif link = find_link(locale, key)
+            store_link(locale, key, key.gsub(*link))
+          else
+            key
+          end
+        end
+
+        def find_link(locale, key) #:nodoc:
+          links[locale].each do |from, to|
+            return [from, to] if key[0, from.length] == from
+          end && nil
+        end
+
+        def escape_default_separator(key) #:nodoc:
+          I18n::Backend::Flatten.escape_default_separator(key)
+        end
+
+    end
+  end
+end
\ No newline at end of file