paypal-sdk-rest 0.10.0 → 1.0.0

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 (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