~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to lib/wsdl/soap/methodDefCreator.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# WSDL4R - Creating driver code from WSDL.
 
2
# Copyright (C) 2002, 2003, 2005  NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
 
3
 
 
4
# This program is copyrighted free software by NAKAMURA, Hiroshi.  You can
 
5
# redistribute it and/or modify it under the same terms of Ruby's license;
 
6
# either the dual license version in 2003, or any later version.
 
7
 
 
8
 
 
9
require 'wsdl/info'
 
10
require 'wsdl/soap/classDefCreatorSupport'
 
11
require 'soap/rpc/element'
 
12
 
 
13
 
 
14
module WSDL
 
15
module SOAP
 
16
 
 
17
 
 
18
class MethodDefCreator
 
19
  include ClassDefCreatorSupport
 
20
 
 
21
  attr_reader :definitions
 
22
 
 
23
  def initialize(definitions)
 
24
    @definitions = definitions
 
25
    @simpletypes = @definitions.collect_simpletypes
 
26
    @complextypes = @definitions.collect_complextypes
 
27
    @elements = @definitions.collect_elements
 
28
    @types = []
 
29
  end
 
30
 
 
31
  def dump(porttype)
 
32
    @types.clear
 
33
    result = ""
 
34
    operations = @definitions.porttype(porttype).operations
 
35
    binding = @definitions.porttype_binding(porttype)
 
36
    operations.each do |operation|
 
37
      op_bind = binding.operations[operation.name]
 
38
      next unless op_bind # no binding is defined
 
39
      next unless op_bind.soapoperation # not a SOAP operation binding
 
40
      result << ",\n" unless result.empty?
 
41
      result << dump_method(operation, op_bind).chomp
 
42
    end
 
43
    return result, @types
 
44
  end
 
45
 
 
46
  def collect_rpcparameter(operation)
 
47
    result = operation.inputparts.collect { |part|
 
48
      collect_type(part.type)
 
49
      param_set(::SOAP::RPC::SOAPMethod::IN, part.name, rpcdefinedtype(part))
 
50
    }
 
51
    outparts = operation.outputparts
 
52
    if outparts.size > 0
 
53
      retval = outparts[0]
 
54
      collect_type(retval.type)
 
55
      result << param_set(::SOAP::RPC::SOAPMethod::RETVAL, retval.name,
 
56
        rpcdefinedtype(retval))
 
57
      cdr(outparts).each { |part|
 
58
        collect_type(part.type)
 
59
        result << param_set(::SOAP::RPC::SOAPMethod::OUT, part.name,
 
60
          rpcdefinedtype(part))
 
61
      }
 
62
    end
 
63
    result
 
64
  end
 
65
 
 
66
  def collect_documentparameter(operation)
 
67
    param = []
 
68
    operation.inputparts.each do |input|
 
69
      param << param_set(::SOAP::RPC::SOAPMethod::IN, input.name,
 
70
        documentdefinedtype(input), elementqualified(input))
 
71
    end
 
72
    operation.outputparts.each do |output|
 
73
      param << param_set(::SOAP::RPC::SOAPMethod::OUT, output.name,
 
74
        documentdefinedtype(output), elementqualified(output))
 
75
    end
 
76
    param
 
77
  end
 
78
 
 
79
private
 
80
 
 
81
  def dump_method(operation, binding)
 
82
    name = safemethodname(operation.name.name)
 
83
    name_as = operation.name.name
 
84
    style = binding.soapoperation_style
 
85
    inputuse = binding.input.soapbody_use
 
86
    outputuse = binding.output.soapbody_use
 
87
    namespace = binding.input.soapbody.namespace
 
88
    if style == :rpc
 
89
      qname = XSD::QName.new(namespace, name_as)
 
90
      paramstr = param2str(collect_rpcparameter(operation))
 
91
    else
 
92
      qname = nil
 
93
      paramstr = param2str(collect_documentparameter(operation))
 
94
    end
 
95
    if paramstr.empty?
 
96
      paramstr = '[]'
 
97
    else
 
98
      paramstr = "[ " << paramstr.split(/\r?\n/).join("\n    ") << " ]"
 
99
    end
 
100
    definitions = <<__EOD__
 
101
#{ndq(binding.soapaction)},
 
102
  #{dq(name)},
 
103
  #{paramstr},
 
104
  { :request_style =>  #{sym(style.id2name)}, :request_use =>  #{sym(inputuse.id2name)},
 
105
    :response_style => #{sym(style.id2name)}, :response_use => #{sym(outputuse.id2name)} }
 
106
__EOD__
 
107
    if style == :rpc
 
108
      return <<__EOD__
 
109
[ #{qname.dump},
 
110
  #{definitions}]
 
111
__EOD__
 
112
    else
 
113
      return <<__EOD__
 
114
[ #{definitions}]
 
115
__EOD__
 
116
    end
 
117
  end
 
118
 
 
119
  def rpcdefinedtype(part)
 
120
    if mapped = basetype_mapped_class(part.type)
 
121
      ['::' + mapped.name]
 
122
    elsif definedtype = @simpletypes[part.type]
 
123
      ['::' + basetype_mapped_class(definedtype.base).name]
 
124
    elsif definedtype = @elements[part.element]
 
125
      #['::SOAP::SOAPStruct', part.element.namespace, part.element.name]
 
126
      ['nil', part.element.namespace, part.element.name]
 
127
    elsif definedtype = @complextypes[part.type]
 
128
      case definedtype.compoundtype
 
129
      when :TYPE_STRUCT, :TYPE_EMPTY    # ToDo: empty should be treated as void.
 
130
        type = create_class_name(part.type)
 
131
        [type, part.type.namespace, part.type.name]
 
132
      when :TYPE_MAP
 
133
        [Hash.name, part.type.namespace, part.type.name]
 
134
      when :TYPE_ARRAY
 
135
        arytype = definedtype.find_arytype || XSD::AnyTypeName
 
136
        ns = arytype.namespace
 
137
        name = arytype.name.sub(/\[(?:,)*\]$/, '')
 
138
        type = create_class_name(XSD::QName.new(ns, name))
 
139
        [type + '[]', ns, name]
 
140
      else
 
141
        raise NotImplementedError.new("must not reach here")
 
142
      end
 
143
    else
 
144
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
 
145
    end
 
146
  end
 
147
 
 
148
  def documentdefinedtype(part)
 
149
    if mapped = basetype_mapped_class(part.type)
 
150
      ['::' + mapped.name, nil, part.name]
 
151
    elsif definedtype = @simpletypes[part.type]
 
152
      ['::' + basetype_mapped_class(definedtype.base).name, nil, part.name]
 
153
    elsif definedtype = @elements[part.element]
 
154
      ['::SOAP::SOAPElement', part.element.namespace, part.element.name]
 
155
    elsif definedtype = @complextypes[part.type]
 
156
      ['::SOAP::SOAPElement', part.type.namespace, part.type.name]
 
157
    else
 
158
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
 
159
    end
 
160
  end
 
161
 
 
162
  def elementqualified(part)
 
163
    if mapped = basetype_mapped_class(part.type)
 
164
      false
 
165
    elsif definedtype = @simpletypes[part.type]
 
166
      false
 
167
    elsif definedtype = @elements[part.element]
 
168
      definedtype.elementform == 'qualified'
 
169
    elsif definedtype = @complextypes[part.type]
 
170
      false
 
171
    else
 
172
      raise RuntimeError.new("part: #{part.name} cannot be resolved")
 
173
    end
 
174
  end
 
175
 
 
176
  def param_set(io_type, name, type, ele = nil)
 
177
    [io_type, name, type, ele]
 
178
  end
 
179
 
 
180
  def collect_type(type)
 
181
    # ignore inline type definition.
 
182
    return if type.nil?
 
183
    return if @types.include?(type)
 
184
    @types << type
 
185
    return unless @complextypes[type]
 
186
    @complextypes[type].each_element do |element|
 
187
      collect_type(element.type)
 
188
    end
 
189
  end
 
190
 
 
191
  def param2str(params)
 
192
    params.collect { |param|
 
193
      io, name, type, ele = param
 
194
      unless ele.nil?
 
195
        "[#{dq(io)}, #{dq(name)}, #{type2str(type)}, #{ele2str(ele)}]"
 
196
      else
 
197
        "[#{dq(io)}, #{dq(name)}, #{type2str(type)}]"
 
198
      end
 
199
    }.join(",\n")
 
200
  end
 
201
 
 
202
  def type2str(type)
 
203
    if type.size == 1
 
204
      "[#{dq(type[0])}]" 
 
205
    else
 
206
      "[#{dq(type[0])}, #{ndq(type[1])}, #{dq(type[2])}]" 
 
207
    end
 
208
  end
 
209
 
 
210
  def ele2str(ele)
 
211
    qualified = ele
 
212
    if qualified
 
213
      "true"
 
214
    else
 
215
      "false"
 
216
    end
 
217
  end
 
218
 
 
219
  def cdr(ary)
 
220
    result = ary.dup
 
221
    result.shift
 
222
    result
 
223
  end
 
224
end
 
225
 
 
226
 
 
227
end
 
228
end