rubyamf-ouvrages 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ coverage/
5
+ rdoc
6
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rubyamf', :path => File.dirname(__FILE__)
4
+
5
+ gem 'rspec', '~>2.6'
6
+ gem 'rcov'
7
+ gem 'rdoc'
8
+ gem 'rack', '~>1.0'
9
+ gem 'sqlite3'
10
+ gem "RocketAMF", :git => "git://github.com/rubyamf/rocketamf.git"
11
+
12
+ case 'Rails 3.1'
13
+ when 'Rails 2.3'
14
+ gem 'rails', '~>2.3'
15
+ gem 'composite_primary_keys', '~> 2.3'
16
+ when 'Rails 3.0'
17
+ gem 'rails', '~>3.0'
18
+ gem 'composite_primary_keys', '~> 3.1.8'
19
+ when 'Rails 3.1'
20
+ gem 'rails', '~>3.1'
21
+ gem 'composite_primary_keys', '~> 4'
22
+ end
data/README.rdoc ADDED
@@ -0,0 +1,105 @@
1
+ == DESCRIPTION:
2
+
3
+ RubyAMF is a full-featured AMF gateway based off of Rack and supporting advanced
4
+ integration with Rails and other Rack-based frameworks. It includes advanced
5
+ class mapping functionality, like camel to underscore case translation,
6
+ parameter mapping to convert function calls to parameter hashes for actions,
7
+ hooks for processing AMF authentication credentials, and many more features.
8
+
9
+ == UPGRADE FROM rubyamf_plugin:
10
+
11
+ 1. Delete <tt>RAILS_ROOT/vendor/plugins/rubyamf</tt> or comment out every line
12
+ in <tt>RAILS_ROOT/vendor/plugins/rubyamf/init.rb</tt>.
13
+
14
+ 2. Add gems to application:
15
+
16
+ <b>Bundler:</b>
17
+ gem "RocketAMF", :git => "git://github.com/rubyamf/rocketamf.git"
18
+ gem 'rubyamf', :git => 'git://github.com/rubyamf/rubyamf.git'
19
+
20
+ <b>environment.rb:</b>
21
+ config.gem "RocketAMF"
22
+ config.gem "rubyamf"
23
+
24
+ 3. Configure the endpoint path by adding the following to the end of your
25
+ <tt>environment.rb</tt> file:
26
+
27
+ RubyAMF.configure do |config|
28
+ config.gateway_path = "/rubyamf/gateway"
29
+ end
30
+
31
+ The gateway path is no longer specified in <tt>routes.rb</tt>, so you can
32
+ remove it and <tt>rubyamf_controller.rb</tt> if you want.
33
+
34
+ 4. Try out your application!
35
+
36
+ RubyAMF should load your legacy <tt>rubyamf_config.rb</tt> file and you should
37
+ be on your way.
38
+
39
+ If you want to learn more about the new features, please check out the demo app
40
+ at https://github.com/rubyamf/rubyamf-demo or the RDoc at (SOMEWHERE).
41
+
42
+ == RAILS 2 INSTALL:
43
+
44
+ 1. Add gems to application:
45
+
46
+ <b>Bundler:</b>
47
+ gem "RocketAMF", :git => "git://github.com/rubyamf/rocketamf.git"
48
+ gem 'rubyamf', :git => 'git://github.com/rubyamf/rubyamf.git'
49
+
50
+ <b>environment.rb:</b>
51
+ config.gem "RocketAMF"
52
+ config.gem "rubyamf"
53
+
54
+ 2. Configure the endpoint path by adding the following to the end of your
55
+ <tt>environment.rb</tt> file:
56
+
57
+ RubyAMF.configure do |config|
58
+ config.gateway_path = "/rubyamf/gateway"
59
+ end
60
+
61
+ Check out the demo app at (SOMEWHERE) or the RDoc at (SOMEWHERE) for information
62
+ about configuration and use.
63
+
64
+ == RAILS 3 INSTALL:
65
+
66
+ 1. Add the gems to your Gemfile:
67
+
68
+ gem "RocketAMF", :git => "git://github.com/rubyamf/rocketamf.git"
69
+ gem 'rubyamf', :git => 'git://github.com/rubyamf/rubyamf.git'
70
+
71
+ 2. Configure the endpoint path by adding the following to your <tt>application.rb</tt>:
72
+
73
+ config.rubyamf.gateway_path = "/amf"
74
+
75
+ Check out the demo app at https://github.com/rubyamf/rubyamf-demo or the RDoc at (SOMEWHERE) for information
76
+ about configuration and use.
77
+
78
+ == OTHER RACK FRAMEWORK INSTALL:
79
+
80
+ TODO: Write up instructions
81
+
82
+ == LICENSE:
83
+
84
+ (The MIT License)
85
+
86
+ Copyright (c) 2011 Stephen Augenstein
87
+
88
+ Permission is hereby granted, free of charge, to any person obtaining
89
+ a copy of this software and associated documentation files (the
90
+ 'Software'), to deal in the Software without restriction, including
91
+ without limitation the rights to use, copy, modify, merge, publish,
92
+ distribute, sublicense, and/or sell copies of the Software, and to
93
+ permit persons to whom the Software is furnished to do so, subject to
94
+ the following conditions:
95
+
96
+ The above copyright notice and this permission notice shall be
97
+ included in all copies or substantial portions of the Software.
98
+
99
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
100
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
102
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
103
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
104
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
105
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'rspec/core/rake_task'
4
+ require 'rdoc/task'
5
+
6
+ g = Bundler::GemHelper.new(File.dirname(__FILE__))
7
+ g.install
8
+
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.rcov = true
11
+ t.rcov_opts = ['--exclude', 'spec,gems,.bundler']
12
+ end
13
+
14
+ desc 'Generate documentation for RubyAMF'
15
+ Rake::RDocTask.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = g.gemspec.name
18
+ rdoc.options += g.gemspec.rdoc_options
19
+ rdoc.rdoc_files.include(*g.gemspec.extra_rdoc_files)
20
+ rdoc.rdoc_files.include("lib") # Don't include ext folder because no one cares
21
+ end
data/lib/rubyamf.rb ADDED
@@ -0,0 +1,64 @@
1
+ require 'rocketamf'
2
+ require 'active_support/inflector'
3
+ require 'active_support/core_ext/array'
4
+ require 'rubyamf/version'
5
+ require 'rubyamf/logger'
6
+ require 'rubyamf/fault'
7
+ require 'rubyamf/intermediate_object'
8
+ require 'rubyamf/class_mapping'
9
+ require 'rubyamf/model'
10
+ require 'rubyamf/configuration'
11
+ require 'rubyamf/envelope'
12
+ require 'rubyamf/request_parser'
13
+ require 'rubyamf/test'
14
+
15
+ module RubyAMF
16
+ MIME_TYPE = "application/x-amf".freeze
17
+
18
+ class << self
19
+ def configuration
20
+ @configuration ||= RubyAMF::Configuration.new
21
+ end
22
+
23
+ def configuration= config
24
+ @configuration = config
25
+ end
26
+
27
+ def logger
28
+ @logger ||= RubyAMF::Logger.new
29
+ end
30
+
31
+ def configure
32
+ yield configuration
33
+ bootstrap
34
+ end
35
+
36
+ def bootstrap
37
+ configuration.preload_models.flatten.each {|m| m.to_s.constantize}
38
+ RubyAMF::ClassMapper.use_array_collection = configuration.use_array_collection # Make sure it gets copied over for RocketAMF
39
+ end
40
+
41
+ def const_missing const #:nodoc:
42
+ if const == :ClassMapper
43
+ class_mapper = configuration.class_mapper
44
+ RubyAMF.const_set(:ClassMapper, class_mapper)
45
+ RocketAMF.const_set(:ClassMapper, class_mapper)
46
+ else
47
+ super(const)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ # Rails specific bootstrapping
54
+ module RubyAMF::Rails #:nodoc:
55
+ end
56
+ if defined?(Rails)
57
+ if Rails::VERSION::MAJOR == 3
58
+ require 'rubyamf/rails/rails3_bootstrap'
59
+ elsif Rails::VERSION::MAJOR == 2 && Rails::VERSION::MINOR >= 3
60
+ require 'rubyamf/rails/rails2_bootstrap'
61
+ else
62
+ puts "unsupported rails version"
63
+ end
64
+ end
@@ -0,0 +1,239 @@
1
+ module RubyAMF
2
+ # Advanced mapping container to support various serialization customization
3
+ # settings. Used by RubyAMF class mapper to store advanced mappings.
4
+ class MappingSet < ::RocketAMF::MappingSet
5
+ # Store all property mapping configuration by scope
6
+ class Mapping
7
+ attr_accessor :ruby, :as, :default_scope, :scopes
8
+ def initialize
9
+ @default_scope = :default
10
+ @scopes = {}
11
+ end
12
+ end
13
+
14
+ SERIALIZATION_PROPS = [:except, :only, :methods, :include, :ignore_fields]
15
+
16
+ def initialize
17
+ @as_mappings = {}
18
+ @ruby_mappings = {}
19
+ map_defaults
20
+ end
21
+
22
+ # Map a given actionscript class to a ruby class. You can also control which
23
+ # properties are serialized using <tt>:except</tt>, <tt>:only</tt>,
24
+ # <tt>:methods</tt>, <tt>:include</tt> for relations, and <tt>:ignore_fields</tt>
25
+ # for skipping certain fields during deserialization.
26
+ #
27
+ # Use fully qualified names for both.
28
+ #
29
+ # Examples:
30
+ #
31
+ # m.map :as => 'com.example.Date', :ruby => 'Example::Date'
32
+ # m.map :flash => 'User', :ruby => 'User', :only => 'username'
33
+ # m.map :flash => 'User', :ruby => 'User', :scope => :other, :include => [:courses, :teacher]
34
+ def map params
35
+ # Extract and validate ruby and AS class names
36
+ ruby_class = params[:ruby]
37
+ as_class = params[:as] || params[:flash] || params[:actionscript]
38
+ raise "Must pass ruby class name under :ruby key" unless ruby_class
39
+ raise "Must pass as class name under :flash, :as, or :actionscript key" unless as_class
40
+
41
+ # Get mapping if it already exists
42
+ mapping = @as_mappings[as_class] || @ruby_mappings[ruby_class] || Mapping.new
43
+ mapping.ruby = ruby_class
44
+ mapping.as = as_class
45
+ @as_mappings[as_class] = mapping
46
+ @ruby_mappings[ruby_class] = mapping
47
+
48
+ # If they tried to configure the serialization props, store that too under the proper scope
49
+ serialization_config = {}
50
+ params.each {|k,v| serialization_config[k] = v if SERIALIZATION_PROPS.include?(k)}
51
+ if serialization_config.length > 0
52
+ # Determine scope
53
+ scope = nil
54
+ if params[:default_scope]
55
+ scope = mapping.default_scope = params[:default_scope]
56
+ elsif params[:scope]
57
+ scope = params[:scope]
58
+ else
59
+ scope = mapping.default_scope
60
+ end
61
+
62
+ # Add config to scope hash
63
+ mapping.scopes[scope.to_sym] = serialization_config
64
+ end
65
+ end
66
+
67
+ # Returns the actionscript class name mapped to the given ruby class name.
68
+ # Returns <tt>nil</tt> if not found.
69
+ def get_as_class_name ruby_class_name
70
+ mapping = @ruby_mappings[ruby_class_name]
71
+ return mapping.nil? ? nil : mapping.as
72
+ end
73
+
74
+ # Returns the ruby class name mapped to the given actionscript class name.
75
+ # Returns <tt>nil</tt> if not found.
76
+ def get_ruby_class_name as_class_name
77
+ mapping = @as_mappings[as_class_name]
78
+ return mapping.nil? ? nil : mapping.ruby
79
+ end
80
+
81
+ # Returns the property serialization config for the given ruby class name
82
+ # and scope. If scope is <tt>nil</tt>, it uses the default scope.
83
+ def serialization_config ruby_class_name, scope = nil
84
+ mapping = @ruby_mappings[ruby_class_name]
85
+ if mapping.nil?
86
+ nil
87
+ else
88
+ scope ||= mapping.default_scope
89
+ mapping.scopes[scope.to_sym]
90
+ end
91
+ end
92
+ end
93
+
94
+ # Advanced class mapper based off of RocketAMF class mapper. Adds support for
95
+ # advanced serialization and deserialization.
96
+ class ClassMapping < ::RocketAMF::ClassMapping
97
+ # Override RocketAMF#mappings to return new RubyAMF::MappingSet object rather
98
+ # than RocketAMF::MappingSet
99
+ def self.mappings
100
+ @mappings ||= RubyAMF::MappingSet.new
101
+ end
102
+
103
+ # The mapping scope to use during serialization. This is populated during
104
+ # response serialization automatically by RubyAMF::Envelope.
105
+ attr_accessor :mapping_scope
106
+
107
+ # Return the actionscript class name for the given ruby object. If the object
108
+ # is a string, that is assumed to be the ruby class name. Otherwise it extracts
109
+ # the ruby class name from the object based on its type. As RocketAMF calls
110
+ # this for all objects on serialization, auto-mapping takes place here if
111
+ # enabled.
112
+ def get_as_class_name obj
113
+ # Get class name
114
+ if obj.is_a?(String)
115
+ ruby_class_name = obj
116
+ elsif obj.is_a?(RocketAMF::Values::TypedHash)
117
+ ruby_class_name = obj.type
118
+ elsif obj.is_a?(Hash)
119
+ return nil
120
+ elsif obj.is_a?(RubyAMF::IntermediateObject)
121
+ ruby_class_name = obj.object.class.name
122
+ else
123
+ ruby_class_name = obj.class.name
124
+ end
125
+
126
+ # Get AS class name
127
+ as_class_name = @mappings.get_as_class_name ruby_class_name
128
+
129
+ # Auto-map if necessary, removing namespacing to create mapped class name
130
+ if RubyAMF.configuration.auto_class_mapping && ruby_class_name && as_class_name.nil?
131
+ as_class_name = ruby_class_name.split('::').pop
132
+ @mappings.map :as => as_class_name, :ruby => ruby_class_name
133
+ end
134
+
135
+ as_class_name
136
+ end
137
+
138
+ # Creates a ruby object to populate during deserialization for the given
139
+ # actionscript class name. If that actionscript class name is mapped to a
140
+ # ruby class, an object of that class is created using
141
+ # <tt>obj = ruby_class_name.constantize.allocate</tt> and then
142
+ # <tt>:initialize</tt> is sent to the new instance unless it implements
143
+ # <tt>rubyamf_init</tt>. If no ruby class name is defined, a
144
+ # <tt>RocketAMF::Values::TypedHash</tt> object is created and its type
145
+ # attribute is set to the actionscript class name. As RocketAMF calls this
146
+ # for all objects on deserialization, auto-mapping takes place here if enabled.
147
+ def get_ruby_obj as_class_name
148
+ # Get ruby class name
149
+ ruby_class_name = @mappings.get_ruby_class_name as_class_name
150
+
151
+ # Auto-map if necessary, removing namespacing to create mapped class name
152
+ if RubyAMF.configuration.auto_class_mapping && as_class_name && ruby_class_name.nil?
153
+ ruby_class_name = as_class_name.split('.').pop
154
+ @mappings.map :as => as_class_name, :ruby => ruby_class_name
155
+ end
156
+
157
+ # Create ruby object
158
+ if ruby_class_name.nil?
159
+ return RocketAMF::Values::TypedHash.new(as_class_name)
160
+ else
161
+ ruby_class = ruby_class_name.constantize
162
+ obj = ruby_class.allocate
163
+ obj.send(:initialize) unless obj.respond_to?(:rubyamf_init) # warhammerkid: Should we check if it has initialize?
164
+ return obj
165
+ end
166
+ end
167
+
168
+ # Performs all enabled property translations (case, key type, ignore_fields)
169
+ # before passing to <tt>rubyamf_init</tt> if implemented, or to the RocketAMF
170
+ # class mapper implementation.
171
+ def populate_ruby_obj obj, props, dynamic_props=nil
172
+ # Translate case of properties before passing down to super
173
+ if RubyAMF.configuration.translate_case && !obj.is_a?(RocketAMF::Values::AbstractMessage)
174
+ case_translator = lambda {|injected, pair| injected[pair[0].underscore] = pair[1]; injected}
175
+ props = props.inject({}, &case_translator)
176
+ dynamic_props = dynamic_props.inject({}, &case_translator) if dynamic_props
177
+ end
178
+
179
+ # Convert hash key type to string if it's a hash
180
+ if RubyAMF.configuration.hash_key_access == :symbol && obj.is_a?(Hash)
181
+ key_change = lambda {|injected, pair| injected[pair[0].to_sym] = pair[1]; injected}
182
+ props = props.inject({}, &key_change)
183
+ dynamic_props = dynamic_props.inject({}, &key_change) if dynamic_props
184
+ end
185
+
186
+ # Remove ignore_fields if there is a config
187
+ config = @mappings.serialization_config(obj.class.name, mapping_scope) || {}
188
+ ignore_fields = Array.wrap(config[:ignore_fields])
189
+ ignore_fields = RubyAMF.configuration.ignore_fields unless ignore_fields.any?
190
+ ignore_fields.each do |ignore|
191
+ props.delete(ignore.to_s)
192
+ props.delete(ignore.to_sym)
193
+ if dynamic_props
194
+ dynamic_props.delete(ignore.to_s)
195
+ dynamic_props.delete(ignore.to_sym)
196
+ end
197
+ end
198
+
199
+ # Handle custom init
200
+ if obj.respond_to?(:rubyamf_init)
201
+ obj.rubyamf_init props, dynamic_props
202
+ else
203
+ # Fall through to default populator
204
+ super(obj, props, dynamic_props)
205
+ end
206
+ end
207
+
208
+ # Extracts a hash of all object properties for serialization from the object,
209
+ # using <tt>rubyamf_hash</tt> if implemented with the proper mapping configs
210
+ # for the scope, or the RocketAMF implementation. Before being returned to
211
+ # the serializer, case translation is performed if enabled.
212
+ def props_for_serialization ruby_obj
213
+ props = nil
214
+
215
+ # Get properties for serialization
216
+ if ruby_obj.respond_to?(:rubyamf_hash)
217
+ if ruby_obj.is_a?(RubyAMF::IntermediateObject)
218
+ props = ruby_obj.rubyamf_hash
219
+ else
220
+ config = @mappings.serialization_config(ruby_obj.class.name, mapping_scope)
221
+ props = ruby_obj.rubyamf_hash config
222
+ end
223
+ else
224
+ # Fall through to default handlers
225
+ props = super(ruby_obj)
226
+ end
227
+
228
+ # Translate case of properties if necessary
229
+ if RubyAMF.configuration.translate_case
230
+ props = props.inject({}) do |injected, pair|
231
+ injected[pair[0].to_s.camelize(:lower)] = pair[1]
232
+ injected
233
+ end
234
+ end
235
+
236
+ props
237
+ end
238
+ end
239
+ end