Class | SOAP::SOAPGenerator |
In: |
lib/soap/generator.rb
|
Parent: | Object |
CAUTION: MT-unsafe
EncodeMap | = | { '&' => '&', '<' => '<', '>' => '>', '"' => '"', '\'' => ''', "\r" => '
' |
EncodeCharRegexp | = | Regexp.new("[#{EncodeMap.keys.join}]") |
charset | [RW] | |
default_encodingstyle | [RW] | |
generate_explicit_type | [RW] | |
use_numeric_character_reference | [RW] |
# File lib/soap/generator.rb, line 225 225: def self.assign_ns(attrs, ns, namespace, tag = nil) 226: if namespace.nil? 227: raise FormatEncodeError.new("empty namespace") 228: end 229: unless ns.assigned?(namespace) 230: tag = ns.assign(namespace, tag) 231: if tag == '' 232: attr = 'xmlns' 233: else 234: attr = "xmlns:#{tag}" 235: end 236: attrs[attr] = namespace 237: end 238: end
# File lib/soap/generator.rb, line 33 33: def initialize(opt = {}) 34: @reftarget = nil 35: @handlers = {} 36: @charset = opt[:charset] || XSD::Charset.xml_encoding_label 37: @default_encodingstyle = opt[:default_encodingstyle] || EncodingNamespace 38: @generate_explicit_type = 39: opt.key?(:generate_explicit_type) ? opt[:generate_explicit_type] : true 40: @elementformdefault = opt[:elementformdefault] 41: @attributeformdefault = opt[:attributeformdefault] 42: @use_numeric_character_reference = opt[:use_numeric_character_reference] 43: @indentstr = opt[:no_indent] ? '' : ' ' 44: @buf = @indent = @curr = nil 45: end
# File lib/soap/generator.rb, line 97 97: def add_reftarget(name, node) 98: unless @reftarget 99: raise FormatEncodeError.new("Reftarget is not defined.") 100: end 101: @reftarget.add(name, node) 102: end
# File lib/soap/generator.rb, line 209 209: def element_local?(element) 210: element.elename.namespace.nil? 211: end
# File lib/soap/generator.rb, line 213 213: def element_qualified?(element) 214: if element.respond_to?(:qualified) 215: if element.qualified.nil? 216: @elementformdefault 217: else 218: element.qualified 219: end 220: else 221: @elementformdefault 222: end 223: end
# File lib/soap/generator.rb, line 104 104: def encode_child(ns, child, parent) 105: indent_backup, @indent = @indent, @indent + @indentstr 106: encode_data(ns.clone_ns, child, parent) 107: @indent = indent_backup 108: end
# File lib/soap/generator.rb, line 68 68: def encode_data(ns, obj, parent) 69: if obj.is_a?(SOAPEnvelopeElement) 70: encode_element(ns, obj, parent) 71: return 72: end 73: if @reftarget && !obj.precedents.empty? 74: add_reftarget(obj.elename.name, obj) 75: ref = SOAPReference.new(obj) 76: ref.elename = ref.elename.dup_name(obj.elename.name) 77: obj.precedents.clear # Avoid cyclic delay. 78: obj.encodingstyle = parent.encodingstyle 79: # SOAPReference is encoded here. 80: obj = ref 81: end 82: encodingstyle = obj.encodingstyle 83: # Children's encodingstyle is derived from its parent. 84: encodingstyle ||= parent.encodingstyle if parent 85: obj.encodingstyle = encodingstyle 86: handler = find_handler(encodingstyle || @default_encodingstyle) 87: unless handler 88: raise FormatEncodeError.new("Unknown encodingStyle: #{ encodingstyle }.") 89: end 90: if !obj.elename.name 91: raise FormatEncodeError.new("Element name not defined: #{ obj }.") 92: end 93: handler.encode_data(self, ns, obj, parent) 94: handler.encode_data_end(self, ns, obj, parent) 95: end
# File lib/soap/generator.rb, line 110 110: def encode_element(ns, obj, parent) 111: attrs = {} 112: if obj.is_a?(SOAPBody) 113: @reftarget = obj 114: obj.encode(self, ns, attrs) do |child| 115: indent_backup, @indent = @indent, @indent + @indentstr 116: encode_data(ns.clone_ns, child, obj) 117: @indent = indent_backup 118: end 119: @reftarget = nil 120: else 121: if obj.is_a?(SOAPEnvelope) 122: # xsi:nil="true" can appear even if dumping without explicit type. 123: SOAPGenerator.assign_ns(attrs, ns, 124: XSD::InstanceNamespace, XSINamespaceTag) 125: if @generate_explicit_type 126: SOAPGenerator.assign_ns(attrs, ns, XSD::Namespace, XSDNamespaceTag) 127: end 128: end 129: obj.encode(self, ns, attrs) do |child| 130: indent_backup, @indent = @indent, @indent + @indentstr 131: encode_data(ns.clone_ns, child, obj) 132: @indent = indent_backup 133: end 134: end 135: end
# File lib/soap/generator.rb, line 137 137: def encode_name(ns, data, attrs) 138: if element_local?(data) 139: data.elename.name 140: else 141: if element_qualified?(data) 142: SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace, '') 143: else 144: SOAPGenerator.assign_ns(attrs, ns, data.elename.namespace) 145: end 146: ns.name(data.elename) 147: end 148: end
# File lib/soap/generator.rb, line 150 150: def encode_name_end(ns, data) 151: if element_local?(data) 152: data.elename.name 153: else 154: ns.name(data.elename) 155: end 156: end
# File lib/soap/generator.rb, line 194 194: def encode_string(str) 195: if @use_numeric_character_reference and !XSD::Charset.is_us_ascii(str) 196: str.gsub!(EncodeCharRegexp) { |c| EncodeMap[c] } 197: @buf << str.unpack("U*").collect { |c| 198: if c == 0x9 or c == 0xa or c == 0xd or (c >= 0x20 and c <= 0x7f) 199: c.chr 200: else 201: sprintf("&#x%x;", c) 202: end 203: }.join 204: else 205: @buf << str.gsub(EncodeCharRegexp) { |c| EncodeMap[c] } 206: end 207: end
# File lib/soap/generator.rb, line 158 158: def encode_tag(elename, attrs = nil) 159: if !attrs or attrs.empty? 160: @buf << "\n#{ @indent }<#{ elename }>" 161: elsif attrs.size == 1 162: key, value = attrs.shift 163: @buf << %Q[\n#{ @indent }<#{ elename } #{ key }="#{ value }">] 164: else 165: @buf << "\n#{ @indent }<#{ elename } " << 166: attrs.collect { |key, value| 167: %Q[#{ key }="#{ value }"] 168: }.join("\n#{ @indent }#{ @indentstr * 2 }") << 169: '>' 170: end 171: end
# File lib/soap/generator.rb, line 173 173: def encode_tag_end(elename, cr = nil) 174: if cr 175: @buf << "\n#{ @indent }</#{ elename }>" 176: else 177: @buf << "</#{ elename }>" 178: end 179: end
# File lib/soap/generator.rb, line 47 47: def generate(obj, io = nil) 48: @buf = io || '' 49: @indent = '' 50: 51: prologue 52: @handlers.each do |uri, handler| 53: handler.encode_prologue 54: end 55: 56: ns = XSD::NS.new 57: @buf << xmldecl 58: encode_data(ns, obj, nil) 59: 60: @handlers.each do |uri, handler| 61: handler.encode_epilogue 62: end 63: epilogue 64: 65: @buf 66: end
# File lib/soap/generator.rb, line 248 248: def find_handler(encodingstyle) 249: unless @handlers.key?(encodingstyle) 250: handler = SOAP::EncodingStyle::Handler.handler(encodingstyle).new(@charset) 251: handler.generate_explicit_type = @generate_explicit_type 252: handler.encode_prologue 253: @handlers[encodingstyle] = handler 254: end 255: @handlers[encodingstyle] 256: end