actionservice 0.2.102 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,13 +5,13 @@ require 'xsd/datatypes'
5
5
  require 'xsd/ns'
6
6
  require 'singleton'
7
7
 
8
- module ActionService
9
- module Protocol
10
- module Soap
11
- class ProtocolError < ActionService::ActionServiceError
8
+ module ActionService # :nodoc:
9
+ module Protocol # :nodoc:
10
+ module Soap # :nodoc:
11
+ class ProtocolError < ActionService::ActionServiceError # :nodoc:
12
12
  end
13
13
 
14
- def self.append_features(base)
14
+ def self.append_features(base) # :nodoc:
15
15
  super
16
16
  base.register_protocol(HeaderAndBody, SoapProtocol)
17
17
  base.extend(ClassMethods)
@@ -19,16 +19,24 @@ module ActionService
19
19
  end
20
20
 
21
21
  module ClassMethods
22
+ # Specifies the WSDL service name to use when generating WSDL. Highly
23
+ # recommended that you set this value, or code generators may generate
24
+ # classes with very generic names.
25
+ #
26
+ # === Example
27
+ # class ApiController < ActionController::Base
28
+ # wsdl_service_name 'Test'
29
+ # end
22
30
  def wsdl_service_name(name)
23
31
  write_inheritable_attribute("soap_mapper", SoapMapper.new("urn:#{name}"))
24
32
  end
25
33
 
26
- def soap_mapper
34
+ def soap_mapper # :nodoc:
27
35
  read_inheritable_attribute("soap_mapper")
28
36
  end
29
37
  end
30
38
 
31
- class SoapProtocol < AbstractProtocol
39
+ class SoapProtocol < AbstractProtocol # :nodoc:
32
40
  def self.create_protocol_request(container_class, action_pack_request)
33
41
  soap_action = extract_soap_action(action_pack_request)
34
42
  return nil unless soap_action
@@ -178,7 +186,7 @@ module ActionService
178
186
  end
179
187
  end
180
188
 
181
- class SoapMapper
189
+ class SoapMapper # :nodoc:
182
190
  attr :registry
183
191
  attr :custom_namespace
184
192
  attr :custom_types
@@ -383,7 +391,7 @@ module ActionService
383
391
  end
384
392
  end
385
393
 
386
- class SoapMapping
394
+ class SoapMapping # :nodoc:
387
395
  attr :ruby_klass
388
396
  attr :generated_klass
389
397
  attr :soap_klass
@@ -440,7 +448,7 @@ module ActionService
440
448
  end
441
449
  end
442
450
 
443
- class SoapArrayMapping < SoapMapping
451
+ class SoapArrayMapping < SoapMapping # :nodoc:
444
452
  attr :element_mapping
445
453
 
446
454
  def initialize(mapper, type_name, ruby_klass, soap_klass, registry_mapping, element_mapping)
@@ -1,36 +1,41 @@
1
1
  require 'xmlrpc/parser'
2
+ require 'xmlrpc/create'
3
+ require 'xmlrpc/config'
2
4
  require 'xmlrpc/utils'
3
5
  require 'singleton'
4
6
 
5
- module ActionService
6
- module Protocol
7
- module XmlRpc
8
- def self.append_features(base)
7
+ module XMLRPC # :nodoc:
8
+ class XmlRpcHelper # :nodoc:
9
+ include Singleton
10
+ include ParserWriterChooseMixin
11
+
12
+ def parse_method_call(message)
13
+ parser().parseMethodCall(message)
14
+ end
15
+
16
+ def create_method_response(successful, return_value)
17
+ create().methodResponse(successful, return_value)
18
+ end
19
+ end
20
+ end
21
+
22
+ module ActionService # :nodoc:
23
+ module Protocol # :nodoc:
24
+ module XmlRpc # :nodoc:
25
+ def self.append_features(base) # :nodoc:
9
26
  super
10
27
  base.register_protocol(BodyOnly, XmlRpcProtocol)
11
28
  end
12
29
 
13
- class XmlRpcProtocol < AbstractProtocol
14
- private
15
- class Helper
16
- include Singleton
17
- include XMLRPC::ParserWriterChooseMixin
18
-
19
- def get_parser
20
- parser()
21
- end
22
-
23
- def get_create
24
- create()
25
- end
26
- end
30
+ class XmlRpcProtocol < AbstractProtocol # :nodoc:
27
31
 
28
32
  public
29
33
 
30
34
  def self.create_protocol_request(container_class, action_pack_request)
31
- parser = Helper.instance.get_parser
35
+ helper = XMLRPC::XmlRpcHelper.instance
32
36
  service_name = action_pack_request.parameters['action']
33
- methodname, params = parser.parseMethodCall(action_pack_request.raw_post)
37
+ methodname, params = helper.parse_method_call(action_pack_request.raw_post)
38
+ methodname.gsub!(/^[^\.]+\./, '') unless methodname =~ /^system\./ # XXX
34
39
  protocol = XmlRpcProtocol.new(container_class)
35
40
  content_type = action_pack_request.env['HTTP_CONTENT_TYPE']
36
41
  content_type ||= 'text/xml'
@@ -38,8 +43,8 @@ module ActionService
38
43
  action_pack_request.raw_post,
39
44
  service_name.to_sym,
40
45
  methodname,
41
- content_type)
42
- request.values = params
46
+ content_type,
47
+ :xmlrpc_values => params)
43
48
  request
44
49
  rescue
45
50
  nil
@@ -51,10 +56,11 @@ module ActionService
51
56
  end
52
57
 
53
58
  def unmarshal_request(protocol_request)
54
- values = protocol_request.values
59
+ values = protocol_request.options[:xmlrpc_values]
55
60
  signature = protocol_request.signature
56
61
  if signature
57
62
  signature = array_types(signature)
63
+ values = transform_expected_params(signature, values)
58
64
  protocol_request.check_parameter_types(values, signature)
59
65
  values
60
66
  else
@@ -63,30 +69,31 @@ module ActionService
63
69
  end
64
70
 
65
71
  def marshal_response(protocol_request, return_value)
66
- create = Helper.instance.get_create
72
+ helper = XMLRPC::XmlRpcHelper.instance
67
73
  signature = protocol_request.return_signature
68
74
  if signature
69
75
  signature = array_types(signature)
70
76
  protocol_request.check_parameter_types([return_value], signature)
71
- return_value = fixup_values_for_return(return_value)
72
- raw_response = create.methodResponse(true, return_value)
77
+ return_value = transform_return_value(return_value)
78
+ raw_response = helper.create_method_response(true, return_value)
73
79
  else
74
80
  # XML-RPC doesn't have the concept of a void method, nor does it
75
81
  # support a nil return value, so return true if we would have returned
76
82
  # nil
77
83
  if protocol_request.checked?
78
- raw_response = create.methodResponse(true, true)
84
+ raw_response = helper.create_method_response(true, true)
79
85
  else
80
86
  return_value = true if return_value.nil?
81
- raw_response = create.methodResponse(true, return_value)
87
+ raw_response = helper.create_method_response(true, return_value)
82
88
  end
83
89
  end
84
90
  ProtocolResponse.new(self, raw_response, 'text/xml')
85
91
  end
86
92
 
87
93
  def marshal_exception(exception)
88
- create = Helper.instance.get_create
89
- raw_response = create.methodResponse(false, exception)
94
+ helper = XMLRPC::XmlRpcHelper.instance
95
+ exception = XMLRPC::FaultException.new(1, exception.message)
96
+ raw_response = helper.create_method_response(false, exception)
90
97
  ProtocolResponse.new(self, raw_response, 'text/xml')
91
98
  end
92
99
 
@@ -108,14 +115,40 @@ module ActionService
108
115
  signature.map{|x| x.is_a?(Array) ? Array : x}
109
116
  end
110
117
 
111
- def fixup_values_for_return(return_value)
118
+ def transform_expected_params(signature, params)
119
+ (1..signature.size).each do |i|
120
+ i -= 1
121
+ if signature[i].ancestors.include?(ActionService::Struct)
122
+ if params[i].class.ancestors.include?(Hash)
123
+ new_param = signature[i].new
124
+ signature[i].members.each do |name, klass|
125
+ new_param.send('%s=' % name.to_s, params[i][name.to_s])
126
+ end
127
+ params[i] = new_param
128
+ else
129
+ raise(ProtocolError, "expected input parameter #{i+1} to be a Hash")
130
+ end
131
+ end
132
+ end
133
+ params
134
+ end
135
+
136
+ def transform_return_value(return_value)
112
137
  if return_value.is_a?(Array)
113
138
  (1..return_value.size).each do |i|
114
- return_value[i-1] = fixup_values_for_return(return_value[i-1])
139
+ return_value[i-1] = transform_return_value(return_value[i-1])
115
140
  end
116
141
  else
117
142
  if return_value.is_a?(ActiveRecord::Base)
118
143
  return_value = return_value.instance_variable_get('@attributes')
144
+ elsif return_value.is_a?(ActionService::Struct)
145
+ struct = {}
146
+ return_value.class.members.each do |name, klass|
147
+ value = return_value.send(name)
148
+ next if value.nil?
149
+ struct[name.to_s] = value
150
+ end
151
+ return_value = struct
119
152
  end
120
153
  end
121
154
  return_value
@@ -1,7 +1,7 @@
1
- module ActionService
2
- module Router
3
- module ActionController
4
- def self.append_features(base)
1
+ module ActionService # :nodoc:
2
+ module Router # :nodoc:
3
+ module ActionController # :nodoc:
4
+ def self.append_features(base) # :nodoc:
5
5
  base.add_export_definition_callback do |klass, export_name, export_info|
6
6
  if klass.service_dispatching_mode == :direct && !klass.method_defined?(:api)
7
7
  klass.class_eval <<-EOS
@@ -23,16 +23,22 @@ module ActionService
23
23
  base.send(:include, ActionService::Router::ActionController::InstanceMethods)
24
24
  end
25
25
 
26
- module InstanceMethods
26
+ module InstanceMethods # :nodoc:
27
27
  private
28
28
  def process_action_service_request
29
29
  protocol_request = nil
30
30
  begin
31
- protocol_request = probe_request_protocol(self.request)
31
+ begin
32
+ protocol_request = probe_request_protocol(self.request)
33
+ rescue Exception => e
34
+ logger.error "Invalid request: #{e.message}"
35
+ logger.error self.request.raw_post
36
+ raise
37
+ end
32
38
  if protocol_request
33
39
  log_request(protocol_request)
34
40
  protocol_response = dispatch_service_request(protocol_request)
35
- log_response(protocol_request)
41
+ log_response(protocol_response)
36
42
  response_options = {
37
43
  :type => protocol_response.content_type,
38
44
  :disposition => 'inline'
@@ -44,16 +50,24 @@ module ActionService
44
50
  end
45
51
  rescue Exception => e
46
52
  log_error e unless logger.nil?
47
- service_object = service_object(protocol_request.service_name) rescue nil
48
53
  exc_response = nil
49
- if service_object && service_object.class.report_exceptions
50
- exc_response = protocol_request.protocol.marshal_exception(e) rescue nil
54
+ case service_dispatching_mode
55
+ when :direct
56
+ if self.class.report_exceptions
57
+ exc_response = protocol_request.protocol.marshal_exception(e)
58
+ end
59
+ when :delegated
60
+ service_object = service_object(protocol_request.service_name) rescue nil
61
+ if service_object && service_object.class.report_exceptions
62
+ exc_response = protocol_request.protocol.marshal_exception(e) rescue nil
63
+ end
51
64
  end
52
65
  if exc_response
53
66
  response_options = {
54
67
  :type => exc_response.content_type,
55
68
  :disposition => 'inline'
56
69
  }
70
+ log_response exc_response
57
71
  send_data(exc_response.raw_body, response_options)
58
72
  else
59
73
  render_text 'Internal protocol error', "500 #{e.message}"
@@ -1,11 +1,11 @@
1
- module ActionService
2
- module Router
3
- module Wsdl
4
- def self.append_features(base)
1
+ module ActionService # :nodoc:
2
+ module Router # :nodoc:
3
+ module Wsdl # :nodoc:
4
+ def self.append_features(base) # :nodoc:
5
5
  base.send(:include, ActionService::Router::Wsdl::InstanceMethods)
6
6
  end
7
7
 
8
- module InstanceMethods
8
+ module InstanceMethods # :nodoc:
9
9
  XsdNs = 'http://www.w3.org/2001/XMLSchema'
10
10
  WsdlNs = 'http://schemas.xmlsoap.org/wsdl/'
11
11
  SoapNs = 'http://schemas.xmlsoap.org/wsdl/soap/'
@@ -1,5 +1,21 @@
1
1
  module ActionService
2
+ # To send structured types across the wire, derive from ActionService::Struct,
3
+ # and use +member+ to declare structure members.
4
+ #
5
+ # === Example
6
+ #
7
+ # class Person < ActionService::Struct
8
+ # member :firstnames, [String]
9
+ # member :lastname, String
10
+ # member :email, String
11
+ # end
12
+ #
13
+ # Active Record model classes are already implicitly supported for return
14
+ # value signatures. A structure containing its columns as members will be
15
+ # automatically generated if its present in a signature.
2
16
  class Struct
17
+ # Creates a structure member accessible using +name+. Generates
18
+ # accessor methods for reading and writing the member value.
3
19
  def self.member(name, type)
4
20
  write_inheritable_hash("struct_members", name => type)
5
21
  class_eval <<-END
@@ -8,7 +24,7 @@ module ActionService
8
24
  END
9
25
  end
10
26
 
11
- def self.members
27
+ def self.members # :nodoc:
12
28
  read_inheritable_attribute("struct_members") || {}
13
29
  end
14
30
  end
@@ -1,4 +1,4 @@
1
- class Class
1
+ class Class # :nodoc:
2
2
  def class_inheritable_option(sym, default_value=nil)
3
3
  write_inheritable_attribute sym, default_value
4
4
  class_eval <<-EOS
@@ -4,7 +4,7 @@ require 'xmlrpc/create'
4
4
  require 'xmlrpc/config'
5
5
 
6
6
  module XMLRPC
7
- class XmlRpcHelper
7
+ class XmlRpcTestHelper
8
8
  include ParserWriterChooseMixin
9
9
 
10
10
  def create_request(methodName, *args)
@@ -18,6 +18,12 @@ module XMLRPC
18
18
  end
19
19
 
20
20
  module ProtocolXmlRpcTest
21
+ class Person < ActionService::Struct
22
+ member :firstname, String
23
+ member :lastname, String
24
+ member :active, TrueClass
25
+ end
26
+
21
27
  class Service < ActionService::Base
22
28
  attr :result
23
29
  attr :hashvalue
@@ -44,6 +50,14 @@ module ProtocolXmlRpcTest
44
50
  def hash_returner
45
51
  {'name' => 1, 'value' => 2}
46
52
  end
53
+
54
+ def struct_array_returner
55
+ person = Person.new
56
+ person.firstname = "John"
57
+ person.lastname = "Doe"
58
+ person.active = true
59
+ [person]
60
+ end
47
61
 
48
62
  def default(*args)
49
63
  @default_args = args
@@ -54,6 +68,7 @@ module ProtocolXmlRpcTest
54
68
  export :hash_returner, :returns => [Hash]
55
69
  export :array_returner, :returns => [[Integer]]
56
70
  export :something_hash, :expects => [Hash]
71
+ export :struct_array_returner, :returns => [[Person]]
57
72
 
58
73
  default_export :default
59
74
  end
@@ -81,7 +96,7 @@ end
81
96
 
82
97
  class TC_ProtocolXmlRpc < Test::Unit::TestCase
83
98
  def setup
84
- @helper = XMLRPC::XmlRpcHelper.new
99
+ @helper = XMLRPC::XmlRpcTestHelper.new
85
100
  @container = ProtocolXmlRpcTest::Container.new
86
101
  end
87
102
 
@@ -100,6 +115,11 @@ class TC_ProtocolXmlRpc < Test::Unit::TestCase
100
115
  assert(retval == [true, {'name' => 1, 'value' => 2}])
101
116
  end
102
117
 
118
+ def test_struct_array_returning
119
+ retval = do_xmlrpc_call('StructArrayReturner')
120
+ assert(retval == [true, [{"firstname"=>"John", "lastname"=>"Doe", "active"=>true}]])
121
+ end
122
+
103
123
  def test_hash_parameter
104
124
  retval = do_xmlrpc_call('SomethingHash', {'name' => 1, 'value' => 2})
105
125
  assert(retval == [true, true])
@@ -114,7 +134,7 @@ class TC_ProtocolXmlRpc < Test::Unit::TestCase
114
134
 
115
135
  def test_xmlrpc_introspection
116
136
  retval = do_xmlrpc_call('system.listMethods', 'test', [1, 2], {'name'=>'value'})
117
- assert(retval == [true, ["Add", "ArrayReturner", "HashReturner", "SomethingHash"]])
137
+ assert(retval == [true, ["Add", "ArrayReturner", "HashReturner", "SomethingHash", "StructArrayReturner"]])
118
138
  end
119
139
 
120
140
  private
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.4
3
3
  specification_version: 1
4
4
  name: actionservice
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.102
7
- date: 2005-02-12
6
+ version: 0.3.0
7
+ date: 2005-02-13
8
8
  summary: Web service support for Action Pack.
9
9
  require_paths:
10
10
  - lib
@@ -34,13 +34,16 @@ files:
34
34
  - HACKING
35
35
  - ChangeLog
36
36
  - MIT-LICENSE
37
- - examples/soap
38
- - examples/soap/lib
39
- - examples/soap/README
40
- - examples/soap/app
41
- - examples/soap/lib/google_search_service.rb
42
- - examples/soap/app/controllers
43
- - examples/soap/app/controllers/search_controller.rb
37
+ - examples/metaWeblog
38
+ - examples/googlesearch
39
+ - examples/metaWeblog/blog_controller.rb
40
+ - examples/metaWeblog/README
41
+ - examples/googlesearch/README
42
+ - examples/googlesearch/direct
43
+ - examples/googlesearch/delegated
44
+ - examples/googlesearch/direct/search_controller.rb
45
+ - examples/googlesearch/delegated/google_search_service.rb
46
+ - examples/googlesearch/delegated/search_controller.rb
44
47
  - lib/action_service
45
48
  - lib/action_service.rb
46
49
  - lib/action_service/protocol