paypal-sdk-rest 0.10.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +44 -0
  4. data/lib/generators/paypal/sdk/USAGE +3 -0
  5. data/lib/generators/paypal/sdk/install_generator.rb +17 -0
  6. data/lib/generators/paypal/sdk/templates/paypal.rb +2 -0
  7. data/lib/generators/paypal/sdk/templates/paypal.yml +31 -0
  8. data/lib/paypal-sdk-core.rb +38 -0
  9. data/lib/paypal-sdk/core/api.rb +20 -0
  10. data/lib/paypal-sdk/core/api/base.rb +162 -0
  11. data/lib/paypal-sdk/core/api/data_types/array_with_block.rb +44 -0
  12. data/lib/paypal-sdk/core/api/data_types/base.rb +224 -0
  13. data/lib/paypal-sdk/core/api/data_types/enum.rb +26 -0
  14. data/lib/paypal-sdk/core/api/data_types/simple_types.rb +52 -0
  15. data/lib/paypal-sdk/core/api/ipn.rb +66 -0
  16. data/lib/paypal-sdk/core/api/rest.rb +163 -0
  17. data/lib/paypal-sdk/core/authentication.rb +66 -0
  18. data/lib/paypal-sdk/core/config.rb +249 -0
  19. data/lib/paypal-sdk/core/credential.rb +16 -0
  20. data/lib/paypal-sdk/core/credential/base.rb +27 -0
  21. data/lib/paypal-sdk/core/credential/certificate.rb +32 -0
  22. data/lib/paypal-sdk/core/credential/signature.rb +22 -0
  23. data/lib/paypal-sdk/core/credential/third_party/subject.rb +25 -0
  24. data/lib/paypal-sdk/core/credential/third_party/token.rb +39 -0
  25. data/lib/paypal-sdk/core/exceptions.rb +96 -0
  26. data/lib/paypal-sdk/core/logging.rb +45 -0
  27. data/lib/paypal-sdk/core/openid_connect.rb +122 -0
  28. data/lib/paypal-sdk/core/openid_connect/api.rb +49 -0
  29. data/lib/paypal-sdk/core/openid_connect/data_types.rb +73 -0
  30. data/lib/paypal-sdk/core/openid_connect/get_api.rb +28 -0
  31. data/lib/paypal-sdk/core/openid_connect/request_data_type.rb +52 -0
  32. data/lib/paypal-sdk/core/openid_connect/set_api.rb +36 -0
  33. data/lib/paypal-sdk/core/util.rb +11 -0
  34. data/lib/paypal-sdk/core/util/http_helper.rb +159 -0
  35. data/lib/paypal-sdk/core/util/oauth_signature.rb +64 -0
  36. data/lib/paypal-sdk/core/util/ordered_hash.rb +165 -0
  37. data/lib/paypal-sdk/rest/data_types.rb +1 -0
  38. data/lib/paypal-sdk/rest/version.rb +1 -1
  39. data/spec/config/paypal.yml +27 -0
  40. data/spec/config/sample_data.yml +3 -0
  41. data/spec/core/api/data_type_spec.rb +189 -0
  42. data/spec/core/api/rest_spec.rb +147 -0
  43. data/spec/core/config_spec.rb +192 -0
  44. data/spec/core/logging_spec.rb +28 -0
  45. data/spec/core/openid_connect_spec.rb +144 -0
  46. data/spec/log/http.log +71 -32
  47. data/spec/log/rest_http.log +133 -0
  48. data/spec/spec_helper.rb +7 -0
  49. data/spec/support/sample_data.rb +5 -0
  50. metadata +82 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00ac164bfad60dba6661fc2974c6894dc9eb1e14
4
- data.tar.gz: 9218e8c10cbdc08fef6c79ef5be392ac79763b7e
3
+ metadata.gz: a369569eb5ff7fefd5a919a9935a16a9679c06ea
4
+ data.tar.gz: e9aaebaabd2099f8d2615fa30c9fad23af18407b
5
5
  SHA512:
6
- metadata.gz: f5d3e5d5f6c676bdfaebf33ad5e0247818401af6e1742a64487041c952d4628fff2fd699a2f98d9799901528ca55ca9c185eb5aa043c858c35274bc9f5d37b89
7
- data.tar.gz: 91f3ecfeadb88bb0e7d6d3a909c6643ff54e1191a8065997a03630e7c8eb239d87255475d09392779dab3a0faae0cc3c8ee9a5b21360445cfe47f340694dcd2c
6
+ metadata.gz: 1696f507a5fcc328f2a8362fda8268339be044ab277583f239d7541be13eace7dd152552ec9a74ccc369410503b212a82cbbbce7d28652afa9e24835a706beeb
7
+ data.tar.gz: b5e30d11a4016f6af6f24b79d1b6967ab00f390f5cfea04401da4c381ada9bad7dfa44d0a0cfb5e8d55fc7f8875692b803d841cdb459f94eff13e7d113b05e78
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'paypal-sdk-core', :git => "https://github.com/paypal/sdk-core-ruby.git"
5
+ #gem 'paypal-sdk-core', :git => "https://github.com/paypal/sdk-core-ruby.git"
6
6
 
7
7
  gem 'rake', :require => false
8
8
 
data/README.md CHANGED
@@ -69,6 +69,50 @@ PayPal::SDK.configure(
69
69
  :ssl_options => { } )
70
70
  ```
71
71
 
72
+ Logger configuration:
73
+
74
+ ```ruby
75
+ PayPal::SDK.logger = Logger.new(STDERR)
76
+ ```
77
+
78
+
79
+ ### OpenIDConnect Samples
80
+
81
+ ```ruby
82
+ require 'paypal-sdk-rest'
83
+
84
+ # Update client_id, client_secret and redirect_uri
85
+ PayPal::SDK.configure({
86
+ :openid_client_id => "client_id",
87
+ :openid_client_secret => "client_secret",
88
+ :openid_redirect_uri => "http://google.com"
89
+ })
90
+ include PayPal::SDK::OpenIDConnect
91
+
92
+ # Generate URL to Get Authorize code
93
+ puts Tokeninfo.authorize_url( :scope => "openid profile" )
94
+
95
+ # Create tokeninfo by using AuthorizeCode from redirect_uri
96
+ tokeninfo = Tokeninfo.create("Replace with Authorize Code received on redirect_uri")
97
+ puts tokeninfo.to_hash
98
+
99
+ # Refresh tokeninfo object
100
+ tokeninfo = tokeninfo.refresh
101
+ puts tokeninfo.to_hash
102
+
103
+ # Create tokeninfo by using refresh token
104
+ tokeninfo = Tokeninfo.refresh("Replace with refresh_token")
105
+ puts tokeninfo.to_hash
106
+
107
+ # Get Userinfo
108
+ userinfo = tokeninfo.userinfo
109
+ puts userinfo.to_hash
110
+
111
+ # Get logout url
112
+ put tokeninfo.logout_url
113
+ ```
114
+
115
+
72
116
  ## Create Payment
73
117
 
74
118
  ```ruby
@@ -0,0 +1,3 @@
1
+ To copy a PayPal SDK default configuration and initializer to your Rails App.
2
+
3
+ rails g paypal-sdk:install
@@ -0,0 +1,17 @@
1
+ module Paypal
2
+ module Sdk
3
+ module Generators
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def copy_config_file
8
+ copy_file "paypal.yml", "config/paypal.yml"
9
+ end
10
+
11
+ def copy_initializer_file
12
+ copy_file "paypal.rb", "config/initializers/paypal.rb"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ PayPal::SDK.load("config/paypal.yml", Rails.env)
2
+ PayPal::SDK.logger = Rails.logger
@@ -0,0 +1,31 @@
1
+ test: &default
2
+
3
+ # Credentials for REST APIs
4
+ client_id: EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM
5
+ client_secret: EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM
6
+
7
+ # Mode can be 'live' or 'sandbox'
8
+ mode: sandbox
9
+
10
+ # Credentials for Classic APIs
11
+ app_id: APP-80W284485P519543T
12
+ username: jb-us-seller_api1.paypal.com
13
+ password: WX4WTU3S8MY44S7F
14
+ signature: AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy
15
+ # # With Certificate
16
+ # cert_path: "config/cert_key.pem"
17
+ sandbox_email_address: Platform.sdk.seller@gmail.com
18
+
19
+ # # IP Address
20
+ # ip_address: 127.0.0.1
21
+ # # HTTP Proxy
22
+ # http_proxy: http://proxy-ipaddress:3129/
23
+
24
+ # verbose_logging: true
25
+
26
+ development:
27
+ <<: *default
28
+
29
+ production:
30
+ <<: *default
31
+ mode: live
@@ -0,0 +1,38 @@
1
+ module PayPal
2
+ module SDK
3
+ module Core
4
+
5
+ autoload :VERSION, "paypal-sdk/rest/version"
6
+ autoload :Config, "paypal-sdk/core/config"
7
+ autoload :Configuration, "paypal-sdk/core/config"
8
+ autoload :Logging, "paypal-sdk/core/logging"
9
+ autoload :Authentication, "paypal-sdk/core/authentication"
10
+ autoload :Exceptions, "paypal-sdk/core/exceptions"
11
+ autoload :OpenIDConnect, "paypal-sdk/core/openid_connect"
12
+ autoload :API, "paypal-sdk/core/api"
13
+ autoload :Util, "paypal-sdk/core/util"
14
+ autoload :Credential, "paypal-sdk/core/credential"
15
+
16
+ end
17
+
18
+ autoload :OpenIDConnect, "paypal-sdk/core/openid_connect"
19
+
20
+ class << self
21
+ def configure(options = {}, &block)
22
+ Core::Config.configure(options, &block)
23
+ end
24
+
25
+ def load(*args)
26
+ Core::Config.load(*args)
27
+ end
28
+
29
+ def logger
30
+ Core::Config.logger
31
+ end
32
+
33
+ def logger=(log)
34
+ Core::Config.logger = log
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ module PayPal
2
+ module SDK
3
+ module Core
4
+ module API
5
+ autoload :Base, "paypal-sdk/core/api/base"
6
+ autoload :Merchant, "paypal-sdk/core/api/merchant"
7
+ autoload :Platform, "paypal-sdk/core/api/platform"
8
+ autoload :REST, "paypal-sdk/core/api/rest"
9
+ autoload :IPN, "paypal-sdk/core/api/ipn"
10
+
11
+ module DataTypes
12
+ autoload :Base, "paypal-sdk/core/api/data_types/base"
13
+ autoload :Enum, "paypal-sdk/core/api/data_types/enum"
14
+ autoload :SimpleTypes, "paypal-sdk/core/api/data_types/simple_types"
15
+ autoload :ArrayWithBlock, "paypal-sdk/core/api/data_types/array_with_block"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,162 @@
1
+ module PayPal::SDK::Core
2
+
3
+ module API
4
+ # API class provide default functionality for accessing the API web services.
5
+ # == Example
6
+ # api = API::Base.new("AdaptivePayments")
7
+ # response = api.request("GetPaymentOptions", "")
8
+ class Base
9
+
10
+ include Util::HTTPHelper
11
+
12
+ attr_accessor :http, :uri, :service_name
13
+
14
+ DEFAULT_API_MODE = :sandbox
15
+ API_MODES = [ :live, :sandbox ]
16
+
17
+ # Initialize API object
18
+ # === Argument
19
+ # * <tt>service_name</tt> -- (Optional) Service name
20
+ # * <tt>environment</tt> -- (Optional) Configuration environment to load
21
+ # * <tt>options</tt> -- (Optional) Override configuration.
22
+ # === Example
23
+ # new("AdaptivePayments")
24
+ # new("AdaptivePayments", :development)
25
+ # new(:wsdl_service) # It load wsdl_service configuration
26
+ def initialize(service_name = "", environment = nil, options = {})
27
+ unless service_name.is_a? String
28
+ environment, options, service_name = service_name, environment || {}, ""
29
+ end
30
+ @service_name = service_name
31
+ set_config(environment, options)
32
+ end
33
+
34
+ def uri
35
+ @uri ||=
36
+ begin
37
+ uri = URI.parse("#{service_endpoint}/#{service_name}")
38
+ uri.path = uri.path.gsub(/\/+/, "/")
39
+ uri
40
+ end
41
+ end
42
+
43
+ def http
44
+ @http ||= create_http_connection(uri)
45
+ end
46
+
47
+ # Override set_config method to create http connection on changing the configuration.
48
+ def set_config(*args)
49
+ @http = @uri = nil
50
+ super
51
+ end
52
+
53
+ # Get configured API mode( sandbox or live)
54
+ def api_mode
55
+ if config.mode and API_MODES.include? config.mode.to_sym
56
+ config.mode.to_sym
57
+ else
58
+ DEFAULT_API_MODE
59
+ end
60
+ end
61
+
62
+ # Get service end point
63
+ def service_endpoint
64
+ config.endpoint
65
+ end
66
+
67
+ # Default Http header
68
+ def default_http_header
69
+ { "User-Agent" => self.class.user_agent }
70
+ end
71
+
72
+ # Generate HTTP request for given action and parameters
73
+ # === Arguments
74
+ # * <tt>http_method</tt> -- HTTP method(get/put/post/delete/patch)
75
+ # * <tt>action</tt> -- Action to perform
76
+ # * <tt>params</tt> -- (Optional) Parameters for the action
77
+ # * <tt>initheader</tt> -- (Optional) HTTP header
78
+ def api_call(payload)
79
+ payload[:header] = default_http_header.merge(payload[:header])
80
+ payload[:uri] ||= uri.dup
81
+ payload[:http] ||= http.dup
82
+ payload[:uri].query = encode_www_form(payload[:query]) if payload[:query] and payload[:query].any?
83
+ format_request(payload)
84
+ payload[:response] = http_call(payload)
85
+ format_response(payload)
86
+ payload[:data]
87
+ end
88
+
89
+ # Generate HTTP request for given action and parameters
90
+ # === Arguments
91
+ # * <tt>action</tt> -- Action to perform
92
+ # * <tt>params</tt> -- (Optional) Parameters for the action
93
+ # * <tt>initheader</tt> -- (Optional) HTTP header
94
+ def post(action, params = {}, header = {})
95
+ action, params, header = "", action, params if action.is_a? Hash
96
+ api_call(:method => :post, :action => action, :params => params, :header => header)
97
+ end
98
+ alias_method :request, :post
99
+
100
+ def get(action, params = {}, header = {})
101
+ action, params, header = "", action, params if action.is_a? Hash
102
+ api_call(:method => :get, :action => action, :query => params, :params => nil, :header => header)
103
+ end
104
+
105
+ def patch(action, params = {}, header = {})
106
+ action, params, header = "", action, params if action.is_a? Hash
107
+ api_call(:method => :patch, :action => action, :params => params, :header => header)
108
+ end
109
+
110
+ def put(action, params = {}, header = {})
111
+ action, params, header = "", action, params if action.is_a? Hash
112
+ api_call(:method => :put, :action => action, :params => params, :header => header)
113
+ end
114
+
115
+ def delete(action, params = {}, header = {})
116
+ action, params, header = "", action, params if action.is_a? Hash
117
+ api_call(:method => :delete, :action => action, :params => params, :header => header)
118
+ end
119
+
120
+ # Format Request data. It will be override by child class
121
+ # == Arguments
122
+ # * <tt>action</tt> -- Request action
123
+ # * <tt>params</tt> -- Request parameters
124
+ # == Return
125
+ # * <tt>path</tt> -- Formated request uri object
126
+ # * <tt>params</tt> -- Formated request Parameters
127
+ # * <tt>header</tt> -- HTTP Header
128
+ def format_request(payload)
129
+ payload[:uri].path = url_join(payload[:uri].path, payload[:action])
130
+ payload[:body] = payload[:params].to_s
131
+ payload
132
+ end
133
+
134
+ # Format Response object. It will be override by child class
135
+ # == Argument
136
+ # * <tt>action</tt> -- Request action
137
+ # * <tt>response</tt> -- HTTP response object
138
+ def format_response(payload)
139
+ payload[:data] = payload[:response].body
140
+ payload
141
+ end
142
+
143
+ # Format Error object. It will be override by child class.
144
+ # == Arguments
145
+ # * <tt>exception</tt> -- Exception object.
146
+ # * <tt>message</tt> -- Readable error message.
147
+ def format_error(exception, message)
148
+ raise exception
149
+ end
150
+
151
+ class << self
152
+ def sdk_library_details
153
+ @library_details ||= "paypal-sdk-core #{PayPal::SDK::REST::VERSION}; ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}-#{RUBY_PLATFORM}"
154
+ end
155
+
156
+ def user_agent
157
+ @user_agent ||= "PayPalSDK/rest-sdk-ruby #{VERSION} (#{sdk_library_details})"
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,44 @@
1
+ module PayPal::SDK::Core
2
+ module API
3
+ module DataTypes
4
+ # Create Array with block.
5
+ # === Example
6
+ # ary = ArrayWithBlock.new{|val| val.to_i }
7
+ # ary.push("123") # [ 123 ]
8
+ # ary.merge!(["1", "3"]) # [ 123, 1, 3 ]
9
+ class ArrayWithBlock < ::Array
10
+ def initialize(&block)
11
+ @block = block
12
+ super()
13
+ end
14
+
15
+ def [](key)
16
+ super(key) || send(:"[]=", key, nil)
17
+ end
18
+
19
+ def []=(key, value)
20
+ super(key, @block ? @block.call(value) : value)
21
+ end
22
+
23
+ def push(value)
24
+ super(@block ? @block.call(value) : value)
25
+ end
26
+
27
+ def merge!(array)
28
+ if array.is_a? Array
29
+ array.each do |object|
30
+ push(object)
31
+ end
32
+ elsif array.is_a? Hash and array.keys.first.to_s =~ /^\d+$/
33
+ array.each do |key, object|
34
+ self[key.to_i] = object
35
+ end
36
+ else
37
+ push(array)
38
+ end
39
+ self
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,224 @@
1
+ require 'date'
2
+
3
+ module PayPal::SDK::Core
4
+ module API
5
+
6
+ module DataTypes
7
+
8
+ # Create attributes and restrict the object type.
9
+ # == Example
10
+ # class ConvertCurrencyRequest < Core::API::DataTypes::Base
11
+ # object_of :baseAmountList, CurrencyList
12
+ # object_of :convertToCurrencyList, CurrencyCodeList
13
+ # object_of :countryCode, String
14
+ # object_of :conversionType, String
15
+ # end
16
+ class Base
17
+
18
+ HashOptions = { :attribute => true, :namespace => true, :symbol => false }
19
+ ContentKey = :value
20
+
21
+ include SimpleTypes
22
+ include Logging
23
+
24
+ class << self
25
+
26
+ # Add attribute
27
+ # === Arguments
28
+ # * <tt>name</tt> -- attribute name
29
+ # * <tt>options</tt> -- options
30
+ def add_attribute(name, options = {})
31
+ add_member(name, SimpleTypes::String, options.merge( :attribute => true ))
32
+ end
33
+
34
+ # Fields list for the DataTye
35
+ def members
36
+ @members ||=
37
+ begin
38
+ superclass.load_members if defined? superclass.load_members
39
+ parent_members = superclass.instance_variable_get("@members")
40
+ parent_members ? parent_members.dup : Util::OrderedHash.new
41
+ end
42
+ end
43
+
44
+ # Add Field to class variable hash and generate methods
45
+ # === Example
46
+ # add_member(:errorMessage, String) # Generate Code
47
+ # # attr_reader :errorMessage
48
+ # # alias_method :error_message, :errorMessage
49
+ # # alias_method :error_message=, :errorMessage=
50
+ def add_member(member_name, klass, options = {})
51
+ member_name = member_name.to_sym
52
+ return if members[member_name]
53
+ members[member_name] = options.merge( :type => klass )
54
+ member_variable_name = "@#{member_name}"
55
+ define_method "#{member_name}=" do |value|
56
+ object = options[:array] ? convert_array(value, klass) : convert_object(value, klass)
57
+ instance_variable_set(member_variable_name, object)
58
+ end
59
+ default_value = ( options[:array] ? [] : ( klass < Base ? Util::OrderedHash.new : nil ) )
60
+ define_method member_name do |&block|
61
+ value = instance_variable_get(member_variable_name) || ( default_value && send("#{member_name}=", default_value) )
62
+ value.instance_eval(&block) if block
63
+ value
64
+ end
65
+ define_alias_methods(member_name, options)
66
+ end
67
+
68
+ # Define alias methods for getter and setter
69
+ def define_alias_methods(member_name, options)
70
+ snakecase_name = snakecase(member_name)
71
+ alias_method snakecase_name, member_name
72
+ alias_method "#{snakecase_name}=", "#{member_name}="
73
+ alias_method "#{options[:namespace]}:#{member_name}=", "#{member_name}=" if options[:namespace]
74
+ if options[:attribute]
75
+ alias_method "@#{member_name}=", "#{member_name}="
76
+ alias_method "@#{options[:namespace]}:#{member_name}=", "#{member_name}=" if options[:namespace]
77
+ end
78
+ end
79
+
80
+ # define method for given member and the class name
81
+ # === Example
82
+ # object_of(:errorMessage, ErrorMessage) # Generate Code
83
+ # # def errorMessage=(options)
84
+ # # @errorMessage = ErrorMessage.new(options)
85
+ # # end
86
+ # # add_member :errorMessage, ErrorMessage
87
+ def object_of(key, klass, options = {})
88
+ add_member(key, klass, options)
89
+ end
90
+
91
+ # define method for given member and the class name
92
+ # === Example
93
+ # array_of(:errorMessage, ErrorMessage) # It Generate below code
94
+ # # def errorMessage=(array)
95
+ # # @errorMessage = array.map{|options| ErrorMessage.new(options) }
96
+ # # end
97
+ # # add_member :errorMessage, ErrorMessage
98
+ def array_of(key, klass, options = {})
99
+ add_member(key, klass, options.merge(:array => true))
100
+ end
101
+
102
+ # Generate snakecase string.
103
+ # === Example
104
+ # snakecase("errorMessage")
105
+ # # error_message
106
+ def snakecase(string)
107
+ string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').gsub(/([A-Z])([A-Z][a-z])/, '\1_\2').downcase
108
+ end
109
+
110
+ end
111
+
112
+ # Initialize options.
113
+ def initialize(options = {}, &block)
114
+ merge!(options, &block)
115
+ end
116
+
117
+ # Merge values
118
+ def merge!(options, &block)
119
+ if options.is_a? Hash
120
+ options.each do |key, value|
121
+ set(key, value)
122
+ end
123
+ elsif members[ContentKey]
124
+ set(ContentKey, options)
125
+ else
126
+ raise ArgumentError, "invalid data(#{options.inspect}) for #{self.class.name} class"
127
+ end
128
+ self.instance_eval(&block) if block
129
+ self
130
+ end
131
+
132
+ # Set value for given member
133
+ # === Arguments
134
+ # * <tt>key</tt> -- member name
135
+ # * <tt>value</tt> -- value for member
136
+ def set(key, value)
137
+ send("#{key}=", value)
138
+ rescue NoMethodError => error
139
+ logger.warn error.message
140
+ rescue TypeError, ArgumentError => error
141
+ raise TypeError, "#{error.message}(#{value.inspect}) for #{self.class.name}.#{key} member"
142
+ end
143
+
144
+ # Create array of objects.
145
+ # === Example
146
+ # covert_array([{ :amount => "55", :code => "USD"}], CurrencyType)
147
+ # covert_array({ "0" => { :amount => "55", :code => "USD"} }, CurrencyType)
148
+ # covert_array({ :amount => "55", :code => "USD"}, CurrencyType)
149
+ # # @return
150
+ # # [ <CurrencyType#object @amount="55" @code="USD" > ]
151
+ def convert_array(array, klass)
152
+ default_value = ( klass < Base ? Util::OrderedHash.new : nil )
153
+ data_type_array = ArrayWithBlock.new{|object| convert_object(object || default_value, klass) }
154
+ data_type_array.merge!(array)
155
+ end
156
+
157
+ # Create object based on given data.
158
+ # === Example
159
+ # covert_object({ :amount => "55", :code => "USD"}, CurrencyType )
160
+ # # @return
161
+ # # <CurrencyType#object @amount="55" @code="USD" >
162
+ def convert_object(object, klass)
163
+ object.is_a?(klass) ? object : ( ( object.nil? or object == "" ) ? nil : klass.new(object) )
164
+ end
165
+
166
+ # Alias instance method for the class method.
167
+ def members
168
+ self.class.members
169
+ end
170
+
171
+ # Get configured member names
172
+ def member_names
173
+ members.keys
174
+ end
175
+
176
+ # Create Hash based configured members
177
+ def to_hash(options = {})
178
+ options = HashOptions.merge(options)
179
+ hash = Util::OrderedHash.new
180
+ member_names.each do |member|
181
+ value = value_to_hash(instance_variable_get("@#{member}"), options)
182
+ hash[hash_key(member, options)] = value unless skip_value?(value)
183
+ end
184
+ hash
185
+ end
186
+
187
+ # Skip nil, empty array and empty hash.
188
+ def skip_value?(value)
189
+ value.nil? || ( ( value.is_a?(Array) || value.is_a?(Hash) ) && value.empty? )
190
+ end
191
+
192
+ # Generate Hash key for given member name based on configuration
193
+ # === Example
194
+ # hash_key(:amount) # @return :"ebl:amount"
195
+ # hash_key(:type) # @return :"@type"
196
+ def hash_key(key, options = {})
197
+ unless key == ContentKey
198
+ member_option = members[key]
199
+ key = member_option[:name] if member_option.include? :name
200
+ if !member_option[:attribute] and member_option[:namespace] and options[:namespace]
201
+ key = "#{member_option[:namespace]}:#{key}"
202
+ end
203
+ key = "@#{key}" if member_option[:attribute] and options[:attribute]
204
+ end
205
+ options[:symbol] ? key.to_sym : key.to_s
206
+ end
207
+
208
+ # Covert the object to hash based on class.
209
+ def value_to_hash(value, options = {})
210
+ case value
211
+ when Array
212
+ value = value.map{|object| value_to_hash(object, options) }
213
+ value.delete_if{|v| skip_value?(v) }
214
+ value
215
+ when Base
216
+ value.to_hash(options)
217
+ else
218
+ value
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end