wash_away_the_soap 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wash_away_the_soap.rb +62 -12
- data/spec/wash_away_the_soap_spec.rb +41 -0
- metadata +2 -2
data/lib/wash_away_the_soap.rb
CHANGED
@@ -3,7 +3,7 @@ require "bundler/setup"
|
|
3
3
|
require "nokogiri"
|
4
4
|
|
5
5
|
class WashAwayTheSoap
|
6
|
-
attr_accessor :wsdls, :xsds, :wsdl_operations, :xsd_objects
|
6
|
+
attr_accessor :wsdls, :xsds, :wsdl_operations, :xsd_objects, :complex_objects, :temp_objects
|
7
7
|
|
8
8
|
class << self
|
9
9
|
def parse
|
@@ -14,6 +14,8 @@ class WashAwayTheSoap
|
|
14
14
|
def initialize
|
15
15
|
@wsdl_operations = []
|
16
16
|
@xsd_objects = {}
|
17
|
+
@complex_objects = {}
|
18
|
+
@temp_objects = {}
|
17
19
|
@wsdls = []
|
18
20
|
@xsds = []
|
19
21
|
end
|
@@ -38,23 +40,44 @@ class WashAwayTheSoap
|
|
38
40
|
end
|
39
41
|
rescue => e
|
40
42
|
puts "Error parsing wsdl file #{filename}"
|
43
|
+
exit 1
|
41
44
|
end
|
42
45
|
|
43
46
|
def parse_xsd(xsd, filename = nil)
|
44
47
|
doc = Nokogiri::XML(xsd)
|
45
|
-
doc.xpath("//xs:sequence//xs:element", doc.root.namespaces).each do |field|
|
48
|
+
doc.xpath("//xs:element//xs:sequence//xs:element", doc.root.namespaces).each do |field|
|
46
49
|
operation = field.parent.parent.parent.attributes["name"]
|
47
50
|
unless operation.nil?
|
48
51
|
next unless operation.value
|
49
52
|
next unless field.attributes["name"]
|
50
53
|
operation_name = operation.value
|
51
54
|
field_name = field.attributes["name"].value
|
52
|
-
|
53
|
-
field_type = field.attributes["type"].value.gsub(/^xs:/, "") if field.attributes["type"]
|
54
|
-
allow_blank = (field.attributes["nillable"].value ? true : false) if field.attributes["nillable"]
|
55
|
-
required = (field.attributes["minOccurs"].value.to_i > 0 ? true : false) if field.attributes["minOccurs"]
|
55
|
+
|
56
56
|
xsd_objects[operation_name] ||= {}
|
57
|
-
xsd_objects[operation_name][field_name] ||=
|
57
|
+
xsd_objects[operation_name][field_name] ||= build_field_attributes(field)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
doc.xpath("//xs:complexType//xs:element", doc.root.namespaces).each do |field|
|
61
|
+
if field.parent.parent.parent == doc.root
|
62
|
+
if field.attributes["type"].value =~ /tns:.*/
|
63
|
+
complex_name = field.parent.parent.attributes["name"].value
|
64
|
+
field_name = field.attributes["name"].value
|
65
|
+
complex_objects[complex_name] ||= {}
|
66
|
+
complex_objects[complex_name][field_name] ||= -1
|
67
|
+
else
|
68
|
+
complex_name = field.parent.parent.attributes["name"].value
|
69
|
+
field_name = field.attributes["name"].value
|
70
|
+
temp_objects[complex_name] ||= {}
|
71
|
+
temp_objects[complex_name][field_name] ||= build_field_attributes(field)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
complex_objects.each do |key, hash|
|
77
|
+
hash.each do |k, v|
|
78
|
+
if v == -1
|
79
|
+
complex_objects[key][k] = temp_objects[k] # inplace modification horribleness
|
80
|
+
end
|
58
81
|
end
|
59
82
|
end
|
60
83
|
rescue => e
|
@@ -62,6 +85,23 @@ class WashAwayTheSoap
|
|
62
85
|
exit 1
|
63
86
|
end
|
64
87
|
|
88
|
+
def build_field_attributes(nokogiri_element)
|
89
|
+
field_type, allow_blank, required = "unknown", false, false
|
90
|
+
|
91
|
+
field_type = nokogiri_element.attributes["type"].value.gsub(/^xs:/, "") if nokogiri_element.attributes["type"]
|
92
|
+
allow_blank = (nokogiri_element.attributes["nillable"].value ? true : false) if nokogiri_element.attributes["nillable"]
|
93
|
+
required = (nokogiri_element.attributes["minOccurs"].value.to_i > 0 ? true : false) if nokogiri_element.attributes["minOccurs"]
|
94
|
+
{"type" => field_type, "allow_blank" => allow_blank, "required" => required}
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_field_options(values)
|
98
|
+
field_options = []
|
99
|
+
field_options << values["type"]
|
100
|
+
field_options << "required" if values["required"]
|
101
|
+
field_options << "no_blanks" unless values["allow_blank"]
|
102
|
+
field_options.join(", ")
|
103
|
+
end
|
104
|
+
|
65
105
|
def build_results
|
66
106
|
output = []
|
67
107
|
longest_field_name = 0
|
@@ -77,11 +117,21 @@ class WashAwayTheSoap
|
|
77
117
|
output << operation
|
78
118
|
if xsd_objects[operation]
|
79
119
|
xsd_objects[operation].each do |field, values|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
120
|
+
if values["type"] =~ /.*:.*/ && complex_objects.keys.include?(values["type"].split(":").last)
|
121
|
+
complex_name = values["type"].split(":").last
|
122
|
+
complex_line = " #{field.rjust(longest_field_name)}: #{complex_name}"
|
123
|
+
output << complex_line
|
124
|
+
|
125
|
+
complex_objects[complex_name].each do |object_name, fields|
|
126
|
+
object_line = "- #{object_name}".rjust(complex_line.length + 1)
|
127
|
+
output << object_line
|
128
|
+
fields.each do |field_name, complex_values|
|
129
|
+
output << " #{field_name.rjust(object_line.length + 5)}: #{build_field_options(complex_values)}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
else
|
133
|
+
output << " #{field.rjust(longest_field_name)}: #{build_field_options(values)}"
|
134
|
+
end
|
85
135
|
end
|
86
136
|
else
|
87
137
|
output << " - no fields found?"
|
@@ -49,6 +49,17 @@ describe WashAwayTheSoap do
|
|
49
49
|
<xs:simpleType name="ignoredSimpleType">
|
50
50
|
<xs:restriction base="xs:int" />
|
51
51
|
</xs:simpleType>
|
52
|
+
<xs:complexType name="ArrayOfStuff">
|
53
|
+
<xs:sequence>
|
54
|
+
<xs:element minOccurs="0" maxOccurs="unbounded" name="SOME_STUFF" nillable="true" type="tns:SOME_STUFF" />
|
55
|
+
</xs:sequence>
|
56
|
+
</xs:complexType>
|
57
|
+
<xs:element name="ArrayOfStuff" nillable="true" type="tns:ArrayOfStuff" />
|
58
|
+
<xs:complexType name="SOME_STUFF">
|
59
|
+
<xs:sequence>
|
60
|
+
<xs:element minOccurs="0" name="SOME_COMPLEX_FIELD" nillable="true" type="xs:dateTime" />
|
61
|
+
</xs:sequence>
|
62
|
+
</xs:complexType>
|
52
63
|
</xs:schema>
|
53
64
|
XML
|
54
65
|
subject.parse_xsd(@xsd_doc)
|
@@ -74,6 +85,11 @@ describe WashAwayTheSoap do
|
|
74
85
|
subject.xsd_objects["OperationFoo"]["NillableStringField"]["allow_blank"].should be_true
|
75
86
|
end
|
76
87
|
|
88
|
+
it "records complex types for later use" do
|
89
|
+
subject.complex_objects["ArrayOfStuff"].should == {"SOME_STUFF" => {"SOME_COMPLEX_FIELD" =>
|
90
|
+
{"allow_blank" => true, "required" => false, "type" => "dateTime"}}}
|
91
|
+
end
|
92
|
+
|
77
93
|
end
|
78
94
|
describe "#build_results" do
|
79
95
|
before do
|
@@ -89,6 +105,9 @@ describe WashAwayTheSoap do
|
|
89
105
|
<soap:body use="literal" />
|
90
106
|
</wsdl:output>
|
91
107
|
</wsdl:operation>
|
108
|
+
<wsdl:operation name="OperationBar">
|
109
|
+
<soap:operation soapAction="http://tempuri.org/SomeService/OperationBar" style="document" />
|
110
|
+
</wsdl:operation>
|
92
111
|
</wsdl:binding>
|
93
112
|
</wsdl:definitions>
|
94
113
|
XML
|
@@ -104,6 +123,24 @@ describe WashAwayTheSoap do
|
|
104
123
|
</xs:sequence>
|
105
124
|
</xs:complexType>
|
106
125
|
</xs:element>
|
126
|
+
<xs:element name="OperationBar">
|
127
|
+
<xs:complexType>
|
128
|
+
<xs:sequence>
|
129
|
+
<xs:element xmlns:q10="http://whatever" minOccurs="0" name="someName" nillable="true" type="q10:ArrayOfStuff" />
|
130
|
+
</xs:sequence>
|
131
|
+
</xs:complexType>
|
132
|
+
</xs:element>
|
133
|
+
<xs:complexType name="ArrayOfStuff">
|
134
|
+
<xs:sequence>
|
135
|
+
<xs:element minOccurs="0" maxOccurs="unbounded" name="SOME_STUFF" nillable="true" type="tns:SOME_STUFF" />
|
136
|
+
</xs:sequence>
|
137
|
+
</xs:complexType>
|
138
|
+
<xs:element name="ArrayOfStuff" nillable="true" type="tns:ArrayOfStuff" />
|
139
|
+
<xs:complexType name="SOME_STUFF">
|
140
|
+
<xs:sequence>
|
141
|
+
<xs:element minOccurs="0" name="SOME_COMPLEX_FIELD" nillable="true" type="xs:dateTime" />
|
142
|
+
</xs:sequence>
|
143
|
+
</xs:complexType>
|
107
144
|
</xs:schema>
|
108
145
|
XML
|
109
146
|
subject.parse_xsd(@xsd_doc)
|
@@ -115,6 +152,10 @@ OperationFoo
|
|
115
152
|
UnrequiredNumberField: decimal, no_blanks
|
116
153
|
RequiredDateField: dateTime, required, no_blanks
|
117
154
|
NillableStringField: string
|
155
|
+
OperationBar
|
156
|
+
someName: ArrayOfStuff
|
157
|
+
- SOME_STUFF
|
158
|
+
SOME_COMPLEX_FIELD: dateTime
|
118
159
|
EOS
|
119
160
|
end
|
120
161
|
end
|