yieldmanager 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/soap4r_19_patch/soap/generator.rb +307 -0
- data/lib/soap4r_19_patch/soap/property.rb +340 -0
- data/lib/soap4r_19_patch/xsd/charset.rb +190 -0
- data/lib/soap4r_19_patch/xsd/xmlparser.rb +79 -0
- data/lib/yieldmanager.rb +8 -0
- data/spec/spec_helper.rb +1 -1
- data/yieldmanager.gemspec +6 -2
- metadata +8 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.3
|
@@ -0,0 +1,307 @@
|
|
1
|
+
# SOAP4R - SOAP XML Instance Generator library.
|
2
|
+
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
require 'soap/soap'
|
10
|
+
require 'soap/ns'
|
11
|
+
require 'soap/baseData'
|
12
|
+
require 'soap/encodingstyle/handler'
|
13
|
+
require 'xsd/codegen/gensupport'
|
14
|
+
|
15
|
+
|
16
|
+
module SOAP
|
17
|
+
|
18
|
+
|
19
|
+
###
|
20
|
+
## CAUTION: MT-unsafe
|
21
|
+
#
|
22
|
+
class Generator
|
23
|
+
include SOAP
|
24
|
+
include XSD::CodeGen::GenSupport
|
25
|
+
|
26
|
+
class FormatEncodeError < Error; end
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
attr_accessor :charset
|
31
|
+
attr_accessor :default_encodingstyle
|
32
|
+
attr_accessor :generate_explicit_type
|
33
|
+
attr_accessor :use_numeric_character_reference
|
34
|
+
attr_accessor :use_default_namespace
|
35
|
+
|
36
|
+
def initialize(opt = {})
|
37
|
+
@reftarget = nil
|
38
|
+
@handlers = {}
|
39
|
+
@charset = opt[:charset] || XSD::Charset.xml_encoding_label
|
40
|
+
@default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace
|
41
|
+
@generate_explicit_type =
|
42
|
+
opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true
|
43
|
+
@use_default_namespace = opt[:use_default_namespace]
|
44
|
+
@attributeformdefault = opt[:attributeformdefault]
|
45
|
+
@use_numeric_character_reference = opt[:use_numeric_character_reference]
|
46
|
+
@indentstr = opt[:no_indent] ? '' : ' '
|
47
|
+
@buf = @indent = @curr = nil
|
48
|
+
@default_ns = opt[:default_ns]
|
49
|
+
@default_ns_tag = opt[:default_ns_tag]
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate(obj, io = nil)
|
53
|
+
@buf = io || ''
|
54
|
+
@indent = ''
|
55
|
+
@encode_char_regexp = get_encode_char_regexp()
|
56
|
+
|
57
|
+
prologue
|
58
|
+
@handlers.each do |uri, handler|
|
59
|
+
handler.encode_prologue
|
60
|
+
end
|
61
|
+
|
62
|
+
ns = SOAP::NS.new
|
63
|
+
if @default_ns
|
64
|
+
@default_ns.each_ns do |default_ns, default_tag|
|
65
|
+
Generator.assign_ns(obj.extraattr, ns, default_ns, default_tag)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
if @default_ns_tag
|
69
|
+
@default_ns_tag.each_ns do |default_ns, default_tag|
|
70
|
+
ns.known_tag[default_ns] = default_tag
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@buf << xmldecl
|
74
|
+
encode_data(ns, obj, nil)
|
75
|
+
|
76
|
+
@handlers.each do |uri, handler|
|
77
|
+
handler.encode_epilogue
|
78
|
+
end
|
79
|
+
epilogue
|
80
|
+
|
81
|
+
@buf
|
82
|
+
end
|
83
|
+
|
84
|
+
def encode_data(ns, obj, parent)
|
85
|
+
if obj.respond_to?(:to_xmlpart)
|
86
|
+
formatted = trim_eol(obj.to_xmlpart)
|
87
|
+
formatted = trim_indent(formatted)
|
88
|
+
formatted = formatted.gsub(/^/, @indent).sub(/\n+\z/, '')
|
89
|
+
@buf << "\n#{formatted}"
|
90
|
+
return
|
91
|
+
elsif obj.is_a?(SOAPEnvelopeElement)
|
92
|
+
encode_element(ns, obj, parent)
|
93
|
+
return
|
94
|
+
end
|
95
|
+
if @reftarget && !obj.precedents.empty?
|
96
|
+
add_reftarget(obj.elename.name, obj)
|
97
|
+
ref = SOAPReference.new(obj)
|
98
|
+
ref.elename = ref.elename.dup_name(obj.elename.name)
|
99
|
+
obj.precedents.clear # Avoid cyclic delay.
|
100
|
+
obj.encodingstyle = parent.encodingstyle
|
101
|
+
# SOAPReference is encoded here.
|
102
|
+
obj = ref
|
103
|
+
end
|
104
|
+
encodingstyle = obj.encodingstyle
|
105
|
+
# Children's encodingstyle is derived from its parent.
|
106
|
+
encodingstyle ||= parent.encodingstyle if parent
|
107
|
+
obj.encodingstyle = encodingstyle
|
108
|
+
handler = find_handler(encodingstyle || @default_encodingstyle)
|
109
|
+
unless handler
|
110
|
+
raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.")
|
111
|
+
end
|
112
|
+
if !obj.elename.name
|
113
|
+
raise FormatEncodeError.new("Element name not defined: #{ obj }.")
|
114
|
+
end
|
115
|
+
handler.encode_data(self, ns, obj, parent)
|
116
|
+
handler.encode_data_end(self, ns, obj, parent)
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_reftarget(name, node)
|
120
|
+
unless @reftarget
|
121
|
+
raise FormatEncodeError.new("Reftarget is not defined.")
|
122
|
+
end
|
123
|
+
@reftarget.add(name, node)
|
124
|
+
end
|
125
|
+
|
126
|
+
def encode_child(ns, child, parent)
|
127
|
+
indent_backup, @indent = @indent, @indent + @indentstr
|
128
|
+
encode_data(ns.clone_ns, child, parent)
|
129
|
+
@indent = indent_backup
|
130
|
+
end
|
131
|
+
|
132
|
+
def encode_element(ns, obj, parent)
|
133
|
+
attrs = obj.extraattr
|
134
|
+
if obj.is_a?(SOAPBody)
|
135
|
+
@reftarget = obj
|
136
|
+
obj.encode(self, ns, attrs) do |child|
|
137
|
+
indent_backup, @indent = @indent, @indent + @indentstr
|
138
|
+
encode_data(ns.clone_ns, child, obj)
|
139
|
+
@indent = indent_backup
|
140
|
+
end
|
141
|
+
@reftarget = nil
|
142
|
+
else
|
143
|
+
if obj.is_a?(SOAPEnvelope)
|
144
|
+
# xsi:nil="true" can appear even if dumping without explicit type.
|
145
|
+
Generator.assign_ns(attrs, ns, XSD::InstanceNamespace)
|
146
|
+
if @generate_explicit_type
|
147
|
+
Generator.assign_ns(attrs, ns, XSD::Namespace)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
obj.encode(self, ns, attrs) do |child|
|
151
|
+
indent_backup, @indent = @indent, @indent + @indentstr
|
152
|
+
encode_data(ns.clone_ns, child, obj)
|
153
|
+
@indent = indent_backup
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def encode_name(ns, data, attrs)
|
159
|
+
if element_local?(data)
|
160
|
+
data.elename.name
|
161
|
+
else
|
162
|
+
if @use_default_namespace
|
163
|
+
Generator.assign_ns(attrs, ns, data.elename.namespace, '')
|
164
|
+
else
|
165
|
+
Generator.assign_ns(attrs, ns, data.elename.namespace)
|
166
|
+
end
|
167
|
+
ns.name(data.elename)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def encode_name_end(ns, data)
|
172
|
+
if element_local?(data)
|
173
|
+
data.elename.name
|
174
|
+
else
|
175
|
+
ns.name(data.elename)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def encode_tag(elename, attrs = nil)
|
180
|
+
if attrs.nil? or attrs.empty?
|
181
|
+
@buf << "\n#{ @indent }<#{ elename }>"
|
182
|
+
return
|
183
|
+
end
|
184
|
+
ary = []
|
185
|
+
attrs.each do |key, value|
|
186
|
+
ary << %Q[#{ key }="#{ get_encoded(value.to_s) }"]
|
187
|
+
end
|
188
|
+
case ary.size
|
189
|
+
when 0
|
190
|
+
@buf << "\n#{ @indent }<#{ elename }>"
|
191
|
+
when 1
|
192
|
+
@buf << %Q[\n#{ @indent }<#{ elename } #{ ary[0] }>]
|
193
|
+
else
|
194
|
+
@buf << "\n#{ @indent }<#{ elename } " <<
|
195
|
+
ary.join("\n#{ @indent }#{ @indentstr * 2 }") <<
|
196
|
+
'>'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def encode_tag_end(elename, cr = nil)
|
201
|
+
if cr
|
202
|
+
@buf << "\n#{ @indent }</#{ elename }>"
|
203
|
+
else
|
204
|
+
@buf << "</#{ elename }>"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def encode_rawstring(str)
|
209
|
+
@buf << str
|
210
|
+
end
|
211
|
+
|
212
|
+
def encode_string(str)
|
213
|
+
@buf << get_encoded(str)
|
214
|
+
end
|
215
|
+
|
216
|
+
def element_local?(element)
|
217
|
+
element.elename.namespace.nil?
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.assign_ns(attrs, ns, namespace, tag = nil)
|
221
|
+
if namespace.nil?
|
222
|
+
raise FormatEncodeError.new("empty namespace")
|
223
|
+
end
|
224
|
+
override_default_ns = (tag == '' and namespace != ns.default_namespace)
|
225
|
+
if override_default_ns or !ns.assigned?(namespace)
|
226
|
+
assign_ns!(attrs, ns, namespace, tag)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.assign_ns!(attrs, ns, namespace, tag = nil)
|
231
|
+
tag = ns.assign(namespace, tag)
|
232
|
+
if tag == ''
|
233
|
+
attr = 'xmlns'
|
234
|
+
else
|
235
|
+
attr = "xmlns:#{tag}"
|
236
|
+
end
|
237
|
+
attrs[attr] = namespace
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def prologue
|
243
|
+
end
|
244
|
+
|
245
|
+
def epilogue
|
246
|
+
end
|
247
|
+
|
248
|
+
ENCODE_CHAR_REGEXP = {}
|
249
|
+
|
250
|
+
EncodeMap = {
|
251
|
+
'&' => '&',
|
252
|
+
'<' => '<',
|
253
|
+
'>' => '>',
|
254
|
+
'"' => '"',
|
255
|
+
'\'' => ''',
|
256
|
+
"\r" => '
'
|
257
|
+
}
|
258
|
+
|
259
|
+
def get_encoded(str)
|
260
|
+
if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str)
|
261
|
+
str.gsub!(@encode_char_regexp) { |c| EncodeMap[c] }
|
262
|
+
str.unpack("U*").collect { |c|
|
263
|
+
if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f)
|
264
|
+
c.chr
|
265
|
+
else
|
266
|
+
sprintf("&#x%x;", c)
|
267
|
+
end
|
268
|
+
}.join
|
269
|
+
else
|
270
|
+
str.gsub(@encode_char_regexp) { |c| EncodeMap[c] }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_encode_char_regexp
|
275
|
+
ENCODE_CHAR_REGEXP[XSD::Charset.encoding] ||=
|
276
|
+
# PATCH TO SUPPORT 1.9
|
277
|
+
# Regexp.new("[#{EncodeMap.keys.join}]", nil, XSD::Charset.encoding)
|
278
|
+
Regexp.new("[#{EncodeMap.keys.join}]")
|
279
|
+
#
|
280
|
+
end
|
281
|
+
|
282
|
+
def find_handler(encodingstyle)
|
283
|
+
unless @handlers.key?(encodingstyle)
|
284
|
+
factory = SOAP::EncodingStyle::Handler.handler(encodingstyle)
|
285
|
+
if factory
|
286
|
+
handler = factory.new(@charset)
|
287
|
+
handler.generate_explicit_type = @generate_explicit_type
|
288
|
+
handler.encode_prologue
|
289
|
+
@handlers[encodingstyle] = handler
|
290
|
+
end
|
291
|
+
end
|
292
|
+
@handlers[encodingstyle]
|
293
|
+
end
|
294
|
+
|
295
|
+
def xmldecl
|
296
|
+
if @charset
|
297
|
+
%Q[<?xml version="1.0" encoding="#{ @charset }" ?>]
|
298
|
+
else
|
299
|
+
%Q[<?xml version="1.0" ?>]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
SOAPGenerator = Generator # for backward compatibility
|
305
|
+
|
306
|
+
|
307
|
+
end
|
@@ -0,0 +1,340 @@
|
|
1
|
+
# soap/property.rb: SOAP4R - Property implementation.
|
2
|
+
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
module SOAP
|
10
|
+
|
11
|
+
|
12
|
+
# Property stream format:
|
13
|
+
#
|
14
|
+
# line separator is \r?\n. 1 line per a property.
|
15
|
+
# line which begins with '#' is a comment line. empty line is ignored, too.
|
16
|
+
# key/value separator is ':' or '='.
|
17
|
+
# '\' as escape character. but line separator cannot be escaped.
|
18
|
+
# \s at the head/tail of key/value are trimmed.
|
19
|
+
#
|
20
|
+
# '[' + key + ']' indicates property section. for example,
|
21
|
+
#
|
22
|
+
# [aaa.bbb]
|
23
|
+
# ccc = ddd
|
24
|
+
# eee.fff = ggg
|
25
|
+
# []
|
26
|
+
# aaa.hhh = iii
|
27
|
+
#
|
28
|
+
# is the same as;
|
29
|
+
#
|
30
|
+
# aaa.bbb.ccc = ddd
|
31
|
+
# aaa.bbb.eee.fff = ggg
|
32
|
+
# aaa.hhh = iii
|
33
|
+
#
|
34
|
+
class Property
|
35
|
+
FrozenError = (RUBY_VERSION >= "1.9.0") ? RuntimeError : TypeError
|
36
|
+
|
37
|
+
include Enumerable
|
38
|
+
|
39
|
+
module Util
|
40
|
+
def const_from_name(fqname)
|
41
|
+
fqname.split("::").inject(Kernel) { |klass, name| klass.const_get(name) }
|
42
|
+
end
|
43
|
+
module_function :const_from_name
|
44
|
+
|
45
|
+
def require_from_name(fqname)
|
46
|
+
require File.join(fqname.split("::").collect { |ele| ele.downcase })
|
47
|
+
end
|
48
|
+
module_function :require_from_name
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.load(stream)
|
52
|
+
new.load(stream)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.loadproperty(propname)
|
56
|
+
new.loadproperty(propname)
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
@store = Hash.new
|
61
|
+
@hook = Hash.new
|
62
|
+
@self_hook = Array.new
|
63
|
+
@locked = false
|
64
|
+
end
|
65
|
+
|
66
|
+
KEY_REGSRC = '([^=:\\\\]*(?:\\\\.[^=:\\\\]*)*)'
|
67
|
+
DEF_REGSRC = '\\s*' + KEY_REGSRC + '\\s*[=:]\\s*(.*)'
|
68
|
+
# PATCH TO SUPPORT 1.9
|
69
|
+
# COMMENT_REGEXP = Regexp.new('^(?:#.*|)$', nil, 'u')
|
70
|
+
# CATDEF_REGEXP = Regexp.new("^\\[\\s*#{KEY_REGSRC}\\s*\\]$", nil, 'u')
|
71
|
+
# LINE_REGEXP = Regexp.new("^#{DEF_REGSRC}$", nil, 'u')
|
72
|
+
COMMENT_REGEXP = Regexp.new("^(?:#.*|)$")
|
73
|
+
CATDEF_REGEXP = Regexp.new("^\\[\\s*#{KEY_REGSRC}\\s*\\]$")
|
74
|
+
LINE_REGEXP = Regexp.new("^#{DEF_REGSRC}$")
|
75
|
+
#
|
76
|
+
|
77
|
+
def load(stream)
|
78
|
+
key_prefix = ""
|
79
|
+
stream.each_with_index do |line, lineno|
|
80
|
+
line.sub!(/\r?\n\z/u, '')
|
81
|
+
case line
|
82
|
+
when COMMENT_REGEXP
|
83
|
+
next
|
84
|
+
when CATDEF_REGEXP
|
85
|
+
key_prefix = $1.strip
|
86
|
+
when LINE_REGEXP
|
87
|
+
key, value = $1.strip, $2.strip
|
88
|
+
key = "#{key_prefix}.#{key}" unless key_prefix.empty?
|
89
|
+
key, value = loadstr(key), loadstr(value)
|
90
|
+
self[key] = value
|
91
|
+
else
|
92
|
+
raise TypeError.new(
|
93
|
+
"property format error at line #{lineno + 1}: `#{line}'")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
# find property from $:.
|
100
|
+
def loadproperty(propname)
|
101
|
+
return loadpropertyfile(propname) if File.file?(propname)
|
102
|
+
$:.each do |path|
|
103
|
+
if File.file?(file = File.join(path, propname))
|
104
|
+
return loadpropertyfile(file)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
# name: a Symbol, String or an Array
|
111
|
+
def [](name)
|
112
|
+
referent(name_to_a(name))
|
113
|
+
end
|
114
|
+
|
115
|
+
# name: a Symbol, String or an Array
|
116
|
+
# value: an Object
|
117
|
+
def []=(name, value)
|
118
|
+
name_pair = name_to_a(name).freeze
|
119
|
+
hooks = assign(name_pair, value)
|
120
|
+
hooks.each do |hook|
|
121
|
+
hook.call(name_pair, value)
|
122
|
+
end
|
123
|
+
value
|
124
|
+
end
|
125
|
+
|
126
|
+
# value: an Object
|
127
|
+
# key is generated by property
|
128
|
+
def <<(value)
|
129
|
+
self[generate_new_key] = value
|
130
|
+
end
|
131
|
+
|
132
|
+
# name: a Symbol, String or an Array; nil means hook to the root
|
133
|
+
# cascade: true/false; for cascading hook of sub key
|
134
|
+
# hook: block which will be called with 2 args, name and value
|
135
|
+
def add_hook(name = nil, cascade = false, &hook)
|
136
|
+
if name == nil or name == true or name == false
|
137
|
+
cascade = name
|
138
|
+
assign_self_hook(cascade, &hook)
|
139
|
+
else
|
140
|
+
assign_hook(name_to_a(name), cascade, &hook)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def each
|
145
|
+
@store.each do |key, value|
|
146
|
+
yield(key, value)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def empty?
|
151
|
+
@store.empty?
|
152
|
+
end
|
153
|
+
|
154
|
+
def keys
|
155
|
+
@store.keys
|
156
|
+
end
|
157
|
+
|
158
|
+
def values
|
159
|
+
@store.values
|
160
|
+
end
|
161
|
+
|
162
|
+
def lock(cascade = false)
|
163
|
+
if cascade
|
164
|
+
each_key do |key|
|
165
|
+
key.lock(cascade)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
@locked = true
|
169
|
+
self
|
170
|
+
end
|
171
|
+
|
172
|
+
def unlock(cascade = false)
|
173
|
+
@locked = false
|
174
|
+
if cascade
|
175
|
+
each_key do |key|
|
176
|
+
key.unlock(cascade)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
def locked?
|
183
|
+
@locked
|
184
|
+
end
|
185
|
+
|
186
|
+
protected
|
187
|
+
|
188
|
+
def deref_key(key)
|
189
|
+
check_lock(key)
|
190
|
+
ref = @store[key] ||= self.class.new
|
191
|
+
unless propkey?(ref)
|
192
|
+
raise ArgumentError.new("key `#{key}' already defined as a value")
|
193
|
+
end
|
194
|
+
ref
|
195
|
+
end
|
196
|
+
|
197
|
+
def local_referent(key)
|
198
|
+
check_lock(key)
|
199
|
+
if propkey?(@store[key]) and @store[key].locked?
|
200
|
+
raise FrozenError.new("cannot split any key from locked property")
|
201
|
+
end
|
202
|
+
@store[key]
|
203
|
+
end
|
204
|
+
|
205
|
+
def local_assign(key, value)
|
206
|
+
check_lock(key)
|
207
|
+
if @locked
|
208
|
+
if propkey?(value)
|
209
|
+
raise FrozenError.new("cannot add any key to locked property")
|
210
|
+
elsif propkey?(@store[key])
|
211
|
+
raise FrozenError.new("cannot override any key in locked property")
|
212
|
+
end
|
213
|
+
end
|
214
|
+
@store[key] = value
|
215
|
+
end
|
216
|
+
|
217
|
+
def local_hook(key, direct)
|
218
|
+
hooks = []
|
219
|
+
(@self_hook + (@hook[key] || NO_HOOK)).each do |hook, cascade|
|
220
|
+
hooks << hook if direct or cascade
|
221
|
+
end
|
222
|
+
hooks
|
223
|
+
end
|
224
|
+
|
225
|
+
def local_assign_hook(key, cascade, &hook)
|
226
|
+
check_lock(key)
|
227
|
+
@store[key] ||= nil
|
228
|
+
(@hook[key] ||= []) << [hook, cascade]
|
229
|
+
end
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
NO_HOOK = [].freeze
|
234
|
+
|
235
|
+
def referent(ary)
|
236
|
+
ary[0..-2].inject(self) { |ref, name|
|
237
|
+
ref.deref_key(to_key(name))
|
238
|
+
}.local_referent(to_key(ary.last))
|
239
|
+
end
|
240
|
+
|
241
|
+
def assign(ary, value)
|
242
|
+
ref = self
|
243
|
+
hook = NO_HOOK
|
244
|
+
ary[0..-2].each do |name|
|
245
|
+
key = to_key(name)
|
246
|
+
hook += ref.local_hook(key, false)
|
247
|
+
ref = ref.deref_key(key)
|
248
|
+
end
|
249
|
+
last_key = to_key(ary.last)
|
250
|
+
ref.local_assign(last_key, value)
|
251
|
+
hook + ref.local_hook(last_key, true)
|
252
|
+
end
|
253
|
+
|
254
|
+
def assign_hook(ary, cascade, &hook)
|
255
|
+
ary[0..-2].inject(self) { |ref, name|
|
256
|
+
ref.deref_key(to_key(name))
|
257
|
+
}.local_assign_hook(to_key(ary.last), cascade, &hook)
|
258
|
+
end
|
259
|
+
|
260
|
+
def assign_self_hook(cascade, &hook)
|
261
|
+
check_lock(nil)
|
262
|
+
@self_hook << [hook, cascade]
|
263
|
+
end
|
264
|
+
|
265
|
+
def each_key
|
266
|
+
self.each do |key, value|
|
267
|
+
if propkey?(value)
|
268
|
+
yield(value)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def check_lock(key)
|
274
|
+
if @locked and (key.nil? or !@store.key?(key))
|
275
|
+
raise FrozenError.new("cannot add any key to locked property")
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def propkey?(value)
|
280
|
+
value.is_a?(::SOAP::Property)
|
281
|
+
end
|
282
|
+
|
283
|
+
def name_to_a(name)
|
284
|
+
case name
|
285
|
+
when Symbol
|
286
|
+
[name]
|
287
|
+
when String
|
288
|
+
name.scan(/[^.\\]+(?:\\.[^.\\])*/u) # split with unescaped '.'
|
289
|
+
when Array
|
290
|
+
name
|
291
|
+
else
|
292
|
+
raise ArgumentError.new("Unknown name #{name}(#{name.class})")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def to_key(name)
|
297
|
+
name.to_s.downcase
|
298
|
+
end
|
299
|
+
|
300
|
+
def generate_new_key
|
301
|
+
if @store.empty?
|
302
|
+
"0"
|
303
|
+
else
|
304
|
+
(key_max + 1).to_s
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def key_max
|
309
|
+
(@store.keys.max { |l, r| l.to_s.to_i <=> r.to_s.to_i }).to_s.to_i
|
310
|
+
end
|
311
|
+
|
312
|
+
def loadpropertyfile(file)
|
313
|
+
puts "find property at #{file}" if $DEBUG
|
314
|
+
File.open(file) do |f|
|
315
|
+
load(f)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def loadstr(str)
|
320
|
+
str.gsub(/\\./u) { |c| eval("\"#{c}\"") }
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
# for ruby/1.6.
|
329
|
+
unless Enumerable.instance_methods.include?('inject')
|
330
|
+
module Enumerable
|
331
|
+
def inject(init)
|
332
|
+
result = init
|
333
|
+
each do |item|
|
334
|
+
result = yield(result, item)
|
335
|
+
end
|
336
|
+
result
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# XSD4R - Charset handling library.
|
2
|
+
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
module XSD
|
10
|
+
|
11
|
+
|
12
|
+
module Charset
|
13
|
+
@internal_encoding = "UTF8"
|
14
|
+
|
15
|
+
class XSDError < StandardError; end
|
16
|
+
class CharsetError < XSDError; end
|
17
|
+
class UnknownCharsetError < CharsetError; end
|
18
|
+
class CharsetConversionError < CharsetError; end
|
19
|
+
|
20
|
+
public
|
21
|
+
|
22
|
+
###
|
23
|
+
## Maps
|
24
|
+
#
|
25
|
+
EncodingConvertMap = {}
|
26
|
+
def Charset.init
|
27
|
+
EncodingConvertMap[['UTF8', 'X_ISO_8859_1']] =
|
28
|
+
Proc.new { |str| str.unpack('U*').pack('C*') }
|
29
|
+
EncodingConvertMap[['X_ISO_8859_1', 'UTF8']] =
|
30
|
+
Proc.new { |str| str.unpack('C*').pack('U*') }
|
31
|
+
begin
|
32
|
+
require 'xsd/iconvcharset'
|
33
|
+
@internal_encoding = 'UTF8'
|
34
|
+
sjtag = (/(mswin|bccwin|mingw|cygwin|emx)/ =~ RUBY_PLATFORM) ? 'cp932' :
|
35
|
+
'shift_jis'
|
36
|
+
EncodingConvertMap[['UTF8', 'EUC' ]] =
|
37
|
+
Proc.new { |str| IconvCharset.safe_iconv("euc-jp", "utf-8", str) }
|
38
|
+
EncodingConvertMap[['EUC' , 'UTF8']] =
|
39
|
+
Proc.new { |str| IconvCharset.safe_iconv("utf-8", "euc-jp", str) }
|
40
|
+
EncodingConvertMap[['EUC' , 'SJIS']] =
|
41
|
+
Proc.new { |str| IconvCharset.safe_iconv(sjtag, "euc-jp", str) }
|
42
|
+
EncodingConvertMap[['UTF8', 'SJIS']] =
|
43
|
+
Proc.new { |str| IconvCharset.safe_iconv(sjtag, "utf-8", str) }
|
44
|
+
EncodingConvertMap[['SJIS', 'UTF8']] =
|
45
|
+
Proc.new { |str| IconvCharset.safe_iconv("utf-8", sjtag, str) }
|
46
|
+
EncodingConvertMap[['SJIS', 'EUC' ]] =
|
47
|
+
Proc.new { |str| IconvCharset.safe_iconv("euc-jp", sjtag, str) }
|
48
|
+
rescue LoadError
|
49
|
+
begin
|
50
|
+
require 'nkf'
|
51
|
+
EncodingConvertMap[['EUC' , 'SJIS']] =
|
52
|
+
Proc.new { |str| NKF.nkf('-sXm0', str) }
|
53
|
+
EncodingConvertMap[['SJIS', 'EUC' ]] =
|
54
|
+
Proc.new { |str| NKF.nkf('-eXm0', str) }
|
55
|
+
rescue LoadError
|
56
|
+
end
|
57
|
+
|
58
|
+
begin
|
59
|
+
require 'uconv'
|
60
|
+
@internal_encoding = 'UTF8'
|
61
|
+
EncodingConvertMap[['UTF8', 'EUC' ]] = Uconv.method(:u8toeuc)
|
62
|
+
EncodingConvertMap[['UTF8', 'SJIS']] = Uconv.method(:u8tosjis)
|
63
|
+
EncodingConvertMap[['EUC' , 'UTF8']] = Uconv.method(:euctou8)
|
64
|
+
EncodingConvertMap[['SJIS', 'UTF8']] = Uconv.method(:sjistou8)
|
65
|
+
rescue LoadError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
self.init
|
70
|
+
|
71
|
+
CharsetMap = {
|
72
|
+
'NONE' => 'us-ascii',
|
73
|
+
'EUC' => 'euc-jp',
|
74
|
+
'SJIS' => 'shift_jis',
|
75
|
+
'UTF8' => 'utf-8',
|
76
|
+
'X_ISO_8859_1' => 'iso-8859-1',
|
77
|
+
'X_UNKNOWN' => nil,
|
78
|
+
}
|
79
|
+
|
80
|
+
CharsetStrCache = {}
|
81
|
+
|
82
|
+
|
83
|
+
###
|
84
|
+
## handlers
|
85
|
+
#
|
86
|
+
def Charset.encoding
|
87
|
+
@internal_encoding
|
88
|
+
end
|
89
|
+
|
90
|
+
def Charset.encoding=(encoding)
|
91
|
+
warn("xsd charset is set to #{encoding}") if $DEBUG
|
92
|
+
@internal_encoding = encoding
|
93
|
+
end
|
94
|
+
|
95
|
+
def Charset.xml_encoding_label
|
96
|
+
charset_label(@internal_encoding)
|
97
|
+
end
|
98
|
+
|
99
|
+
def Charset.encoding_to_xml(str, charset)
|
100
|
+
encoding_conv(str, @internal_encoding, charset_str(charset))
|
101
|
+
end
|
102
|
+
|
103
|
+
def Charset.encoding_from_xml(str, charset)
|
104
|
+
encoding_conv(str, charset_str(charset), @internal_encoding)
|
105
|
+
end
|
106
|
+
|
107
|
+
def Charset.encoding_conv(str, enc_from, enc_to)
|
108
|
+
if enc_from == enc_to or enc_from == 'NONE' or enc_to == 'NONE'
|
109
|
+
str
|
110
|
+
elsif converter = EncodingConvertMap[[enc_from, enc_to]]
|
111
|
+
converter.call(str)
|
112
|
+
else
|
113
|
+
raise CharsetConversionError.new(
|
114
|
+
"Converter not found: #{enc_from} -> #{enc_to}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def Charset.charset_label(encoding)
|
119
|
+
CharsetMap[encoding.upcase]
|
120
|
+
end
|
121
|
+
|
122
|
+
def Charset.charset_str(label)
|
123
|
+
if CharsetMap.respond_to?(:key)
|
124
|
+
CharsetStrCache[label] ||= CharsetMap.key(label.downcase) || 'X_UNKNOWN'
|
125
|
+
else
|
126
|
+
CharsetStrCache[label] ||= CharsetMap.index(label.downcase) || 'X_UNKNOWN'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# us_ascii = '[\x00-\x7F]'
|
131
|
+
us_ascii = '[\x9\xa\xd\x20-\x7F]' # XML 1.0 restricted.
|
132
|
+
USASCIIRegexp = Regexp.new("\\A#{us_ascii}*\\z", nil, 'NONE')
|
133
|
+
|
134
|
+
twobytes_euc = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'
|
135
|
+
threebytes_euc = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'
|
136
|
+
character_euc = "(?:#{us_ascii}|#{twobytes_euc}|#{threebytes_euc})"
|
137
|
+
EUCRegexp = Regexp.new("\\A#{character_euc}*\\z", nil, 'NONE')
|
138
|
+
|
139
|
+
# onebyte_sjis = '[\x00-\x7F\xA1-\xDF]'
|
140
|
+
onebyte_sjis = '[\x9\xa\xd\x20-\x7F\xA1-\xDF]' # XML 1.0 restricted.
|
141
|
+
twobytes_sjis = '(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC])'
|
142
|
+
character_sjis = "(?:#{onebyte_sjis}|#{twobytes_sjis})"
|
143
|
+
SJISRegexp = Regexp.new("\\A#{character_sjis}*\\z", nil, 'NONE')
|
144
|
+
|
145
|
+
# 0xxxxxxx
|
146
|
+
# 110yyyyy 10xxxxxx
|
147
|
+
twobytes_utf8 = '(?:[\xC0-\xDF][\x80-\xBF])'
|
148
|
+
# 1110zzzz 10yyyyyy 10xxxxxx
|
149
|
+
threebytes_utf8 = '(?:[\xE0-\xEF][\x80-\xBF][\x80-\xBF])'
|
150
|
+
# 11110uuu 10uuuzzz 10yyyyyy 10xxxxxx
|
151
|
+
fourbytes_utf8 = '(?:[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])'
|
152
|
+
character_utf8 =
|
153
|
+
"(?:#{us_ascii}|#{twobytes_utf8}|#{threebytes_utf8}|#{fourbytes_utf8})"
|
154
|
+
UTF8Regexp = Regexp.new("\\A#{character_utf8}*\\z", nil, 'NONE')
|
155
|
+
|
156
|
+
def Charset.is_us_ascii(str)
|
157
|
+
USASCIIRegexp =~ str
|
158
|
+
end
|
159
|
+
|
160
|
+
def Charset.is_utf8(str)
|
161
|
+
UTF8Regexp =~ str
|
162
|
+
end
|
163
|
+
|
164
|
+
def Charset.is_euc(str)
|
165
|
+
EUCRegexp =~ str
|
166
|
+
end
|
167
|
+
|
168
|
+
def Charset.is_sjis(str)
|
169
|
+
SJISRegexp =~ str
|
170
|
+
end
|
171
|
+
|
172
|
+
def Charset.is_ces(str, code = @internal_encoding)
|
173
|
+
case code
|
174
|
+
when 'NONE'
|
175
|
+
is_us_ascii(str)
|
176
|
+
when 'UTF8'
|
177
|
+
is_utf8(str)
|
178
|
+
when 'EUC'
|
179
|
+
is_euc(str)
|
180
|
+
when 'SJIS'
|
181
|
+
is_sjis(str)
|
182
|
+
else
|
183
|
+
raise UnknownCharsetError.new("Unknown charset: #{code}")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
end
|
190
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# XSD4R - XML Instance parser library.
|
2
|
+
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
require 'xsd/xmlparser/parser'
|
10
|
+
|
11
|
+
|
12
|
+
module XSD
|
13
|
+
|
14
|
+
|
15
|
+
module XMLParser
|
16
|
+
def create_parser(host, opt)
|
17
|
+
XSD::XMLParser::Parser.create_parser(host, opt)
|
18
|
+
end
|
19
|
+
module_function :create_parser
|
20
|
+
|
21
|
+
# $1 is necessary.
|
22
|
+
NSParseRegexp = Regexp.new('^xmlns:?(.*)$', nil, 'NONE')
|
23
|
+
|
24
|
+
def filter_ns(ns, attrs)
|
25
|
+
ns_updated = false
|
26
|
+
if attrs.nil? or attrs.empty?
|
27
|
+
return [ns, attrs]
|
28
|
+
end
|
29
|
+
newattrs = {}
|
30
|
+
attrs.each do |key, value|
|
31
|
+
if NSParseRegexp =~ key
|
32
|
+
unless ns_updated
|
33
|
+
ns = ns.clone_ns
|
34
|
+
ns_updated = true
|
35
|
+
end
|
36
|
+
# tag == '' means 'default namespace'
|
37
|
+
# value == '' means 'no default namespace'
|
38
|
+
tag = $1 || ''
|
39
|
+
ns.assign(value, tag)
|
40
|
+
else
|
41
|
+
newattrs[key] = value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
return [ns, newattrs]
|
45
|
+
end
|
46
|
+
module_function :filter_ns
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Try to load XML processor.
|
54
|
+
loaded = false
|
55
|
+
[
|
56
|
+
'xsd/xmlparser/xmlparser',
|
57
|
+
'xsd/xmlparser/xmlscanner',
|
58
|
+
'xsd/xmlparser/rexmlparser',
|
59
|
+
].each do |lib|
|
60
|
+
begin
|
61
|
+
require lib
|
62
|
+
# XXX: for a workaround of rubygems' require inconsistency
|
63
|
+
# XXX: MUST BE REMOVED IN THE FUTURE
|
64
|
+
name = lib.sub(/^.*\//, '')
|
65
|
+
raise LoadError unless XSD::XMLParser.constants.find { |c|
|
66
|
+
# PATCHING TO HANDLE 1.9
|
67
|
+
#c.downcase == name
|
68
|
+
c.to_s.downcase == name
|
69
|
+
#
|
70
|
+
}
|
71
|
+
loaded = true
|
72
|
+
break
|
73
|
+
rescue LoadError
|
74
|
+
end
|
75
|
+
end
|
76
|
+
unless loaded
|
77
|
+
raise RuntimeError.new("XML processor module not found.")
|
78
|
+
end
|
79
|
+
|
data/lib/yieldmanager.rb
CHANGED
@@ -12,6 +12,14 @@ end
|
|
12
12
|
require 'patch_detector'
|
13
13
|
include PatchDetector
|
14
14
|
|
15
|
+
if (RUBY_VERSION.start_with?("1.9"))
|
16
|
+
#
|
17
|
+
# This patch based on Tomer Doron's "Fixing soap4r for ruby 1.9" post
|
18
|
+
# http://tomerdoron.blogspot.com/2009/10/fixing-soap4r-for-ruby-19.html
|
19
|
+
#
|
20
|
+
$LOAD_PATH.unshift 'lib/soap4r_19_patch'
|
21
|
+
end
|
22
|
+
|
15
23
|
require 'yieldmanager/client'
|
16
24
|
|
17
25
|
if needs_patching?(:ruby_version => RUBY_VERSION, :minimum_ruby_version_for_patch => "1.8.7")
|
data/spec/spec_helper.rb
CHANGED
data/yieldmanager.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{yieldmanager}
|
8
|
-
s.version = "0.8.
|
8
|
+
s.version = "0.8.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bill Gathen"]
|
12
|
-
s.date = %q{2011-05-
|
12
|
+
s.date = %q{2011-05-18}
|
13
13
|
s.description = %q{This gem offers full access to YieldManager's API tools (read/write) as well as ad-hoc reporting through the Reportware tool}
|
14
14
|
s.email = %q{bill@billgathen.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,6 +27,10 @@ Gem::Specification.new do |s|
|
|
27
27
|
"TODO",
|
28
28
|
"VERSION",
|
29
29
|
"lib/patch_detector.rb",
|
30
|
+
"lib/soap4r_19_patch/soap/generator.rb",
|
31
|
+
"lib/soap4r_19_patch/soap/property.rb",
|
32
|
+
"lib/soap4r_19_patch/xsd/charset.rb",
|
33
|
+
"lib/soap4r_19_patch/xsd/xmlparser.rb",
|
30
34
|
"lib/wsdl/patch.rb",
|
31
35
|
"lib/yieldmanager.rb",
|
32
36
|
"lib/yieldmanager/builder.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yieldmanager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 3
|
10
|
+
version: 0.8.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bill Gathen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-05-
|
18
|
+
date: 2011-05-18 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -70,6 +70,10 @@ files:
|
|
70
70
|
- TODO
|
71
71
|
- VERSION
|
72
72
|
- lib/patch_detector.rb
|
73
|
+
- lib/soap4r_19_patch/soap/generator.rb
|
74
|
+
- lib/soap4r_19_patch/soap/property.rb
|
75
|
+
- lib/soap4r_19_patch/xsd/charset.rb
|
76
|
+
- lib/soap4r_19_patch/xsd/xmlparser.rb
|
73
77
|
- lib/wsdl/patch.rb
|
74
78
|
- lib/yieldmanager.rb
|
75
79
|
- lib/yieldmanager/builder.rb
|