shapewear 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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