aboutsummaryrefslogtreecommitdiffstats
path: root/lib/wsdl
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-07-03 13:33:20 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-07-03 13:33:20 +0000
commitdf731e37a1953755edfedd1462995fa824ca22bf (patch)
tree38a98e1b29b3784843ad079fa003790c8f352f58 /lib/wsdl
parent0d6fa996d9e842fe435308cef68df06bc3596a76 (diff)
downloadruby-df731e37a1953755edfedd1462995fa824ca22bf.tar.gz
* added files:
* lib/soap/header/* * lib/soap/rpc/httpserver.rb * lib/wsdl/soap/cgiStubCreator.rb * lib/wsdl/soap/classDefCreator.rb * lib/wsdl/soap/classDefCreatorSupport.rb * lib/wsdl/soap/clientSkeltonCreator.rb * lib/wsdl/soap/driverCreator.rb * lib/wsdl/soap/mappingRegistryCreator.rb * lib/wsdl/soap/methodDefCreator.rb * lib/wsdl/soap/servantSkeltonCreator.rb * lib/wsdl/soap/standaloneServerStubCreator.rb * lib/wsdl/xmlSchema/enumeration.rb * lib/wsdl/xmlSchema/simpleRestriction.rb * lib/wsdl/xmlSchema/simpleType.rb * lib/xsd/codegen/* * lib/xsd/codegen.rb * sample/soap/authheader/* * sample/soap/raa2.4/* * sample/soap/ssl/* * sample/soap/swa/* * sample/soap/whois.rb * sample/wsdl/raa2.4/* * test/soap/header/* * test/soap/ssl/* * test/soap/struct/* * test/soap/swa/* * test/soap/wsdlDriver/* * test/wsdl/multiplefault.wsdl * test/wsdl/simpletype/* * test/wsdl/test_multiplefault.rb * modified files: * lib/soap/baseData.rb * lib/soap/element.rb * lib/soap/generator.rb * lib/soap/netHttpClient.rb * lib/soap/parser.rb * lib/soap/property.rb * lib/soap/soap.rb * lib/soap/streamHandler.rb * lib/soap/wsdlDriver.rb * lib/soap/wsdlDriver.rb * lib/soap/encodingstyle/handler.rb * lib/soap/encodingstyle/literalHandler.rb * lib/soap/encodingstyle/soapHandler.rb * lib/soap/mapping/factory.rb * lib/soap/mapping/mapping.rb * lib/soap/mapping/registry.rb * lib/soap/mapping/rubytypeFactory.rb * lib/soap/mapping/wsdlRegistry.rb * lib/soap/rpc/cgistub.rb * lib/soap/rpc/driver.rb * lib/soap/rpc/proxy.rb * lib/soap/rpc/router.rb * lib/soap/rpc/soaplet.rb * lib/soap/rpc/standaloneServer.rb * lib/wsdl/data.rb * lib/wsdl/definitions.rb * lib/wsdl/operation.rb * lib/wsdl/parser.rb * lib/wsdl/soap/definitions.rb * lib/wsdl/xmlSchema/complexContent.rb * lib/wsdl/xmlSchema/complexType.rb * lib/wsdl/xmlSchema/data.rb * lib/wsdl/xmlSchema/parser.rb * lib/wsdl/xmlSchema/schema.rb * lib/xsd/datatypes.rb * lib/xsd/qname.rb * sample/soap/sampleStruct/server.rb * sample/wsdl/amazon/AmazonSearch.rb * sample/wsdl/amazon/AmazonSearchDriver.rb * test/soap/test_property.rb * test/soap/calc/test_calc_cgi.rb * test/wsdl/test_emptycomplextype.rb * summary * add SOAP Header mustUnderstand support. * add HTTP client SSL configuration and Cookies support (works completely with http-access2). * add header handler for handling sending/receiving SOAP Header. * map Ruby's anonymous Struct to common SOAP Struct in SOAP Object Model. it caused error. * add WSDL simpleType support to restrict lexical value space. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6565 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/wsdl')
-rw-r--r--lib/wsdl/data.rb1
-rw-r--r--lib/wsdl/definitions.rb21
-rw-r--r--lib/wsdl/operation.rb2
-rw-r--r--lib/wsdl/parser.rb3
-rw-r--r--lib/wsdl/soap/cgiStubCreator.rb73
-rw-r--r--lib/wsdl/soap/classDefCreator.rb112
-rw-r--r--lib/wsdl/soap/classDefCreatorSupport.rb106
-rw-r--r--lib/wsdl/soap/clientSkeltonCreator.rb78
-rw-r--r--lib/wsdl/soap/definitions.rb28
-rw-r--r--lib/wsdl/soap/driverCreator.rb84
-rw-r--r--lib/wsdl/soap/mappingRegistryCreator.rb90
-rw-r--r--lib/wsdl/soap/methodDefCreator.rb148
-rw-r--r--lib/wsdl/soap/servantSkeltonCreator.rb65
-rw-r--r--lib/wsdl/soap/standaloneServerStubCreator.rb79
-rw-r--r--lib/wsdl/xmlSchema/complexContent.rb4
-rw-r--r--lib/wsdl/xmlSchema/complexType.rb22
-rw-r--r--lib/wsdl/xmlSchema/data.rb7
-rw-r--r--lib/wsdl/xmlSchema/enumeration.rb36
-rw-r--r--lib/wsdl/xmlSchema/parser.rb3
-rw-r--r--lib/wsdl/xmlSchema/schema.rb13
-rw-r--r--lib/wsdl/xmlSchema/simpleRestriction.rb48
-rw-r--r--lib/wsdl/xmlSchema/simpleType.rb81
22 files changed, 1090 insertions, 14 deletions
diff --git a/lib/wsdl/data.rb b/lib/wsdl/data.rb
index 8a14dd14d7..45eaad8526 100644
--- a/lib/wsdl/data.rb
+++ b/lib/wsdl/data.rb
@@ -6,6 +6,7 @@
# either the dual license version in 2003, or any later version.
+require 'xsd/qname'
require 'wsdl/documentation'
require 'wsdl/definitions'
require 'wsdl/types'
diff --git a/lib/wsdl/definitions.rb b/lib/wsdl/definitions.rb
index 561a335744..c530220fde 100644
--- a/lib/wsdl/definitions.rb
+++ b/lib/wsdl/definitions.rb
@@ -43,8 +43,7 @@ class Definitions < Info
end
def inspect
- name = @name || '(unnamed)'
- "#<#{self.class}:#{name}>"
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__, @name || '(unnamed)')
end
def targetnamespace=(targetnamespace)
@@ -58,7 +57,7 @@ class Definitions < Info
result = XSD::NamedElements.new
if @types
@types.schemas.each do |schema|
- result.concat(schema.elements)
+ result.concat(schema.collect_elements)
end
end
@imports.each do |import|
@@ -71,7 +70,7 @@ class Definitions < Info
result = @anontypes.dup
if @types
@types.schemas.each do |schema|
- result.concat(schema.complextypes)
+ result.concat(schema.collect_complextypes)
end
end
@imports.each do |import|
@@ -80,6 +79,20 @@ class Definitions < Info
result
end
+ def collect_simpletypes
+ result = XSD::NamedElements.new
+ if @types
+ @types.schemas.each do |schema|
+ result.concat(schema.collect_simpletypes)
+ end
+ end
+ @imports.each do |import|
+ result.concat(import.content.collect_simpletypes)
+ end
+ result
+ end
+
+ # ToDo: simpletype must be accepted...
def add_type(complextype)
@anontypes << complextype
end
diff --git a/lib/wsdl/operation.rb b/lib/wsdl/operation.rb
index 228dc85b05..be28446d34 100644
--- a/lib/wsdl/operation.rb
+++ b/lib/wsdl/operation.rb
@@ -119,7 +119,7 @@ private
return parts.dup
end
if parts.length != result.length
- raise RuntimeError.new("Incomplete parameter order list.")
+ raise RuntimeError.new("Incomplete prarmeterOrder list.")
end
result
end
diff --git a/lib/wsdl/parser.rb b/lib/wsdl/parser.rb
index 7e7a4d8bce..6387911f79 100644
--- a/lib/wsdl/parser.rb
+++ b/lib/wsdl/parser.rb
@@ -119,7 +119,8 @@ private
STDERR.puts("Unknown element #{ element }.")
o = Documentation.new # which accepts any element.
end
- o.parent = parent
+ # node could be a pseudo element. pseudo element has its own parent.
+ o.parent = parent if o.parent.nil?
end
attrs.each do |key, value|
attr = unless /:/ =~ key
diff --git a/lib/wsdl/soap/cgiStubCreator.rb b/lib/wsdl/soap/cgiStubCreator.rb
new file mode 100644
index 0000000000..e5b64336e7
--- /dev/null
+++ b/lib/wsdl/soap/cgiStubCreator.rb
@@ -0,0 +1,73 @@
+# WSDL4R - Creating CGI stub code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/mappingRegistryCreator'
+require 'wsdl/soap/methodDefCreator'
+require 'wsdl/soap/classDefCreatorSupport'
+
+
+module WSDL
+module SOAP
+
+
+class CGIStubCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ end
+
+ def dump(service_name)
+ STDERR.puts "!!! IMPORTANT !!!"
+ STDERR.puts "- CGI stub can only 1 port. Creating stub for the first port... Rests are ignored."
+ STDERR.puts "!!! IMPORTANT !!!"
+ port = @definitions.service(service_name).ports[0]
+ dump_porttype(port.porttype.name)
+ end
+
+private
+
+ def dump_porttype(name)
+ class_name = create_class_name(name)
+ methoddef, types = MethodDefCreator.new(@definitions).dump(name)
+ mr_creator = MappingRegistryCreator.new(@definitions)
+ c1 = ::XSD::CodeGen::ClassDef.new(class_name)
+ c1.def_require("soap/rpc/cgistub")
+ c1.def_require("soap/mapping/registry")
+ c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
+ c1.def_code(mr_creator.dump(types))
+ c1.def_code <<-EOD
+Methods = [
+#{ methoddef.gsub(/^/, " ") }
+]
+ EOD
+ c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App",
+ "::SOAP::RPC::CGIStub")
+ c2.def_method("initialize", "*arg") do
+ <<-EOD
+ super(*arg)
+ servant = #{class_name}.new
+ #{class_name}::Methods.each do |name_as, name, params, soapaction, ns|
+ add_method_with_namespace_as(ns, servant, name, name_as, params, soapaction)
+ end
+ self.mapping_registry = #{class_name}::MappingRegistry
+ self.level = Logger::Severity::ERROR
+ EOD
+ end
+ c1.dump + "\n" + c2.dump + format(<<-EOD)
+ #{class_name}App.new('app', nil).start
+ EOD
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/classDefCreator.rb b/lib/wsdl/soap/classDefCreator.rb
new file mode 100644
index 0000000000..6c7d381932
--- /dev/null
+++ b/lib/wsdl/soap/classDefCreator.rb
@@ -0,0 +1,112 @@
+# WSDL4R - Creating class definition from WSDL
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/data'
+require 'wsdl/soap/classDefCreatorSupport'
+require 'xsd/codegen'
+
+
+module WSDL
+module SOAP
+
+
+class ClassDefCreator
+ include ClassDefCreatorSupport
+
+ def initialize(definitions)
+ @simpletypes = definitions.collect_simpletypes
+ @complextypes = definitions.collect_complextypes
+ @faulttypes = definitions.collect_faulttypes
+ end
+
+ def dump(class_name = nil)
+ result = ""
+ if class_name
+ result = dump_classdef(class_name)
+ else
+ @complextypes.each do |type|
+ case type.compoundtype
+ when :TYPE_STRUCT
+ result << dump_classdef(type)
+ when :TYPE_ARRAY
+ result << dump_arraydef(type)
+ else
+ raise RuntimeError.new("Unknown complexContent definition...")
+ end
+ result << "\n"
+ end
+
+ result << @simpletypes.collect { |type|
+ dump_simpletypedef(type)
+ }.join("\n")
+ end
+ result
+ end
+
+private
+
+ def dump_simpletypedef(simpletype)
+ qname = simpletype.name
+ if simpletype.restriction.enumeration.empty?
+ STDERR.puts("#{qname}: simpleType which is not enum type not supported.")
+ return ""
+ end
+ c = XSD::CodeGen::ModuleDef.new(create_class_name(qname))
+ c.comment = "#{ qname.namespace }"
+ simpletype.restriction.enumeration.each do |value|
+ c.def_const(safeconstname(value), value.dump)
+ end
+ c.dump
+ end
+
+ def dump_classdef(complextype)
+ qname = complextype.name
+ if @faulttypes.index(qname)
+ c = XSD::CodeGen::ClassDef.new(create_class_name(qname),
+ "::StandardError")
+ else
+ c = XSD::CodeGen::ClassDef.new(create_class_name(qname))
+ end
+ c.comment = "#{ qname.namespace }"
+ c.def_classvar("schema_type", qname.name.dump)
+ c.def_classvar("schema_ns", qname.namespace.dump)
+ init_lines = ""
+ params = []
+ complextype.each_element do |element|
+ name = element.name.name
+ varname = safevarname(name)
+ c.def_attr(name, true, varname)
+ init_lines << "@#{ varname } = #{ varname }\n"
+ params << "#{ varname } = nil"
+ end
+ complextype.attributes.each do |attribute|
+ name = "attr_" + attribute.name
+ varname = safevarname(name)
+ c.def_attr(name, true, varname)
+ init_lines << "@#{ varname } = #{ varname }\n"
+ params << "#{ varname } = nil"
+ end
+ c.def_method("initialize", *params) do
+ init_lines
+ end
+ c.dump
+ end
+
+ def dump_arraydef(complextype)
+ qname = complextype.name
+ c = XSD::CodeGen::ClassDef.new(create_class_name(qname), "::Array")
+ c.comment = "#{ qname.namespace }"
+ c.def_classvar("schema_type", qname.name.dump)
+ c.def_classvar("schema_ns", qname.namespace.dump)
+ c.dump
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/classDefCreatorSupport.rb b/lib/wsdl/soap/classDefCreatorSupport.rb
new file mode 100644
index 0000000000..dbcc55f7b9
--- /dev/null
+++ b/lib/wsdl/soap/classDefCreatorSupport.rb
@@ -0,0 +1,106 @@
+# WSDL4R - Creating class code support from WSDL.
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'soap/mapping'
+require 'soap/mapping/typeMap'
+require 'xsd/codegen/gensupport'
+
+
+module WSDL
+module SOAP
+
+
+module ClassDefCreatorSupport
+ include XSD::CodeGen::GenSupport
+
+ def create_class_name(qname)
+ if klass = basetype_mapped_class(qname)
+ ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass.name)
+ else
+ safeconstname(qname.name)
+ end
+ end
+
+ def basetype_mapped_class(name)
+ ::SOAP::TypeMap[name]
+ end
+
+ def dump_method_signature(operation)
+ name = operation.name.name
+ input = operation.input
+ output = operation.output
+ fault = operation.fault
+ signature = "#{ name }#{ dump_inputparam(input) }"
+ str = <<__EOD__
+# SYNOPSIS
+# #{name}#{dump_inputparam(input)}
+#
+# ARGS
+#{dump_inout_type(input).chomp}
+#
+# RETURNS
+#{dump_inout_type(output).chomp}
+#
+__EOD__
+ unless fault.empty?
+ faultstr = (fault.collect { |f| dump_inout_type(f).chomp }).join(', ')
+ str <<<<__EOD__
+# RAISES
+# #{faultstr}
+#
+__EOD__
+ end
+ str
+ end
+
+private
+
+ def dump_inout_type(param)
+ if param
+ message = param.find_message
+ params = ""
+ message.parts.each do |part|
+ next unless part.type
+ name = safevarname(part.name)
+ typename = safeconstname(part.type.name)
+ params << add_at("# #{name}", "#{typename} - #{part.type}\n", 20)
+ end
+ unless params.empty?
+ return params
+ end
+ end
+ "# N/A\n"
+ end
+
+ def dump_inputparam(input)
+ message = input.find_message
+ params = ""
+ message.parts.each do |part|
+ params << ", " unless params.empty?
+ params << safevarname(part.name)
+ end
+ if params.empty?
+ ""
+ else
+ "(#{ params })"
+ end
+ end
+
+ def add_at(base, str, pos)
+ if base.size >= pos
+ base + ' ' + str
+ else
+ base + ' ' * (pos - base.size) + str
+ end
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/clientSkeltonCreator.rb b/lib/wsdl/soap/clientSkeltonCreator.rb
new file mode 100644
index 0000000000..9c538dd612
--- /dev/null
+++ b/lib/wsdl/soap/clientSkeltonCreator.rb
@@ -0,0 +1,78 @@
+# WSDL4R - Creating client skelton code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/classDefCreatorSupport'
+
+
+module WSDL
+module SOAP
+
+
+class ClientSkeltonCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ end
+
+ def dump(service_name)
+ result = ""
+ @definitions.service(service_name).ports.each do |port|
+ result << dump_porttype(port.porttype.name)
+ result << "\n"
+ end
+ result
+ end
+
+private
+
+ def dump_porttype(name)
+ drv_name = create_class_name(name)
+
+ result = ""
+ result << <<__EOD__
+endpoint_url = ARGV.shift
+obj = #{ drv_name }.new(endpoint_url)
+
+# Uncomment the below line to see SOAP wiredumps.
+# obj.wiredump_dev = STDERR
+
+__EOD__
+ @definitions.porttype(name).operations.each do |operation|
+ result << dump_method_signature(operation)
+ result << dump_input_init(operation.input) << "\n"
+ result << dump_operation(operation) << "\n\n"
+ end
+ result
+ end
+
+ def dump_operation(operation)
+ name = operation.name
+ input = operation.input
+ "puts obj.#{ safemethodname(name.name) }#{ dump_inputparam(input) }"
+ end
+
+ def dump_input_init(input)
+ result = input.find_message.parts.collect { |part|
+ "#{ uncapitalize(part.name) }"
+ }.join(" = ")
+ if result.empty?
+ ""
+ else
+ result << " = nil"
+ end
+ result
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/definitions.rb b/lib/wsdl/soap/definitions.rb
index 7a62242204..2f6e7e19f0 100644
--- a/lib/wsdl/soap/definitions.rb
+++ b/lib/wsdl/soap/definitions.rb
@@ -75,8 +75,36 @@ class Definitions < Info
types + self.class.soap_rpc_complextypes
end
+ def collect_faulttypes
+ result = []
+ collect_fault_messages.each do |message|
+ parts = message(message).parts
+ if parts.size != 1
+ raise RuntimeError.new("Expecting fault message to have only 1 part.")
+ end
+ if result.index(parts[0].type).nil?
+ result << parts[0].type
+ end
+ end
+ result
+ end
+
private
+ def collect_fault_messages
+ result = []
+ porttypes.each do |porttype|
+ porttype.operations.each do |operation|
+ operation.fault.each do |fault|
+ if result.index(fault.message).nil?
+ result << fault.message
+ end
+ end
+ end
+ end
+ result
+ end
+
def rpc_operation_complextypes(binding)
types = XSD::NamedElements.new
binding.operations.each do |op_bind|
diff --git a/lib/wsdl/soap/driverCreator.rb b/lib/wsdl/soap/driverCreator.rb
new file mode 100644
index 0000000000..50be8ed1dc
--- /dev/null
+++ b/lib/wsdl/soap/driverCreator.rb
@@ -0,0 +1,84 @@
+# WSDL4R - Creating driver code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/mappingRegistryCreator'
+require 'wsdl/soap/methodDefCreator'
+require 'wsdl/soap/classDefCreatorSupport'
+require 'xsd/codegen'
+
+
+module WSDL
+module SOAP
+
+
+class DriverCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ end
+
+ def dump(porttype = nil)
+ if porttype.nil?
+ result = ""
+ @definitions.porttypes.each do |type|
+ result << dump_porttype(type.name)
+ result << "\n"
+ end
+ else
+ result = dump_porttype(porttype)
+ end
+ result
+ end
+
+private
+
+ def dump_porttype(name)
+ class_name = create_class_name(name)
+ methoddef, types = MethodDefCreator.new(@definitions).dump(name)
+ mr_creator = MappingRegistryCreator.new(@definitions)
+ binding = @definitions.bindings.find { |item| item.type == name }
+ addresses = @definitions.porttype(name).locations
+
+ c = ::XSD::CodeGen::ClassDef.new(class_name, "::SOAP::RPC::Driver")
+ c.def_require("soap/rpc/driver")
+ c.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
+ c.def_const("DefaultEndpointUrl", addresses[0].dump)
+ c.def_code(mr_creator.dump(types))
+ c.def_code <<-EOD
+Methods = [
+#{ methoddef.gsub(/^/, " ") }
+]
+ EOD
+ c.def_method("initialize", "endpoint_url = nil") do
+ <<-EOD
+ endpoint_url ||= DefaultEndpointUrl
+ super(endpoint_url, nil)
+ self.mapping_registry = MappingRegistry
+ init_methods
+ EOD
+ end
+ c.def_privatemethod("init_methods") do
+ <<-EOD
+ Methods.each do |name_as, name, params, soapaction, namespace|
+ qname = ::XSD::QName.new(namespace, name_as)
+ @proxy.add_method(qname, soapaction, name, params)
+ add_rpc_method_interface(name, params)
+ end
+ EOD
+ end
+ c.dump
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/mappingRegistryCreator.rb b/lib/wsdl/soap/mappingRegistryCreator.rb
new file mode 100644
index 0000000000..d3b28f47e0
--- /dev/null
+++ b/lib/wsdl/soap/mappingRegistryCreator.rb
@@ -0,0 +1,90 @@
+# WSDL4R - Creating MappingRegistry code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/classDefCreatorSupport'
+
+
+module WSDL
+module SOAP
+
+
+class MappingRegistryCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ @complextypes = @definitions.collect_complextypes
+ @types = nil
+ end
+
+ def dump(types)
+ @types = types
+ map_cache = []
+ map = ""
+ @types.each do |type|
+ if map_cache.index(type).nil?
+ map_cache << type
+ if type.namespace != XSD::Namespace
+ if typemap = dump_typemap(type)
+ map << typemap
+ end
+ end
+ end
+ end
+ return map
+ end
+
+private
+
+ def dump_typemap(type)
+ if definedtype = @complextypes[type]
+ case definedtype.compoundtype
+ when :TYPE_STRUCT
+ dump_struct_typemap(definedtype)
+ when :TYPE_ARRAY
+ dump_array_typemap(definedtype)
+ else
+ raise NotImplementedError.new("Must not reach here.")
+ end
+ end
+ end
+
+ def dump_struct_typemap(definedtype)
+ ele = definedtype.name
+ return <<__EOD__
+MappingRegistry.set(
+ #{ create_class_name(ele) },
+ ::SOAP::SOAPStruct,
+ ::SOAP::Mapping::Registry::TypedStructFactory,
+ { :type => ::XSD::QName.new("#{ ele.namespace }", "#{ ele.name }") }
+)
+__EOD__
+ end
+
+ def dump_array_typemap(definedtype)
+ ele = definedtype.name
+ arytype = definedtype.find_arytype || XSD::AnyTypeName
+ type = XSD::QName.new(arytype.namespace, arytype.name.sub(/\[(?:,)*\]$/, ''))
+ @types << type
+ return <<__EOD__
+MappingRegistry.set(
+ #{ create_class_name(ele) },
+ ::SOAP::SOAPArray,
+ ::SOAP::Mapping::Registry::TypedArrayFactory,
+ { :type => ::XSD::QName.new("#{ type.namespace }", "#{ type.name }") }
+)
+__EOD__
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/methodDefCreator.rb b/lib/wsdl/soap/methodDefCreator.rb
new file mode 100644
index 0000000000..eded972cdc
--- /dev/null
+++ b/lib/wsdl/soap/methodDefCreator.rb
@@ -0,0 +1,148 @@
+# WSDL4R - Creating driver code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/classDefCreatorSupport'
+
+
+module WSDL
+module SOAP
+
+
+class MethodDefCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ @simpletypes = @definitions.collect_simpletypes
+ @complextypes = @definitions.collect_complextypes
+ @elements = @definitions.collect_elements
+ @types = nil
+ end
+
+ def dump(porttype)
+ @types = []
+ result = ""
+ operations = @definitions.porttype(porttype).operations
+ binding = @definitions.porttype_binding(porttype)
+ operations.each do |operation|
+ op_bind = binding.operations[operation.name]
+ result << ",\n" unless result.empty?
+ result << dump_method(operation, op_bind).chomp
+ end
+ return result, @types
+ end
+
+private
+
+ def dump_method(operation, binding)
+ name = safemethodname(operation.name.name)
+ name_as = operation.name.name
+ params = collect_parameter(operation)
+ soapaction = binding.soapoperation.soapaction
+ namespace = binding.input.soapbody.namespace
+ paramstr = param2str(params)
+ if paramstr.empty?
+ paramstr = '[]'
+ else
+ paramstr = "[\n" << paramstr.gsub(/^/, ' ') << "\n ]"
+ end
+ return <<__EOD__
+[#{ dq(name_as) }, #{ dq(name) },
+ #{ paramstr },
+ #{ soapaction ? dq(soapaction) : "nil" }, #{ dq(namespace) }
+]
+__EOD__
+ end
+
+ def collect_parameter(operation)
+ result = operation.inputparts.collect { |part|
+ collect_type(part.type)
+ param_set('in', definedtype(part), part.name)
+ }
+ outparts = operation.outputparts
+ if outparts.size > 0
+ retval = outparts[0]
+ collect_type(retval.type)
+ result << param_set('retval', definedtype(retval), retval.name)
+ cdr(outparts).each { |part|
+ collect_type(part.type)
+ result << param_set('out', definedtype(part), part.name)
+ }
+ end
+ result
+ end
+
+ def definedtype(part)
+ if mapped = basetype_mapped_class(part.type)
+ ['::' + mapped.name]
+ elsif definedelement = @elements[part.element]
+ raise RuntimeError.new("Part: #{part.name} should be typed for RPC service for now.")
+ elsif definedtype = @simpletypes[part.type]
+ ['::' + basetype_mapped_class(definedtype.base).name]
+ elsif definedtype = @complextypes[part.type]
+ case definedtype.compoundtype
+ when :TYPE_STRUCT
+ ['::SOAP::SOAPStruct', part.type.namespace, part.type.name]
+ when :TYPE_ARRAY
+ arytype = definedtype.find_arytype || XSD::AnyTypeName
+ ns = arytype.namespace
+ name = arytype.name.sub(/\[(?:,)*\]$/, '')
+ ['::SOAP::SOAPArray', ns, name]
+ else
+ raise NotImplementedError.new("Must not reach here.")
+ end
+ else
+ raise RuntimeError.new("Part: #{part.name} cannot be resolved.")
+ end
+ end
+
+ def param_set(io_type, type, name)
+ [io_type, type, name]
+ end
+
+ def collect_type(type)
+ # ignore inline type definition.
+ return if type.nil?
+ @types << type
+ return unless @complextypes[type]
+ @complextypes[type].each_element do |element|
+ collect_type(element.type)
+ end
+ end
+
+ def param2str(params)
+ params.collect { |param|
+ "[#{ dq(param[0]) }, #{ dq(param[2]) }, #{ type2str(param[1]) }]"
+ }.join(",\n")
+ end
+
+ def type2str(type)
+ if type.size == 1
+ "[#{ type[0] }]"
+ else
+ "[#{ type[0] }, #{ dq(type[1]) }, #{ dq(type[2]) }]"
+ end
+ end
+
+ def dq(ele)
+ "\"" << ele << "\""
+ end
+
+ def cdr(ary)
+ result = ary.dup
+ result.shift
+ result
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/servantSkeltonCreator.rb b/lib/wsdl/soap/servantSkeltonCreator.rb
new file mode 100644
index 0000000000..bf293949b8
--- /dev/null
+++ b/lib/wsdl/soap/servantSkeltonCreator.rb
@@ -0,0 +1,65 @@
+# WSDL4R - Creating servant skelton code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/classDefCreatorSupport'
+require 'xsd/codegen'
+
+
+module WSDL
+module SOAP
+
+
+class ServantSkeltonCreator
+ include ClassDefCreatorSupport
+ include ::XSD::CodeGen::GenSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ end
+
+ def dump(porttype = nil)
+ if porttype.nil?
+ result = ""
+ @definitions.porttypes.each do |type|
+ result << dump_porttype(type.name)
+ result << "\n"
+ end
+ else
+ result = dump_porttype(porttype)
+ end
+ result
+ end
+
+private
+
+ def dump_porttype(name)
+ class_name = create_class_name(name)
+ c = ::XSD::CodeGen::ClassDef.new(class_name)
+ operations = @definitions.porttype(name).operations
+ operations.each do |operation|
+ name = operation.name.name
+ input = operation.input
+ m = ::XSD::CodeGen::MethodDef.new(name,
+ input.find_message.parts.collect { |part| safevarname(part.name) }) do
+ <<-EOD
+ raise NotImplementedError.new
+ EOD
+ end
+ m.comment = dump_method_signature(operation)
+ c.add_method(m)
+ end
+ c.dump
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/soap/standaloneServerStubCreator.rb b/lib/wsdl/soap/standaloneServerStubCreator.rb
new file mode 100644
index 0000000000..34bcfdbba9
--- /dev/null
+++ b/lib/wsdl/soap/standaloneServerStubCreator.rb
@@ -0,0 +1,79 @@
+# WSDL4R - Creating standalone server stub code from WSDL.
+# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'wsdl/soap/mappingRegistryCreator'
+require 'wsdl/soap/methodDefCreator'
+require 'wsdl/soap/classDefCreatorSupport'
+
+
+module WSDL
+module SOAP
+
+
+class StandaloneServerStubCreator
+ include ClassDefCreatorSupport
+
+ attr_reader :definitions
+
+ def initialize(definitions)
+ @definitions = definitions
+ end
+
+ def dump(service_name)
+ STDERR.puts "!!! IMPORTANT !!!"
+ STDERR.puts "- Standalone stub can have only 1 port for now. So creating stub for the first port and rests are ignored."
+ STDERR.puts "- Standalone server stub ignores port location defined in WSDL. Location is http://localhost:10080/ by default. Generated client from WSDL must be configured to point this endpoint by hand."
+ STDERR.puts "!!! IMPORTANT !!!"
+ port = @definitions.service(service_name).ports[0]
+ dump_porttype(port.porttype.name)
+ end
+
+private
+
+ def dump_porttype(name)
+ class_name = create_class_name(name)
+ methoddef, types = MethodDefCreator.new(@definitions).dump(name)
+ mr_creator = MappingRegistryCreator.new(@definitions)
+
+ c1 = ::XSD::CodeGen::ClassDef.new(class_name)
+ c1.def_require("soap/rpc/standaloneServer")
+ c1.def_require("soap/mapping/registry")
+ c1.def_const("MappingRegistry", "::SOAP::Mapping::Registry.new")
+ c1.def_code(mr_creator.dump(types))
+ c1.def_code <<-EOD
+Methods = [
+#{ methoddef.gsub(/^/, " ") }
+]
+ EOD
+ c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App",
+ "::SOAP::RPC::StandaloneServer")
+ c2.def_method("initialize", "*arg") do
+ <<-EOD
+ super(*arg)
+ servant = #{class_name}.new
+ #{class_name}::Methods.each do |name_as, name, params, soapaction, ns|
+ qname = XSD::QName.new(ns, name_as)
+ @soaplet.app_scope_router.add_method(servant, qname, soapaction, name, params)
+ end
+ self.mapping_registry = #{class_name}::MappingRegistry
+ EOD
+ end
+ c1.dump + "\n" + c2.dump + format(<<-EOD)
+
+ if $0 == __FILE__
+ # Change listen port.
+ #{class_name}App.new('app', nil, '0.0.0.0', 10080).start
+ end
+ EOD
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/xmlSchema/complexContent.rb b/lib/wsdl/xmlSchema/complexContent.rb
index 22f6851864..66ad9e251d 100644
--- a/lib/wsdl/xmlSchema/complexContent.rb
+++ b/lib/wsdl/xmlSchema/complexContent.rb
@@ -28,6 +28,10 @@ class ComplexContent < Info
@attributes = XSD::NamedElements.new
end
+ def targetnamespace
+ parent.targetnamespace
+ end
+
def parse_element(element)
case element
when RestrictionName, ExtensionName
diff --git a/lib/wsdl/xmlSchema/complexType.rb b/lib/wsdl/xmlSchema/complexType.rb
index e889482d09..056a806dc5 100644
--- a/lib/wsdl/xmlSchema/complexType.rb
+++ b/lib/wsdl/xmlSchema/complexType.rb
@@ -8,6 +8,7 @@
require 'wsdl/info'
require 'wsdl/xmlSchema/content'
+require 'wsdl/xmlSchema/element'
require 'xsd/namedelements'
@@ -36,11 +37,16 @@ class ComplexType < Info
def targetnamespace
parent.targetnamespace
end
-
+
+ AnyAsElement = Element.new(XSD::QName.new(nil, 'any'), XSD::AnyTypeName)
def each_element
if @content
@content.elements.each do |element|
- yield(element.name, element)
+ if element.is_a?(Any)
+ yield(AnyAsElement)
+ else
+ yield(element)
+ end
end
end
end
@@ -48,7 +54,11 @@ class ComplexType < Info
def find_element(name)
if @content
@content.elements.each do |element|
- return element if name == element.name
+ if element.is_a?(Any)
+ return AnyAsElement if name == AnyAsElement.name
+ else
+ return element if name == element.name
+ end
end
end
nil
@@ -57,7 +67,11 @@ class ComplexType < Info
def find_element_by_name(name)
if @content
@content.elements.each do |element|
- return element if name == element.name.name
+ if element.is_a?(Any)
+ return AnyAsElement if name == AnyAsElement.name.name
+ else
+ return element if name == element.name.name
+ end
end
end
nil
diff --git a/lib/wsdl/xmlSchema/data.rb b/lib/wsdl/xmlSchema/data.rb
index 2fa8ad6a91..1283ac2a1d 100644
--- a/lib/wsdl/xmlSchema/data.rb
+++ b/lib/wsdl/xmlSchema/data.rb
@@ -6,8 +6,11 @@
# either the dual license version in 2003, or any later version.
+require 'xsd/datatypes'
require 'wsdl/xmlSchema/schema'
require 'wsdl/xmlSchema/import'
+require 'wsdl/xmlSchema/simpleType'
+require 'wsdl/xmlSchema/simpleRestriction'
require 'wsdl/xmlSchema/complexType'
require 'wsdl/xmlSchema/complexContent'
require 'wsdl/xmlSchema/any'
@@ -17,7 +20,7 @@ require 'wsdl/xmlSchema/choice'
require 'wsdl/xmlSchema/sequence'
require 'wsdl/xmlSchema/attribute'
require 'wsdl/xmlSchema/unique'
-
+require 'wsdl/xmlSchema/enumeration'
module WSDL
module XMLSchema
@@ -30,6 +33,7 @@ ChoiceName = XSD::QName.new(XSD::Namespace, 'choice')
ComplexContentName = XSD::QName.new(XSD::Namespace, 'complexContent')
ComplexTypeName = XSD::QName.new(XSD::Namespace, 'complexType')
ElementName = XSD::QName.new(XSD::Namespace, 'element')
+EnumerationName = XSD::QName.new(XSD::Namespace, 'enumeration')
ExtensionName = XSD::QName.new(XSD::Namespace, 'extension')
ImportName = XSD::QName.new(XSD::Namespace, 'import')
RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction')
@@ -57,6 +61,7 @@ SchemaLocationAttrName = XSD::QName.new(nil, 'schemaLocation')
TargetNamespaceAttrName = XSD::QName.new(nil, 'targetNamespace')
TypeAttrName = XSD::QName.new(nil, 'type')
UseAttrName = XSD::QName.new(nil, 'use')
+ValueAttrName = XSD::QName.new(nil, 'value')
end
diff --git a/lib/wsdl/xmlSchema/enumeration.rb b/lib/wsdl/xmlSchema/enumeration.rb
new file mode 100644
index 0000000000..cd61572d07
--- /dev/null
+++ b/lib/wsdl/xmlSchema/enumeration.rb
@@ -0,0 +1,36 @@
+# WSDL4R - XMLSchema enumeration definition for WSDL.
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+
+
+module WSDL
+module XMLSchema
+
+
+class Enumeration < Info
+ def initialize
+ super
+ end
+
+ def parse_element(element)
+ nil
+ end
+
+ def parse_attr(attr, value)
+ case attr
+ when ValueAttrName
+ parent.enumeration << value
+ value
+ end
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/xmlSchema/parser.rb b/lib/wsdl/xmlSchema/parser.rb
index 688af27c8c..5401c5f729 100644
--- a/lib/wsdl/xmlSchema/parser.rb
+++ b/lib/wsdl/xmlSchema/parser.rb
@@ -116,7 +116,8 @@ private
unless o
raise UnknownElementError.new("Unknown element #{ element }.")
end
- o.parent = parent
+ # node could be a pseudo element. pseudo element has its own parent.
+ o.parent = parent if o.parent.nil?
end
attrs.each do |key, value|
attr = unless /:/ =~ key
diff --git a/lib/wsdl/xmlSchema/schema.rb b/lib/wsdl/xmlSchema/schema.rb
index b2a195d41f..b530a92556 100644
--- a/lib/wsdl/xmlSchema/schema.rb
+++ b/lib/wsdl/xmlSchema/schema.rb
@@ -17,6 +17,7 @@ module XMLSchema
class Schema < Info
attr_reader :targetnamespace # required
attr_reader :complextypes
+ attr_reader :simpletypes
attr_reader :elements
attr_reader :attributes
attr_reader :imports
@@ -27,6 +28,7 @@ class Schema < Info
super
@targetnamespace = nil
@complextypes = XSD::NamedElements.new
+ @simpletypes = XSD::NamedElements.new
@elements = XSD::NamedElements.new
@attributes = XSD::NamedElements.new
@imports = []
@@ -44,8 +46,9 @@ class Schema < Info
@complextypes << o
o
when SimpleTypeName
- STDERR.puts("Restriction of basetype with simpleType definition is ignored for now.")
- nil
+ o = SimpleType.new
+ @simpletypes << o
+ o
when ElementName
o = Element.new
@elements << o
@@ -83,6 +86,12 @@ class Schema < Info
result
end
+ def collect_simpletypes
+ result = XSD::NamedElements.new
+ result.concat(@simpletypes)
+ result
+ end
+
def self.parse_element(element)
if element == SchemaName
Schema.new
diff --git a/lib/wsdl/xmlSchema/simpleRestriction.rb b/lib/wsdl/xmlSchema/simpleRestriction.rb
new file mode 100644
index 0000000000..6986e74423
--- /dev/null
+++ b/lib/wsdl/xmlSchema/simpleRestriction.rb
@@ -0,0 +1,48 @@
+# WSDL4R - XMLSchema simpleType definition for WSDL.
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'xsd/namedelements'
+
+
+module WSDL
+module XMLSchema
+
+
+class SimpleRestriction < Info
+ attr_reader :base
+ attr_reader :enumeration
+
+ def initialize
+ super
+ @base = nil
+ @enumeration = [] # NamedElements?
+ end
+
+ def valid?(value)
+ @enumeration.include?(value)
+ end
+
+ def parse_element(element)
+ case element
+ when EnumerationName
+ Enumeration.new # just a parsing handler
+ end
+ end
+
+ def parse_attr(attr, value)
+ case attr
+ when BaseAttrName
+ @base = value
+ end
+ end
+end
+
+
+end
+end
diff --git a/lib/wsdl/xmlSchema/simpleType.rb b/lib/wsdl/xmlSchema/simpleType.rb
new file mode 100644
index 0000000000..830086f99e
--- /dev/null
+++ b/lib/wsdl/xmlSchema/simpleType.rb
@@ -0,0 +1,81 @@
+# WSDL4R - XMLSchema simpleType definition for WSDL.
+# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+
+# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
+# redistribute it and/or modify it under the same terms of Ruby's license;
+# either the dual license version in 2003, or any later version.
+
+
+require 'wsdl/info'
+require 'xsd/namedelements'
+
+
+module WSDL
+module XMLSchema
+
+
+class SimpleType < Info
+ attr_accessor :name
+ attr_reader :derivetype
+ attr_reader :restriction
+
+ def check_lexical_format(value)
+ if @restriction
+ check_restriction(value)
+ elsif @extension
+ raise NotImplementedError
+ # ToDo
+ else
+ raise ArgumentError.new("incomplete simpleType")
+ end
+ end
+
+ def base
+ if @restriction
+ @restriction.base
+ elsif @extension
+ @extension.base
+ else
+ raise ArgumentError.new("incomplete simpleType")
+ end
+ end
+
+ def initialize(name = nil)
+ super()
+ @name = name
+ @derivetype = nil
+ @restriction = nil
+ end
+
+ def targetnamespace
+ parent.targetnamespace
+ end
+
+ def parse_element(element)
+ case element
+ when RestrictionName
+ @restriction = SimpleRestriction.new
+ @derivetype = element.name
+ @restriction
+ end
+ end
+
+ def parse_attr(attr, value)
+ case attr
+ when NameAttrName
+ @name = XSD::QName.new(targetnamespace, value)
+ end
+ end
+
+private
+
+ def check_restriction(value)
+ unless @restriction.valid?(value)
+ raise ::XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'.")
+ end
+ end
+end
+
+
+end
+end