From e83a05af076637cc78f0408f5810d5f8f965e10c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 11 Jul 2009 16:20:58 -0500 Subject: Integrate AMo XML serializer into AR --- activemodel/lib/active_model/serializers/xml.rb | 49 +++++---- .../active_record/serializers/xml_serializer.rb | 113 +-------------------- 2 files changed, 31 insertions(+), 131 deletions(-) diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index d187859b44..7cdd281223 100644 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -17,6 +17,15 @@ module ActiveModel @value = compute_value end + # There is a significant speed improvement if the value + # does not need to be escaped, as tag! escapes all values + # to ensure that valid XML is generated. For known binary + # values, it is at least an order of magnitude faster to + # Base64 encode binary values and directly put them in the + # output XML than to pass the original value or the Base64 + # encoded value to the tag! method. It definitely makes + # no sense to Base64 encode the value and then give it to + # tag!, since that just adds additional overhead. def needs_encoding? ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type) end @@ -105,28 +114,6 @@ module ActiveModel end end - def add_attributes - (serializable_attributes + serializable_method_attributes).each do |attribute| - add_tag(attribute) - end - end - - def add_procs - if procs = options.delete(:procs) - [ *procs ].each do |proc| - proc.call(options) - end - end - end - - def add_tag(attribute) - builder.tag!( - reformat_name(attribute.name), - attribute.value.to_s, - attribute.decorations(!options[:skip_types]) - ) - end - def serialize args = [root] @@ -152,6 +139,24 @@ module ActiveModel name = name.camelize if camelize? dasherize? ? name.dasherize : name end + + def add_attributes + (serializable_attributes + serializable_method_attributes).each do |attribute| + builder.tag!( + reformat_name(attribute.name), + attribute.value.to_s, + attribute.decorations(!options[:skip_types]) + ) + end + end + + def add_procs + if procs = options.delete(:procs) + [ *procs ].each do |proc| + proc.call(options) + end + end + end end def to_xml(options = {}, &block) diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index c3811caa53..253fa03785 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -164,42 +164,9 @@ module ActiveRecord #:nodoc: end end - class XmlSerializer < ActiveModel::Serializer #:nodoc: + class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: include Serialization::RecordSerializer - def builder - @builder ||= begin - require 'builder' unless defined? ::Builder - options[:indent] ||= 2 - builder = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent]) - - unless options[:skip_instruct] - builder.instruct! - options[:skip_instruct] = true - end - - builder - end - end - - def root - root = (options[:root] || @serializable.class.to_s.underscore).to_s - reformat_name(root) - end - - def dasherize? - !options.has_key?(:dasherize) || options[:dasherize] - end - - def camelize? - options.has_key?(:camelize) && options[:camelize] - end - - def reformat_name(name) - name = name.camelize if camelize? - dasherize? ? name.dasherize : name - end - def serializable_attributes serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) } end @@ -211,28 +178,6 @@ module ActiveRecord #:nodoc: end end - def add_attributes - (serializable_attributes + serializable_method_attributes).each do |attribute| - add_tag(attribute) - end - end - - def add_procs - if procs = options.delete(:procs) - [ *procs ].each do |proc| - proc.call(options) - end - end - end - - def add_tag(attribute) - builder.tag!( - reformat_name(attribute.name), - attribute.value.to_s, - attribute.decorations(!options[:skip_types]) - ) - end - def add_associations(association, records, opts) if records.is_a?(Enumerable) tag = reformat_name(association.to_s) @@ -282,50 +227,10 @@ module ActiveRecord #:nodoc: end end - class Attribute #:nodoc: - attr_reader :name, :value, :type - - def initialize(name, record) - @name, @record = name, record - - @type = compute_type - @value = compute_value - end - - # There is a significant speed improvement if the value - # does not need to be escaped, as tag! escapes all values - # to ensure that valid XML is generated. For known binary - # values, it is at least an order of magnitude faster to - # Base64 encode binary values and directly put them in the - # output XML than to pass the original value or the Base64 - # encoded value to the tag! method. It definitely makes - # no sense to Base64 encode the value and then give it to - # tag!, since that just adds additional overhead. - def needs_encoding? - ![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type) - end - - def decorations(include_types = true) - decorations = {} - - if type == :binary - decorations[:encoding] = 'base64' - end - - if include_types && type != :string - decorations[:type] = type - end - - if value.nil? - decorations[:nil] = true - end - - decorations - end - + class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: protected def compute_type - type = @record.class.serialized_attributes.has_key?(name) ? :yaml : @record.class.columns_hash[name].type + type = @serializable.class.serialized_attributes.has_key?(name) ? :yaml : @serializable.class.columns_hash[name].type case type when :text @@ -336,22 +241,12 @@ module ActiveRecord #:nodoc: type end end - - def compute_value - value = @record.send(name) - - if formatter = Hash::XML_FORMATTING[type.to_s] - value ? formatter.call(value) : nil - else - value - end - end end class MethodAttribute < Attribute #:nodoc: protected def compute_type - Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string + Hash::XML_TYPE_NAMES[@serializable.send(name).class.name] || :string end end end -- cgit v1.2.3