actionservice 0.2.102 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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