summaryrefslogtreecommitdiff
path: root/lib/wsdl
diff options
context:
space:
mode:
authornahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-05-22 13:20:28 +0000
committernahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-05-22 13:20:28 +0000
commit991d0c409cc6b1d916330a32a9624aef808176a4 (patch)
tree5e2cc150dc84ab3f6f64685ec7f54e6b2077eae7 /lib/wsdl
parent15b7d439885f4aa97e0f508ef485cadab4b23577 (diff)
* lib/{soap,wsdl,xsd}, test/{soap,wsdl,xsd}: imported soap4r/1.5.4.
== SOAP client and server == === for both client side and server side === * improved document/literal service support. style(rpc,document)/use(encoding, literal) combination are all supported. for the detail about combination, see test/soap/test_style.rb. * let WSDLEncodedRegistry#soap2obj map SOAP/OM to Ruby according to WSDL as well as obj2soap. closes #70. * let SOAP::Mapping::Object handle XML attribute for doc/lit service. you can set/get XML attribute via accessor methods which as a name 'xmlattr_' prefixed (<foo name="bar"/> -> Foo#xmlattr_name). === client side === * WSDLDriver capitalized name operation bug fixed. from 1.5.3-ruby1.8.2, operation which has capitalized name (such as KeywordSearchRequest in AWS) is defined as a method having uncapitalized name. (converted with GenSupport.safemethodname to handle operation name 'foo-bar'). it introduced serious incompatibility; in the past, it was defined as a capitalized. define capitalized method as well under that circumstance. * added new factory interface 'WSDLDriverFactory#create_rpc_driver' to create RPC::Driver, not WSDLDriver (RPC::Driver and WSDLDriver are merged). 'WSDLDriverFactory#create_driver' still creates WSDLDriver for compatibility but it warns that the method is deprecated. please use create_rpc_driver instead of create_driver. * allow to use an URI object as an endpoint_url even with net/http, not http-access2. === server side === * added mod_ruby support to SOAP::CGIStub. rename a CGI script server.cgi to server.rb and let mod_ruby's RubyHandler handles the script. CGIStub detects if it's running under mod_ruby environment or not. * added fcgi support to SOAP::CGIStub. see the sample at sample/soap/calc/server.fcgi. (almost same as server.cgi but has fcgi handler at the bottom.) * allow to return a SOAPFault object to respond customized SOAP fault. * added the interface 'generate_explicit_type' for server side (CGIStub, HTTPServer). call 'self.generate_explicit_type = true' if you want to return simplified XML even if it's rpc/encoded service. == WSDL == === WSDL definition === * improved XML Schema support such as extension, restriction, simpleType, complexType + simpleContent, ref, length, import, include. * reduced "unknown element/attribute" warnings (warn only 1 time for each QName). * importing XSD file at schemaLocation with xsd:import. === code generation from WSDL === * generator crashed when there's '-' in defined element/attribute name. * added ApacheMap WSDL definition. * sample/{soap,wsdl}: removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8502 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/wsdl')
-rw-r--r--lib/wsdl/definitions.rb26
-rw-r--r--lib/wsdl/import.rb26
-rw-r--r--lib/wsdl/importer.rb58
-rw-r--r--lib/wsdl/info.rb10
-rw-r--r--lib/wsdl/operation.rb14
-rw-r--r--lib/wsdl/operationBinding.rb30
-rw-r--r--lib/wsdl/param.rb5
-rw-r--r--lib/wsdl/parser.rb35
-rw-r--r--lib/wsdl/port.rb2
-rw-r--r--lib/wsdl/portType.rb3
-rw-r--r--lib/wsdl/soap/cgiStubCreator.rb18
-rw-r--r--lib/wsdl/soap/classDefCreator.rb226
-rw-r--r--lib/wsdl/soap/classDefCreatorSupport.rb6
-rw-r--r--lib/wsdl/soap/complexType.rb37
-rw-r--r--lib/wsdl/soap/definitions.rb39
-rw-r--r--lib/wsdl/soap/driverCreator.rb22
-rw-r--r--lib/wsdl/soap/element.rb6
-rw-r--r--lib/wsdl/soap/fault.rb4
-rw-r--r--lib/wsdl/soap/header.rb13
-rw-r--r--lib/wsdl/soap/mappingRegistryCreator.rb16
-rw-r--r--lib/wsdl/soap/methodDefCreator.rb116
-rw-r--r--lib/wsdl/soap/operation.rb6
-rw-r--r--lib/wsdl/soap/servantSkeltonCreator.rb8
-rw-r--r--lib/wsdl/soap/standaloneServerStubCreator.rb20
-rw-r--r--lib/wsdl/xmlSchema/attribute.rb60
-rw-r--r--lib/wsdl/xmlSchema/complexContent.rb5
-rw-r--r--lib/wsdl/xmlSchema/data.rb11
-rw-r--r--lib/wsdl/xmlSchema/element.rb72
-rw-r--r--lib/wsdl/xmlSchema/import.rb25
-rw-r--r--lib/wsdl/xmlSchema/parser.rb39
-rw-r--r--lib/wsdl/xmlSchema/schema.rb36
-rw-r--r--lib/wsdl/xmlSchema/simpleContent.rb56
-rw-r--r--lib/wsdl/xmlSchema/simpleRestriction.rb29
-rw-r--r--lib/wsdl/xmlSchema/simpleType.rb12
34 files changed, 715 insertions, 376 deletions
diff --git a/lib/wsdl/definitions.rb b/lib/wsdl/definitions.rb
index a7c71f2a93..5235037cfe 100644
--- a/lib/wsdl/definitions.rb
+++ b/lib/wsdl/definitions.rb
@@ -18,19 +18,16 @@ class Definitions < Info
attr_reader :targetnamespace
attr_reader :imports
- # Overrides Info#root
- def root
- @root
- end
-
- def root=(root)
- @root = root
- end
+ attr_accessor :location
+ attr_reader :importedschema
def initialize
super
@name = nil
@targetnamespace = nil
+ @location = nil
+ @importedschema = {}
+
@types = nil
@imports = []
@messages = XSD::NamedElements.new
@@ -53,6 +50,19 @@ class Definitions < Info
end
end
+ def collect_attributes
+ result = XSD::NamedElements.new
+ if @types
+ @types.schemas.each do |schema|
+ result.concat(schema.collect_attributes)
+ end
+ end
+ @imports.each do |import|
+ result.concat(import.content.collect_attributes)
+ end
+ result
+ end
+
def collect_elements
result = XSD::NamedElements.new
if @types
diff --git a/lib/wsdl/import.rb b/lib/wsdl/import.rb
index 706cb95fe2..faf60871a5 100644
--- a/lib/wsdl/import.rb
+++ b/lib/wsdl/import.rb
@@ -45,13 +45,23 @@ class Import < Info
end
@namespace
when LocationAttrName
- @location = value.source
- @content = import(@location)
- if @content.is_a?(Definitions)
- @content.root = root
- if @namespace
- @content.targetnamespace = @namespace
- end
+ @location = URI.parse(value.source)
+ if @location.relative? and !parent.location.nil? and
+ !parent.location.relative?
+ @location = parent.location + @location
+ end
+ if root.importedschema.key?(@location)
+ @content = root.importedschema[@location]
+ else
+ root.importedschema[@location] = nil # placeholder
+ @content = import(@location)
+ if @content.is_a?(Definitions)
+ @content.root = root
+ if @namespace
+ @content.targetnamespace = @namespace
+ end
+ end
+ root.importedschema[@location] = @content
end
@location
else
@@ -62,7 +72,7 @@ class Import < Info
private
def import(location)
- Importer.import(location)
+ Importer.import(location, root)
end
end
diff --git a/lib/wsdl/importer.rb b/lib/wsdl/importer.rb
index 873be710b5..481bd81b25 100644
--- a/lib/wsdl/importer.rb
+++ b/lib/wsdl/importer.rb
@@ -1,69 +1,37 @@
# WSDL4R - WSDL importer library.
-# Copyright (C) 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2003, 2005 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/xmlSchema/importer'
require 'wsdl/parser'
-require 'soap/soap'
-require 'soap/property'
module WSDL
-class Importer
- def self.import(location)
- new.import(location)
+class Importer < WSDL::XMLSchema::Importer
+ def self.import(location, originalroot = nil)
+ new.import(location, originalroot)
end
- def initialize
- @web_client = nil
- end
+private
- def import(location)
- STDERR.puts("importing: #{location}") if $DEBUG
- content = nil
- if FileTest.exist?(location)
- content = File.open(location).read
- else
- client = web_client.new(nil, "WSDL4R")
- if opt = ::SOAP::Property.loadproperty(::SOAP::PropertyName)
- client.proxy = opt["client.protocol.http.proxy"]
- client.no_proxy = opt["client.protocol.http.no_proxy"]
- end
- client.proxy ||= ::SOAP::Env::HTTP_PROXY
- client.no_proxy ||= ::SOAP::Env::NO_PROXY
- content = client.get_content(location)
- end
- opt = {}
+ def parse(content, location, originalroot)
+ opt = {
+ :location => location,
+ :originalroot => originalroot
+ }
begin
WSDL::Parser.new(opt).parse(content)
- rescue WSDL::Parser::ParseError => orgexcn
- require 'wsdl/xmlSchema/parser'
- WSDL::XMLSchema::Parser.new(opt).parse(content)
+ rescue WSDL::Parser::ParseError
+ super(content, location, originalroot)
end
end
-private
-
- def web_client
- @web_client ||= begin
- require 'http-access2'
- if HTTPAccess2::VERSION < "2.0"
- raise LoadError.new("http-access/2.0 or later is required.")
- end
- HTTPAccess2::Client
- rescue LoadError
- STDERR.puts "Loading http-access2 failed. Net/http is used." if $DEBUG
- require 'soap/netHttpClient'
- ::SOAP::NetHttpClient
- end
- @web_client
- end
end
diff --git a/lib/wsdl/info.rb b/lib/wsdl/info.rb
index 657ff5863a..ffd90390a4 100644
--- a/lib/wsdl/info.rb
+++ b/lib/wsdl/info.rb
@@ -10,16 +10,22 @@ module WSDL
class Info
+ attr_accessor :root
attr_accessor :parent
attr_accessor :id
def initialize
+ @root = nil
@parent = nil
@id = nil
end
- def root
- @parent.root
+ def inspect
+ if self.respond_to?(:name)
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__, self.name)
+ else
+ sprintf("#<%s:0x%x>", self.class.name, __id__)
+ end
end
def parse_element(element); end # abstract
diff --git a/lib/wsdl/operation.rb b/lib/wsdl/operation.rb
index 3c1f66859f..727bb9a56c 100644
--- a/lib/wsdl/operation.rb
+++ b/lib/wsdl/operation.rb
@@ -46,21 +46,23 @@ class Operation < Info
end
def input_info
- op_name = @name
- optype_name = XSD::QName.new(targetnamespace, input.name ? input.name.name : @name.name)
- NameInfo.new(op_name, optype_name, inputparts)
+ typename = input.find_message.name
+ NameInfo.new(@name, typename, inputparts)
end
def output_info
- op_name = @name
- optype_name = XSD::QName.new(targetnamespace, output.name ? output.name.name : @name.name)
- NameInfo.new(op_name, optype_name, outputparts)
+ typename = output.find_message.name
+ NameInfo.new(@name, typename, outputparts)
end
def inputparts
sort_parts(input.find_message.parts)
end
+ def inputname
+ XSD::QName.new(targetnamespace, input.name ? input.name.name : @name.name)
+ end
+
def outputparts
sort_parts(output.find_message.parts)
end
diff --git a/lib/wsdl/operationBinding.rb b/lib/wsdl/operationBinding.rb
index fb44eb9660..c2b8cd6591 100644
--- a/lib/wsdl/operationBinding.rb
+++ b/lib/wsdl/operationBinding.rb
@@ -37,7 +37,35 @@ class OperationBinding < Info
end
def find_operation
- porttype.operations[@name]
+ porttype.operations[@name] or raise RuntimeError.new("#{@name} not found")
+ end
+
+ def soapoperation_name
+ if @soapoperation
+ @soapoperation.input_info.op_name
+ else
+ find_operation.name
+ end
+ end
+
+ def soapoperation_style
+ style = nil
+ if @soapoperation
+ style = @soapoperation.operation_style
+ elsif parent.soapbinding
+ style = parent.soapbinding.style
+ else
+ raise TypeError.new("operation style definition not found")
+ end
+ style || :document
+ end
+
+ def soapaction
+ if @soapoperation
+ @soapoperation.soapaction
+ else
+ nil
+ end
end
def parse_element(element)
diff --git a/lib/wsdl/param.rb b/lib/wsdl/param.rb
index 581ecbd8d3..08ba07ee9b 100644
--- a/lib/wsdl/param.rb
+++ b/lib/wsdl/param.rb
@@ -33,7 +33,7 @@ class Param < Info
end
def find_message
- root.message(@message)
+ root.message(@message) or raise RuntimeError.new("#{@message} not found")
end
def parse_element(element)
@@ -61,6 +61,9 @@ class Param < Info
def parse_attr(attr, value)
case attr
when MessageAttrName
+ if value.namespace.nil?
+ value = XSD::QName.new(targetnamespace, value.source)
+ end
@message = value
when NameAttrName
@name = XSD::QName.new(targetnamespace, value.source)
diff --git a/lib/wsdl/parser.rb b/lib/wsdl/parser.rb
index 417ea20b47..f96e96ee2a 100644
--- a/lib/wsdl/parser.rb
+++ b/lib/wsdl/parser.rb
@@ -1,5 +1,5 @@
# WSDL4R - WSDL XML Instance parser library.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -53,6 +53,9 @@ public
@parser = XSD::XMLParser.create_parser(self, opt)
@parsestack = nil
@lastnode = nil
+ @ignored = {}
+ @location = opt[:location]
+ @originalroot = opt[:originalroot]
end
def parse(string_or_readable)
@@ -96,7 +99,7 @@ public
def end_element(name)
lastframe = @parsestack.pop
unless name == lastframe.name
- raise UnexpectedElementError.new("Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.")
+ raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'")
end
decode_tag_end(lastframe.ns, lastframe.node)
@lastnode = lastframe.node
@@ -106,20 +109,31 @@ private
def decode_tag(ns, name, attrs, parent)
o = nil
- element = ns.parse(name)
+ elename = ns.parse(name)
if !parent
- if element == DefinitionsName
- o = Definitions.parse_element(element)
+ if elename == DefinitionsName
+ o = Definitions.parse_element(elename)
+ o.location = @location
else
- raise UnknownElementError.new("Unknown element #{ element }.")
+ raise UnknownElementError.new("unknown element: #{elename}")
end
+ o.root = @originalroot if @originalroot # o.root = o otherwise
else
- o = parent.parse_element(element)
+ if elename == XMLSchema::AnnotationName
+ # only the first annotation element is allowed for each xsd element.
+ o = XMLSchema::Annotation.new
+ else
+ o = parent.parse_element(elename)
+ end
unless o
- STDERR.puts("Unknown element #{ element }.")
+ unless @ignored.key?(elename)
+ warn("ignored element: #{elename}")
+ @ignored[elename] = elename
+ end
o = Documentation.new # which accepts any element.
end
# node could be a pseudo element. pseudo element has its own parent.
+ o.root = parent.root
o.parent = parent if o.parent.nil?
end
attrs.each do |key, value|
@@ -127,7 +141,10 @@ private
value_ele = ns.parse(value, true)
value_ele.source = value # for recovery; value may not be a QName
unless o.parse_attr(attr_ele, value_ele)
- STDERR.puts("Unknown attr #{ attr_ele }.")
+ unless @ignored.key?(attr_ele)
+ warn("ignored attr: #{attr_ele}")
+ @ignored[attr_ele] = attr_ele
+ end
end
end
o
diff --git a/lib/wsdl/port.rb b/lib/wsdl/port.rb
index 15ba86ad7c..883cc3232d 100644
--- a/lib/wsdl/port.rb
+++ b/lib/wsdl/port.rb
@@ -33,7 +33,7 @@ class Port < Info
end
def find_binding
- root.binding(@binding)
+ root.binding(@binding) or raise RuntimeError.new("#{@binding} not found")
end
def inputoperation_map
diff --git a/lib/wsdl/portType.rb b/lib/wsdl/portType.rb
index 86893ba039..03e37690a8 100644
--- a/lib/wsdl/portType.rb
+++ b/lib/wsdl/portType.rb
@@ -28,7 +28,8 @@ class PortType < Info
end
def find_binding
- root.bindings.find { |item| item.type == @name }
+ root.bindings.find { |item| item.type == @name } or
+ raise RuntimeError.new("#{@name} not found")
end
def locations
diff --git a/lib/wsdl/soap/cgiStubCreator.rb b/lib/wsdl/soap/cgiStubCreator.rb
index 68ecfaf0a4..0a76dc43a1 100644
--- a/lib/wsdl/soap/cgiStubCreator.rb
+++ b/lib/wsdl/soap/cgiStubCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating CGI stub code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -26,9 +26,7 @@ class CGIStubCreator
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 !!!"
+ warn("CGI stub can have only 1 port. Creating stub for the first port... Rests are ignored.")
port = @definitions.service(service_name).ports[0]
dump_porttype(port.porttype.name)
end
@@ -39,28 +37,28 @@ private
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 = 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(/^/, " ") }
+#{methoddef.gsub(/^/, " ")}
]
EOD
- c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App",
+ 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, param_def, soapaction, namespace, style|
- qname = XSD::QName.new(namespace, name_as)
if style == :document
- @router.add_document_method(servant, qname, soapaction, name, param_def)
+ @router.add_document_operation(servant, soapaction, name, param_def)
else
- @router.add_rpc_method(servant, qname, soapaction, name, param_def)
+ qname = XSD::QName.new(namespace, name_as)
+ @router.add_rpc_operation(servant, qname, soapaction, name, param_def)
end
end
self.mapping_registry = #{class_name}::MappingRegistry
diff --git a/lib/wsdl/soap/classDefCreator.rb b/lib/wsdl/soap/classDefCreator.rb
index 13f7802b72..deda4f131f 100644
--- a/lib/wsdl/soap/classDefCreator.rb
+++ b/lib/wsdl/soap/classDefCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating class definition from WSDL
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 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;
@@ -22,13 +22,16 @@ class ClassDefCreator
@elements = definitions.collect_elements
@simpletypes = definitions.collect_simpletypes
@complextypes = definitions.collect_complextypes
- @faulttypes = definitions.collect_faulttypes if definitions.respond_to?(:collect_faulttypes)
+ @faulttypes = nil
+ if definitions.respond_to?(:collect_faulttypes)
+ @faulttypes = definitions.collect_faulttypes
+ end
end
- def dump(class_name = nil)
- result = ''
- if class_name
- result = dump_classdef(class_name)
+ def dump(type = nil)
+ result = "require 'xsd/qname'\n"
+ if type
+ result = dump_classdef(type.name, type)
else
str = dump_element
unless str.empty?
@@ -53,117 +56,129 @@ private
def dump_element
@elements.collect { |ele|
- ele.local_complextype ? dump_classdef(ele) : ''
- }.join("\n")
+ if ele.local_complextype
+ dump_classdef(ele.name, ele.local_complextype)
+ elsif ele.local_simpletype
+ dump_simpletypedef(ele.name, ele.local_simpletype)
+ else
+ nil
+ end
+ }.compact.join("\n")
end
def dump_simpletype
@simpletypes.collect { |type|
- dump_simpletypedef(type)
- }.join("\n")
+ dump_simpletypedef(type.name, type)
+ }.compact.join("\n")
end
def dump_complextype
@complextypes.collect { |type|
case type.compoundtype
- when :TYPE_STRUCT
- dump_classdef(type)
+ when :TYPE_STRUCT, :TYPE_EMPTY
+ dump_classdef(type.name, type)
when :TYPE_ARRAY
dump_arraydef(type)
when :TYPE_SIMPLE
- STDERR.puts("not implemented: ToDo")
+ dump_simpleclassdef(type)
+ when :TYPE_MAP
+ # mapped as a general Hash
+ nil
else
raise RuntimeError.new(
- "Unknown kind of complexContent: #{type.compoundtype}")
+ "unknown kind of complexContent: #{type.compoundtype}")
end
- }.join("\n")
+ }.compact.join("\n")
end
- def dump_simpletypedef(simpletype)
- qname = simpletype.name
- if simpletype.restriction.enumeration.empty?
- STDERR.puts("#{qname}: simpleType which is not enum type not supported.")
- return ''
+ def dump_simpletypedef(qname, simpletype)
+ if !simpletype.restriction or simpletype.restriction.enumeration.empty?
+ return nil
end
c = XSD::CodeGen::ModuleDef.new(create_class_name(qname))
- c.comment = "#{ qname.namespace }"
+ c.comment = "#{qname}"
+ const = {}
simpletype.restriction.enumeration.each do |value|
- c.def_const(safeconstname(value), value.dump)
+ constname = safeconstname(value)
+ const[constname] ||= 0
+ if (const[constname] += 1) > 1
+ constname += "_#{const[constname]}"
+ end
+ c.def_const(constname, ndq(value))
end
c.dump
end
- def dump_classdef(type_or_element)
+ def dump_simpleclassdef(type_or_element)
qname = type_or_element.name
+ base = create_class_name(type_or_element.simplecontent.base)
+ c = XSD::CodeGen::ClassDef.new(create_class_name(qname), base)
+ c.comment = "#{qname}"
+ c.dump
+ end
+
+ def dump_classdef(qname, typedef)
if @faulttypes and @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)
- schema_attribute = []
+ c.comment = "#{qname}"
+ c.def_classvar('schema_type', ndq(qname.name))
+ c.def_classvar('schema_ns', ndq(qname.namespace))
schema_element = []
init_lines = ''
params = []
- type_or_element.each_element do |element|
- next unless element.name
- name = element.name.name
+ typedef.each_element do |element|
if element.type == XSD::AnyTypeName
type = nil
- elsif basetype = basetype_class(element.type)
- type = basetype.name
- else
+ elsif klass = element_basetype(element)
+ type = klass.name
+ elsif element.type
type = create_class_name(element.type)
+ else
+ type = nil # means anyType.
+ # do we define a class for local complexType from it's name?
+ # type = create_class_name(element.name)
+ # <element>
+ # <complexType>
+ # <seq...>
+ # </complexType>
+ # </element>
end
+ name = name_element(element).name
attrname = safemethodname?(name) ? name : safemethodname(name)
varname = safevarname(name)
c.def_attr(attrname, true, varname)
- init_lines << "@#{ varname } = #{ varname }\n"
+ init_lines << "@#{varname} = #{varname}\n"
if element.map_as_array?
- params << "#{ varname } = []"
- type << '[]'
+ params << "#{varname} = []"
+ type << '[]' if type
else
- params << "#{ varname } = nil"
+ params << "#{varname} = nil"
end
- schema_element << [name, type]
+ eleqname = (varname == name) ? nil : element.name
+ schema_element << [varname, eleqname, type]
end
- unless type_or_element.attributes.empty?
- type_or_element.attributes.each do |attribute|
- name = attribute.name.name
- if basetype = basetype_class(attribute.type)
- type = basetype_class(attribute.type).name
- else
- type = nil
- end
- varname = safevarname('attr_' + name)
- c.def_method(varname) do <<-__EOD__
- @__soap_attribute[#{name.dump}]
- __EOD__
- end
- c.def_method(varname + '=', 'value') do <<-__EOD__
- @__soap_attribute[#{name.dump}] = value
- __EOD__
- end
- schema_attribute << [name, type]
- end
- init_lines << "@__soap_attribute = {}\n"
+ unless typedef.attributes.empty?
+ define_attribute(c, typedef.attributes)
+ init_lines << "@__xmlattr = {}\n"
end
- c.def_classvar('schema_attribute',
- '{' +
- schema_attribute.collect { |name, type|
- name.dump + ' => ' + ndq(type)
- }.join(', ') +
- '}'
- )
c.def_classvar('schema_element',
- '{' +
- schema_element.collect { |name, type|
- name.dump + ' => ' + ndq(type)
+ '[' +
+ schema_element.collect { |varname, name, type|
+ '[' +
+ (
+ if name
+ varname.dump + ', [' + ndq(type) + ', ' + dqname(name) + ']'
+ else
+ varname.dump + ', ' + ndq(type)
+ end
+ ) +
+ ']'
}.join(', ') +
- '}'
+ ']'
)
c.def_method('initialize', *params) do
init_lines
@@ -171,20 +186,83 @@ private
c.dump
end
+ def element_basetype(ele)
+ if klass = basetype_class(ele.type)
+ klass
+ elsif ele.local_simpletype
+ basetype_class(ele.local_simpletype.base)
+ else
+ nil
+ end
+ end
+
+ def attribute_basetype(attr)
+ if klass = basetype_class(attr.type)
+ klass
+ elsif attr.local_simpletype
+ basetype_class(attr.local_simpletype.base)
+ else
+ nil
+ end
+ end
+
def basetype_class(type)
- if @simpletypes[type]
- basetype_mapped_class(@simpletypes[type].base)
+ return nil if type.nil?
+ if simpletype = @simpletypes[type]
+ basetype_mapped_class(simpletype.base)
else
basetype_mapped_class(type)
end
end
+ def define_attribute(c, attributes)
+ schema_attribute = []
+ attributes.each do |attribute|
+ name = name_attribute(attribute)
+ if klass = attribute_basetype(attribute)
+ type = klass.name
+ else
+ type = nil
+ end
+ methodname = safemethodname('xmlattr_' + name.name)
+ c.def_method(methodname) do <<-__EOD__
+ (@__xmlattr ||= {})[#{dqname(name)}]
+ __EOD__
+ end
+ c.def_method(methodname + '=', 'value') do <<-__EOD__
+ (@__xmlattr ||= {})[#{dqname(name)}] = value
+ __EOD__
+ end
+ schema_attribute << [name, type]
+ end
+ c.def_classvar('schema_attribute',
+ '{' +
+ schema_attribute.collect { |name, type|
+ dqname(name) + ' => ' + ndq(type)
+ }.join(', ') +
+ '}'
+ )
+ end
+
+ def name_element(element)
+ return element.name if element.name
+ return element.ref if element.ref
+ raise RuntimeError.new("cannot define name of #{element}")
+ end
+
+ def name_attribute(attribute)
+ return attribute.name if attribute.name
+ return attribute.ref if attribute.ref
+ raise RuntimeError.new("cannot define name of #{attribute}")
+ 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.comment = "#{qname}"
+ type = complextype.child_type
+ c.def_classvar('schema_type', ndq(type.name))
+ c.def_classvar('schema_ns', ndq(type.namespace))
c.dump
end
end
diff --git a/lib/wsdl/soap/classDefCreatorSupport.rb b/lib/wsdl/soap/classDefCreatorSupport.rb
index 706c00d4f6..8f335653c8 100644
--- a/lib/wsdl/soap/classDefCreatorSupport.rb
+++ b/lib/wsdl/soap/classDefCreatorSupport.rb
@@ -21,7 +21,7 @@ module ClassDefCreatorSupport
def create_class_name(qname)
if klass = basetype_mapped_class(qname)
- ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass.name)
+ ::SOAP::Mapping::DefaultRegistry.find_mapped_obj_class(klass).name
else
safeconstname(qname.name)
end
@@ -71,6 +71,10 @@ __EOD__
':' + ele
end
+ def dqname(qname)
+ qname.dump
+ end
+
private
def dump_inout_type(param)
diff --git a/lib/wsdl/soap/complexType.rb b/lib/wsdl/soap/complexType.rb
index 1bed059f7e..bba50fd153 100644
--- a/lib/wsdl/soap/complexType.rb
+++ b/lib/wsdl/soap/complexType.rb
@@ -31,42 +31,44 @@ class ComplexType < Info
else
:TYPE_STRUCT
end
- elsif complexcontent and complexcontent.base == ::SOAP::ValueArrayName
- :TYPE_ARRAY
+ elsif complexcontent
+ if complexcontent.base == ::SOAP::ValueArrayName
+ :TYPE_ARRAY
+ else
+ complexcontent.basetype.check_type
+ end
elsif simplecontent
:TYPE_SIMPLE
elsif !attributes.empty?
:TYPE_STRUCT
- else
- raise NotImplementedError.new("Unknown kind of complexType.")
+ else # empty complexType definition (seen in partner.wsdl of salesforce)
+ :TYPE_EMPTY
end
end
def child_type(name = nil)
- type = nil
case compoundtype
when :TYPE_STRUCT
if ele = find_element(name)
- type = ele.type
+ ele.type
elsif ele = find_element_by_name(name.name)
- type = ele.type
+ ele.type
end
when :TYPE_ARRAY
- type = @contenttype ||= content_arytype
+ @contenttype ||= content_arytype
when :TYPE_MAP
item_ele = find_element_by_name("item") or
raise RuntimeError.new("'item' element not found in Map definition.")
content = item_ele.local_complextype or
raise RuntimeError.new("No complexType definition for 'item'.")
if ele = content.find_element(name)
- type = ele.type
+ ele.type
elsif ele = content.find_element_by_name(name.name)
- type = ele.type
+ ele.type
end
else
raise NotImplementedError.new("Unknown kind of complexType.")
end
- type
end
def child_defined_complextype(name)
@@ -103,16 +105,21 @@ class ComplexType < Info
return attribute.arytype
end
end
- elsif content.elements.size == 1 and content.elements[0].maxoccurs != '1'
+ if check_array_content(complexcontent.content)
+ return complexcontent.content.elements[0].type
+ end
+ elsif check_array_content(content)
return content.elements[0].type
- else
- raise RuntimeError.new("Assert: Unknown array definition.")
end
- nil
+ raise RuntimeError.new("Assert: Unknown array definition.")
end
private
+ def check_array_content(content)
+ content.elements.size == 1 and content.elements[0].maxoccurs != '1'
+ end
+
def content_arytype
if arytype = find_arytype
ns = arytype.namespace
diff --git a/lib/wsdl/soap/definitions.rb b/lib/wsdl/soap/definitions.rb
index 2f6e7e19f0..b014d5af6b 100644
--- a/lib/wsdl/soap/definitions.rb
+++ b/lib/wsdl/soap/definitions.rb
@@ -1,5 +1,5 @@
# WSDL4R - WSDL additional definitions for SOAP.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002-2005 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;
@@ -77,13 +77,13 @@ class Definitions < Info
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.")
+ collect_fault_messages.each do |name|
+ faultparts = message(name).parts
+ if faultparts.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
+ if result.index(faultparts[0].type).nil?
+ result << faultparts[0].type
end
end
result
@@ -111,13 +111,13 @@ private
if op_bind_rpc?(op_bind)
operation = op_bind.find_operation
if op_bind.input
- type = XMLSchema::ComplexType.new(operation_input_name(operation))
+ type = XMLSchema::ComplexType.new(op_bind.soapoperation_name)
message = messages[operation.input.message]
type.sequence_elements = elements_from_message(message)
types << type
end
if op_bind.output
- type = XMLSchema::ComplexType.new(operation_output_name(operation))
+ type = XMLSchema::ComplexType.new(operation.outputname)
message = messages[operation.output.message]
type.sequence_elements = elements_from_message(message)
types << type
@@ -127,23 +127,20 @@ private
types
end
- def operation_input_name(operation)
- operation.input.name || operation.name
- end
-
- def operation_output_name(operation)
- operation.output.name ||
- XSD::QName.new(operation.name.namespace, operation.name.name + "Response")
- end
-
def op_bind_rpc?(op_bind)
- op_bind.soapoperation and op_bind.soapoperation.operation_style == :rpc
+ op_bind.soapoperation_style == :rpc
end
def elements_from_message(message)
message.parts.collect { |part|
- qname = XSD::QName.new(nil, part.name)
- XMLSchema::Element.new(qname, part.type)
+ if part.element
+ collect_elements[part.element]
+ elsif part.name.nil? or part.type.nil?
+ raise RuntimeError.new("part of a message must be an element or typed")
+ else
+ qname = XSD::QName.new(nil, part.name)
+ XMLSchema::Element.new(qname, part.type)
+ end
}
end
end
diff --git a/lib/wsdl/soap/driverCreator.rb b/lib/wsdl/soap/driverCreator.rb
index b752ee336d..dd504210f1 100644
--- a/lib/wsdl/soap/driverCreator.rb
+++ b/lib/wsdl/soap/driverCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating driver code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -46,16 +46,17 @@ private
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
+ return '' unless binding.soapbinding # not a SOAP binding
+ address = @definitions.porttype(name).locations[0]
- c = ::XSD::CodeGen::ClassDef.new(class_name, "::SOAP::RPC::Driver")
+ 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_const("DefaultEndpointUrl", ndq(address))
c.def_code(mr_creator.dump(types))
c.def_code <<-EOD
Methods = [
-#{ methoddef.gsub(/^/, " ") }
+#{methoddef.gsub(/^/, " ")}
]
EOD
c.def_method("initialize", "endpoint_url = nil") do
@@ -69,14 +70,19 @@ Methods = [
c.def_privatemethod("init_methods") do
<<-EOD
Methods.each do |name_as, name, params, soapaction, namespace, style|
- qname = ::XSD::QName.new(namespace, name_as)
+ qname = XSD::QName.new(namespace, name_as)
if style == :document
- @proxy.add_document_method(qname, soapaction, name, params)
- add_document_method_interface(name, name_as)
+ @proxy.add_document_method(soapaction, name, params)
+ add_document_method_interface(name, params)
else
@proxy.add_rpc_method(qname, soapaction, name, params)
add_rpc_method_interface(name, params)
end
+ if name_as != name and name_as.capitalize == name.capitalize
+ ::SOAP::Mapping.define_singleton_method(self, name_as) do |*arg|
+ __send__(name, *arg)
+ end
+ end
end
EOD
end
diff --git a/lib/wsdl/soap/element.rb b/lib/wsdl/soap/element.rb
index c39a00d25a..0fa6017c5b 100644
--- a/lib/wsdl/soap/element.rb
+++ b/lib/wsdl/soap/element.rb
@@ -21,12 +21,6 @@ class Element < Info
def attributes
@local_complextype.attributes
end
-
- def each_element
- @local_complextype.each_element do |element|
- yield(element)
- end
- end
end
diff --git a/lib/wsdl/soap/fault.rb b/lib/wsdl/soap/fault.rb
index 019c881f97..2862b659ab 100644
--- a/lib/wsdl/soap/fault.rb
+++ b/lib/wsdl/soap/fault.rb
@@ -27,6 +27,10 @@ class Fault < Info
@namespace = nil
end
+ def targetnamespace
+ parent.targetnamespace
+ end
+
def parse_element(element)
nil
end
diff --git a/lib/wsdl/soap/header.rb b/lib/wsdl/soap/header.rb
index 247531a76d..8d7c4e9d70 100644
--- a/lib/wsdl/soap/header.rb
+++ b/lib/wsdl/soap/header.rb
@@ -32,8 +32,12 @@ class Header < Info
@headerfault = nil
end
+ def targetnamespace
+ parent.targetnamespace
+ end
+
def find_message
- root.message(@message)
+ root.message(@message) or raise RuntimeError.new("#{@message} not found")
end
def find_part
@@ -42,7 +46,7 @@ class Header < Info
return part
end
end
- nil
+ raise RuntimeError.new("#{@part} not found")
end
def parse_element(element)
@@ -59,7 +63,10 @@ class Header < Info
def parse_attr(attr, value)
case attr
when MessageAttrName
- @message = XSD::QName.new(targetnamespace, value.source)
+ if value.namespace.nil?
+ value = XSD::QName.new(targetnamespace, value.source)
+ end
+ @message = value
when PartAttrName
@part = value.source
when UseAttrName
diff --git a/lib/wsdl/soap/mappingRegistryCreator.rb b/lib/wsdl/soap/mappingRegistryCreator.rb
index d3b28f47e0..8669339ce4 100644
--- a/lib/wsdl/soap/mappingRegistryCreator.rb
+++ b/lib/wsdl/soap/mappingRegistryCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating MappingRegistry code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -38,7 +38,7 @@ class MappingRegistryCreator
end
end
end
- end
+ end
return map
end
@@ -51,8 +51,10 @@ private
dump_struct_typemap(definedtype)
when :TYPE_ARRAY
dump_array_typemap(definedtype)
+ when :TYPE_MAP, :TYPE_EMPTY
+ nil
else
- raise NotImplementedError.new("Must not reach here.")
+ raise NotImplementedError.new("must not reach here")
end
end
end
@@ -61,10 +63,10 @@ private
ele = definedtype.name
return <<__EOD__
MappingRegistry.set(
- #{ create_class_name(ele) },
+ #{create_class_name(ele)},
::SOAP::SOAPStruct,
::SOAP::Mapping::Registry::TypedStructFactory,
- { :type => ::XSD::QName.new("#{ ele.namespace }", "#{ ele.name }") }
+ { :type => #{dqname(ele)} }
)
__EOD__
end
@@ -76,10 +78,10 @@ __EOD__
@types << type
return <<__EOD__
MappingRegistry.set(
- #{ create_class_name(ele) },
+ #{create_class_name(ele)},
::SOAP::SOAPArray,
::SOAP::Mapping::Registry::TypedArrayFactory,
- { :type => ::XSD::QName.new("#{ type.namespace }", "#{ type.name }") }
+ { :type => #{dqname(type)} }
)
__EOD__
end
diff --git a/lib/wsdl/soap/methodDefCreator.rb b/lib/wsdl/soap/methodDefCreator.rb
index 59b8ee4253..f256b42451 100644
--- a/lib/wsdl/soap/methodDefCreator.rb
+++ b/lib/wsdl/soap/methodDefCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating driver code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -8,6 +8,7 @@
require 'wsdl/info'
require 'wsdl/soap/classDefCreatorSupport'
+require 'soap/rpc/element'
module WSDL
@@ -24,75 +25,80 @@ class MethodDefCreator
@simpletypes = @definitions.collect_simpletypes
@complextypes = @definitions.collect_complextypes
@elements = @definitions.collect_elements
- @types = nil
+ @types = []
end
def dump(porttype)
- @types = []
+ @types.clear
result = ""
operations = @definitions.porttype(porttype).operations
binding = @definitions.porttype_binding(porttype)
operations.each do |operation|
op_bind = binding.operations[operation.name]
+ next unless op_bind # no binding is defined
+ next unless op_bind.soapoperation # not a SOAP operation binding
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
- stylestr = binding.soapoperation.operation_style.id2name
- if binding.soapoperation.operation_style == :rpc
- soapaction = binding.soapoperation.soapaction
- namespace = binding.input.soapbody.namespace
- params = collect_rpcparameter(operation)
- else
- soapaction = namespace = nil
- params = collect_documentparameter(operation)
- end
- paramstr = param2str(params)
- if paramstr.empty?
- paramstr = '[]'
- else
- paramstr = "[\n" << paramstr.gsub(/^/, ' ') << "\n ]"
- end
- return <<__EOD__
-[#{ dq(name_as) }, #{ dq(name) },
- #{ paramstr },
- #{ ndq(soapaction) }, #{ ndq(namespace) }, #{ sym(stylestr) }
-]
-__EOD__
- end
-
def collect_rpcparameter(operation)
result = operation.inputparts.collect { |part|
collect_type(part.type)
- param_set('in', rpcdefinedtype(part), part.name)
+ param_set(::SOAP::RPC::SOAPMethod::IN, rpcdefinedtype(part), part.name)
}
outparts = operation.outputparts
if outparts.size > 0
retval = outparts[0]
collect_type(retval.type)
- result << param_set('retval', rpcdefinedtype(retval), retval.name)
+ result << param_set(::SOAP::RPC::SOAPMethod::RETVAL,
+ rpcdefinedtype(retval), retval.name)
cdr(outparts).each { |part|
collect_type(part.type)
- result << param_set('out', rpcdefinedtype(part), part.name)
+ result << param_set(::SOAP::RPC::SOAPMethod::OUT, rpcdefinedtype(part),
+ part.name)
}
end
result
end
def collect_documentparameter(operation)
- input = operation.inputparts[0]
- output = operation.outputparts[0]
- [
- param_set('input', documentdefinedtype(input), input.name),
- param_set('output', documentdefinedtype(output), output.name)
- ]
+ param = []
+ operation.inputparts.each do |input|
+ param << param_set(::SOAP::RPC::SOAPMethod::IN,
+ documentdefinedtype(input), input.name)
+ end
+ operation.outputparts.each do |output|
+ param << param_set(::SOAP::RPC::SOAPMethod::OUT,
+ documentdefinedtype(output), output.name)
+ end
+ param
+ end
+
+private
+
+ def dump_method(operation, binding)
+ name = safemethodname(operation.name.name)
+ name_as = operation.name.name
+ style = binding.soapoperation_style
+ namespace = binding.input.soapbody.namespace
+ if style == :rpc
+ paramstr = param2str(collect_rpcparameter(operation))
+ else
+ paramstr = param2str(collect_documentparameter(operation))
+ end
+ if paramstr.empty?
+ paramstr = '[]'
+ else
+ paramstr = "[\n" << paramstr.gsub(/^/, ' ') << "\n ]"
+ end
+ return <<__EOD__
+[#{dq(name_as)}, #{dq(name)},
+ #{paramstr},
+ #{ndq(binding.soapaction)}, #{ndq(namespace)}, #{sym(style.id2name)}
+]
+__EOD__
end
def rpcdefinedtype(part)
@@ -101,33 +107,40 @@ __EOD__
elsif definedtype = @simpletypes[part.type]
['::' + basetype_mapped_class(definedtype.base).name]
elsif definedtype = @elements[part.element]
- ['::SOAP::SOAPStruct', part.element.namespace, part.element.name]
+ #['::SOAP::SOAPStruct', part.element.namespace, part.element.name]
+ ['nil', part.element.namespace, part.element.name]
elsif definedtype = @complextypes[part.type]
case definedtype.compoundtype
- when :TYPE_STRUCT
- ['::SOAP::SOAPStruct', part.type.namespace, part.type.name]
+ when :TYPE_STRUCT, :TYPE_EMPTY # ToDo: empty should be treated as void.
+ type = create_class_name(part.type)
+ [type, part.type.namespace, part.type.name]
+ when :TYPE_MAP
+ [Hash.name, 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]
+ type = create_class_name(XSD::QName.new(ns, name))
+ [type + '[]', ns, name]
else
- raise NotImplementedError.new("Must not reach here.")
+ raise NotImplementedError.new("must not reach here")
end
else
- raise RuntimeError.new("Part: #{part.name} cannot be resolved.")
+ raise RuntimeError.new("part: #{part.name} cannot be resolved")
end
end
def documentdefinedtype(part)
- if definedtype = @simpletypes[part.type]
+ if mapped = basetype_mapped_class(part.type)
+ ['::' + mapped.name, nil, part.name]
+ elsif definedtype = @simpletypes[part.type]
['::' + basetype_mapped_class(definedtype.base).name, nil, part.name]
elsif definedtype = @elements[part.element]
['::SOAP::SOAPElement', part.element.namespace, part.element.name]
elsif definedtype = @complextypes[part.type]
['::SOAP::SOAPElement', part.type.namespace, part.type.name]
else
- raise RuntimeError.new("Part: #{part.name} cannot be resolved.")
+ raise RuntimeError.new("part: #{part.name} cannot be resolved")
end
end
@@ -138,6 +151,7 @@ __EOD__
def collect_type(type)
# ignore inline type definition.
return if type.nil?
+ return if @types.include?(type)
@types << type
return unless @complextypes[type]
@complextypes[type].each_element do |element|
@@ -147,15 +161,15 @@ __EOD__
def param2str(params)
params.collect { |param|
- "[#{ dq(param[0]) }, #{ dq(param[2]) }, #{ type2str(param[1]) }]"
+ "[#{dq(param[0])}, #{dq(param[2])}, #{type2str(param[1])}]"
}.join(",\n")
end
def type2str(type)
if type.size == 1
- "[#{ type[0] }]"
+ "[#{dq(type[0])}]"
else
- "[#{ type[0] }, #{ ndq(type[1]) }, #{ dq(type[2]) }]"
+ "[#{dq(type[0])}, #{ndq(type[1])}, #{dq(type[2])}]"
end
end
diff --git a/lib/wsdl/soap/operation.rb b/lib/wsdl/soap/operation.rb
index 51bb2e9403..502d34a07d 100644
--- a/lib/wsdl/soap/operation.rb
+++ b/lib/wsdl/soap/operation.rb
@@ -101,8 +101,7 @@ private
"EncodingStyle '#{ soapbody.encodingstyle }' not supported.")
end
if soapbody.namespace
- op_name = op_name.dup
- op_name.namespace = soapbody.namespace
+ op_name = XSD::QName.new(soapbody.namespace, op_name.name)
end
if soapbody.parts
target = soapbody.parts.split(/\s+/)
@@ -114,8 +113,7 @@ private
end
faultpart = nil
- soapaction = parent.soapoperation.soapaction
- OperationInfo.new(operation_style, op_name, optype_name, headerparts, bodyparts, faultpart, soapaction)
+ OperationInfo.new(operation_style, op_name, optype_name, headerparts, bodyparts, faultpart, parent.soapaction)
end
end
diff --git a/lib/wsdl/soap/servantSkeltonCreator.rb b/lib/wsdl/soap/servantSkeltonCreator.rb
index 12761ab5b4..88294ffed8 100644
--- a/lib/wsdl/soap/servantSkeltonCreator.rb
+++ b/lib/wsdl/soap/servantSkeltonCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating servant skelton code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -17,7 +17,7 @@ module SOAP
class ServantSkeltonCreator
include ClassDefCreatorSupport
- include ::XSD::CodeGen::GenSupport
+ include XSD::CodeGen::GenSupport
attr_reader :definitions
@@ -42,7 +42,7 @@ private
def dump_porttype(name)
class_name = create_class_name(name)
- c = ::XSD::CodeGen::ClassDef.new(class_name)
+ c = XSD::CodeGen::ClassDef.new(class_name)
operations = @definitions.porttype(name).operations
operations.each do |operation|
name = safemethodname(operation.name.name)
@@ -50,7 +50,7 @@ private
params = input.find_message.parts.collect { |part|
safevarname(part.name)
}
- m = ::XSD::CodeGen::MethodDef.new(name, params) do <<-EOD
+ m = XSD::CodeGen::MethodDef.new(name, params) do <<-EOD
p [#{params.join(", ")}]
raise NotImplementedError.new
EOD
diff --git a/lib/wsdl/soap/standaloneServerStubCreator.rb b/lib/wsdl/soap/standaloneServerStubCreator.rb
index 779139a5f4..243ac12216 100644
--- a/lib/wsdl/soap/standaloneServerStubCreator.rb
+++ b/lib/wsdl/soap/standaloneServerStubCreator.rb
@@ -1,5 +1,5 @@
# WSDL4R - Creating standalone server stub code from WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -26,10 +26,8 @@ class StandaloneServerStubCreator
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 !!!"
+ warn("- Standalone stub can have only 1 port for now. So creating stub for the first port and rests are ignored.")
+ warn("- 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 manually.")
port = @definitions.service(service_name).ports[0]
dump_porttype(port.porttype.name)
end
@@ -41,28 +39,28 @@ private
methoddef, types = MethodDefCreator.new(@definitions).dump(name)
mr_creator = MappingRegistryCreator.new(@definitions)
- c1 = ::XSD::CodeGen::ClassDef.new(class_name)
+ 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(/^/, " ") }
+#{methoddef.gsub(/^/, " ")}
]
EOD
- c2 = ::XSD::CodeGen::ClassDef.new(class_name + "App",
+ 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, param_def, soapaction, namespace, style|
- qname = XSD::QName.new(namespace, name_as)
if style == :document
- @soaplet.app_scope_router.add_document_method(servant, qname, soapaction, name, param_def)
+ @router.add_document_operation(servant, soapaction, name, param_def)
else
- @soaplet.app_scope_router.add_rpc_method(servant, qname, soapaction, name, param_def)
+ qname = XSD::QName.new(namespace, name_as)
+ @router.add_rpc_operation(servant, qname, soapaction, name, param_def)
end
end
self.mapping_registry = #{class_name}::MappingRegistry
diff --git a/lib/wsdl/xmlSchema/attribute.rb b/lib/wsdl/xmlSchema/attribute.rb
index 6861fc171e..cfd4c68422 100644
--- a/lib/wsdl/xmlSchema/attribute.rb
+++ b/lib/wsdl/xmlSchema/attribute.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema attribute definition for WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -14,34 +14,74 @@ module XMLSchema
class Attribute < Info
- attr_accessor :ref
- attr_accessor :use
- attr_accessor :form
- attr_accessor :name
- attr_accessor :type
- attr_accessor :default
- attr_accessor :fixed
+ class << self
+ if RUBY_VERSION > "1.7.0"
+ def attr_reader_ref(symbol)
+ name = symbol.to_s
+ self.__send__(:define_method, name, proc {
+ instance_variable_get("@#{name}") ||
+ (refelement ? refelement.__send__(name) : nil)
+ })
+ end
+ else
+ def attr_reader_ref(symbol)
+ name = symbol.to_s
+ module_eval <<-EOS
+ def #{name}
+ @#{name} || (refelement ? refelement.#{name} : nil)
+ end
+ EOS
+ end
+ end
+ end
+
+ attr_writer :use
+ attr_writer :form
+ attr_writer :name
+ attr_writer :type
+ attr_writer :local_simpletype
+ attr_writer :default
+ attr_writer :fixed
+
+ attr_reader_ref :use
+ attr_reader_ref :form
+ attr_reader_ref :name
+ attr_reader_ref :type
+ attr_reader_ref :local_simpletype
+ attr_reader_ref :default
+ attr_reader_ref :fixed
+ attr_accessor :ref
attr_accessor :arytype
def initialize
super
- @ref = nil
@use = nil
@form = nil
@name = nil
@type = nil
+ @local_simpletype = nil
@default = nil
@fixed = nil
+ @ref = nil
+ @refelement = nil
@arytype = nil
end
+ def refelement
+ @refelement ||= root.collect_attributes[@ref]
+ end
+
def targetnamespace
parent.targetnamespace
end
def parse_element(element)
- nil
+ case element
+ when SimpleTypeName
+ @local_simpletype = SimpleType.new
+ @local_simpletype
+ end
end
def parse_attr(attr, value)
diff --git a/lib/wsdl/xmlSchema/complexContent.rb b/lib/wsdl/xmlSchema/complexContent.rb
index 66ad9e251d..eddb52f5ef 100644
--- a/lib/wsdl/xmlSchema/complexContent.rb
+++ b/lib/wsdl/xmlSchema/complexContent.rb
@@ -26,12 +26,17 @@ class ComplexContent < Info
@derivetype = nil
@content = nil
@attributes = XSD::NamedElements.new
+ @basetype = nil
end
def targetnamespace
parent.targetnamespace
end
+ def basetype
+ @basetype ||= root.collect_complextypes[@base]
+ end
+
def parse_element(element)
case element
when RestrictionName, ExtensionName
diff --git a/lib/wsdl/xmlSchema/data.rb b/lib/wsdl/xmlSchema/data.rb
index 10bc343adb..23ab1adf0b 100644
--- a/lib/wsdl/xmlSchema/data.rb
+++ b/lib/wsdl/xmlSchema/data.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema data definitions.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -7,10 +7,13 @@
require 'xsd/datatypes'
+require 'wsdl/xmlSchema/annotation'
require 'wsdl/xmlSchema/schema'
require 'wsdl/xmlSchema/import'
+require 'wsdl/xmlSchema/include'
require 'wsdl/xmlSchema/simpleType'
require 'wsdl/xmlSchema/simpleRestriction'
+require 'wsdl/xmlSchema/simpleExtension'
require 'wsdl/xmlSchema/complexType'
require 'wsdl/xmlSchema/complexContent'
require 'wsdl/xmlSchema/simpleContent'
@@ -22,12 +25,15 @@ require 'wsdl/xmlSchema/sequence'
require 'wsdl/xmlSchema/attribute'
require 'wsdl/xmlSchema/unique'
require 'wsdl/xmlSchema/enumeration'
+require 'wsdl/xmlSchema/length'
+require 'wsdl/xmlSchema/pattern'
module WSDL
module XMLSchema
AllName = XSD::QName.new(XSD::Namespace, 'all')
+AnnotationName = XSD::QName.new(XSD::Namespace, 'annotation')
AnyName = XSD::QName.new(XSD::Namespace, 'any')
AttributeName = XSD::QName.new(XSD::Namespace, 'attribute')
ChoiceName = XSD::QName.new(XSD::Namespace, 'choice')
@@ -37,6 +43,9 @@ 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')
+IncludeName = XSD::QName.new(XSD::Namespace, 'include')
+LengthName = XSD::QName.new(XSD::Namespace, 'length')
+PatternName = XSD::QName.new(XSD::Namespace, 'pattern')
RestrictionName = XSD::QName.new(XSD::Namespace, 'restriction')
SequenceName = XSD::QName.new(XSD::Namespace, 'sequence')
SchemaName = XSD::QName.new(XSD::Namespace, 'schema')
diff --git a/lib/wsdl/xmlSchema/element.rb b/lib/wsdl/xmlSchema/element.rb
index cc9d4e9ed8..584afe9dc6 100644
--- a/lib/wsdl/xmlSchema/element.rb
+++ b/lib/wsdl/xmlSchema/element.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema element definition for WSDL.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -14,23 +14,62 @@ module XMLSchema
class Element < Info
- attr_accessor :name # required
- attr_accessor :type
- attr_accessor :local_complextype
- attr_accessor :constraint
- attr_accessor :maxoccurs
- attr_accessor :minoccurs
- attr_accessor :nillable
-
- def initialize(name = nil, type = XSD::AnyTypeName)
+ class << self
+ if RUBY_VERSION > "1.7.0"
+ def attr_reader_ref(symbol)
+ name = symbol.to_s
+ self.__send__(:define_method, name, proc {
+ instance_variable_get("@#{name}") ||
+ (refelement ? refelement.__send__(name) : nil)
+ })
+ end
+ else
+ def attr_reader_ref(symbol)
+ name = symbol.to_s
+ module_eval <<-EOS
+ def #{name}
+ @#{name} || (refelement ? refelement.#{name} : nil)
+ end
+ EOS
+ end
+ end
+ end
+
+ attr_writer :name # required
+ attr_writer :type
+ attr_writer :local_simpletype
+ attr_writer :local_complextype
+ attr_writer :constraint
+ attr_writer :maxoccurs
+ attr_writer :minoccurs
+ attr_writer :nillable
+
+ attr_reader_ref :name
+ attr_reader_ref :type
+ attr_reader_ref :local_simpletype
+ attr_reader_ref :local_complextype
+ attr_reader_ref :constraint
+ attr_reader_ref :maxoccurs
+ attr_reader_ref :minoccurs
+ attr_reader_ref :nillable
+
+ attr_accessor :ref
+
+ def initialize(name = nil, type = nil)
super()
@name = name
@type = type
- @local_complextype = nil
+ @local_simpletype = @local_complextype = nil
@constraint = nil
@maxoccurs = '1'
@minoccurs = '1'
@nillable = nil
+ @ref = nil
+ @refelement = nil
+ end
+
+ def refelement
+ @refelement ||= root.collect_elements[@ref]
end
def targetnamespace
@@ -44,6 +83,9 @@ class Element < Info
def parse_element(element)
case element
+ when SimpleTypeName
+ @local_simpletype = SimpleType.new
+ @local_simpletype
when ComplexTypeName
@type = nil
@local_complextype = ComplexType.new
@@ -62,19 +104,19 @@ class Element < Info
@name = XSD::QName.new(targetnamespace, value.source)
when TypeAttrName
@type = value
+ when RefAttrName
+ @ref = value
when MaxOccursAttrName
if parent.is_a?(All)
if value.source != '1'
- raise Parser::AttrConstraintError.new(
- "Cannot parse #{ value } for #{ attr }.")
+ raise Parser::AttrConstraintError.new("cannot parse #{value} for #{attr}")
end
end
@maxoccurs = value.source
when MinOccursAttrName
if parent.is_a?(All)
unless ['0', '1'].include?(value.source)
- raise Parser::AttrConstraintError.new(
- "Cannot parse #{ value } for #{ attr }.")
+ raise Parser::AttrConstraintError.new("cannot parse #{value} for #{attr}")
end
end
@minoccurs = value.source
diff --git a/lib/wsdl/xmlSchema/import.rb b/lib/wsdl/xmlSchema/import.rb
index e65641330d..d3487af934 100644
--- a/lib/wsdl/xmlSchema/import.rb
+++ b/lib/wsdl/xmlSchema/import.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema import definition.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -7,6 +7,7 @@
require 'wsdl/info'
+require 'wsdl/xmlSchema/importer'
module WSDL
@@ -16,11 +17,13 @@ module XMLSchema
class Import < Info
attr_reader :namespace
attr_reader :schemalocation
+ attr_reader :content
def initialize
super
@namespace = nil
@schemalocation = nil
+ @content = nil
end
def parse_element(element)
@@ -32,11 +35,29 @@ class Import < Info
when NamespaceAttrName
@namespace = value.source
when SchemaLocationAttrName
- @schemalocation = value.source
+ @schemalocation = URI.parse(value.source)
+ if @schemalocation.relative? and !parent.location.nil? and
+ !parent.location.relative?
+ @schemalocation = parent.location + @schemalocation
+ end
+ if root.importedschema.key?(@schemalocation)
+ @content = root.importedschema[@schemalocation]
+ else
+ root.importedschema[@schemalocation] = nil # placeholder
+ @content = import(@schemalocation)
+ root.importedschema[@schemalocation] = @content
+ end
+ @schemalocation
else
nil
end
end
+
+private
+
+ def import(location)
+ Importer.import(location, root)
+ end
end
diff --git a/lib/wsdl/xmlSchema/parser.rb b/lib/wsdl/xmlSchema/parser.rb
index a7f1c29fd4..057d9d9b70 100644
--- a/lib/wsdl/xmlSchema/parser.rb
+++ b/lib/wsdl/xmlSchema/parser.rb
@@ -1,5 +1,5 @@
# WSDL4R - WSDL XML Instance parser library.
-# Copyright (C) 2002, 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2002, 2003, 2005 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;
@@ -51,6 +51,9 @@ public
@parser = XSD::XMLParser.create_parser(self, opt)
@parsestack = nil
@lastnode = nil
+ @ignored = {}
+ @location = opt[:location]
+ @originalroot = opt[:originalroot]
end
def parse(string_or_readable)
@@ -94,7 +97,7 @@ public
def end_element(name)
lastframe = @parsestack.pop
unless name == lastframe.name
- raise UnexpectedElementError.new("Closing element name '#{ name }' does not match with opening element '#{ lastframe.name }'.")
+ raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'")
end
decode_tag_end(lastframe.ns, lastframe.node)
@lastnode = lastframe.node
@@ -104,20 +107,31 @@ private
def decode_tag(ns, name, attrs, parent)
o = nil
- element = ns.parse(name)
+ elename = ns.parse(name)
if !parent
- if element == SchemaName
- o = Schema.parse_element(element)
+ if elename == SchemaName
+ o = Schema.parse_element(elename)
+ o.location = @location
else
- raise UnknownElementError.new("Unknown element #{ element }.")
+ raise UnknownElementError.new("unknown element: #{elename}")
end
+ o.root = @originalroot if @originalroot # o.root = o otherwise
else
- o = parent.parse_element(element)
+ if elename == AnnotationName
+ # only the first annotation element is allowed for each element.
+ o = Annotation.new
+ else
+ o = parent.parse_element(elename)
+ end
unless o
- STDERR.puts("Unknown element #{ element }.")
+ unless @ignored.key?(elename)
+ warn("ignored element: #{elename} of #{parent.class}")
+ @ignored[elename] = elename
+ end
o = Documentation.new # which accepts any element.
end
# node could be a pseudo element. pseudo element has its own parent.
+ o.root = parent.root
o.parent = parent if o.parent.nil?
end
attrs.each do |key, value|
@@ -127,9 +141,12 @@ private
if attr_ele == IdAttrName
o.id = value_ele
else
- unless o.parse_attr(attr_ele, value_ele)
- STDERR.puts("Unknown attr #{ attr_ele }.")
- end
+ unless o.parse_attr(attr_ele, value_ele)
+ unless @ignored.key?(attr_ele)
+ warn("ignored attr: #{attr_ele}")
+ @ignored[attr_ele] = attr_ele
+ end
+ end
end
end
o
diff --git a/lib/wsdl/xmlSchema/schema.rb b/lib/wsdl/xmlSchema/schema.rb
index ddd231bd97..43447f9fbf 100644
--- a/lib/wsdl/xmlSchema/schema.rb
+++ b/lib/wsdl/xmlSchema/schema.rb
@@ -24,6 +24,8 @@ class Schema < Info
attr_accessor :attributeformdefault
attr_accessor :elementformdefault
+ attr_reader :importedschema
+
def initialize
super
@targetnamespace = nil
@@ -33,6 +35,17 @@ class Schema < Info
@attributes = XSD::NamedElements.new
@imports = []
@elementformdefault = "qualified"
+ @importedschema = {}
+ @location = nil
+ @root = self
+ end
+
+ def location
+ @location || (root.nil? ? nil : root.location)
+ end
+
+ def location=(location)
+ @location = location
end
def parse_element(element)
@@ -41,6 +54,10 @@ class Schema < Info
o = Import.new
@imports << o
o
+ when IncludeName
+ o = Include.new
+ @imports << o
+ o
when ComplexTypeName
o = ComplexType.new
@complextypes << o
@@ -55,6 +72,7 @@ class Schema < Info
o
when AttributeName
o = Attribute.new
+ @attributes << o
o
else
nil
@@ -74,21 +92,39 @@ class Schema < Info
end
end
+ def collect_attributes
+ result = XSD::NamedElements.new
+ result.concat(@attributes)
+ @imports.each do |import|
+ result.concat(import.content.collect_attributes) if import.content
+ end
+ result
+ end
+
def collect_elements
result = XSD::NamedElements.new
result.concat(@elements)
+ @imports.each do |import|
+ result.concat(import.content.collect_elements) if import.content
+ end
result
end
def collect_complextypes
result = XSD::NamedElements.new
result.concat(@complextypes)
+ @imports.each do |import|
+ result.concat(import.content.collect_complextypes) if import.content
+ end
result
end
def collect_simpletypes
result = XSD::NamedElements.new
result.concat(@simpletypes)
+ @imports.each do |import|
+ result.concat(import.content.collect_simpletypes) if import.content
+ end
result
end
diff --git a/lib/wsdl/xmlSchema/simpleContent.rb b/lib/wsdl/xmlSchema/simpleContent.rb
index 0d83678a01..e1f35c88b8 100644
--- a/lib/wsdl/xmlSchema/simpleContent.rb
+++ b/lib/wsdl/xmlSchema/simpleContent.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema simpleContent definition for WSDL.
-# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2004, 2005 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;
@@ -15,17 +15,21 @@ module XMLSchema
class SimpleContent < Info
- attr_accessor :base
- attr_reader :derivetype
- attr_reader :content
- attr_reader :attributes
+ attr_reader :restriction
+ attr_reader :extension
+
+ def check_lexical_format(value)
+ check(value)
+ end
def initialize
super
- @base = nil
- @derivetype = nil
- @content = nil
- @attributes = XSD::NamedElements.new
+ @restriction = nil
+ @extension = nil
+ end
+
+ def base
+ content.base
end
def targetnamespace
@@ -34,28 +38,24 @@ class SimpleContent < Info
def parse_element(element)
case element
- when RestrictionName, ExtensionName
- @derivetype = element.name
- self
- when AttributeName
- if @derivetype.nil?
- raise Parser::ElementConstraintError.new("base attr not found.")
- end
- o = Attribute.new
- @attributes << o
- o
+ when RestrictionName
+ @restriction = SimpleRestriction.new
+ @restriction
+ when ExtensionName
+ @extension = SimpleExtension.new
+ @extension
end
end
- def parse_attr(attr, value)
- if @derivetype.nil?
- return nil
- end
- case attr
- when BaseAttrName
- @base = value
- else
- nil
+private
+
+ def content
+ @restriction || @extension
+ end
+
+ def check(value)
+ unless content.valid?(value)
+ raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'")
end
end
end
diff --git a/lib/wsdl/xmlSchema/simpleRestriction.rb b/lib/wsdl/xmlSchema/simpleRestriction.rb
index 6986e74423..e8bf3ebfa5 100644
--- a/lib/wsdl/xmlSchema/simpleRestriction.rb
+++ b/lib/wsdl/xmlSchema/simpleRestriction.rb
@@ -1,4 +1,4 @@
-# WSDL4R - XMLSchema simpleType definition for WSDL.
+# WSDL4R - XMLSchema simpleContent restriction definition for WSDL.
# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
@@ -17,21 +17,32 @@ module XMLSchema
class SimpleRestriction < Info
attr_reader :base
attr_reader :enumeration
+ attr_accessor :length
+ attr_accessor :pattern
def initialize
super
@base = nil
@enumeration = [] # NamedElements?
+ @length = nil
+ @pattern = nil
end
def valid?(value)
- @enumeration.include?(value)
+ return false unless check_restriction(value)
+ return false unless check_length(value)
+ return false unless check_pattern(value)
+ true
end
def parse_element(element)
case element
when EnumerationName
Enumeration.new # just a parsing handler
+ when LengthName
+ Length.new # just a parsing handler
+ when PatternName
+ Pattern.new # just a parsing handler
end
end
@@ -41,6 +52,20 @@ class SimpleRestriction < Info
@base = value
end
end
+
+private
+
+ def check_restriction(value)
+ @enumeration.empty? or @enumeration.include?(value)
+ end
+
+ def check_length(value)
+ @length.nil? or value.size == @length
+ end
+
+ def check_pattern(value)
+ @pattern.nil? or @pattern =~ value
+ end
end
diff --git a/lib/wsdl/xmlSchema/simpleType.rb b/lib/wsdl/xmlSchema/simpleType.rb
index d9f76f345c..e808c318c4 100644
--- a/lib/wsdl/xmlSchema/simpleType.rb
+++ b/lib/wsdl/xmlSchema/simpleType.rb
@@ -1,5 +1,5 @@
# WSDL4R - XMLSchema simpleType definition for WSDL.
-# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
+# Copyright (C) 2004, 2005 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;
@@ -16,15 +16,11 @@ 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
@@ -33,8 +29,6 @@ class SimpleType < Info
def base
if @restriction
@restriction.base
- elsif @extension
- @extension.base
else
raise ArgumentError.new("incomplete simpleType")
end
@@ -43,7 +37,6 @@ class SimpleType < Info
def initialize(name = nil)
super()
@name = name
- @derivetype = nil
@restriction = nil
end
@@ -55,7 +48,6 @@ class SimpleType < Info
case element
when RestrictionName
@restriction = SimpleRestriction.new
- @derivetype = element.name
@restriction
end
end
@@ -71,7 +63,7 @@ private
def check_restriction(value)
unless @restriction.valid?(value)
- raise ::XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'.")
+ raise XSD::ValueSpaceError.new("#{@name}: cannot accept '#{value}'")
end
end
end