<commit_before>module Mondrian
  module OLAP
    class SchemaElement
      def initialize(name = nil, attributes = {}, parent = nil, &block)
        # if just attributes hash provided
        if name.is_a?(Hash) && attributes == {}
          attributes = name
          name = nil
        end
        @attributes = {}
        if name
          if self.class.content
            if attributes.is_a?(Hash)
              @content = name
            else
              # used for Annotation element where both name and content is given as arguments
              @attributes[:name] = name
              @content = attributes
              attributes = {}
            end
          else
            @attributes[:name] = name
          end
        end
        @attributes.merge!(attributes)
        self.class.elements.each do |element|
          instance_variable_set("@#{pluralize(element)}", [])
        end
        # extract annotations from options
        if @attributes[:annotations] && self.class.elements.include?(:annotations)
          annotations @attributes.delete(:annotations)
        end
        @xml_fragments = []
        instance_eval(&block) if block
      end

      def self.attributes(*names)
        names.each do |name|
          class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{name}(*args)
              if args.empty?
                @attributes[:#{name}]
              elsif args.size == 1
                @attributes[:#{name}] = args[0]
              else
                raise ArgumentError, "too many arguments"
              end
            end
          RUBY
        end
      end

      def self.data_dictionary_names(*names)
        return @data_dictionary_names || [] if names.empty?
        @data_dictionary_names ||= []
        @data_dictionary_names.concat(names)
      end

      def self.elements(*names)
        return @elements || [] if names.empty?

        @elements ||= []
        @elements.concat(names)

        names.each do |name|
          next if name == :xml
          attr_reader pluralize(name).to_sym
          class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{name}(name=nil, attributes = {}, &block)
              new_element = Schema::#{camel_case(name)}.new(name, attributes, self, &block)
              @#{pluralize(name)} << new_element
              new_element
            end
          RUBY
          if name == :annotations
            class_eval <<-RUBY, __FILE__, __LINE__ + 1
              def annotations_hash
                hash = {}
                @annotationss.each do |annotations|
                  annotations.annotations.each do |annotation|
                    hash[annotation.name] = annotation.content
                  end
                end
                hash
              end
            RUBY
          end
        end
      end

      def self.content(type = nil)
        return @content if type.nil?
        attr_reader :content
        @content = type
      end

      attr_reader :xml_fragments
      def xml(string)
        string = string.strip
        fragment = Nokogiri::XML::DocumentFragment.parse(string)
        raise ArgumentError, "Invalid XML fragment:\n#{string}" if fragment.children.empty?
        @xml_fragments << string
      end

      def to_xml(options = {})
        options[:upcase_data_dictionary] = @upcase_data_dictionary unless @upcase_data_dictionary.nil?
        Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
          add_to_xml(xml, options)
        end.to_xml
      end

      protected

      def add_to_xml(xml, options)
        if self.class.content
          xml.send(tag_name(self.class.name), @content, xmlized_attributes(options))
        else
          xml.send(tag_name(self.class.name), xmlized_attributes(options)) do
            xml_fragments_added = false
            self.class.elements.each do |element|
              if element == :xml
                add_xml_fragments(xml)
                xml_fragments_added = true
              else
                instance_variable_get("@#{pluralize(element)}").each {|item| item.add_to_xml(xml, options)}
              end
            end
            add_xml_fragments(xml) unless xml_fragments_added
          end
        end
      end

      def add_xml_fragments(xml)
        @xml_fragments.each do |xml_fragment|
          xml.send(:insert, Nokogiri::XML::DocumentFragment.parse(xml_fragment))
        end
      end

      private

      def xmlized_attributes(options)
        # data dictionary values should be in uppercase if schema defined with :upcase_data_dictionary => true
        # or by default when using Oracle or Snowflake driver (can be overridden by :upcase_data_dictionary => false)
        upcase_attributes = if options[:upcase_data_dictionary].nil? && %w(oracle snowflake).include?(options[:driver]) ||
                            options[:upcase_data_dictionary]
          self.class.data_dictionary_names
        else
          []
        end
        hash = {}
        @attributes.each do |attr, value|
          value = value.upcase if upcase_attributes.include?(attr)
          hash[
            # camelcase attribute name
            attr.to_s.gsub(/_([^_]+)/){|m| $1.capitalize}
          ] = value
        end
        hash
      end

      def self.pluralize(string)
        string = string.to_s
        case string
        when /^(.*)y$/
          "#{$1}ies"
        else
          "#{string}s"
        end
      end

      def pluralize(string)
        self.class.pluralize(string)
      end

      def self.camel_case(string)
        string.to_s.split('_').map{|s| s.capitalize}.join('')
      end

      def camel_case(string)
        self.class.camel_case(string)
      end
<commit_msg>Support future attribute values<commit_after>module Mondrian
  module OLAP
    class SchemaElement
      def initialize(name = nil, attributes = {}, parent = nil, &block)
        # if just attributes hash provided
        if name.is_a?(Hash) && attributes == {}
          attributes = name
          name = nil
        end
        @attributes = {}
        if name
          if self.class.content
            if attributes.is_a?(Hash)
              @content = name
            else
              # used for Annotation element where both name and content is given as arguments
              @attributes[:name] = name
              @content = attributes
              attributes = {}
            end
          else
            @attributes[:name] = name
          end
        end
        @attributes.merge!(attributes)
        self.class.elements.each do |element|
          instance_variable_set("@#{pluralize(element)}", [])
        end
        # extract annotations from options
        if @attributes[:annotations] && self.class.elements.include?(:annotations)
          annotations @attributes.delete(:annotations)
        end
        @xml_fragments = []
        instance_eval(&block) if block
      end

      def self.attributes(*names)
        names.each do |name|
          class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{name}(*args)
              if args.empty?
                @attributes[:#{name}]
              elsif args.size == 1
                @attributes[:#{name}] = args[0]
              else
                raise ArgumentError, "too many arguments"
              end
            end
          RUBY
        end
      end

      def self.data_dictionary_names(*names)
        return @data_dictionary_names || [] if names.empty?
        @data_dictionary_names ||= []
        @data_dictionary_names.concat(names)
      end

      def self.elements(*names)
        return @elements || [] if names.empty?

        @elements ||= []
        @elements.concat(names)

        names.each do |name|
          next if name == :xml
          attr_reader pluralize(name).to_sym
          class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{name}(name=nil, attributes = {}, &block)
              new_element = Schema::#{camel_case(name)}.new(name, attributes, self, &block)
              @#{pluralize(name)} << new_element
              new_element
            end
          RUBY
          if name == :annotations
            class_eval <<-RUBY, __FILE__, __LINE__ + 1
              def annotations_hash
                hash = {}
                @annotationss.each do |annotations|
                  annotations.annotations.each do |annotation|
                    hash[annotation.name] = annotation.content
                  end
                end
                hash
              end
            RUBY
          end
        end
      end

      def self.content(type = nil)
        return @content if type.nil?
        attr_reader :content
        @content = type
      end

      attr_reader :xml_fragments
      def xml(string)
        string = string.strip
        fragment = Nokogiri::XML::DocumentFragment.parse(string)
        raise ArgumentError, "Invalid XML fragment:\n#{string}" if fragment.children.empty?
        @xml_fragments << string
      end

      def to_xml(options = {})
        options[:upcase_data_dictionary] = @upcase_data_dictionary unless @upcase_data_dictionary.nil?
        Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
          add_to_xml(xml, options)
        end.to_xml
      end

      protected

      def add_to_xml(xml, options)
        if self.class.content
          xml.send(tag_name(self.class.name), @content, xmlized_attributes(options))
        else
          xml.send(tag_name(self.class.name), xmlized_attributes(options)) do
            xml_fragments_added = false
            self.class.elements.each do |element|
              if element == :xml
                add_xml_fragments(xml)
                xml_fragments_added = true
              else
                instance_variable_get("@#{pluralize(element)}").each {|item| item.add_to_xml(xml, options)}
              end
            end
            add_xml_fragments(xml) unless xml_fragments_added
          end
        end
      end

      def add_xml_fragments(xml)
        @xml_fragments.each do |xml_fragment|
          xml.send(:insert, Nokogiri::XML::DocumentFragment.parse(xml_fragment))
        end
      end

      private

      def xmlized_attributes(options)
        # data dictionary values should be in uppercase if schema defined with :upcase_data_dictionary => true
        # or by default when using Oracle or Snowflake driver (can be overridden by :upcase_data_dictionary => false)
        upcase_attributes = if options[:upcase_data_dictionary].nil? && %w(oracle snowflake).include?(options[:driver]) ||
                            options[:upcase_data_dictionary]
          self.class.data_dictionary_names
        else
          []
        end
        hash = {}
        @attributes.each do |attr, value|
          value = value.upcase if upcase_attributes.include?(attr)
          hash[
            # camelcase attribute name
            attr.to_s.gsub(/_([^_]+)/){|m| $1.capitalize}
          ] = (value.respond_to?(:value) ? value.value : value)
        end
        hash
      end

      def self.pluralize(string)
        string = string.to_s
        case string
        when /^(.*)y$/
          "#{$1}ies"
        else
          "#{string}s"
        end
      end

      def pluralize(string)
        self.class.pluralize(string)
      end

      def self.camel_case(string)
        string.to_s.split('_').map{|s| s.capitalize}.join('')
      end

      def camel_case(string)
        self.class.camel_case(string)
      end

{'fraction_non_alphanumeric': 0.09512237458774518, 'fraction_numerical': 0.0013886478042006596, 'mean_word_length': 1.7112941176470589, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 66}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2745972', 'n_tokens_mistral': 3188, 'n_tokens_neox': 3077, 'n_words': 723}