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.
@@ -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
- field_type, allow_blank, required = "unknown", false, false
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] ||= {"type" => field_type, "allow_blank" => allow_blank, "required" => required}
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
- field_options = []
81
- field_options << values["type"]
82
- field_options << "required" if values["required"]
83
- field_options << "no_blanks" unless values["allow_blank"]
84
- output << " #{field.rjust(longest_field_name)}: #{field_options.join(', ')}"
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
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Michael Schubert