rbook 0.1

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.
Files changed (63) hide show
  1. data/COPYING +340 -0
  2. data/LICENSE +13 -0
  3. data/README +16 -0
  4. data/Rakefile +206 -0
  5. data/examples/titlepage.rb +14 -0
  6. data/examples/www/find_all.rb +23 -0
  7. data/examples/www/find_cover_from_amazon.rb +12 -0
  8. data/examples/www/find_url_from_rainbow.rb +12 -0
  9. data/examples/www/list.rb +13 -0
  10. data/lib/rbook/bisac.rb +175 -0
  11. data/lib/rbook/errors.rb +7 -0
  12. data/lib/rbook/isbn.rb +249 -0
  13. data/lib/rbook/onix.rb +68 -0
  14. data/lib/rbook/onix/contributor.rb +60 -0
  15. data/lib/rbook/onix/lists.rb +2 -0
  16. data/lib/rbook/onix/lists/contributor_role.rb +10 -0
  17. data/lib/rbook/onix/lists/product_form.rb +100 -0
  18. data/lib/rbook/onix/message.rb +101 -0
  19. data/lib/rbook/onix/product.rb +188 -0
  20. data/lib/rbook/onix/sales_restriction.rb +51 -0
  21. data/lib/rbook/onix/supply_detail.rb +68 -0
  22. data/lib/rbook/onix/xchar.rb +98 -0
  23. data/lib/rbook/titlepage.rb +96 -0
  24. data/lib/rbook/titlepage/TitleQueryClient.rb +62 -0
  25. data/lib/rbook/titlepage/titlepage_driver.rb +134 -0
  26. data/lib/rbook/titlepage/titlepage_utils.rb +374 -0
  27. data/lib/rbook/www.rb +172 -0
  28. data/lib/rbook/www/aau_scraper.rb +76 -0
  29. data/lib/rbook/www/amazon_uk_scraper.rb +44 -0
  30. data/lib/rbook/www/base.rb +87 -0
  31. data/lib/rbook/www/harper_au_scraper.rb +56 -0
  32. data/lib/rbook/www/harper_us_scraper.rb +55 -0
  33. data/lib/rbook/www/hha_scraper.rb +50 -0
  34. data/lib/rbook/www/macmillan_scraper.rb +62 -0
  35. data/lib/rbook/www/orbis_scraper.rb +48 -0
  36. data/lib/rbook/www/oup_scraper.rb +64 -0
  37. data/lib/rbook/www/paulist_scraper.rb +53 -0
  38. data/lib/rbook/www/pearson_au_scraper.rb +52 -0
  39. data/lib/rbook/www/penguin_scraper.rb +45 -0
  40. data/lib/rbook/www/random_au_scraper.rb +90 -0
  41. data/lib/rbook/www/random_us_scraper.rb +59 -0
  42. data/lib/rbook/www/sas_scraper.rb +54 -0
  43. data/lib/rbook/www/unireps_scraper.rb +58 -0
  44. data/lib/rbook/www/wiley_us_scraper.rb +54 -0
  45. data/test/data/abingdon.xml +38931 -0
  46. data/test/data/augsburg.xml +39009 -0
  47. data/test/data/chalice.xml +10851 -0
  48. data/test/data/eerdsman.xml +36942 -0
  49. data/test/data/invalid_no_product.xml +9 -0
  50. data/test/data/not_xml.csv +1 -0
  51. data/test/data/single_product.xml +50 -0
  52. data/test/data/xml_not_onix.xml +7 -0
  53. data/test/mocks/titlepage_driver.rb +107 -0
  54. data/test/unit/bisac_test.rb +57 -0
  55. data/test/unit/isbn_test.rb +149 -0
  56. data/test/unit/onix/contributor_test.rb +50 -0
  57. data/test/unit/onix/message_test.rb +119 -0
  58. data/test/unit/onix/product_test.rb +101 -0
  59. data/test/unit/onix/sales_restriction_test.rb +48 -0
  60. data/test/unit/onix/supply_detail_test.rb +53 -0
  61. data/test/unit/onix/xchar_test.rb +37 -0
  62. data/test/unit/titlepage_test.rb +127 -0
  63. metadata +130 -0
@@ -0,0 +1,51 @@
1
+ require 'rexml/document'
2
+ require 'rubygems'
3
+
4
+ module RBook
5
+ module Onix
6
+
7
+ class SalesRestriction
8
+ attr_accessor :type, :detail
9
+
10
+ # Attempts to create a contributor object using the supplied xml element
11
+ def SalesRestriction.load_from_element(element)
12
+ raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
13
+
14
+ if REXML::XPath.first(element, '//SalesRestriction').nil?
15
+ raise LoadError, 'supplied REXML document object does not appear contain a valid SalesRestriction fragment'
16
+ end
17
+
18
+ restriction = SalesRestriction.new
19
+
20
+ tmp = REXML::XPath.first(element, '//SalesRestriction/SalesRestrictionType')
21
+ restriction.type = tmp.text if tmp != nil
22
+
23
+ tmp = REXML::XPath.first(element, '//SalesRestriction/SalesRestrictionDetail')
24
+ restriction.detail = tmp.text if tmp != nil
25
+
26
+ return restriction
27
+
28
+ end
29
+
30
+ # Return an xml element representing this contributor
31
+ def to_element
32
+ raise 'SalesRestriction must have a type to create an element' if self.type.nil?
33
+ raise 'Contributor must have a detail to create an element' if self.detail.nil?
34
+
35
+ restriction = REXML::Element.new('SalesRestriction')
36
+ restriction.add_element('SalesRestrictionType').text = self.type.to_xs
37
+ restriction.add_element('SalesRestrictionDetail').text = self.detail.to_xs
38
+
39
+ return restriction
40
+ end
41
+
42
+ # Return an XML string representing this contributor
43
+ def to_s
44
+ tmp = to_element
45
+ output = ''
46
+ tmp.write(output, 0)
47
+ return output
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,68 @@
1
+ require 'rexml/document'
2
+ require 'bigdecimal'
3
+ require 'rubygems'
4
+
5
+ module RBook
6
+ module Onix
7
+
8
+ class SupplyDetail
9
+ attr_accessor :supplier_name, :availability_code, :intermediary_availability_code, :price
10
+
11
+ # Attempts to create a contributor object using the supplied xml element
12
+ def self.load_from_element(element)
13
+ raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
14
+
15
+ if REXML::XPath.first(element, '//SupplyDetail').nil?
16
+ raise LoadError, 'supplied REXML document object does not appear contain a valid SupplyDetail fragment'
17
+ end
18
+
19
+ supply_detail = SupplyDetail.new
20
+
21
+ tmp = REXML::XPath.first(element, '//SupplyDetail/SupplierName')
22
+ supply_detail.supplier_name = tmp.text if tmp != nil
23
+
24
+ tmp = REXML::XPath.first(element, '//SupplyDetail/AvailabilityCode')
25
+ supply_detail.availability_code = tmp.text if tmp != nil
26
+
27
+ tmp = REXML::XPath.first(element, '//SupplyDetail/IntermediaryAvailabilityCode')
28
+ supply_detail.intermediary_availability_code = tmp.text if tmp != nil
29
+
30
+ tmp = REXML::XPath.first(element, '//SupplyDetail/Price/PriceAmount')
31
+ supply_detail.price = BigDecimal(tmp.text) if tmp != nil
32
+
33
+ return supply_detail
34
+
35
+ end
36
+
37
+ # Return an xml element representing this contributor
38
+ def to_element
39
+ raise 'SupplyDetail must have a supplier name to create an element' if self.supplier_name.nil?
40
+ raise 'SupplyDetail must have a availability code to create an element' if self.availability_code.nil?
41
+
42
+ supply_detail = REXML::Element.new('SupplyDetail')
43
+ supply_detail.add_element('SupplierName').text = self.supplier_name.to_xs
44
+ supply_detail.add_element('AvailabilityCode').text = self.availability_code.to_xs unless self.availability_code.nil?
45
+ supply_detail.add_element('IntermediaryAvailabilityCode').text = self.intermediary_availability_code_to_xs unless self.intermediary_availability_code.nil?
46
+ unless self.price.nil?
47
+ tmp = REXML::Element.new('Price')
48
+ if self.price.kind_of?(BigDecimal)
49
+ tmp.add_element('PriceAmount').text = self.price.to_s("F")
50
+ else
51
+ tmp.add_element('PriceAmount').text = self.price.to_s
52
+ end
53
+ supply_detail.add_element(tmp)
54
+ end
55
+
56
+ return supply_detail
57
+ end
58
+
59
+ # Return an XML string representing this contributor
60
+ def to_s
61
+ tmp = to_element
62
+ output = ''
63
+ tmp.write(output, 0)
64
+ return output
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,98 @@
1
+ # sourced from http://www.intertwingly.net/blog/2005/09/28/XML-Cleansing
2
+
3
+ module XChar
4
+ # http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
5
+ CP1252 = {
6
+ 128 => 8364, # euro sign
7
+ 130 => 8218, # single low-9 quotation mark
8
+ 131 => 402, # latin small letter f with hook
9
+ 132 => 8222, # double low-9 quotation mark
10
+ 133 => 8230, # horizontal ellipsis
11
+ 134 => 8224, # dagger
12
+ 135 => 8225, # double dagger
13
+ 136 => 710, # modifier letter circumflex accent
14
+ 137 => 8240, # per mille sign
15
+ 138 => 352, # latin capital letter s with caron
16
+ 139 => 8249, # single left-pointing angle quotation mark
17
+ 140 => 338, # latin capital ligature oe
18
+ 142 => 381, # latin capital letter z with caron
19
+ 145 => 8216, # left single quotation mark
20
+ 146 => 8217, # right single quotation mark
21
+ 147 => 8220, # left double quotation mark
22
+ 148 => 8221, # right double quotation mark
23
+ 149 => 8226, # bullet
24
+ 150 => 8211, # en dash
25
+ 151 => 8212, # em dash
26
+ 152 => 732, # small tilde
27
+ 153 => 8482, # trade mark sign
28
+ 154 => 353, # latin small letter s with caron
29
+ 155 => 8250, # single right-pointing angle quotation mark
30
+ 156 => 339, # latin small ligature oe
31
+ 158 => 382, # latin small letter z with caron
32
+ 159 => 376} # latin capital letter y with diaeresis
33
+
34
+ # http://www.w3.org/TR/REC-xml/#dt-chardata
35
+ PREDEFINED = {
36
+ 38 => '&', # ampersand
37
+ 60 => '<', # left angle bracket
38
+ 62 => '>'} # right angle bracket
39
+
40
+ # http://www.w3.org/TR/REC-xml/#charsets
41
+ VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
42
+ (0xE000..0xFFFD), (0x10000..0x10FFFF)]
43
+ end
44
+
45
+ class Fixnum
46
+ # xml escaped version of chr
47
+ def xchr
48
+ n = XChar::CP1252[self] || self
49
+ n = 42 unless XChar::VALID.find {|range| range.include? n}
50
+ XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
51
+ end
52
+ end
53
+
54
+ class String
55
+ # xml escaped version of to_s
56
+ def to_xs
57
+ unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
58
+ rescue
59
+ unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
60
+ end
61
+ end
62
+
63
+ =begin
64
+ require 'test/unit'
65
+
66
+ class TestXmlEscaping < Test::Unit::TestCase
67
+ def test_ascii
68
+ assert_equal 'abc', 'abc'.to_xs
69
+ end
70
+
71
+ def test_predefined
72
+ assert_equal '&amp;', '&'.to_xs # ampersand
73
+ assert_equal '&lt;', '<'.to_xs # left angle bracket
74
+ assert_equal '&gt;', '>'.to_xs # right angle bracket
75
+ end
76
+
77
+ def test_invalid
78
+ assert_equal '*', "\x00".to_xs # null
79
+ assert_equal '*', "\x0C".to_xs # form feed
80
+ assert_equal '*', "\xEF\xBF\xBF".to_xs # U+FFFF
81
+ end
82
+
83
+ def test_iso_8859_1
84
+ assert_equal '&#231;', "\xE7".to_xs # small c cedilla
85
+ assert_equal '&#169;', "\xA9".to_xs # copyright symbol
86
+ end
87
+
88
+ def test_win_1252
89
+ assert_equal '&#8217;', "\x92".to_xs # smart quote
90
+ assert_equal '&#8364;', "\x80".to_xs # euro
91
+ end
92
+
93
+ def test_utf8
94
+ assert_equal '&#8217;', "\xE2\x80\x99".to_xs # right single quote
95
+ assert_equal '&#169;', "\xC2\xA9".to_xs # copy
96
+ end
97
+ end
98
+ =end
@@ -0,0 +1,96 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + "/../")
2
+
3
+ require 'rbook/isbn'
4
+ require 'rbook/errors'
5
+ require 'rbook/titlepage/titlepage_driver'
6
+
7
+ module RBook
8
+
9
+ # a convenience class for accessing the SOAP API for http://www.titlepage.com.
10
+ # Uses boilerplate code generated by soap4r.
11
+ #
12
+ # You should be aware of any limits of query volume imposed by the provider - currently a
13
+ # maximum of 30 queries per minute is permitted.
14
+ #
15
+ # All examples require the following two lines at the top of your file:
16
+ # require 'rubygems'
17
+ # require 'rbook/titlepage'
18
+ #
19
+ # Basic usage:
20
+ # tp = Book::TitlePage.new
21
+ # tp.login('someuser','topsecret')
22
+ # puts tp.find("0091835135").inspect
23
+ # sleep 3
24
+ # puts tp.find("9780672327568").inspect
25
+ # tp.logout
26
+ #
27
+ # Alternative Usage:
28
+ # RBook::TitlePage.open("username","password") do |tp|
29
+ # puts tp.find("0091835135").inspect
30
+ # sleep 3
31
+ # puts tp.find("9780672327568").inspect
32
+ # end
33
+ class TitlePage
34
+
35
+ # Optional driver parameter allows an alternative SOAP driver to the default to be specified.
36
+ # This is primarily for testing purposes and probably isn't useful to anyone in the real world.
37
+ def initialize(driver = nil)
38
+ @driver = driver || TitleQueryPortType.new
39
+ @token = nil
40
+ end
41
+
42
+ # login to the titlepage API.
43
+ def login(username, password)
44
+ raise InvalidRubyVersionError, 'Ruby 1.8.3 or higher is required to use this class' unless RUBY_VERSION >= "1.8.3"
45
+ logout if @token
46
+ @token = @driver.login(username, password)
47
+ return true if @token
48
+ end
49
+
50
+ # logout from the titlepage API
51
+ def logout
52
+ if @token
53
+ @driver.logout(@token)
54
+ end
55
+ end
56
+
57
+ # retrieve information on a specified ISBN
58
+ def find(isbn)
59
+ return NotLoggedInError, 'You must login to titlepage API before performing a search' unless @token
60
+ isbn = ISBN::convert_to_isbn13(isbn)
61
+ return nil if isbn.nil?
62
+ begin
63
+ result = @driver.SearchByEAN(@token, isbn)
64
+ if result.Product.nil?
65
+ return nil
66
+ else
67
+ return result
68
+ end
69
+ rescue
70
+ return nil
71
+ end
72
+
73
+ end
74
+
75
+ # a convenience method to make queries to title page a little cleaner. This function
76
+ # essentially calls the login and logout functions for you automatically.
77
+ #
78
+ # RBook::TitlePage.open("username","password") do |tp|
79
+ # result = tp.find("9780091835132")
80
+ # end
81
+ def TitlePage.open(username, password, driver = nil)
82
+
83
+ tp = TitlePage.new(driver || TitleQueryPortType.new)
84
+
85
+ begin
86
+ tp.login(username, password)
87
+
88
+ yield(tp)
89
+
90
+ ensure
91
+ tp.logout
92
+ end
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ require 'defaultDriver.rb'
3
+
4
+ endpoint_url = ARGV.shift
5
+ obj = TitleQueryPortType.new(endpoint_url)
6
+
7
+ # run ruby with -d to see SOAP wiredumps.
8
+ obj.wiredump_dev = STDERR if $DEBUG
9
+
10
+ # SYNOPSIS
11
+ # Login(userName, password)
12
+ #
13
+ # ARGS
14
+ # userName String - {http://www.w3.org/2001/XMLSchema}string
15
+ # password String - {http://www.w3.org/2001/XMLSchema}string
16
+ #
17
+ # RETURNS
18
+ # token String - {http://www.w3.org/2001/XMLSchema}string
19
+ #
20
+ userName = "rba303"
21
+ password = "ra1nb0Wb"
22
+ puts obj.login(userName, password)
23
+
24
+ # SYNOPSIS
25
+ # SearchByISBN(token, iSBN)
26
+ #
27
+ # ARGS
28
+ # token String - {http://www.w3.org/2001/XMLSchema}string
29
+ # iSBN String - {http://www.w3.org/2001/XMLSchema}string
30
+ #
31
+ # RETURNS
32
+ # searchResults SearchResults - {urn:TitleQuery}SearchResults
33
+ #
34
+ token = iSBN = nil
35
+ puts obj.searchByISBN(token, iSBN)
36
+
37
+ # SYNOPSIS
38
+ # SearchByEAN(token, eAN)
39
+ #
40
+ # ARGS
41
+ # token String - {http://www.w3.org/2001/XMLSchema}string
42
+ # eAN String - {http://www.w3.org/2001/XMLSchema}string
43
+ #
44
+ # RETURNS
45
+ # searchResults SearchResults - {urn:TitleQuery}SearchResults
46
+ #
47
+ token = eAN = nil
48
+ puts obj.searchByEAN(token, eAN)
49
+
50
+ # SYNOPSIS
51
+ # Logout(token)
52
+ #
53
+ # ARGS
54
+ # token String - {http://www.w3.org/2001/XMLSchema}string
55
+ #
56
+ # RETURNS
57
+ # N/A
58
+ #
59
+ token = nil
60
+ puts obj.logout(token)
61
+
62
+
@@ -0,0 +1,134 @@
1
+ require File.dirname(__FILE__) + '/titlepage_utils.rb'
2
+
3
+ require 'soap/rpc/driver'
4
+
5
+ class TitleQueryPortType < ::SOAP::RPC::Driver
6
+ DefaultEndpointUrl = "http://www.titlepage.com.au/ws/TitleQuery.php"
7
+ MappingRegistry = ::SOAP::Mapping::Registry.new
8
+
9
+ MappingRegistry.set(
10
+ SearchResults,
11
+ ::SOAP::SOAPStruct,
12
+ ::SOAP::Mapping::Registry::TypedStructFactory,
13
+ { :type => XSD::QName.new("urn:TitleQuery", "SearchResults") }
14
+ )
15
+ MappingRegistry.set(
16
+ Product,
17
+ ::SOAP::SOAPStruct,
18
+ ::SOAP::Mapping::Registry::TypedStructFactory,
19
+ { :type => XSD::QName.new("urn:TitleQuery", "Product") }
20
+ )
21
+ MappingRegistry.set(
22
+ ArrayOfProductIdentifier,
23
+ ::SOAP::SOAPArray,
24
+ ::SOAP::Mapping::Registry::TypedArrayFactory,
25
+ { :type => XSD::QName.new("urn:TitleQuery", "ProductIdentifier") }
26
+ )
27
+ MappingRegistry.set(
28
+ Title,
29
+ ::SOAP::SOAPStruct,
30
+ ::SOAP::Mapping::Registry::TypedStructFactory,
31
+ { :type => XSD::QName.new("urn:TitleQuery", "Title") }
32
+ )
33
+ MappingRegistry.set(
34
+ ArrayOfContributor,
35
+ ::SOAP::SOAPArray,
36
+ ::SOAP::Mapping::Registry::TypedArrayFactory,
37
+ { :type => XSD::QName.new("urn:TitleQuery", "Contributor") }
38
+ )
39
+ MappingRegistry.set(
40
+ SupplyDetail,
41
+ ::SOAP::SOAPStruct,
42
+ ::SOAP::Mapping::Registry::TypedStructFactory,
43
+ { :type => XSD::QName.new("urn:TitleQuery", "SupplyDetail") }
44
+ )
45
+ MappingRegistry.set(
46
+ Stock,
47
+ ::SOAP::SOAPStruct,
48
+ ::SOAP::Mapping::Registry::TypedStructFactory,
49
+ { :type => XSD::QName.new("urn:TitleQuery", "Stock") }
50
+ )
51
+ MappingRegistry.set(
52
+ Price,
53
+ ::SOAP::SOAPStruct,
54
+ ::SOAP::Mapping::Registry::TypedStructFactory,
55
+ { :type => XSD::QName.new("urn:TitleQuery", "Price") }
56
+ )
57
+ MappingRegistry.set(
58
+ ProductIdentifier,
59
+ ::SOAP::SOAPStruct,
60
+ ::SOAP::Mapping::Registry::TypedStructFactory,
61
+ { :type => XSD::QName.new("urn:TitleQuery", "ProductIdentifier") }
62
+ )
63
+ MappingRegistry.set(
64
+ Contributor,
65
+ ::SOAP::SOAPStruct,
66
+ ::SOAP::Mapping::Registry::TypedStructFactory,
67
+ { :type => XSD::QName.new("urn:TitleQuery", "Contributor") }
68
+ )
69
+
70
+ Methods = [
71
+ [ XSD::QName.new("http://www.titlepage.com/ws", "Login"),
72
+ "http://www.titlepage.com.au/ws/TitleQuery.php/Login",
73
+ "login",
74
+ [ ["in", "UserName", ["::SOAP::SOAPString"]],
75
+ ["in", "Password", ["::SOAP::SOAPString"]],
76
+ ["retval", "Token", ["::SOAP::SOAPString"]] ],
77
+ { :request_style => :rpc, :request_use => :encoded,
78
+ :response_style => :rpc, :response_use => :encoded }
79
+ ],
80
+ [ XSD::QName.new("http://www.titlepage.com/ws", "SearchByISBN"),
81
+ "http://www.titlepage.com.au/ws/TitleQuery.php/SearchByISBN",
82
+ "searchByISBN",
83
+ [ ["in", "Token", ["::SOAP::SOAPString"]],
84
+ ["in", "ISBN", ["::SOAP::SOAPString"]],
85
+ ["retval", "SearchResults", ["SearchResults", "urn:TitleQuery", "SearchResults"]] ],
86
+ { :request_style => :rpc, :request_use => :encoded,
87
+ :response_style => :rpc, :response_use => :encoded }
88
+ ],
89
+ [ XSD::QName.new("http://www.titlepage.com/ws", "SearchByEAN"),
90
+ "http://www.titlepage.com.au/ws/TitleQuery.php/SearchByEAN",
91
+ "searchByEAN",
92
+ [ ["in", "Token", ["::SOAP::SOAPString"]],
93
+ ["in", "EAN", ["::SOAP::SOAPString"]],
94
+ ["retval", "SearchResults", ["SearchResults", "urn:TitleQuery", "SearchResults"]] ],
95
+ { :request_style => :rpc, :request_use => :encoded,
96
+ :response_style => :rpc, :response_use => :encoded }
97
+ ],
98
+ [ XSD::QName.new("http://www.titlepage.com/ws", "Logout"),
99
+ "http://www.titlepage.com.au/ws/TitleQuery.php/Logout",
100
+ "logout",
101
+ [ ["in", "token", ["::SOAP::SOAPString"]] ],
102
+ { :request_style => :rpc, :request_use => :encoded,
103
+ :response_style => :rpc, :response_use => :encoded }
104
+ ]
105
+ ]
106
+
107
+ def initialize(endpoint_url = nil)
108
+ endpoint_url ||= DefaultEndpointUrl
109
+ super(endpoint_url, nil)
110
+ self.mapping_registry = MappingRegistry
111
+ init_methods
112
+ end
113
+
114
+ private
115
+
116
+ def init_methods
117
+ Methods.each do |definitions|
118
+ opt = definitions.last
119
+ if opt[:request_style] == :document
120
+ add_document_operation(*definitions)
121
+ else
122
+ add_rpc_operation(*definitions)
123
+ qname = definitions[0]
124
+ name = definitions[2]
125
+ if qname.name != name and qname.name.capitalize == name.capitalize
126
+ ::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|
127
+ __send__(name, *arg)
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+