Welcome to the "trac"-ing site of soap4r!
[soap4r] [httpclient] [openpgp4u] [pkcs1] [logger] [csv] [vtr]

root/branches/1_5/lib/wsdl/soap/classDefCreatorSupport.rb

Revision 2001, 5.7 kB (checked in by nahi, 1 year ago)
  • wsdl2ruby.rb did not generate proper definitions for overloaded method in WSDL. closes #446.
  • Property svn:eol-style set to native
  • Property svn:keywords set to author date id revision
Line 
1 # WSDL4R - Creating class code support from WSDL.
2 # Copyright (C) 2000-2007  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 'soap/mapping'
11 require 'soap/mapping/typeMap'
12 require 'xsd/codegen/gensupport'
13
14
15 module WSDL
16 module SOAP
17
18
19 # requires @defined_const, @simpletypes, @name_creator
20 module ClassDefCreatorSupport
21   include XSD::CodeGen::GenSupport
22
23   def mapped_class_name(qname, modulepath)
24     @name_creator.assign_name(qname, modulepath)
25   end
26
27   def mapped_class_basename(qname, modulepath)
28     classname = @name_creator.assign_name(qname, modulepath)
29     classname.sub(/\A.*:/, '')
30   end
31
32   def basetype_mapped_class(name)
33     ::SOAP::TypeMap[name]
34   end
35
36   def dump_method_signature(name, operation, element_definitions)
37     methodname = safemethodname(name)
38     input = operation.input
39     output = operation.output
40     fault = operation.fault
41     signature = "#{methodname}#{dump_inputparam(input)}"
42     str = <<__EOD__
43 # SYNOPSIS
44 #   #{methodname}#{dump_inputparam(input)}
45 #
46 # ARGS
47 #{dump_inout_type(input, element_definitions).chomp}
48 #
49 # RETURNS
50 #{dump_inout_type(output, element_definitions).chomp}
51 #
52 __EOD__
53     unless fault.empty?
54       str <<<<__EOD__
55 # RAISES
56 #{dump_fault_type(fault, element_definitions)}
57 #
58 __EOD__
59     end
60     str
61   end
62
63   def dq(ele)
64     ele.dump
65   end
66
67   def ndq(ele)
68     ele.nil? ? 'nil' : dq(ele)
69   end
70
71   def sym(ele)
72     ':' + ele.id2name
73   end
74
75   def nsym(ele)
76     ele.nil? ? 'nil' : sym(ele)
77   end
78
79   def dqname(qname)
80     if @defined_const.key?(qname.namespace)
81       qname.dump(@defined_const[qname.namespace])
82     else
83       qname.dump
84     end
85   end
86
87   def assign_const(value, prefix = '')
88     return if value.nil? or @defined_const.key?(value)
89     name = value.scan(/[^:\/]+\/?\z/)[0] || 'C'
90     tag = prefix + safeconstname(name)
91     if @defined_const.value?(tag)
92       idx = 0
93       while true
94         tag = prefix + safeconstname(name + "_#{idx}")
95         break unless @defined_const.value?(tag)
96         idx += 1
97         raise RuntimeError.new("too much similar names") if idx > 100
98       end
99     end
100     @defined_const[value] = tag
101   end
102
103   def create_type_name(modulepath, element)
104     if element.type == XSD::AnyTypeName
105       # nil means anyType.
106       nil
107     elsif simpletype = @simpletypes[element.type]
108       if simpletype.restriction and simpletype.restriction.enumeration?
109         mapped_class_name(element.type, modulepath)
110       else
111         nil
112       end
113     elsif klass = element_basetype(element)
114       klass.name
115     elsif element.type
116       mapped_class_name(element.type, modulepath)
117     elsif element.ref
118       mapped_class_name(element.ref, modulepath)
119     elsif element.anonymous_type?
120       # inner class
121       mapped_class_name(element.name, modulepath)
122     else
123       nil
124     end
125   end
126
127 private
128
129   def dump_inout_type(param, element_definitions)
130     if param
131       message = param.find_message
132       params = ""
133       message.parts.each do |part|
134         name = safevarname(part.name)
135         if part.type
136           typename = safeconstname(part.type.name)
137           qname = part.type
138           params << add_at("#   #{name}", "#{typename} - #{qname}\n", 20)
139         elsif part.element
140           ele = element_definitions[part.element]
141           if ele.type
142             typename = safeconstname(ele.type.name)
143             qname = ele.type
144           else
145             typename = safeconstname(ele.name.name)
146             qname = ele.name
147           end
148           params << add_at("#   #{name}", "#{typename} - #{qname}\n", 20)
149         end
150       end
151       unless params.empty?
152         return params
153       end
154     end
155     "#   N/A\n"
156   end
157
158   def dump_inputparam(input)
159     message = input.find_message
160     params = ""
161     message.parts.each do |part|
162       params << ", " unless params.empty?
163       params << safevarname(part.name)
164     end
165     if params.empty?
166       ""
167     else
168       "(#{ params })"
169     end
170   end
171
172   def add_at(base, str, pos)
173     if base.size >= pos
174       base + ' ' + str
175     else
176       base + ' ' * (pos - base.size) + str
177     end
178   end
179
180   def dump_fault_type(fault, element_definitions)
181     fault.collect { |ele|
182       dump_inout_type(ele, element_definitions).chomp
183     }.join("\n")
184   end
185
186   def element_basetype(ele)
187     if klass = basetype_class(ele.type)
188       klass
189     elsif ele.local_simpletype
190       basetype_class(ele.local_simpletype.base)
191     else
192       nil
193     end
194   end
195
196   def attribute_basetype(attr)
197     if klass = basetype_class(attr.type)
198       klass
199     elsif attr.local_simpletype
200       basetype_class(attr.local_simpletype.base)
201     else
202       nil
203     end
204   end
205
206   def basetype_class(type)
207     return nil if type.nil?
208     if simpletype = @simpletypes[type]
209       basetype_mapped_class(simpletype.base)
210     else
211       basetype_mapped_class(type)
212     end
213   end
214
215   def name_element(element)
216     return element.name if element.name
217     return element.ref if element.ref
218     raise RuntimeError.new("cannot define name of #{element}")
219   end
220
221   def name_attribute(attribute)
222     return attribute.name if attribute.name
223     return attribute.ref if attribute.ref
224     raise RuntimeError.new("cannot define name of #{attribute}")
225   end
226
227   # TODO: run MethodDefCreator just once in 1.6.X.
228   # MethodDefCreator should return parsed struct, not a String.
229   def collect_assigned_method(wsdl, porttypename, modulepath = nil)
230     name_creator = WSDL::SOAP::ClassNameCreator.new
231     methoddefcreator =
232       WSDL::SOAP::MethodDefCreator.new(wsdl, name_creator, modulepath, {})
233     methoddefcreator.dump(porttypename)
234     methoddefcreator.assigned_method
235   end
236 end
237
238
239 end
240 end
Note: See TracBrowser for help on using the browser.