class AdsCommon::Build::SavonRegistry
Contains the methods that extracts WSDL data.
Attributes
Public Class Methods
Initializes the instance.
Args:
-
wsdl: string containing wsdl to parse
-
options: variuos generation options
# File lib/ads_common/build/savon_registry.rb, line 41 def initialize(wsdl, options = {}) @options = options @default_namespace = options[:namespace] do_process_wsdl(wsdl) end
Private Instance Methods
Simple converter for boolean values.
# File lib/ads_common/build/savon_registry.rb, line 255 def attribute_to_boolean(attribute) return (attribute.nil?) ? nil : attribute.value.eql?('true') end
Simple converter for int values.
# File lib/ads_common/build/savon_registry.rb, line 248 def attribute_to_int(attribute) return nil if attribute.nil? return attribute.value.eql?('unbounded') ? :unbounded : attribute.value.to_i end
Includes exception into ordered_exceptions if not already there and makes sure its base is already included.
# File lib/ads_common/build/savon_registry.rb, line 268 def do_include_exception(exception) return if find_exception(exception, @ordered_exceptions) if exception[:base].nil? @ordered_exceptions.push(exception) else base = find_exception(exception[:base], @soap_exceptions) do_include_exception(base) @ordered_exceptions.push(exception) end end
Generate code for given Savon client.
# File lib/ads_common/build/savon_registry.rb, line 50 def do_process_wsdl(wsdl) @soap_exceptions = [] @soap_types = [] @soap_methods = [] @soap_namespaces = [] doc = REXML::Document.new(wsdl.xml) process_types(doc) process_methods(doc) sort_exceptions() end
Extracts all possible enumerations for a type and adds them as an `enumerations` key on the type.
# File lib/ads_common/build/savon_registry.rb, line 160 def extract_enumerations(type_element, type) REXML::XPath.each(type_element, "restriction[@base='xsd:string']") do |enum_node| type.delete(:fields) type[:type] = enum_node.attribute('base').to_s.gsub(/^.+:/, '') end REXML::XPath.each(type_element, "restriction[@base='xsd:string']/enumeration") do |enum_node| type[:enumerations] ||= [] type[:enumerations] << enum_node.attribute('value').to_s end return type end
Extracts exception parameters from ComplexTypes element.
# File lib/ads_common/build/savon_registry.rb, line 112 def extract_exception(exception_element) return {:name => get_element_name(exception_element), :doc => get_element_doc(exception_element), :base => get_element_base(exception_element), :fields => get_element_fields(exception_element)} end
Extracts input parameters of given method as an array.
# File lib/ads_common/build/savon_registry.rb, line 175 def extract_input_parameters(op_node, doc) op_name = get_element_name(op_node) return find_sequence_fields(op_name, doc) end
Extracts method parameters from ComplexTypes element.
# File lib/ads_common/build/savon_registry.rb, line 120 def extract_method(method_element, doc) name = get_element_name(method_element) method = { :name => name.snakecase, :input => extract_input_parameters(method_element, doc), :output => extract_output_parameters(method_element, doc) # This could be used to include documentation from wsdl. #:doc => get_element_doc(operation, 'wsdl') } original_name = get_original_name_if_needed(name) method[:original_name] = original_name unless original_name.nil? return method end
Extracts output parameter name and fields.
# File lib/ads_common/build/savon_registry.rb, line 181 def extract_output_parameters(op_node, doc) output_element = REXML::XPath.first(op_node, 'descendant::wsdl:output') output_name = get_element_name(output_element) output_fields = find_sequence_fields(output_name, doc) return {:name => output_name.snakecase, :fields => output_fields} end
Extracts definition of all types. If a non standard undefined type is found it process it recursively.
# File lib/ads_common/build/savon_registry.rb, line 136 def extract_type(type_element, ns_index) type = {:name => get_element_name(type_element), :fields => []} if attribute_to_boolean(type_element.attribute('abstract')) type[:abstract] = true end base_type = get_element_base(type_element) type[:base] = base_type if base_type type[:ns] = ns_index if ns_index REXML::XPath.each(type_element, 'sequence | complexContent/extension/sequence') do |seq_node| type[:fields] += get_element_fields(seq_node) end extract_enumerations(type_element, type) REXML::XPath.each(type_element, 'choice') do |seq_node| type[:choices] ||= [] type[:choices] += get_element_fields(seq_node) end return type end
Finds object (exception) by name attribute in a list.
# File lib/ads_common/build/savon_registry.rb, line 280 def find_exception(exception, list) list.each do |e| return e if (e.eql?(exception) || e[:name].eql?(exception)) end return nil end
Finds sequence fields for the element of given name.
# File lib/ads_common/build/savon_registry.rb, line 189 def find_sequence_fields(name, doc) result = [] doc.each_element_with_attribute('name', name, 0, '//schema/element') do |element_node| REXML::XPath.each(element_node, 'complexType/sequence') do |seq_node| result += get_element_fields(seq_node) end end return result end
Extracts ComplexTypes from node into an array.
# File lib/ads_common/build/savon_registry.rb, line 102 def get_complex_types(node) return REXML::XPath.each(node, 'complexType').to_a end
Gets element base defined as an attribute in sibling.
# File lib/ads_common/build/savon_registry.rb, line 206 def get_element_base(element) base_element = REXML::XPath.first(element, 'complexContent/extension') base = (base_element.nil?) ? nil : base_element.attribute('base').to_s.gsub(/^.+:/, '') return base end
Gets element documentation text.
# File lib/ads_common/build/savon_registry.rb, line 214 def get_element_doc(root, namespace = nil) key = 'documentation' key = "%s:%s" % [namespace, key] if namespace doc_element = REXML::XPath.first(root, "descendant::%s" % key) doc = (doc_element.nil?) ? '' : REXML::Text.unnormalize(doc_element.get_text.to_s) return doc end
Gets subfields defined as elements under given root.
# File lib/ads_common/build/savon_registry.rb, line 224 def get_element_fields(element) fields = [] REXML::XPath.each(element, 'descendant::element') do |item| name = get_element_name(item) original_name = get_original_name_if_needed(name) field = { :name => name.snakecase.to_sym, :original_name => original_name, :type => item.attribute('type').to_s.gsub(/^.+:/, ''), :min_occurs => attribute_to_int(item.attribute('minOccurs')), :max_occurs => attribute_to_int(item.attribute('maxOccurs'))} fields << field.reject {|k, v| v.nil?} end return fields end
Gets element name defined as its attribute.
# File lib/ads_common/build/savon_registry.rb, line 201 def get_element_name(element) return element.attribute('name').to_s end
Returns original name if it can not be back-converted and required for XML serialization.
# File lib/ads_common/build/savon_registry.rb, line 242 def get_original_name_if_needed(name) return (name.nil? || (name.snakecase.lower_camelcase == name)) ? nil : name end
Extracts SimpleTypes from node into an array.
# File lib/ads_common/build/savon_registry.rb, line 107 def get_simple_types(node) return REXML::XPath.each(node, 'simpleType').to_a end
Extracts SOAP actions as methods.
# File lib/ads_common/build/savon_registry.rb, line 94 def process_methods(doc) iface = REXML::XPath.first(doc, 'descendant::wsdl:portType') REXML::XPath.each(iface, 'descendant::wsdl:operation') do |operation| @soap_methods << extract_method(operation, doc) end end
Returns index of namespace for given schema. Adds namespace to internal array if not yet present. Returns nil for service default namespace.
# File lib/ads_common/build/savon_registry.rb, line 80 def process_namespace(schema) namespace_url = schema.attribute('targetNamespace').value unless namespace_url == @default_namespace ns_index = @soap_namespaces.index(namespace_url) if ns_index.nil? ns_index = @soap_namespaces.length @soap_namespaces << namespace_url end return ns_index end return nil end
Extracts different types from XML.
# File lib/ads_common/build/savon_registry.rb, line 63 def process_types(doc) REXML::XPath.each(doc, '//schema') do |schema| ns_index = process_namespace(schema) complex_types = get_complex_types(schema) simple_types = get_simple_types(schema) (complex_types + simple_types).each do |ctype| ctype_name = get_element_name(ctype) @soap_types << extract_type(ctype, ns_index) if ctype_name.match('.+Exception$') @soap_exceptions << extract_exception(ctype) end end end end
Reorders exceptions so that base ones always come before derived.
# File lib/ads_common/build/savon_registry.rb, line 260 def sort_exceptions() @ordered_exceptions = [] @soap_exceptions.each {|exception| do_include_exception(exception)} @soap_exceptions = @ordered_exceptions end