require "nokogiri" require "wasabi/parser" module Wasabi # = Wasabi::Document # # Represents a WSDL document. class Document ELEMENT_FORM_DEFAULTS = [:unqualified, :qualified] # Validates if a given +value+ is a valid elementFormDefault value. # Raises an +ArgumentError+ if the value is not valid. def self.validate_element_form_default!(value) return if ELEMENT_FORM_DEFAULTS.include?(value) raise ArgumentError, "Invalid value for elementFormDefault: #{value}\n" + "Must be one of: #{ELEMENT_FORM_DEFAULTS.inspect}" end # Accepts a WSDL +document+ to parse. def initialize(document = nil) self.document = document end attr_accessor :document # Returns whether a +document+ was set. def document? !!document end # Returns the SOAP endpoint. def endpoint @endpoint ||= parser.endpoint end # Sets the SOAP endpoint. attr_writer :endpoint # Returns the target namespace. def namespace @namespace ||= parser.namespace end # Sets the target namespace. attr_writer :namespace # Returns the value of elementFormDefault. def element_form_default @element_form_default ||= xml? ? parser.element_form_default : :unqualified end # Sets the elementFormDefault value. def element_form_default=(value) self.class.validate_element_form_default!(value) @element_form_default = value end # Returns a list of available SOAP actions. def soap_actions @soap_actions ||= parser.operations.keys end # Returns the SOAP action for a given +key+. def soap_action(key) operations[key][:action] if operations[key] end # Returns the SOAP input for a given +key+. def soap_input(key) operations[key][:input] if operations[key] end # Returns a map of SOAP operations. def operations @operations ||= parser.operations end def type_namespaces @type_namespaces ||= begin namespaces = [] parser.types.each do |type, info| namespaces << [[type], info[:namespace]] (info.keys - [:namespace]).each { |field| namespaces << [[type, field], info[:namespace]] } end if document? namespaces end end def type_definitions @type_definitions ||= begin result = [] parser.types.each do |type, info| (info.keys - [:namespace]).each do |field| field_type = info[field][:type] tag, namespace = field_type.split(":").reverse result << [[type, field], tag] if user_defined(namespace) end end if document? result end end # Returns whether the given +namespace+ was defined manually. def user_defined(namespace) uri = parser.namespaces[namespace] !(uri =~ %r{^http://schemas.xmlsoap.org} || uri =~ %r{^http://www.w3.org}) end # Returns the raw WSDL document. # Can be used as a hook to extend the library. def xml @xml ||= document end # Returns whether there is a WSDL document to parse. def xml? xml.kind_of?(String) end # Parses the WSDL document and returns the Wasabi::Parser. def parser @parser ||= guard_parse && parse end private # Raises an error if the WSDL document is missing. def guard_parse return true if xml? raise ArgumentError, "Wasabi needs a WSDL document" end # Parses the WSDL document and returns Wasabi::Parser. def parse parser = Parser.new Nokogiri::XML(xml) parser.parse parser end end end