Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Include support for relative paths / Support for Sabre API #22

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions lib/sekken/importer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,41 @@ def import(location)
# resolve xml schema imports
import_schemas do |schema_location|
@logger.info("Resolving XML schema import #{schema_location.inspect}.")

import_document(schema_location) do |document|
@schemas.push(document.schemas)
end
end

import_included_schemas do |schema_location|
@logger.info("Resolving included schema #{schema_location.inspect}.")

import_document(schema_location) do |document|
document.schemas.each do |schema|
existing = @schemas.find_by_namespace(schema.target_namespace)
existing.merge(schema)
end
end
end
end

private

def import_document(location, &block)
@logger.info("Importing #{location.inspect}.")
if @import_locations.include? location
@logger.info("Skipping already imported location #{location.inspect}.")
@logger.warn("Skipping already imported location #{location.inspect}.")
return
end

xml = @resolver.resolve(location)

@import_locations << location

document = WSDL::Document.new Nokogiri.XML(xml), @schemas

block.call(document)

# resolve wsdl imports
document.imports.each do |import_location|
@logger.info("Resolving WSDL import #{import_location.inspect}.")
Expand All @@ -57,20 +71,25 @@ def import_schemas
schema.imports.each do |namespace, schema_location|
next unless schema_location

unless absolute_url? schema_location
unless @resolver.can_resolve? schema_location
@logger.warn("Skipping XML Schema import #{schema_location.inspect}.")
next
end

# TODO: also skip if the schema was already imported

yield(schema_location)
end
end
end

def absolute_url?(location)
location =~ Resolver::URL_PATTERN
def import_included_schemas
@schemas.each do |schema|
schema.includes.each do |include_location|
if @resolver.can_resolve? include_location
yield include_location
end
end
end
end

end
Expand Down
14 changes: 12 additions & 2 deletions lib/sekken/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@ class Resolver
URL_PATTERN = /^http[s]?:/
XML_PATTERN = /^</

def initialize(http)
def initialize(http, base_file_path="")
@http = http
@base_file_path = base_file_path
end

def resolve(location)
case location
when URL_PATTERN then @http.get(location)
when XML_PATTERN then location
else File.read(location)
else
begin
File.read(location)
rescue
File.read(File.join(@base_file_path, location))
end
end
end

def can_resolve?(location)
(location =~ Resolver::URL_PATTERN) || (File.readable?(location)) || (File.readable?(File.join(@base_file_path, location)))
end

end
end
7 changes: 5 additions & 2 deletions lib/sekken/wsdl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ class WSDL
def initialize(wsdl, http)
@documents = WSDL::DocumentCollection.new
@schemas = XS::SchemaCollection.new

resolver = Resolver.new(http)

base_file_path = ""
base_file_path = File.dirname(wsdl) if File.exists?(wsdl)

resolver = Resolver.new(http, base_file_path)
importer = Importer.new(resolver, @documents, @schemas)
importer.import(wsdl)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/sekken/wsdl/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ def schemas

def imports
imports = []

@document.root.xpath('wsdl:import', 'wsdl' => Sekken::NS_WSDL).each do |node|
location = node['location']
imports << location if location
end

imports
end

Expand Down
2 changes: 1 addition & 1 deletion lib/sekken/xml/element_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def build_element(part)
local, namespace = expand_qname(part[:element], part[:namespaces])
schema = @schemas.find_by_namespace(namespace)
raise "Unable to find schema for #{namespace.inspect}" unless schema

xs_element = schema.elements.fetch(local)
type = find_type_for_element(xs_element)

Expand Down
20 changes: 18 additions & 2 deletions lib/sekken/xs/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,32 @@ def initialize(schema, schemas)
@complex_types = {}
@simple_types = {}
@imports = {}
@includes = []

parse
end

attr_accessor :target_namespace, :element_form_default, :imports,
attr_accessor :target_namespace, :element_form_default, :imports, :includes,
:attributes, :attribute_groups, :elements, :complex_types, :simple_types


def merge schema
@attributes.merge! schema.attributes unless @attributes.nil?
@attributes_groups.merge! schema.attribute_groups unless @attributes_groups.nil?
@elements.merge! schema.elements unless @elements.nil?
@complex_types.merge! schema.complex_types unless @complex_types.nil?
@simple_types.merge! schema.simple_types unless @simple_types.nil?

end

private

def parse
schema = {
:target_namespace => @target_namespace,
:element_form_default => @element_form_default
}

@schema.element_children.each do |node|
case node.name
when 'attribute' then store_element(@attributes, node, schema)
Expand All @@ -40,6 +51,7 @@ def parse
when 'complexType' then store_element(@complex_types, node, schema)
when 'simpleType' then store_element(@simple_types, node, schema)
when 'import' then store_import(node)
when 'include' then store_include(node)
end
end
end
Expand All @@ -52,6 +64,10 @@ def store_import(node)
@imports[node['namespace']] = node['schemaLocation']
end

def store_include node
@includes.push node['schemaLocation']
end

end
end
end
15 changes: 15 additions & 0 deletions spec/fixtures/wsdl/folder/imported.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>

<definitions name="ImportedService"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
>
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
>
</schema>
</types>
</definitions>
7 changes: 7 additions & 0 deletions spec/fixtures/wsdl/import.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="ImportService"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<import location="folder/imported.wsdl" />
</definitions>
47 changes: 47 additions & 0 deletions spec/fixtures/wsdl/sabre/SessionCreateRQ.wsdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd1="http://www.opentravel.org/OTA/2002/11" xmlns:tns="https://webservices.sabre.com/websvc" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" targetNamespace="https://webservices.sabre.com/websvc">
<types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.opentravel.org/OTA/2002/11" schemaLocation="SessionCreateRQRS.xsd"/>
<xsd:import namespace="http://www.ebxml.org/namespaces/messageHeader" schemaLocation="msg-header-2_0.xsd"/>
<xsd:import namespace="http://schemas.xmlsoap.org/ws/2002/12/secext" schemaLocation="wsse.xsd"/>
</xsd:schema>
</types>
<message name="GetSessionCreateInput">
<part name="header" element="eb:MessageHeader"/>
<part name="header2" element="wsse:Security"/>
<part name="body" element="xsd1:SessionCreateRQ"/>
</message>
<message name="GetSessionCreateOutput">
<part name="header" element="eb:MessageHeader"/>
<part name="header2" element="wsse:Security"/>
<part name="body" element="xsd1:SessionCreateRS"/>
</message>
<portType name="SessionCreatePortType">
<operation name="SessionCreateRQ">
<input message="tns:GetSessionCreateInput"/>
<output message="tns:GetSessionCreateOutput"/>
</operation>
</portType>
<binding name="SessionCreateSoapBinding" type="tns:SessionCreatePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="SessionCreateRQ">
<soap:operation soapAction="OTA"/>
<input>
<soap:header message="tns:GetSessionCreateInput" part="header" use="literal"/>
<soap:header message="tns:GetSessionCreateInput" part="header2" use="literal"/>
<soap:body parts="body" use="literal"/>
</input>
<output>
<soap:header message="tns:GetSessionCreateOutput" part="header" use="literal"/>
<soap:header message="tns:GetSessionCreateOutput" part="header2" use="literal"/>
<soap:body parts="body" use="literal"/>
</output>
</operation>
</binding>
<service name="SessionCreateRQService">
<port name="SessionCreatePortType" binding="tns:SessionCreateSoapBinding">
<soap:address location="https://webservices.sabre.com/websvc"/>
</port>
</service>
</definitions>
21 changes: 21 additions & 0 deletions spec/fixtures/wsdl/sabre/SessionCreateRQ.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.opentravel.org/OTA/2002/11" xmlns="http://www.opentravel.org/OTA/2002/11" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="SessionCreateRQ">
<xs:complexType>
<xs:sequence>
<xs:element name="POS">
<xs:complexType>
<xs:sequence>
<xs:element name="Source">
<xs:complexType>
<xs:attribute name="PseudoCityCode" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="returnContextID" type="xs:boolean"/>
</xs:complexType>
</xs:element>
</xs:schema>
5 changes: 5 additions & 0 deletions spec/fixtures/wsdl/sabre/SessionCreateRQRS.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://www.opentravel.org/OTA/2002/11" xmlns:tns="http://www.opentravel.org/OTA/2002/11" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<include schemaLocation="SessionCreateRQ.xsd"/>
<include schemaLocation="SessionCreateRS.xsd"/>
</schema>
Loading