openxml/openxml-docx

View on GitHub
lib/openxml/docx/properties/container_property.rb

Summary

Maintainability
A
0 mins
Test Coverage
require "openxml/has_attributes"

module OpenXml
  module Docx
    module Properties
      class ContainerProperty < BaseProperty
        include Enumerable
        include HasAttributes

        class << self
          def child_class(*args)
            @child_classes = args.map do |arg|
              prop_name = arg.to_s.split(/_/).map(&:capitalize).join # LazyCamelCase
              OpenXml::Docx::Properties.const_get prop_name
            end unless args.empty?

            @child_classes
          end
          alias :child_classes :child_class
        end

        def initialize
          @children = []
        end

        def <<(child)
          raise ArgumentError, invalid_child_message unless valid_child?(child)
          children << child
        end

        def each(*args, &block)
          children.each *args, &block
        end

        def render?
          !children.length.zero?
        end

        def to_xml(xml)
          return unless render?

          xml["w"].public_send(tag, xml_attributes) {
            each { |child| child.to_xml(xml) }
          }
        end

      private

        attr_reader :children

        def invalid_child_message
          class_name = self.class.to_s.split(/::/).last
          "#{class_name} must be instances of one of the following: #{child_classes}"
        end

        def valid_child?(child)
          child_classes.any? {|child_class| child.is_a?(child_class) }
        end

        def child_classes
          self.class.child_classes
        end

      end
    end
  end
end