Class: RubyAMF::ClassMapping

Inherits:
RocketAMF::ClassMapping
  • Object
show all
Defined in:
lib/rubyamf/class_mapping.rb

Overview

Advanced class mapper based off of RocketAMF class mapper. Adds support for advanced serialization and deserialization.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#mapping_scopeObject

The mapping scope to use during serialization. This is populated during response serialization automatically by RubyAMF::Envelope.



105
106
107
# File 'lib/rubyamf/class_mapping.rb', line 105

def mapping_scope
  @mapping_scope
end

Class Method Details

.mappingsObject

Override RocketAMF#mappings to return new RubyAMF::MappingSet object rather than RocketAMF::MappingSet



99
100
101
# File 'lib/rubyamf/class_mapping.rb', line 99

def self.mappings
  @mappings ||= RubyAMF::MappingSet.new
end

Instance Method Details

#get_as_class_name(obj) ⇒ Object

Return the actionscript class name for the given ruby object. If the object is a string, that is assumed to be the ruby class name. Otherwise it extracts the ruby class name from the object based on its type. As RocketAMF calls this for all objects on serialization, auto-mapping takes place here if enabled.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rubyamf/class_mapping.rb', line 112

def get_as_class_name obj
  # Get class name
  if obj.is_a?(String)
    ruby_class_name = obj
  elsif obj.is_a?(RocketAMF::Values::TypedHash)
    ruby_class_name = obj.type
  elsif obj.is_a?(Hash)
    return nil
  elsif obj.is_a?(RubyAMF::IntermediateObject)
    ruby_class_name = obj.object.class.name
  else
    ruby_class_name = obj.class.name
  end

  # Get AS class name
  as_class_name = @mappings.get_as_class_name ruby_class_name

  # Auto-map if necessary, removing namespacing to create mapped class name
  if RubyAMF.configuration.auto_class_mapping && ruby_class_name && as_class_name.nil?
    as_class_name = ruby_class_name.split('::').pop
    @mappings.map :as => as_class_name, :ruby => ruby_class_name
  end

  as_class_name
end

#get_ruby_obj(as_class_name) ⇒ Object

Creates a ruby object to populate during deserialization for the given actionscript class name. If that actionscript class name is mapped to a ruby class, an object of that class is created using obj = ruby_class_name.constantize.allocate and then :initialize is sent to the new instance unless it implements rubyamf_init. If no ruby class name is defined, a RocketAMF::Values::TypedHash object is created and its type attribute is set to the actionscript class name. As RocketAMF calls this for all objects on deserialization, auto-mapping takes place here if enabled.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/rubyamf/class_mapping.rb', line 147

def get_ruby_obj as_class_name
  # Get ruby class name
  ruby_class_name = @mappings.get_ruby_class_name as_class_name

  # Auto-map if necessary, removing namespacing to create mapped class name
  if RubyAMF.configuration.auto_class_mapping && as_class_name && ruby_class_name.nil?
    ruby_class_name = as_class_name.split('.').pop
    @mappings.map :as => as_class_name, :ruby => ruby_class_name
  end

  # Create ruby object
  if ruby_class_name.nil?
    return RocketAMF::Values::TypedHash.new(as_class_name)
  else
    ruby_class = ruby_class_name.constantize
    obj = ruby_class.allocate
    obj.send(:initialize) unless obj.respond_to?(:rubyamf_init) # warhammerkid: Should we check if it has initialize?
    return obj
  end
end

#populate_ruby_obj(obj, props, dynamic_props = nil) ⇒ Object

Performs all enabled property translations (case, key type, ignore_fields) before passing to rubyamf_init if implemented, or to the RocketAMF class mapper implementation.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/rubyamf/class_mapping.rb', line 171

def populate_ruby_obj obj, props, dynamic_props=nil
  # Translate case of properties before passing down to super
  if RubyAMF.configuration.translate_case && !obj.is_a?(RocketAMF::Values::AbstractMessage)
    case_translator = lambda {|injected, pair| injected[pair[0].underscore] = pair[1]; injected}
    props = props.inject({}, &case_translator)
    dynamic_props = dynamic_props.inject({}, &case_translator) if dynamic_props
  end

  # Convert hash key type to string if it's a hash
  if RubyAMF.configuration.hash_key_access == :symbol && obj.is_a?(Hash)
    key_change = lambda {|injected, pair| injected[pair[0].to_sym] = pair[1]; injected}
    props = props.inject({}, &key_change)
    dynamic_props = dynamic_props.inject({}, &key_change) if dynamic_props
  end

  # Remove ignore_fields if there is a config
  config = @mappings.serialization_config(obj.class.name, mapping_scope) || {}
  ignore_fields = Array.wrap(config[:ignore_fields])
  ignore_fields = RubyAMF.configuration.ignore_fields unless ignore_fields.any?
  ignore_fields.each do |ignore|
    props.delete(ignore.to_s)
    props.delete(ignore.to_sym)
    if dynamic_props
      dynamic_props.delete(ignore.to_s)
      dynamic_props.delete(ignore.to_sym)
    end
  end

  # Handle custom init
  if obj.respond_to?(:rubyamf_init)
    obj.rubyamf_init props, dynamic_props
  else
    # Fall through to default populator
    super(obj, props, dynamic_props)
  end
end

#props_for_serialization(ruby_obj) ⇒ Object

Extracts a hash of all object properties for serialization from the object, using rubyamf_hash if implemented with the proper mapping configs for the scope, or the RocketAMF implementation. Before being returned to the serializer, case translation is performed if enabled.



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/rubyamf/class_mapping.rb', line 212

def props_for_serialization ruby_obj
  props = nil

  # Get properties for serialization
  if ruby_obj.respond_to?(:rubyamf_hash)
    if ruby_obj.is_a?(RubyAMF::IntermediateObject)
      props = ruby_obj.rubyamf_hash
    else
      config = @mappings.serialization_config(ruby_obj.class.name, mapping_scope)
      props = ruby_obj.rubyamf_hash config
    end
  else
    # Fall through to default handlers
    props = super(ruby_obj)
  end

  # Translate case of properties if necessary
  if RubyAMF.configuration.translate_case
    props = props.inject({}) do |injected, pair|
      injected[pair[0].to_s.camelize(:lower)] = pair[1]
      injected
    end
  end

  props
end