mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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/trunk@8500 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7aea792d3b
commit
eb3f829be9
211 changed files with 5997 additions and 9378 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@web_client = nil
|
||||
end
|
||||
|
||||
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 = {}
|
||||
begin
|
||||
WSDL::Parser.new(opt).parse(content)
|
||||
rescue WSDL::Parser::ParseError => orgexcn
|
||||
require 'wsdl/xmlSchema/parser'
|
||||
WSDL::XMLSchema::Parser.new(opt).parse(content)
|
||||
end
|
||||
class Importer < WSDL::XMLSchema::Importer
|
||||
def self.import(location, originalroot = nil)
|
||||
new.import(location, originalroot)
|
||||
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
|
||||
def parse(content, location, originalroot)
|
||||
opt = {
|
||||
:location => location,
|
||||
:originalroot => originalroot
|
||||
}
|
||||
begin
|
||||
WSDL::Parser.new(opt).parse(content)
|
||||
rescue WSDL::Parser::ParseError
|
||||
super(content, location, originalroot)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 |m|
|
||||
parts = message(m).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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ class Fault < Info
|
|||
@namespace = nil
|
||||
end
|
||||
|
||||
def targetnamespace
|
||||
parent.targetnamespace
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,110 +25,122 @@ 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
|
||||
|
||||
def collect_rpcparameter(operation)
|
||||
result = operation.inputparts.collect { |part|
|
||||
collect_type(part.type)
|
||||
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(::SOAP::RPC::SOAPMethod::RETVAL,
|
||||
rpcdefinedtype(retval), retval.name)
|
||||
cdr(outparts).each { |part|
|
||||
collect_type(part.type)
|
||||
result << param_set(::SOAP::RPC::SOAPMethod::OUT, rpcdefinedtype(part),
|
||||
part.name)
|
||||
}
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def collect_documentparameter(operation)
|
||||
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
|
||||
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)
|
||||
style = binding.soapoperation_style
|
||||
namespace = binding.input.soapbody.namespace
|
||||
if style == :rpc
|
||||
paramstr = param2str(collect_rpcparameter(operation))
|
||||
else
|
||||
soapaction = namespace = nil
|
||||
params = collect_documentparameter(operation)
|
||||
paramstr = param2str(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) }
|
||||
[#{dq(name_as)}, #{dq(name)},
|
||||
#{paramstr},
|
||||
#{ndq(binding.soapaction)}, #{ndq(namespace)}, #{sym(style.id2name)}
|
||||
]
|
||||
__EOD__
|
||||
end
|
||||
|
||||
def collect_rpcparameter(operation)
|
||||
result = operation.inputparts.collect { |part|
|
||||
collect_type(part.type)
|
||||
param_set('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)
|
||||
cdr(outparts).each { |part|
|
||||
collect_type(part.type)
|
||||
result << param_set('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)
|
||||
]
|
||||
end
|
||||
|
||||
def rpcdefinedtype(part)
|
||||
if mapped = basetype_mapped_class(part.type)
|
||||
['::' + mapped.name]
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
176
lib/wsdl/soap/wsdl2ruby.rb
Normal file
176
lib/wsdl/soap/wsdl2ruby.rb
Normal file
|
@ -0,0 +1,176 @@
|
|||
# WSDL4R - WSDL to ruby mapping library.
|
||||
# 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;
|
||||
# either the dual license version in 2003, or any later version.
|
||||
|
||||
|
||||
require 'logger'
|
||||
require 'xsd/qname'
|
||||
require 'wsdl/importer'
|
||||
require 'wsdl/soap/classDefCreator'
|
||||
require 'wsdl/soap/servantSkeltonCreator'
|
||||
require 'wsdl/soap/driverCreator'
|
||||
require 'wsdl/soap/clientSkeltonCreator'
|
||||
require 'wsdl/soap/standaloneServerStubCreator'
|
||||
require 'wsdl/soap/cgiStubCreator'
|
||||
|
||||
|
||||
module WSDL
|
||||
module SOAP
|
||||
|
||||
|
||||
class WSDL2Ruby
|
||||
attr_accessor :location
|
||||
attr_reader :opt
|
||||
attr_accessor :logger
|
||||
attr_accessor :basedir
|
||||
|
||||
def run
|
||||
unless @location
|
||||
raise RuntimeError, "WSDL location not given"
|
||||
end
|
||||
@wsdl = import(@location)
|
||||
@name = @wsdl.name ? @wsdl.name.name : 'default'
|
||||
create_file
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize
|
||||
@location = nil
|
||||
@opt = {}
|
||||
@logger = Logger.new(STDERR)
|
||||
@basedir = nil
|
||||
@wsdl = nil
|
||||
@name = nil
|
||||
end
|
||||
|
||||
def create_file
|
||||
create_classdef if @opt.key?('classdef')
|
||||
create_servant_skelton(@opt['servant_skelton']) if @opt.key?('servant_skelton')
|
||||
create_cgi_stub(@opt['cgi_stub']) if @opt.key?('cgi_stub')
|
||||
create_standalone_server_stub(@opt['standalone_server_stub']) if @opt.key?('standalone_server_stub')
|
||||
create_driver(@opt['driver']) if @opt.key?('driver')
|
||||
create_client_skelton(@opt['client_skelton']) if @opt.key?('client_skelton')
|
||||
end
|
||||
|
||||
def create_classdef
|
||||
@logger.info { "Creating class definition." }
|
||||
@classdef_filename = @name + '.rb'
|
||||
check_file(@classdef_filename) or return
|
||||
write_file(@classdef_filename) do |f|
|
||||
f << WSDL::SOAP::ClassDefCreator.new(@wsdl).dump
|
||||
end
|
||||
end
|
||||
|
||||
def create_client_skelton(servicename)
|
||||
@logger.info { "Creating client skelton." }
|
||||
servicename ||= @wsdl.services[0].name.name
|
||||
@client_skelton_filename = servicename + 'Client.rb'
|
||||
check_file(@client_skelton_filename) or return
|
||||
write_file(@client_skelton_filename) do |f|
|
||||
f << shbang << "\n"
|
||||
f << "require '#{@driver_filename}'\n\n" if @driver_filename
|
||||
f << WSDL::SOAP::ClientSkeltonCreator.new(@wsdl).dump(
|
||||
create_name(servicename))
|
||||
end
|
||||
end
|
||||
|
||||
def create_servant_skelton(porttypename)
|
||||
@logger.info { "Creating servant skelton." }
|
||||
@servant_skelton_filename = (porttypename || @name + 'Servant') + '.rb'
|
||||
check_file(@servant_skelton_filename) or return
|
||||
write_file(@servant_skelton_filename) do |f|
|
||||
f << "require '#{@classdef_filename}'\n\n" if @classdef_filename
|
||||
f << WSDL::SOAP::ServantSkeltonCreator.new(@wsdl).dump(
|
||||
create_name(porttypename))
|
||||
end
|
||||
end
|
||||
|
||||
def create_cgi_stub(servicename)
|
||||
@logger.info { "Creating CGI stub." }
|
||||
servicename ||= @wsdl.services[0].name.name
|
||||
@cgi_stubFilename = servicename + '.cgi'
|
||||
check_file(@cgi_stubFilename) or return
|
||||
write_file(@cgi_stubFilename) do |f|
|
||||
f << shbang << "\n"
|
||||
if @servant_skelton_filename
|
||||
f << "require '#{@servant_skelton_filename}'\n\n"
|
||||
end
|
||||
f << WSDL::SOAP::CGIStubCreator.new(@wsdl).dump(create_name(servicename))
|
||||
end
|
||||
end
|
||||
|
||||
def create_standalone_server_stub(servicename)
|
||||
@logger.info { "Creating standalone stub." }
|
||||
servicename ||= @wsdl.services[0].name.name
|
||||
@standalone_server_stub_filename = servicename + '.rb'
|
||||
check_file(@standalone_server_stub_filename) or return
|
||||
write_file(@standalone_server_stub_filename) do |f|
|
||||
f << shbang << "\n"
|
||||
f << "require '#{@servant_skelton_filename}'\n\n" if @servant_skelton_filename
|
||||
f << WSDL::SOAP::StandaloneServerStubCreator.new(@wsdl).dump(
|
||||
create_name(servicename))
|
||||
end
|
||||
end
|
||||
|
||||
def create_driver(porttypename)
|
||||
@logger.info { "Creating driver." }
|
||||
@driver_filename = (porttypename || @name) + 'Driver.rb'
|
||||
check_file(@driver_filename) or return
|
||||
write_file(@driver_filename) do |f|
|
||||
f << "require '#{@classdef_filename}'\n\n" if @classdef_filename
|
||||
f << WSDL::SOAP::DriverCreator.new(@wsdl).dump(
|
||||
create_name(porttypename))
|
||||
end
|
||||
end
|
||||
|
||||
def write_file(filename)
|
||||
if @basedir
|
||||
filename = File.join(basedir, filename)
|
||||
end
|
||||
File.open(filename, "w") do |f|
|
||||
yield f
|
||||
end
|
||||
end
|
||||
|
||||
def check_file(filename)
|
||||
if @basedir
|
||||
filename = File.join(basedir, filename)
|
||||
end
|
||||
if FileTest.exist?(filename)
|
||||
if @opt.key?('force')
|
||||
@logger.warn {
|
||||
"File '#{filename}' exists but overrides it."
|
||||
}
|
||||
true
|
||||
else
|
||||
@logger.warn {
|
||||
"File '#{filename}' exists. #{$0} did not override it."
|
||||
}
|
||||
false
|
||||
end
|
||||
else
|
||||
@logger.info { "Creates file '#{filename}'." }
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def shbang
|
||||
"#!/usr/bin/env ruby"
|
||||
end
|
||||
|
||||
def create_name(name)
|
||||
name ? XSD::QName.new(@wsdl.targetnamespace, name) : nil
|
||||
end
|
||||
|
||||
def import(location)
|
||||
WSDL::Importer.import(location)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
34
lib/wsdl/xmlSchema/annotation.rb
Normal file
34
lib/wsdl/xmlSchema/annotation.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# WSDL4R - WSDL SOAP documentation element.
|
||||
# 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'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class Annotation < Info
|
||||
def initialize
|
||||
super
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
# Accepts any element.
|
||||
self
|
||||
end
|
||||
|
||||
def parse_attr(attr, value)
|
||||
# Accepts any attribute.
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
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
|
||||
|
||||
def initialize(name = nil, type = XSD::AnyTypeName)
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
81
lib/wsdl/xmlSchema/importer.rb
Normal file
81
lib/wsdl/xmlSchema/importer.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
# WSDL4R - XSD importer library.
|
||||
# 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 'soap/httpconfigloader'
|
||||
require 'wsdl/xmlSchema/parser'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class Importer
|
||||
def self.import(location, originalroot = nil)
|
||||
new.import(location, originalroot)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@web_client = nil
|
||||
end
|
||||
|
||||
def import(location, originalroot = nil)
|
||||
unless location.is_a?(URI)
|
||||
location = URI.parse(location)
|
||||
end
|
||||
content = parse(fetch(location), location, originalroot)
|
||||
content.location = location
|
||||
content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse(content, location, originalroot)
|
||||
opt = {
|
||||
:location => location,
|
||||
:originalroot => originalroot
|
||||
}
|
||||
WSDL::XMLSchema::Parser.new(opt).parse(content)
|
||||
end
|
||||
|
||||
def fetch(location)
|
||||
warn("importing: #{location}") if $DEBUG
|
||||
content = nil
|
||||
if location.scheme == 'file' or
|
||||
(location.relative? and FileTest.exist?(location.path))
|
||||
content = File.open(location.path).read
|
||||
else
|
||||
client = web_client.new(nil, "WSDL4R")
|
||||
client.proxy = ::SOAP::Env::HTTP_PROXY
|
||||
client.no_proxy = ::SOAP::Env::NO_PROXY
|
||||
if opt = ::SOAP::Property.loadproperty(::SOAP::PropertyName)
|
||||
::SOAP::HTTPConfigLoader.set_options(client, opt["client.protocol.http"])
|
||||
end
|
||||
content = client.get_content(location)
|
||||
end
|
||||
content
|
||||
end
|
||||
|
||||
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
|
||||
warn("Loading http-access2 failed. Net/http is used.") if $DEBUG
|
||||
require 'soap/netHttpClient'
|
||||
::SOAP::NetHttpClient
|
||||
end
|
||||
@web_client
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
54
lib/wsdl/xmlSchema/include.rb
Normal file
54
lib/wsdl/xmlSchema/include.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# WSDL4R - XMLSchema include definition.
|
||||
# Copyright (C) 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'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class Include < Info
|
||||
attr_reader :schemalocation
|
||||
attr_reader :content
|
||||
|
||||
def initialize
|
||||
super
|
||||
@schemalocation = nil
|
||||
@content = nil
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
nil
|
||||
end
|
||||
|
||||
def parse_attr(attr, value)
|
||||
case attr
|
||||
when SchemaLocationAttrName
|
||||
@schemalocation = URI.parse(value.source)
|
||||
if @schemalocation.relative?
|
||||
@schemalocation = parent.location + @schemalocation
|
||||
end
|
||||
@content = import(@schemalocation)
|
||||
@schemalocation
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def import(location)
|
||||
Importer.import(location)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
35
lib/wsdl/xmlSchema/length.rb
Normal file
35
lib/wsdl/xmlSchema/length.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# WSDL4R - XMLSchema length definition for WSDL.
|
||||
# Copyright (C) 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'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class Length < Info
|
||||
def initialize
|
||||
super
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
nil
|
||||
end
|
||||
|
||||
def parse_attr(attr, value)
|
||||
case attr
|
||||
when ValueAttrName
|
||||
value.source
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
|
@ -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
|
||||
|
|
36
lib/wsdl/xmlSchema/pattern.rb
Normal file
36
lib/wsdl/xmlSchema/pattern.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# WSDL4R - XMLSchema pattern definition for WSDL.
|
||||
# Copyright (C) 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'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class Pattern < Info
|
||||
def initialize
|
||||
super
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
nil
|
||||
end
|
||||
|
||||
def parse_attr(attr, value)
|
||||
case attr
|
||||
when ValueAttrName
|
||||
parent.pattern = /\A#{value.source}\z/n
|
||||
value.source
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
54
lib/wsdl/xmlSchema/simpleExtension.rb
Normal file
54
lib/wsdl/xmlSchema/simpleExtension.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# WSDL4R - XMLSchema simpleType extension definition for WSDL.
|
||||
# Copyright (C) 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 'xsd/namedelements'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class SimpleExtension < Info
|
||||
attr_reader :base
|
||||
attr_reader :attributes
|
||||
|
||||
def initialize
|
||||
super
|
||||
@base = nil
|
||||
@attributes = XSD::NamedElements.new
|
||||
end
|
||||
|
||||
def targetnamespace
|
||||
parent.targetnamespace
|
||||
end
|
||||
|
||||
def valid?(value)
|
||||
true
|
||||
end
|
||||
|
||||
def parse_element(element)
|
||||
case element
|
||||
when AttributeName
|
||||
o = Attribute.new
|
||||
@attributes << o
|
||||
o
|
||||
end
|
||||
end
|
||||
|
||||
def parse_attr(attr, value)
|
||||
case attr
|
||||
when BaseAttrName
|
||||
@base = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
107
lib/wsdl/xmlSchema/xsd2ruby.rb
Normal file
107
lib/wsdl/xmlSchema/xsd2ruby.rb
Normal file
|
@ -0,0 +1,107 @@
|
|||
# XSD4R - XSD to ruby mapping library.
|
||||
# Copyright (C) 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 'xsd/codegen/gensupport'
|
||||
require 'wsdl/xmlSchema/importer'
|
||||
require 'wsdl/soap/classDefCreator'
|
||||
|
||||
|
||||
module WSDL
|
||||
module XMLSchema
|
||||
|
||||
|
||||
class XSD2Ruby
|
||||
attr_accessor :location
|
||||
attr_reader :opt
|
||||
attr_accessor :logger
|
||||
attr_accessor :basedir
|
||||
|
||||
def run
|
||||
unless @location
|
||||
raise RuntimeError, "XML Schema location not given"
|
||||
end
|
||||
@xsd = import(@location)
|
||||
@name = create_classname(@xsd)
|
||||
create_file
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize
|
||||
@location = nil
|
||||
@opt = {}
|
||||
@logger = Logger.new(STDERR)
|
||||
@basedir = nil
|
||||
@xsd = nil
|
||||
@name = nil
|
||||
end
|
||||
|
||||
def create_file
|
||||
create_classdef
|
||||
end
|
||||
|
||||
def create_classdef
|
||||
@logger.info { "Creating class definition." }
|
||||
@classdef_filename = @name + '.rb'
|
||||
check_file(@classdef_filename) or return
|
||||
write_file(@classdef_filename) do |f|
|
||||
f << WSDL::SOAP::ClassDefCreator.new(@xsd).dump
|
||||
end
|
||||
end
|
||||
|
||||
def write_file(filename)
|
||||
if @basedir
|
||||
filename = File.join(basedir, filename)
|
||||
end
|
||||
File.open(filename, "w") do |f|
|
||||
yield f
|
||||
end
|
||||
end
|
||||
|
||||
def check_file(filename)
|
||||
if @basedir
|
||||
filename = File.join(basedir, filename)
|
||||
end
|
||||
if FileTest.exist?(filename)
|
||||
if @opt.key?('force')
|
||||
@logger.warn {
|
||||
"File '#{filename}' exists but overrides it."
|
||||
}
|
||||
true
|
||||
else
|
||||
@logger.warn {
|
||||
"File '#{filename}' exists. #{$0} did not override it."
|
||||
}
|
||||
false
|
||||
end
|
||||
else
|
||||
@logger.info { "Creates file '#{filename}'." }
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def create_classname(xsd)
|
||||
name = nil
|
||||
if xsd.targetnamespace
|
||||
name = xsd.targetnamespace.scan(/[a-zA-Z0-9]+$/)[0]
|
||||
end
|
||||
if name.nil?
|
||||
'default'
|
||||
else
|
||||
XSD::CodeGen::GenSupport.safevarname(name)
|
||||
end
|
||||
end
|
||||
|
||||
def import(location)
|
||||
WSDL::XMLSchema::Importer.import(location)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue