diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-03 13:33:20 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-03 13:33:20 +0000 |
commit | df731e37a1953755edfedd1462995fa824ca22bf (patch) | |
tree | 38a98e1b29b3784843ad079fa003790c8f352f58 /lib/xsd | |
parent | 0d6fa996d9e842fe435308cef68df06bc3596a76 (diff) | |
download | ruby-df731e37a1953755edfedd1462995fa824ca22bf.tar.gz |
* added files:
* lib/soap/header/*
* lib/soap/rpc/httpserver.rb
* lib/wsdl/soap/cgiStubCreator.rb
* lib/wsdl/soap/classDefCreator.rb
* lib/wsdl/soap/classDefCreatorSupport.rb
* lib/wsdl/soap/clientSkeltonCreator.rb
* lib/wsdl/soap/driverCreator.rb
* lib/wsdl/soap/mappingRegistryCreator.rb
* lib/wsdl/soap/methodDefCreator.rb
* lib/wsdl/soap/servantSkeltonCreator.rb
* lib/wsdl/soap/standaloneServerStubCreator.rb
* lib/wsdl/xmlSchema/enumeration.rb
* lib/wsdl/xmlSchema/simpleRestriction.rb
* lib/wsdl/xmlSchema/simpleType.rb
* lib/xsd/codegen/*
* lib/xsd/codegen.rb
* sample/soap/authheader/*
* sample/soap/raa2.4/*
* sample/soap/ssl/*
* sample/soap/swa/*
* sample/soap/whois.rb
* sample/wsdl/raa2.4/*
* test/soap/header/*
* test/soap/ssl/*
* test/soap/struct/*
* test/soap/swa/*
* test/soap/wsdlDriver/*
* test/wsdl/multiplefault.wsdl
* test/wsdl/simpletype/*
* test/wsdl/test_multiplefault.rb
* modified files:
* lib/soap/baseData.rb
* lib/soap/element.rb
* lib/soap/generator.rb
* lib/soap/netHttpClient.rb
* lib/soap/parser.rb
* lib/soap/property.rb
* lib/soap/soap.rb
* lib/soap/streamHandler.rb
* lib/soap/wsdlDriver.rb
* lib/soap/wsdlDriver.rb
* lib/soap/encodingstyle/handler.rb
* lib/soap/encodingstyle/literalHandler.rb
* lib/soap/encodingstyle/soapHandler.rb
* lib/soap/mapping/factory.rb
* lib/soap/mapping/mapping.rb
* lib/soap/mapping/registry.rb
* lib/soap/mapping/rubytypeFactory.rb
* lib/soap/mapping/wsdlRegistry.rb
* lib/soap/rpc/cgistub.rb
* lib/soap/rpc/driver.rb
* lib/soap/rpc/proxy.rb
* lib/soap/rpc/router.rb
* lib/soap/rpc/soaplet.rb
* lib/soap/rpc/standaloneServer.rb
* lib/wsdl/data.rb
* lib/wsdl/definitions.rb
* lib/wsdl/operation.rb
* lib/wsdl/parser.rb
* lib/wsdl/soap/definitions.rb
* lib/wsdl/xmlSchema/complexContent.rb
* lib/wsdl/xmlSchema/complexType.rb
* lib/wsdl/xmlSchema/data.rb
* lib/wsdl/xmlSchema/parser.rb
* lib/wsdl/xmlSchema/schema.rb
* lib/xsd/datatypes.rb
* lib/xsd/qname.rb
* sample/soap/sampleStruct/server.rb
* sample/wsdl/amazon/AmazonSearch.rb
* sample/wsdl/amazon/AmazonSearchDriver.rb
* test/soap/test_property.rb
* test/soap/calc/test_calc_cgi.rb
* test/wsdl/test_emptycomplextype.rb
* summary
* add SOAP Header mustUnderstand support.
* add HTTP client SSL configuration and Cookies support (works
completely with http-access2).
* add header handler for handling sending/receiving SOAP Header.
* map Ruby's anonymous Struct to common SOAP Struct in SOAP Object
Model. it caused error.
* add WSDL simpleType support to restrict lexical value space.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6565 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/xsd')
-rw-r--r-- | lib/xsd/codegen.rb | 12 | ||||
-rw-r--r-- | lib/xsd/codegen/classdef.rb | 203 | ||||
-rw-r--r-- | lib/xsd/codegen/commentdef.rb | 34 | ||||
-rw-r--r-- | lib/xsd/codegen/gensupport.rb | 112 | ||||
-rw-r--r-- | lib/xsd/codegen/methoddef.rb | 63 | ||||
-rw-r--r-- | lib/xsd/codegen/moduledef.rb | 191 | ||||
-rw-r--r-- | lib/xsd/datatypes.rb | 296 | ||||
-rw-r--r-- | lib/xsd/qname.rb | 9 |
8 files changed, 764 insertions, 156 deletions
diff --git a/lib/xsd/codegen.rb b/lib/xsd/codegen.rb new file mode 100644 index 0000000000..d820ebf1f2 --- /dev/null +++ b/lib/xsd/codegen.rb @@ -0,0 +1,12 @@ +# XSD4R - Generating code library +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/classdef' +require 'xsd/codegen/methoddef' diff --git a/lib/xsd/codegen/classdef.rb b/lib/xsd/codegen/classdef.rb new file mode 100644 index 0000000000..8f72e95efd --- /dev/null +++ b/lib/xsd/codegen/classdef.rb @@ -0,0 +1,203 @@ +# XSD4R - Generating class definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/moduledef' +require 'xsd/codegen/methoddef' + + +module XSD +module CodeGen + + +class ClassDef < ModuleDef + include GenSupport + + def initialize(name, baseclass = nil) + super(name) + @baseclass = baseclass + @classvar = [] + @attrdef = [] + end + + def def_classvar(var, value) + var = var.sub(/\A@@/, "") + unless safevarname?(var) + raise ArgumentError.new("#{var} seems to be unsafe") + end + @classvar << [var, value] + end + + def def_attr(attrname, writable = true, varname = nil) + unless safevarname?(varname || attrname) + raise ArgumentError.new("#{varname || attrname} seems to be unsafe") + end + @attrdef << [attrname, writable, varname] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_class_def + spacer = false + unless @classvar.empty? + spacer = true + buf << dump_classvar + end + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @attrdef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_attributes + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_class_def_end + buf << dump_package_def_end(package) unless package.empty? + buf + end + +private + + def dump_class_def + name = @name.to_s.split(/::/) + if @baseclass + format("class #{name.last} < #{@baseclass}") + else + format("class #{name.last}") + end + end + + def dump_class_def_end + str = format("end") + end + + def dump_classvar + dump_static( + @classvar.collect { |var, value| + %Q(@@#{var.sub(/^@@/, "")} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_attributes + str = "" + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname == varname + str << format(dump_accessor(attrname, writable), 2) + end + end + @attrdef.each do |attrname, writable, varname| + varname ||= attrname + if attrname != varname + str << "\n" unless str.empty? + str << format(dump_attribute(attrname, writable, varname), 2) + end + end + str + end + + def dump_accessor(attrname, writable) + if writable + "attr_accessor :#{attrname}" + else + "attr_reader :#{attrname}" + end + end + + def dump_attribute(attrname, writable, varname) + str = nil + mr = MethodDef.new(attrname) + mr.definition = "@#{varname}" + str = mr.dump + if writable + mw = MethodDef.new(attrname + "=", 'value') + mw.definition = "@#{varname} = value" + str << "\n" + mw.dump + end + str + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/classdef' + include XSD::CodeGen + c = ClassDef.new("Foo::Bar::HobbitName", String) + c.def_require("foo/bar") + c.comment = <<-EOD + foo + bar + baz + EOD + c.def_const("FOO", 1) + c.def_classvar("@@foo", "var".dump) + c.def_classvar("baz", "1".dump) + c.def_attr("Foo", true, "foo") + c.def_attr("bar") + c.def_attr("baz", true) + c.def_attr("Foo2", true, "foo2") + c.def_attr("foo3", false, "foo3") + c.def_method("foo") do + <<-EOD + foo.bar = 1 +\tbaz.each do |ele| +\t ele + end + EOD + end + c.def_method("baz", "qux") do + <<-EOD + [1, 2, 3].each do |i| + p i + end + EOD + end + + m = MethodDef.new("qux", "quxx", "quxxx") do + <<-EOD + p quxx + quxxx + EOD + end + m.comment = "hello world\n123" + c.add_method(m) + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_code <<-EOD + Foo.new + Bar.z + EOD + c.def_privatemethod("foo", "baz", "*arg", "&block") + + puts c.dump +end diff --git a/lib/xsd/codegen/commentdef.rb b/lib/xsd/codegen/commentdef.rb new file mode 100644 index 0000000000..f98fade57d --- /dev/null +++ b/lib/xsd/codegen/commentdef.rb @@ -0,0 +1,34 @@ +# XSD4R - Generating comment definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' + + +module XSD +module CodeGen + + +module CommentDef + include GenSupport + + attr_accessor :comment + +private + + def dump_comment + if /^#/ =~ @comment + format(@comment) + else + format(@comment).gsub(/^/, "# ") + end + end +end + + +end +end diff --git a/lib/xsd/codegen/gensupport.rb b/lib/xsd/codegen/gensupport.rb new file mode 100644 index 0000000000..df90550fa0 --- /dev/null +++ b/lib/xsd/codegen/gensupport.rb @@ -0,0 +1,112 @@ +# XSD4R - Code generation support +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +module XSD +module CodeGen + + +module GenSupport + def capitalize(target) + target.sub(/^([a-z])/) { $1.tr!('[a-z]', '[A-Z]') } + end + module_function :capitalize + + def uncapitalize(target) + target.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') } + end + module_function :uncapitalize + + def safeconstname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).collect { |ele| + GenSupport.capitalize(ele) + }.join + unless /^[A-Z]/ =~ safename + safename = "C_#{safename}" + end + safename + end + module_function :safeconstname + + def safeconstname?(name) + /\A[A-Z][a-zA-Z0-9_]*\z/ =~ name + end + module_function :safeconstname? + + def safemethodname(name) + safevarname(name) + end + module_function :safemethodname + + def safemethodname?(name) + /\A[a-zA-Z_][a-zA-Z0-9_]*[=!?]?\z/ =~ name + end + module_function :safemethodname? + + def safevarname(name) + safename = name.scan(/[a-zA-Z0-9_]+/).join('_') + safename = uncapitalize(safename) + unless /^[a-z]/ =~ safename + safename = "m_#{safename}" + end + safename + end + module_function :safevarname + + def safevarname?(name) + /\A[a-z_][a-zA-Z0-9_]*\z/ =~ name + end + module_function :safevarname? + + def format(str, indent = nil) + str = trim_eol(str) + str = trim_indent(str) + if indent + str.gsub(/^/, " " * indent) + else + str + end + end + +private + + def trim_eol(str) + str.collect { |line| + line.sub(/\r?\n$/, "") + "\n" + }.join + end + + def trim_indent(str) + indent = nil + str = str.collect { |line| untab(line) }.join + str.each do |line| + head = line.index(/\S/) + if !head.nil? and (indent.nil? or head < indent) + indent = head + end + end + return str unless indent + str.collect { |line| + line.sub(/^ {0,#{indent}}/, "") + }.join + end + + def untab(line, ts = 8) + while pos = line.index(/\t/) + line = line.sub(/\t/, " " * (ts - (pos % ts))) + end + line + end + + def dump_emptyline + "\n" + end +end + + +end +end diff --git a/lib/xsd/codegen/methoddef.rb b/lib/xsd/codegen/methoddef.rb new file mode 100644 index 0000000000..797a4f024e --- /dev/null +++ b/lib/xsd/codegen/methoddef.rb @@ -0,0 +1,63 @@ +# XSD4R - Generating method definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class MethodDef + include GenSupport + include CommentDef + + attr_accessor :definition + + def initialize(name, *params) + unless safemethodname?(name) + raise ArgumentError.new("#{name} seems to be unsafe") + end + @name = name + @params = params + @comment = nil + @definition = yield if block_given? + end + + def dump + buf = "" + buf << dump_comment if @comment + buf << dump_method_def + buf << dump_definition if @definition + buf << dump_method_def_end + buf + end + +private + + def dump_method_def + if @params.empty? + format("def #{@name}") + else + format("def #{@name}(#{@params.join(", ")})") + end + end + + def dump_method_def_end + format("end") + end + + def dump_definition + format(@definition, 2) + end +end + + +end +end diff --git a/lib/xsd/codegen/moduledef.rb b/lib/xsd/codegen/moduledef.rb new file mode 100644 index 0000000000..dc2746b2ee --- /dev/null +++ b/lib/xsd/codegen/moduledef.rb @@ -0,0 +1,191 @@ +# XSD4R - Generating module definition code +# Copyright (C) 2004 NAKAMURA, Hiroshi <nahi@ruby-lang.org>. + +# This program is copyrighted free software by NAKAMURA, Hiroshi. You can +# redistribute it and/or modify it under the same terms of Ruby's license; +# either the dual license version in 2003, or any later version. + + +require 'xsd/codegen/gensupport' +require 'xsd/codegen/methoddef' +require 'xsd/codegen/commentdef' + + +module XSD +module CodeGen + + +class ModuleDef + include GenSupport + include CommentDef + + def initialize(name) + @name = name + @comment = nil + @const = [] + @code = [] + @requirepath = [] + @methoddef = [] + end + + def def_require(path) + @requirepath << path + end + + def def_const(const, value) + unless safeconstname?(const) + raise ArgumentError.new("#{const} seems to be unsafe") + end + @const << [const, value] + end + + def def_code(code) + @code << code + end + + def def_method(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :public) + end + alias def_publicmethod def_method + + def def_protectedmethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, + :protected) + end + + def def_privatemethod(name, *params) + add_method(MethodDef.new(name, *params) { yield if block_given? }, :private) + end + + def add_method(m, visibility = :public) + @methoddef << [visibility, m] + end + + def dump + buf = "" + unless @requirepath.empty? + buf << dump_requirepath + end + buf << dump_emptyline unless buf.empty? + package = @name.split(/::/)[0..-2] + buf << dump_package_def(package) unless package.empty? + buf << dump_comment if @comment + buf << dump_module_def + spacer = false + unless @const.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_const + end + unless @code.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_code + end + unless @methoddef.empty? + buf << dump_emptyline if spacer + spacer = true + buf << dump_methods + end + buf << dump_module_def_end + buf << dump_package_def_end(package) unless package.empty? + buf + end + +private + + def dump_requirepath + format( + @requirepath.collect { |path| + %Q(require '#{path}') + }.join("\n") + ) + end + + def dump_const + dump_static( + @const.sort.collect { |var, value| + %Q(#{var} = #{dump_value(value)}) + }.join("\n") + ) + end + + def dump_code + dump_static(@code.join("\n")) + end + + def dump_static(str) + format(str, 2) + end + + def dump_methods + methods = {} + @methoddef.each do |visibility, method| + (methods[visibility] ||= []) << method + end + str = "" + [:public, :protected, :private].each do |visibility| + if methods[visibility] + str << "\n" unless str.empty? + str << visibility.to_s << "\n\n" unless visibility == :public + str << methods[visibility].collect { |m| format(m.dump, 2) }.join("\n") + end + end + str + end + + def dump_value(value) + if value.respond_to?(:to_src) + value.to_src + else + value + end + end + + def dump_package_def(package) + format(package.collect { |ele| "module #{ele}" }.join("; ")) + "\n\n" + end + + def dump_package_def_end(package) + "\n\n" + format(package.collect { |ele| "end" }.join("; ")) + end + + def dump_module_def + name = @name.to_s.split(/::/) + format("module #{name.last}") + end + + def dump_module_def_end + format("end") + end +end + + +end +end + + +if __FILE__ == $0 + require 'xsd/codegen/moduledef' + include XSD::CodeGen + m = ModuleDef.new("Foo::Bar::HobbitName") + m.def_require("foo/bar") + m.def_require("baz") + m.comment = <<-EOD + foo + bar + baz + EOD + m.def_method("foo") do + <<-EOD + foo.bar = 1 + baz.each do |ele| + ele + 1 + end + EOD + end + m.def_method("baz", "qux") + #m.def_protectedmethod("aaa") + m.def_privatemethod("bbb") + puts m.dump +end diff --git a/lib/xsd/datatypes.rb b/lib/xsd/datatypes.rb index 7223632b04..7173f52d65 100644 --- a/lib/xsd/datatypes.rb +++ b/lib/xsd/datatypes.rb @@ -103,6 +103,12 @@ class XSDAnySimpleType < NSDBase set(value) if value end + # true or raise + def check_lexical_format(value) + screen_data(value) + true + end + # set accepts a string which follows lexical space (ex. String: "+123"), or # an object which follows canonical space (ex. Integer: 123). def set(value) @@ -111,7 +117,7 @@ class XSDAnySimpleType < NSDBase @data = nil else @is_nil = false - _set(value) + _set(screen_data(value)) end end @@ -126,6 +132,11 @@ class XSDAnySimpleType < NSDBase private + # raises ValueSpaceError if check failed + def screen_data(value) + value + end + def _set(value) @data = value end @@ -144,12 +155,6 @@ class XSDNil < XSDAnySimpleType @type = Type set(value) end - -private - - def _set(value) - @data = value - end end @@ -167,11 +172,11 @@ class XSDString < XSDAnySimpleType private - def _set(value) + def screen_data(value) unless XSD::Charset.is_ces(value, XSD::Charset.encoding) raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end - @data = value + value end end @@ -186,18 +191,18 @@ class XSDBoolean < XSDAnySimpleType private - def _set(value) + def screen_data(value) if value.is_a?(String) str = value.strip if str == 'true' || str == '1' - @data = true + true elsif str == 'false' || str == '0' - @data = false + false else raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end else - @data = value ? true : false + value ? true : false end end end @@ -220,38 +225,39 @@ class XSDDecimal < XSDAnySimpleType private - def _set(d) + def screen_data(d) if d.is_a?(String) # Integer("00012") => 10 in Ruby. d.sub!(/^([+\-]?)0*(?=\d)/, "\\1") end - set_str(d) + screen_data_str(d) end - def set_str(str) + def screen_data_str(str) /^([+\-]?)(\d*)(?:\.(\d*)?)?$/ =~ str.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end - - @sign = $1 || '+' + sign = $1 || '+' int_part = $2 frac_part = $3 - int_part = '0' if int_part.empty? frac_part = frac_part ? frac_part.sub(/0+$/, '') : '' - @point = - frac_part.size - @number = int_part + frac_part - + point = - frac_part.size + number = int_part + frac_part # normalize - if @sign == '+' - @sign = '' - elsif @sign == '-' - if @number == '0' - @sign = '' + if sign == '+' + sign = '' + elsif sign == '-' + if number == '0' + sign = '' end end + [sign, point, number] + end + def _set(pair) + @sign, @point, @number = pair @data = _to_s @data.freeze end @@ -272,7 +278,7 @@ module FloatConstants NEGATIVE_INF = -1.0/0.0 POSITIVE_ZERO = +1.0/POSITIVE_INF NEGATIVE_ZERO = -1.0/POSITIVE_INF - MIN_POSITIVE_SINGLE = 2 ** -149 + MIN_POSITIVE_SINGLE = 2.0 ** -149 end class XSDFloat < XSDAnySimpleType @@ -287,20 +293,18 @@ class XSDFloat < XSDAnySimpleType private - def _set(value) + def screen_data(value) # "NaN".to_f => 0 in some environment. libc? if value.is_a?(Float) - @data = narrow32bit(value) - return + return narrow32bit(value) end - str = value.to_s.strip if str == 'NaN' - @data = NaN + NaN elsif str == 'INF' - @data = POSITIVE_INF + POSITIVE_INF elsif str == '-INF' - @data = NEGATIVE_INF + NEGATIVE_INF else if /^[+\-\.\deE]+$/ !~ str raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") @@ -308,7 +312,7 @@ private # Float("-1.4E") might fail on some system. str << '0' if /e$/i =~ str begin - @data = narrow32bit(Float(str)) + return narrow32bit(Float(str)) rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end @@ -357,28 +361,26 @@ class XSDDouble < XSDAnySimpleType private - def _set(value) + def screen_data(value) # "NaN".to_f => 0 in some environment. libc? if value.is_a?(Float) - @data = value - return + return value end - str = value.to_s.strip if str == 'NaN' - @data = NaN + NaN elsif str == 'INF' - @data = POSITIVE_INF + POSITIVE_INF elsif str == '-INF' - @data = NEGATIVE_INF + NEGATIVE_INF else begin - @data = Float(str) + return Float(str) rescue ArgumentError # '1.4e' cannot be parsed on some architecture. if /e\z/i =~ str begin - @data = Float(str + '0') + return Float(str + '0') rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end @@ -429,24 +431,27 @@ class XSDDuration < XSDAnySimpleType private - def _set(value) + def screen_data(value) /^([+\-]?)P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/ =~ value.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end - if ($5 and ((!$2 and !$3 and !$4) or (!$6 and !$7 and !$8))) # Should we allow 'PT5S' here? raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end + sign = $1 + year = $2.to_i + month = $3.to_i + day = $4.to_i + hour = $6.to_i + min = $7.to_i + sec = $8 ? XSDDecimal.new($8) : 0 + [sign, year, month, day, hour, min, sec] + end - @sign = $1 - @year = $2.to_i - @month = $3.to_i - @day = $4.to_i - @hour = $6.to_i - @min = $7.to_i - @sec = $8 ? XSDDecimal.new($8) : 0 + def _set(ary) + @sign, @year, @month, @day, @hour, @min, @sec = ary @data = _to_s @data.freeze end @@ -524,18 +529,18 @@ module XSDDateTimeImpl end end - def _set(t) - set_datetime_init(t) + def screen_data(t) if (t.is_a?(Date)) - @data = t + t elsif (t.is_a?(Time)) sec, min, hour, mday, month, year = t.to_a[0..5] diffday = t.usec.to_r / 1000000 / SecInDay of = t.utc_offset.to_r / SecInDay - @data = DateTime.civil(year, month, mday, hour, min, sec, of) - @data += diffday + data = DateTime.civil(year, month, mday, hour, min, sec, of) + data += diffday + data else - set_str(t) + screen_data_str(t) end end @@ -557,11 +562,7 @@ class XSDDateTime < XSDAnySimpleType private - def set_datetime_init(t) - @secfrac = nil - end - - def set_str(t) + def screen_data_str(t) /^([+\-]?\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") @@ -569,7 +570,6 @@ private if $1 == '0000' raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - year = $1.to_i if year < 0 year += 1 @@ -581,22 +581,18 @@ private sec = $6.to_i secfrac = $7 zonestr = $8 - - @data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr)) - @secfrac = secfrac - + data = DateTime.civil(year, mon, mday, hour, min, sec, tz2of(zonestr)) if secfrac diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay - # jd = @data.jd - # day_fraction = @data.day_fraction + diffday - # @data = DateTime.new0(DateTime.jd_to_rjd(jd, day_fraction, - # @data.offset), @data.offset) - # - # Thanks to Funaba-san, above code can be simply written as below. - @data += diffday + data += diffday # FYI: new0 and jd_to_rjd are not necessary to use if you don't have # exceptional reason. end + [data, secfrac] + end + + def _set(pair) + @data, @secfrac = pair end def _to_s @@ -607,7 +603,8 @@ private if @secfrac s << ".#{ @secfrac }" else - s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') + s << sprintf("%.16f", + (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') end end add_tz(s) @@ -627,29 +624,26 @@ class XSDTime < XSDAnySimpleType private - def set_datetime_init(t) - @secfrac = nil - end - - def set_str(t) + def screen_data_str(t) /^(\d\d):(\d\d):(\d\d(?:\.(\d*))?)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - hour = $1.to_i min = $2.to_i sec = $3.to_i secfrac = $4 zonestr = $5 - - @data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr)) - @secfrac = secfrac - + data = DateTime.civil(1, 1, 1, hour, min, sec, tz2of(zonestr)) if secfrac diffday = secfrac.to_i.to_r / (10 ** secfrac.size) / SecInDay - @data += diffday + data += diffday end + [data, secfrac] + end + + def _set(pair) + @data, @secfrac = pair end def _to_s @@ -658,7 +652,8 @@ private if @secfrac s << ".#{ @secfrac }" else - s << sprintf("%.16f", (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') + s << sprintf("%.16f", + (@data.sec_fraction * SecInDay).to_f).sub(/^0/, '').sub(/0*$/, '') end end add_tz(s) @@ -677,15 +672,11 @@ class XSDDate < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^([+\-]?\d{4,})-(\d\d)-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - year = $1.to_i if year < 0 year += 1 @@ -693,8 +684,7 @@ private mon = $2.to_i mday = $3.to_i zonestr = $4 - - @data = DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(year, mon, mday, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -716,23 +706,18 @@ class XSDGYearMonth < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^([+\-]?\d{4,})-(\d\d)(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - year = $1.to_i if year < 0 year += 1 end mon = $2.to_i zonestr = $3 - - @data = DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(year, mon, 1, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -754,22 +739,17 @@ class XSDGYear < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^([+\-]?\d{4,})(Z|(?:([+\-])(\d\d):(\d\d))?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - year = $1.to_i if year < 0 year += 1 end zonestr = $2 - - @data = DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(year, 1, 1, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -791,20 +771,15 @@ class XSDGMonthDay < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^(\d\d)-(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - mon = $1.to_i mday = $2.to_i zonestr = $3 - - @data = DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(1, mon, mday, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -825,19 +800,14 @@ class XSDGDay < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - mday = $1.to_i zonestr = $2 - - @data = DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(1, 1, mday, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -858,19 +828,14 @@ class XSDGMonth < XSDAnySimpleType private - def set_datetime_init(t) - end - - def set_str(t) + def screen_data_str(t) /^(\d\d)(Z|(?:[+\-]\d\d:\d\d)?)?$/ =~ t.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ t }'.") end - mon = $1.to_i zonestr = $2 - - @data = DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr)) + DateTime.civil(1, mon, 1, 0, 0, 0, tz2of(zonestr)) end def _to_s @@ -903,9 +868,8 @@ class XSDHexBinary < XSDAnySimpleType private - def _set(value) - @data = value.unpack("H*")[0] - @data.tr!('a-f', 'A-F') + def screen_data(value) + value.unpack("H*")[0].tr('a-f', 'A-F') end end @@ -933,8 +897,8 @@ class XSDBase64Binary < XSDAnySimpleType private - def _set(value) - @data = [value].pack("m").strip + def screen_data(value) + [value].pack("m").strip end end @@ -949,9 +913,9 @@ class XSDAnyURI < XSDAnySimpleType private - def _set(value) + def screen_data(value) begin - @data = URI.parse(value.to_s.strip) + URI.parse(value.to_s.strip) rescue URI::InvalidURIError raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end @@ -969,14 +933,18 @@ class XSDQName < XSDAnySimpleType private - def _set(value) + def screen_data(value) /^(?:([^:]+):)?([^:]+)$/ =~ value.to_s.strip unless Regexp.last_match raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end + prefix = $1 + localpart = $2 + [prefix, localpart] + end - @prefix = $1 - @localpart = $2 + def _set(pair) + @prefix, @localpart = pair @data = _to_s @data.freeze end @@ -1005,7 +973,7 @@ class XSDNormalizedString < XSDString private - def _set(value) + def screen_data(value) if /[\t\r\n]/ =~ value raise ValueSpaceError.new("#{ type }: cannot accept '#{ value }'.") end @@ -1024,12 +992,17 @@ class XSDInteger < XSDDecimal private - def set_str(str) + def screen_data_str(str) begin - @data = Integer(str) + data = Integer(str) rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end + data + end + + def _set(value) + @data = value end def _to_s() @@ -1048,15 +1021,20 @@ class XSDLong < XSDInteger private - def set_str(str) + def screen_data_str(str) begin - @data = Integer(str) + data = Integer(str) rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end - unless validate(@data) + unless validate(data) raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end + data + end + + def _set(value) + @data = value end MaxInclusive = +9223372036854775807 @@ -1077,15 +1055,20 @@ class XSDInt < XSDLong private - def set_str(str) + def screen_data_str(str) begin - @data = Integer(str) + data = Integer(str) rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end - unless validate(@data) + unless validate(data) raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end + data + end + + def _set(value) + @data = value end MaxInclusive = +2147483647 @@ -1106,15 +1089,20 @@ class XSDShort < XSDInt private - def set_str(str) + def screen_data_str(str) begin - @data = Integer(str) + data = Integer(str) rescue ArgumentError raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end - unless validate(@data) + unless validate(data) raise ValueSpaceError.new("#{ type }: cannot accept '#{ str }'.") end + data + end + + def _set(value) + @data = value end MaxInclusive = +32767 diff --git a/lib/xsd/qname.rb b/lib/xsd/qname.rb index 9dce1340f8..7185fedf2d 100644 --- a/lib/xsd/qname.rb +++ b/lib/xsd/qname.rb @@ -1,5 +1,5 @@ # XSD4R - XML QName definition. -# 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; @@ -19,7 +19,7 @@ class QName end def dup_name(name) - self.class.new(@namespace, name) + ::XSD::QName.new(@namespace, name) end def match(rhs) @@ -55,6 +55,11 @@ class QName "{#{ namespace }}#{ name }" end + def inspect + sprintf("#<%s:0x%x %s>", self.class.name, __id__, + "{#{ namespace }}#{ name }") + end + NormalizedNameRegexp = /^\{([^}]*)\}(.*)$/ def parse(str) NormalizedNameRegexp =~ str |