shapewear 0.0.1 → 0.0.2

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.
data/README.md CHANGED
@@ -3,6 +3,11 @@ shapewear [![Build Status](https://secure.travis-ci.org/elementar/shapewear.png)
3
3
 
4
4
  Make your fat service look skinny.
5
5
 
6
+ Work in Progress
7
+ ----------------
8
+
9
+ This gem is still in early development, and it's not yet yet ready for use. Any contribution and feedback is welcome.
10
+
6
11
  Installation
7
12
  ------------
8
13
 
@@ -21,15 +26,25 @@ First, describe your SOAP service:
21
26
  require "shapewear"
22
27
 
23
28
  class MyFirstService
24
- include Shapewear::DSL
29
+ include Shapewear
30
+
31
+ wsdl_namespace 'http://services.example.com/v1'
32
+ schema_namespace 'http://schemas.example.com/v1'
25
33
 
34
+ operation :hello, :parameters => [[:name, String]], :returns => String
26
35
  def hello(name)
27
36
  "hello, #{name}"
28
37
  end
29
38
 
39
+ operation :sum, :parameters => [[:x, Fixnum], [:y, Fixnum]], :returns => Fixnum
30
40
  def sum(x, y)
31
41
  x + y
32
42
  end
43
+
44
+ operation :get_user_info, :parameters => [[:email, String]], :returns => { :name => String, :birthday => DateTime }
45
+ def get_user_info(email)
46
+ User.find_by_email(email)
47
+ end
33
48
  end
34
49
  ```
35
50
 
data/lib/shapewear.rb CHANGED
@@ -2,9 +2,17 @@ require 'nokogiri'
2
2
 
3
3
  require 'shapewear/version'
4
4
  require 'shapewear/dsl'
5
+ require 'shapewear/wsdl'
6
+
7
+ module Shapewear
8
+ def self.included(receiver)
9
+ receiver.extend(Shapewear::DSL)
10
+ receiver.extend(Shapewear::WSDL)
11
+ end
12
+ end
5
13
 
6
14
  # defines String.camelize if it is not defined by, e.g. Rails
7
- unless String.respond_to? :camelize
15
+ unless ''.respond_to? :camelize
8
16
  class String
9
17
  def camelize
10
18
  self.split('_').map(&:capitalize).join
data/lib/shapewear/dsl.rb CHANGED
@@ -2,106 +2,28 @@ require 'builder'
2
2
 
3
3
  module Shapewear
4
4
  module DSL
5
- def self.included(receiver)
6
- receiver.extend(ClassMethods)
7
- end
8
-
9
- #noinspection RubyArgCount,RubyResolve
10
- module ClassMethods
11
-
12
- # reference: http://www.w3.org/TR/wsdl
13
- def to_wsdl
14
- tns = "http://shapewear.elementarsistemas.com.br/auto/#{self.name}.wsdl"
15
- xsd = "http://shapewear.elementarsistemas.com.br/auto/#{self.name}.xsd"
16
-
17
- xm = Builder::XmlMarkup.new
18
-
19
- xm.instruct!
20
- xm.definitions :name => self.name, 'targetNamespace' => tns,
21
- 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
22
- 'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
23
- 'xmlns:xsd1' => xsd, 'tns' => tns do |xdef|
24
-
25
- xdef.types do |xtypes|
26
- xtypes.schema 'xmlns' => 'http://www.w3.org/2000/10/XMLSchema', 'targetNamespace' => xsd do |xschema|
27
-
28
- # define elements for each defined method
29
- instance_methods(false).each do |m|
30
- build_type_elements_for_method(m, xschema)
31
- end
32
- end
33
- end
5
+ private
34
6
 
35
- instance_methods(false).each do |m|
36
- xdef.message :name => "#{m.camelize}Input" do |xmsg|
37
- xmsg.part :name => :body, :element => "xsd1:#{m.camelize}Request"
38
- end unless instance_method(m).arity == 0
39
- xdef.message :name => "#{m.camelize}Output" do |xmsg|
40
- xmsg.part :name => :body, :element => "xsd1:#{m.camelize}"
41
- end
42
- end
43
-
44
- xdef.portType :name => "#{self.name}PortType" do |xpt|
45
- instance_methods(false).each do |m|
46
- xpt.operation :name => m.camelize do |xop|
47
- xop.input :message => "tns:#{m.camelize}Input" unless instance_method(m).arity == 0
48
- xop.output :message => "tns:#{m.camelize}Output"
49
- end
50
- end
51
- end
52
-
53
- xdef.binding :name => "#{self.name}Binding", :type => "tns:#{self.name}PortType" do |xbind|
54
- xbind.tag! 'soap:binding', :style => 'document', :transport => 'http://schemas.xmlsoap.org/soap/http'
55
- instance_methods(false).each do |m|
56
- xbind.operation :name => m.camelize do |xop|
57
- xbind.tag! 'soap:operation', :soapAction => "http://shapewear.elementarsistemas.com.br/auto/op/#{m.camelize}"
58
- xbind.input { |xin| xin.tag! 'soap:body', :use => 'literal' } unless instance_method(m).arity == 0
59
- xbind.output { |xin| xin.tag! 'soap:body', :use => 'literal' }
60
- end
61
- end
62
- end
7
+ def options
8
+ @options ||= {}
9
+ end
63
10
 
64
- xdef.service :name => self.name do |xsrv|
65
- xsrv.documentation "WSDL auto-generated by shapewear."
66
- xsrv.port :name => "#{self.name}Port", :binding => "#{self.name}Binding" do |xport|
67
- xport.tag! 'soap:address', :location => "..." # TODO: let the developer configure
68
- end
69
- end
70
- end
71
- end
11
+ protected
72
12
 
73
- def build_type_elements_for_method(m, xschema)
74
- # element for method arguments
75
- um = instance_method(m)
13
+ def wsdl_namespace(ns)
14
+ options[:wsdl_namespace] = ns
15
+ end
76
16
 
77
- if um.arity > 0
78
- xschema.element :name => "#{m.camelize}Request" do |xreq|
79
- xreq.complexType do |xct|
80
- xct.all do |xall|
81
- if um.respond_to?(:parameters)
82
- # with Ruby 1.9, we can create the parameters with the correct names
83
- params = um.parameters.select { |p| p.first == :in }.map &:first
84
- else
85
- params = (0..um.arity).map { |i| "arg#{i}" }
86
- end
17
+ def schema_namespace(ns)
18
+ options[:schema_namespace] = ns
19
+ end
87
20
 
88
- params.each do |p|
89
- xall.element :name => p, :type => 'xsd:string' # TODO: there must be a better way
90
- end
91
- end
92
- end
93
- end
94
- end
21
+ def endpoint_url(url)
22
+ options[:endpoint_url] = url
23
+ end
95
24
 
96
- # element for method result
97
- xschema.element :name => "#{m.camelize}" do |xreq|
98
- xreq.complexType do |xct|
99
- xct.all do |xall|
100
- xall.element :name => 'result', :type => 'xsd:string'
101
- end
102
- end
103
- end
104
- end
25
+ def operation(name, ops = {})
26
+ (options[:operations] ||= {})[name] = ops
105
27
  end
106
28
  end
107
29
  end
@@ -1,5 +1,5 @@
1
1
  module Shapewear
2
2
 
3
- Version = "0.0.1"
3
+ Version = "0.0.2"
4
4
 
5
5
  end
@@ -0,0 +1,127 @@
1
+ require 'builder'
2
+
3
+ module Shapewear
4
+ #noinspection RubyArgCount,RubyResolve
5
+ module WSDL
6
+ # reference: http://www.w3.org/TR/wsdl
7
+ def to_wsdl
8
+ tns = options[:wsdl_namespace] || "http://shapewear.elementarsistemas.com.br/auto/#{self.name}.wsdl"
9
+ xsd = options[:schema_namespace] || "http://shapewear.elementarsistemas.com.br/auto/#{self.name}.xsd"
10
+
11
+ xm = Builder::XmlMarkup.new
12
+
13
+ xm.instruct!
14
+ xm.definitions :name => self.name, 'targetNamespace' => tns,
15
+ 'xmlns' => 'http://schemas.xmlsoap.org/wsdl/',
16
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
17
+ 'xmlns:xsd1' => xsd, 'xmlns:tns' => tns do |xdef|
18
+
19
+ xdef.types do |xtypes|
20
+ xtypes.schema 'xmlns' => 'http://www.w3.org/2000/10/XMLSchema', 'targetNamespace' => xsd do |xschema|
21
+
22
+ # define elements for each defined method
23
+ instance_methods(false).each do |m|
24
+ build_type_elements_for_method(m, xschema)
25
+ end
26
+ end
27
+ end
28
+
29
+ instance_methods(false).each do |m|
30
+ xdef.message :name => "#{m.camelize}Input" do |xmsg|
31
+ xmsg.part :name => :body, :element => "xsd1:#{m.camelize}Request"
32
+ end unless instance_method(m).arity == 0
33
+ xdef.message :name => "#{m.camelize}Output" do |xmsg|
34
+ xmsg.part :name => :body, :element => "xsd1:#{m.camelize}"
35
+ end
36
+ end
37
+
38
+ xdef.portType :name => "#{self.name}PortType" do |xpt|
39
+ instance_methods(false).each do |m|
40
+ xpt.operation :name => m.camelize do |xop|
41
+ xop.input :message => "tns:#{m.camelize}Input" unless instance_method(m).arity == 0
42
+ xop.output :message => "tns:#{m.camelize}Output"
43
+ end
44
+ end
45
+ end
46
+
47
+ xdef.binding :name => "#{self.name}Binding", :type => "tns:#{self.name}PortType" do |xbind|
48
+ xbind.tag! 'soap:binding', :style => 'document', :transport => 'http://schemas.xmlsoap.org/soap/http'
49
+ instance_methods(false).each do |m|
50
+ xbind.operation :name => m.camelize do |xop|
51
+ xop.tag! 'soap:operation', :soapAction => "#{tns}/#{m.camelize}"
52
+ xop.input { |xin| xin.tag! 'soap:body', :use => 'literal' } unless instance_method(m).arity == 0
53
+ xop.output { |xin| xin.tag! 'soap:body', :use => 'literal' }
54
+ end
55
+ end
56
+ end
57
+
58
+ xdef.service :name => self.name do |xsrv|
59
+ xsrv.documentation "WSDL auto-generated by shapewear."
60
+ xsrv.port :name => "#{self.name}Port", :binding => "#{self.name}Binding" do |xport|
61
+ xport.tag! 'soap:address', :location => options[:endpoint_url]
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def build_type_elements_for_method(m, xschema)
68
+ # element for method arguments
69
+ um = instance_method(m)
70
+ op_options = options[:operations][m.to_sym] rescue nil
71
+
72
+ if um.arity > 0
73
+ xschema.element :name => "#{m.camelize}Request" do |xreq|
74
+ xreq.complexType do |xct|
75
+ xct.all do |xall|
76
+ params = op_options[:parameters] rescue nil
77
+ if params.nil?
78
+ if um.respond_to?(:parameters)
79
+ # with Ruby 1.9, we can create the parameters with the correct names
80
+ params = um.parameters.select { |p| p.first == :in }.map { |p| [p.first, Object] }
81
+ else
82
+ params = (0..um.arity).map { |i| ["arg#{i}", Object] }
83
+ end
84
+ end
85
+
86
+ params.each do |p|
87
+ xall.element :name => p.first, :type => to_xsd_type(p.last)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # element for method result
95
+ xschema.element :name => "#{m.camelize}" do |xreq|
96
+ xreq.complexType do |xct|
97
+ xct.all do |xall|
98
+ ret = op_options[:returns] rescue nil
99
+ if ret.nil?
100
+ xall.element :name => 'result', :type => 'xsd:any'
101
+ elsif ret.is_a?(Class)
102
+ xall.element :name => 'result', :type => to_xsd_type(ret)
103
+ elsif ret.is_a?(Hash)
104
+ ret.each do |name, type|
105
+ xall.element :name => name, :type => to_xsd_type(type)
106
+ end
107
+ else
108
+ raise "Could not interpret #{ret.inspect} as a return type definition"
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ def to_xsd_type(t)
116
+ if t.is_a?(Class)
117
+ return 'xsd:string' if t == String
118
+ return 'xsd:integer' if t == Fixnum
119
+ return 'xsd:dateTime' if t == DateTime
120
+ return 'xsd:any' if t == Object
121
+ raise "Could not convert type #{t} to a valid XSD type"
122
+ elsif t.is_a?(Hash)
123
+ '??'
124
+ end
125
+ end
126
+ end
127
+ end
@@ -7,7 +7,7 @@ describe Shapewear::DSL do
7
7
  describe "basic DSL" do
8
8
  it "should describe parameterless, 'hello world' services" do
9
9
  class ParameterlessHelloWorldService
10
- include Shapewear::DSL
10
+ include Shapewear
11
11
 
12
12
  def hello_world
13
13
  "hello"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapewear
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - "F\xC3\xA1bio Batista"
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-02 00:00:00 Z
18
+ date: 2012-01-03 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder
@@ -102,6 +102,7 @@ files:
102
102
  - lib/shapewear.rb
103
103
  - lib/shapewear/dsl.rb
104
104
  - lib/shapewear/version.rb
105
+ - lib/shapewear/wsdl.rb
105
106
  - shapewear.gemspec
106
107
  - spec/shapewear/dsl_spec.rb
107
108
  - spec/spec_helper.rb