module Scrivito class ObjData internal_key_list = %w[ last_changed modification permalink text_links conflicts ] INTERNAL_KEYS = Set.new(internal_key_list.map { |name| "_#{name}" } ) internal_comparison_key_list = %w[ path permalink widget_pool ] INTERNAL_COMPARISON_KEYS = Set.new(internal_comparison_key_list.map { |name| "_#{name}" }) ATTRIBUTE_DEFAULT_VALUES = { "string" => "", "text" => "", "html" => "", "multienum" => [], "linklist" => [], "referencelist" => [], "widget" => [], "enum" => nil, "binary" => nil, "date" => nil, "reference" => nil, "link" => nil, }.freeze def value_of(attribute_name) value_and_type_of(attribute_name).first end def type_of(attribute_name) value_and_type_of(attribute_name).second end def value_without_default_of(attribute_name) value_and_type_without_default_of(attribute_name).first end def value_and_type_of(attribute_name) if internal_attribute?(attribute_name) internal_value_and_type(attribute_name) else custom_value_and_type_with_default(attribute_name) end end def value_and_type_without_default_of(attribute_name) if internal_attribute?(attribute_name) internal_value_and_type(attribute_name) else raw_value_and_type_of(attribute_name) end end def all_custom_attributes @all_custom_attributes ||= all_attributes.select do |attribute| has_custom_attribute?(attribute) end end def to_h raise NotImplementedError, 'implement in subclass' end def raw_value_and_type_of(attribute_name) raise NotImplementedError, "implement in subclass" end def has_custom_attribute?(name) raise NotImplementedError, "implement in subclass" end def all_attributes raise NotImplementedError, "implement in subclass" end def ==(other) if other.kind_of?(ObjData) (all_attributes | other.all_attributes).each do |attr| attr = attr.to_s next if attr.start_with?('_') && !INTERNAL_COMPARISON_KEYS.include?(attr) if value_without_default_of(attr) != other.value_without_default_of(attr) return false end end return true end false end private def custom_value_and_type_with_default(attribute_name) value, type = raw_value_and_type_of(attribute_name) value = ATTRIBUTE_DEFAULT_VALUES[type] if value.nil? [value, type] end def internal_value_and_type(attribute_name) value, type = raw_value_and_type_of(attribute_name) type = type_of_internal(attribute_name) [value, type] end def internal_attribute?(attribute_name) attribute_name.starts_with?('_') end def type_of_internal(key) case key when "_permalink" "string" when "_text_links" "linklist" when "_last_changed" "date" else nil end end end end