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.
- checksums.yaml +4 -4
 - data/Gemfile +1 -1
 - data/README.md +44 -0
 - data/lib/generators/paypal/sdk/USAGE +3 -0
 - data/lib/generators/paypal/sdk/install_generator.rb +17 -0
 - data/lib/generators/paypal/sdk/templates/paypal.rb +2 -0
 - data/lib/generators/paypal/sdk/templates/paypal.yml +31 -0
 - data/lib/paypal-sdk-core.rb +38 -0
 - data/lib/paypal-sdk/core/api.rb +20 -0
 - data/lib/paypal-sdk/core/api/base.rb +162 -0
 - data/lib/paypal-sdk/core/api/data_types/array_with_block.rb +44 -0
 - data/lib/paypal-sdk/core/api/data_types/base.rb +224 -0
 - data/lib/paypal-sdk/core/api/data_types/enum.rb +26 -0
 - data/lib/paypal-sdk/core/api/data_types/simple_types.rb +52 -0
 - data/lib/paypal-sdk/core/api/ipn.rb +66 -0
 - data/lib/paypal-sdk/core/api/rest.rb +163 -0
 - data/lib/paypal-sdk/core/authentication.rb +66 -0
 - data/lib/paypal-sdk/core/config.rb +249 -0
 - data/lib/paypal-sdk/core/credential.rb +16 -0
 - data/lib/paypal-sdk/core/credential/base.rb +27 -0
 - data/lib/paypal-sdk/core/credential/certificate.rb +32 -0
 - data/lib/paypal-sdk/core/credential/signature.rb +22 -0
 - data/lib/paypal-sdk/core/credential/third_party/subject.rb +25 -0
 - data/lib/paypal-sdk/core/credential/third_party/token.rb +39 -0
 - data/lib/paypal-sdk/core/exceptions.rb +96 -0
 - data/lib/paypal-sdk/core/logging.rb +45 -0
 - data/lib/paypal-sdk/core/openid_connect.rb +122 -0
 - data/lib/paypal-sdk/core/openid_connect/api.rb +49 -0
 - data/lib/paypal-sdk/core/openid_connect/data_types.rb +73 -0
 - data/lib/paypal-sdk/core/openid_connect/get_api.rb +28 -0
 - data/lib/paypal-sdk/core/openid_connect/request_data_type.rb +52 -0
 - data/lib/paypal-sdk/core/openid_connect/set_api.rb +36 -0
 - data/lib/paypal-sdk/core/util.rb +11 -0
 - data/lib/paypal-sdk/core/util/http_helper.rb +159 -0
 - data/lib/paypal-sdk/core/util/oauth_signature.rb +64 -0
 - data/lib/paypal-sdk/core/util/ordered_hash.rb +165 -0
 - data/lib/paypal-sdk/rest/data_types.rb +1 -0
 - data/lib/paypal-sdk/rest/version.rb +1 -1
 - data/spec/config/paypal.yml +27 -0
 - data/spec/config/sample_data.yml +3 -0
 - data/spec/core/api/data_type_spec.rb +189 -0
 - data/spec/core/api/rest_spec.rb +147 -0
 - data/spec/core/config_spec.rb +192 -0
 - data/spec/core/logging_spec.rb +28 -0
 - data/spec/core/openid_connect_spec.rb +144 -0
 - data/spec/log/http.log +71 -32
 - data/spec/log/rest_http.log +133 -0
 - data/spec/spec_helper.rb +7 -0
 - data/spec/support/sample_data.rb +5 -0
 - metadata +82 -5
 
| 
         @@ -0,0 +1,73 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'paypal-sdk-core'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module PayPal::SDK::Core
         
     | 
| 
      
 4 
     | 
    
         
            +
              module OpenIDConnect
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DataTypes
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class Base < PayPal::SDK::Core::API::DataTypes::Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  class Address < Base
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def self.load_members
         
     | 
| 
      
 11 
     | 
    
         
            +
                      object_of :street_address, String
         
     | 
| 
      
 12 
     | 
    
         
            +
                      object_of :locality, String
         
     | 
| 
      
 13 
     | 
    
         
            +
                      object_of :region, String
         
     | 
| 
      
 14 
     | 
    
         
            +
                      object_of :postal_code, String
         
     | 
| 
      
 15 
     | 
    
         
            +
                      object_of :country, String
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  class Userinfo < Base
         
     | 
| 
      
 20 
     | 
    
         
            +
                    def self.load_members
         
     | 
| 
      
 21 
     | 
    
         
            +
                      object_of :user_id, String
         
     | 
| 
      
 22 
     | 
    
         
            +
                      object_of :sub, String
         
     | 
| 
      
 23 
     | 
    
         
            +
                      object_of :name, String
         
     | 
| 
      
 24 
     | 
    
         
            +
                      object_of :given_name, String
         
     | 
| 
      
 25 
     | 
    
         
            +
                      object_of :family_name, String
         
     | 
| 
      
 26 
     | 
    
         
            +
                      object_of :middle_name, String
         
     | 
| 
      
 27 
     | 
    
         
            +
                      object_of :picture, String
         
     | 
| 
      
 28 
     | 
    
         
            +
                      object_of :email, String
         
     | 
| 
      
 29 
     | 
    
         
            +
                      object_of :email_verified, Boolean
         
     | 
| 
      
 30 
     | 
    
         
            +
                      object_of :gender, String
         
     | 
| 
      
 31 
     | 
    
         
            +
                      object_of :birthday, String
         
     | 
| 
      
 32 
     | 
    
         
            +
                      object_of :zoneinfo, String
         
     | 
| 
      
 33 
     | 
    
         
            +
                      object_of :locale, String
         
     | 
| 
      
 34 
     | 
    
         
            +
                      object_of :language, String
         
     | 
| 
      
 35 
     | 
    
         
            +
                      object_of :verified, Boolean
         
     | 
| 
      
 36 
     | 
    
         
            +
                      object_of :phone_number, String
         
     | 
| 
      
 37 
     | 
    
         
            +
                      object_of :address, Address
         
     | 
| 
      
 38 
     | 
    
         
            +
                      object_of :verified_account, Boolean
         
     | 
| 
      
 39 
     | 
    
         
            +
                      object_of :account_type, String
         
     | 
| 
      
 40 
     | 
    
         
            +
                      object_of :account_creation_date, String
         
     | 
| 
      
 41 
     | 
    
         
            +
                      object_of :age_range, String
         
     | 
| 
      
 42 
     | 
    
         
            +
                      object_of :payer_id, String
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  class Tokeninfo < Base
         
     | 
| 
      
 47 
     | 
    
         
            +
                    def self.load_members
         
     | 
| 
      
 48 
     | 
    
         
            +
                      object_of :scope, String
         
     | 
| 
      
 49 
     | 
    
         
            +
                      object_of :access_token, String
         
     | 
| 
      
 50 
     | 
    
         
            +
                      object_of :refresh_token, String
         
     | 
| 
      
 51 
     | 
    
         
            +
                      object_of :token_type, String
         
     | 
| 
      
 52 
     | 
    
         
            +
                      object_of :id_token, String
         
     | 
| 
      
 53 
     | 
    
         
            +
                      object_of :expires_in, Integer
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  class Error < Base
         
     | 
| 
      
 58 
     | 
    
         
            +
                    def self.load_members
         
     | 
| 
      
 59 
     | 
    
         
            +
                      object_of :error, String
         
     | 
| 
      
 60 
     | 
    
         
            +
                      object_of :error_description, String
         
     | 
| 
      
 61 
     | 
    
         
            +
                      object_of :error_uri, String
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  constants.each do |data_type_klass|
         
     | 
| 
      
 67 
     | 
    
         
            +
                    data_type_klass = const_get(data_type_klass)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    data_type_klass.load_members if defined? data_type_klass.load_members
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module PayPal::SDK
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 3 
     | 
    
         
            +
                module OpenIDConnect
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module GetAPI
         
     | 
| 
      
 5 
     | 
    
         
            +
                    # Get API object
         
     | 
| 
      
 6 
     | 
    
         
            +
                    # === Example
         
     | 
| 
      
 7 
     | 
    
         
            +
                    #   Payment.api
         
     | 
| 
      
 8 
     | 
    
         
            +
                    #   payment.api
         
     | 
| 
      
 9 
     | 
    
         
            +
                    def api
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @api || parent_api
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    # Parent API object
         
     | 
| 
      
 14 
     | 
    
         
            +
                    def parent_api
         
     | 
| 
      
 15 
     | 
    
         
            +
                      superclass.respond_to?(:api) ? superclass.api : RequestDataType.api
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    def client_id
         
     | 
| 
      
 19 
     | 
    
         
            +
                      api.config.openid_client_id || api.config.client_id
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def client_secret
         
     | 
| 
      
 23 
     | 
    
         
            +
                      api.config.openid_client_secret || api.config.client_secret
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module PayPal::SDK
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 3 
     | 
    
         
            +
                module OpenIDConnect
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module RequestDataType
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                    # Get a local API object or Class level API object
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def api
         
     | 
| 
      
 8 
     | 
    
         
            +
                      @api || self.class.api
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 12 
     | 
    
         
            +
                      # Global API object
         
     | 
| 
      
 13 
     | 
    
         
            +
                      # === Example
         
     | 
| 
      
 14 
     | 
    
         
            +
                      #   RequestDataType.api
         
     | 
| 
      
 15 
     | 
    
         
            +
                      def api
         
     | 
| 
      
 16 
     | 
    
         
            +
                        @api ||= API.new({})
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      def client_id
         
     | 
| 
      
 20 
     | 
    
         
            +
                        api.config.openid_client_id || api.config.client_id
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      def client_secret
         
     | 
| 
      
 24 
     | 
    
         
            +
                        api.config.openid_client_secret || api.config.client_secret
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      # Setter for RequestDataType.api
         
     | 
| 
      
 28 
     | 
    
         
            +
                      # === Example
         
     | 
| 
      
 29 
     | 
    
         
            +
                      #   RequestDataType.set_config(..)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      include SetAPI
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      # Configure depended module, when RequestDataType is include.
         
     | 
| 
      
 33 
     | 
    
         
            +
                      # === Example
         
     | 
| 
      
 34 
     | 
    
         
            +
                      #   class Payment < DataTypes
         
     | 
| 
      
 35 
     | 
    
         
            +
                      #     include RequestDataType
         
     | 
| 
      
 36 
     | 
    
         
            +
                      #   end
         
     | 
| 
      
 37 
     | 
    
         
            +
                      #   Payment.set_config(..)
         
     | 
| 
      
 38 
     | 
    
         
            +
                      #   payment.set_config(..)
         
     | 
| 
      
 39 
     | 
    
         
            +
                      #   Payment.api
         
     | 
| 
      
 40 
     | 
    
         
            +
                      #   payment.api
         
     | 
| 
      
 41 
     | 
    
         
            +
                      def included(klass)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        klass.class_eval do
         
     | 
| 
      
 43 
     | 
    
         
            +
                          extend GetAPI
         
     | 
| 
      
 44 
     | 
    
         
            +
                          extend SetAPI
         
     | 
| 
      
 45 
     | 
    
         
            +
                          include SetAPI
         
     | 
| 
      
 46 
     | 
    
         
            +
                        end
         
     | 
| 
      
 47 
     | 
    
         
            +
                      end
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module PayPal::SDK
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 3 
     | 
    
         
            +
                module OpenIDConnect
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module SetAPI
         
     | 
| 
      
 5 
     | 
    
         
            +
                    # Set new api
         
     | 
| 
      
 6 
     | 
    
         
            +
                    # === Examples
         
     | 
| 
      
 7 
     | 
    
         
            +
                    #   payment.set_config(:development)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    #   payment.set_config(:client_id => "XYZ", :client_secret => "SECRET")
         
     | 
| 
      
 9 
     | 
    
         
            +
                    #   payment.set_config
         
     | 
| 
      
 10 
     | 
    
         
            +
                    #   payment.api = API.new(:development)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    def set_config(*args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      if args[0].is_a?(API)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        @api = args[0]
         
     | 
| 
      
 14 
     | 
    
         
            +
                      else
         
     | 
| 
      
 15 
     | 
    
         
            +
                        @api ||= API.new({})
         
     | 
| 
      
 16 
     | 
    
         
            +
                        @api.set_config(*args)  # Just override the configuration and Not
         
     | 
| 
      
 17 
     | 
    
         
            +
                        @api
         
     | 
| 
      
 18 
     | 
    
         
            +
                      end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    alias_method :config=, :set_config
         
     | 
| 
      
 21 
     | 
    
         
            +
                    alias_method :set_api, :set_config
         
     | 
| 
      
 22 
     | 
    
         
            +
                    alias_method :api=, :set_config
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    # Override client id
         
     | 
| 
      
 25 
     | 
    
         
            +
                    def client_id=(client_id)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      set_config(:client_id => client_id)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    # Override client secret
         
     | 
| 
      
 30 
     | 
    
         
            +
                    def client_secret=(client_secret)
         
     | 
| 
      
 31 
     | 
    
         
            +
                      set_config(:client_secret => client_secret)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module PayPal
         
     | 
| 
      
 2 
     | 
    
         
            +
              module SDK
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Core
         
     | 
| 
      
 4 
     | 
    
         
            +
                  module Util
         
     | 
| 
      
 5 
     | 
    
         
            +
                    autoload :OauthSignature, "paypal-sdk/core/util/oauth_signature"
         
     | 
| 
      
 6 
     | 
    
         
            +
                    autoload :OrderedHash,    "paypal-sdk/core/util/ordered_hash"
         
     | 
| 
      
 7 
     | 
    
         
            +
                    autoload :HTTPHelper,     "paypal-sdk/core/util/http_helper"
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,159 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'net/https'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module PayPal::SDK::Core
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 7 
     | 
    
         
            +
                module HTTPHelper
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  include Configuration
         
     | 
| 
      
 10 
     | 
    
         
            +
                  include Logging
         
     | 
| 
      
 11 
     | 
    
         
            +
                  include Authentication
         
     | 
| 
      
 12 
     | 
    
         
            +
                  include Exceptions
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  # Create HTTP connection based on given service name or configured end point
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def create_http_connection(uri)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    new_http(uri).tap do |http|
         
     | 
| 
      
 17 
     | 
    
         
            +
                      if config.http_timeout
         
     | 
| 
      
 18 
     | 
    
         
            +
                        http.open_timeout = config.http_timeout
         
     | 
| 
      
 19 
     | 
    
         
            +
                        http.read_timeout = config.http_timeout
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
                      configure_ssl(http) if uri.scheme == "https"
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  # New raw HTTP object
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def new_http(uri)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    if config.http_proxy
         
     | 
| 
      
 28 
     | 
    
         
            +
                      proxy = URI.parse(config.http_proxy)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      Net::HTTP.new(uri.host, uri.port, proxy.host, proxy.port, proxy.user, proxy.password)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    else
         
     | 
| 
      
 31 
     | 
    
         
            +
                      Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  # Default ca file
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def default_ca_file
         
     | 
| 
      
 37 
     | 
    
         
            +
                    File.expand_path("../../../../../data/paypal.crt", __FILE__)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  # Apply ssl configuration to http object
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def configure_ssl(http)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    http.tap do |https|
         
     | 
| 
      
 43 
     | 
    
         
            +
                      https.use_ssl = true
         
     | 
| 
      
 44 
     | 
    
         
            +
                      https.ca_file = default_ca_file
         
     | 
| 
      
 45 
     | 
    
         
            +
                      https.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
      
 46 
     | 
    
         
            +
                      config.ssl_options.each do |key, value|
         
     | 
| 
      
 47 
     | 
    
         
            +
                        http.send("#{key}=", value)
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                      add_certificate(https)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # Join url
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def url_join(path, action)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    path.sub(/\/?$/, "/#{action}")
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  # Make Http call
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # * payload - Hash(:http, :method, :uri, :body, :header)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  def http_call(payload)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    if Config.config.verbose_logging
         
     | 
| 
      
 62 
     | 
    
         
            +
                      logger.info payload.inspect
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    response =
         
     | 
| 
      
 66 
     | 
    
         
            +
                      log_http_call(payload) do
         
     | 
| 
      
 67 
     | 
    
         
            +
                        http = payload[:http] || create_http_connection(payload[:uri])
         
     | 
| 
      
 68 
     | 
    
         
            +
                        http.start do |session|
         
     | 
| 
      
 69 
     | 
    
         
            +
                          if [ :get, :delete, :head ].include? payload[:method]
         
     | 
| 
      
 70 
     | 
    
         
            +
                            session.send(payload[:method], payload[:uri].request_uri, payload[:header])
         
     | 
| 
      
 71 
     | 
    
         
            +
                          else
         
     | 
| 
      
 72 
     | 
    
         
            +
                            session.send(payload[:method], payload[:uri].request_uri, payload[:body], payload[:header])
         
     | 
| 
      
 73 
     | 
    
         
            +
                          end
         
     | 
| 
      
 74 
     | 
    
         
            +
                        end
         
     | 
| 
      
 75 
     | 
    
         
            +
                      end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    if Config.config.verbose_logging
         
     | 
| 
      
 78 
     | 
    
         
            +
                      if response.code.to_i == 200
         
     | 
| 
      
 79 
     | 
    
         
            +
                        logger.info(response.body)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      else
         
     | 
| 
      
 81 
     | 
    
         
            +
                        logger.warn(response.body)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      end
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    handle_response(response)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  # Log Http call
         
     | 
| 
      
 89 
     | 
    
         
            +
                  # * payload - Hash(:http, :method, :uri, :body, :header)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  def log_http_call(payload)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    logger.info "Request[#{payload[:method]}]: #{payload[:uri].to_s}"
         
     | 
| 
      
 92 
     | 
    
         
            +
                    start_time = Time.now
         
     | 
| 
      
 93 
     | 
    
         
            +
                    response = yield
         
     | 
| 
      
 94 
     | 
    
         
            +
                    logger.info sprintf("Response[%s]: %s, Duration: %.3fs", response.code,
         
     | 
| 
      
 95 
     | 
    
         
            +
                      response.message, Time.now - start_time)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    response
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  # Generate header based on given header keys and properties
         
     | 
| 
      
 100 
     | 
    
         
            +
                  # === Arguments
         
     | 
| 
      
 101 
     | 
    
         
            +
                  # * <tt>header_keys</tt> -- List of Header keys for the properties
         
     | 
| 
      
 102 
     | 
    
         
            +
                  # * <tt>properties</tt>  -- properties
         
     | 
| 
      
 103 
     | 
    
         
            +
                  # === Return
         
     | 
| 
      
 104 
     | 
    
         
            +
                  #  Hash with header as key property as value
         
     | 
| 
      
 105 
     | 
    
         
            +
                  # === Example
         
     | 
| 
      
 106 
     | 
    
         
            +
                  # map_header_value( { :username => "X-PAYPAL-USERNAME"}, { :username => "guest" })
         
     | 
| 
      
 107 
     | 
    
         
            +
                  # # Return: { "X-PAYPAL-USERNAME" => "guest" }
         
     | 
| 
      
 108 
     | 
    
         
            +
                  def map_header_value(header_keys, properties)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    header = {}
         
     | 
| 
      
 110 
     | 
    
         
            +
                    properties.each do |key, value|
         
     | 
| 
      
 111 
     | 
    
         
            +
                      key = header_keys[key]
         
     | 
| 
      
 112 
     | 
    
         
            +
                      header[key] = value.to_s if key and value
         
     | 
| 
      
 113 
     | 
    
         
            +
                    end
         
     | 
| 
      
 114 
     | 
    
         
            +
                    header
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  def encode_www_form(hash)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    if defined? URI.encode_www_form
         
     | 
| 
      
 119 
     | 
    
         
            +
                      URI.encode_www_form(hash)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    else
         
     | 
| 
      
 121 
     | 
    
         
            +
                      hash.map{|key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}" }.join("&")
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  # Handles response and error codes from the remote service.
         
     | 
| 
      
 126 
     | 
    
         
            +
                  def handle_response(response)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    case response.code.to_i
         
     | 
| 
      
 128 
     | 
    
         
            +
                      when 301, 302, 303, 307
         
     | 
| 
      
 129 
     | 
    
         
            +
                        raise(Redirection.new(response))
         
     | 
| 
      
 130 
     | 
    
         
            +
                      when 200...400
         
     | 
| 
      
 131 
     | 
    
         
            +
                        response
         
     | 
| 
      
 132 
     | 
    
         
            +
                      when 400
         
     | 
| 
      
 133 
     | 
    
         
            +
                        raise(BadRequest.new(response))
         
     | 
| 
      
 134 
     | 
    
         
            +
                      when 401
         
     | 
| 
      
 135 
     | 
    
         
            +
                        raise(UnauthorizedAccess.new(response))
         
     | 
| 
      
 136 
     | 
    
         
            +
                      when 403
         
     | 
| 
      
 137 
     | 
    
         
            +
                        raise(ForbiddenAccess.new(response))
         
     | 
| 
      
 138 
     | 
    
         
            +
                      when 404
         
     | 
| 
      
 139 
     | 
    
         
            +
                        raise(ResourceNotFound.new(response))
         
     | 
| 
      
 140 
     | 
    
         
            +
                      when 405
         
     | 
| 
      
 141 
     | 
    
         
            +
                        raise(MethodNotAllowed.new(response))
         
     | 
| 
      
 142 
     | 
    
         
            +
                      when 409
         
     | 
| 
      
 143 
     | 
    
         
            +
                        raise(ResourceConflict.new(response))
         
     | 
| 
      
 144 
     | 
    
         
            +
                      when 410
         
     | 
| 
      
 145 
     | 
    
         
            +
                        raise(ResourceGone.new(response))
         
     | 
| 
      
 146 
     | 
    
         
            +
                      when 422
         
     | 
| 
      
 147 
     | 
    
         
            +
                        raise(ResourceInvalid.new(response))
         
     | 
| 
      
 148 
     | 
    
         
            +
                      when 401...500
         
     | 
| 
      
 149 
     | 
    
         
            +
                        raise(ClientError.new(response))
         
     | 
| 
      
 150 
     | 
    
         
            +
                      when 500...600
         
     | 
| 
      
 151 
     | 
    
         
            +
                        raise(ServerError.new(response))
         
     | 
| 
      
 152 
     | 
    
         
            +
                      else
         
     | 
| 
      
 153 
     | 
    
         
            +
                        raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
                  end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
      
 158 
     | 
    
         
            +
              end
         
     | 
| 
      
 159 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'uri'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'base64'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module PayPal::SDK::Core
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 8 
     | 
    
         
            +
                class OauthSignature
         
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_accessor :username, :password, :token, :token_secret, :url, :timestamp
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(username, password, token, token_secret, url, timestamp = nil)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @username = username
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @password = password
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @token = token
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @token_secret = token_secret
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @url = url
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @timestamp = timestamp || Time.now.to_i.to_s
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def authorization_string
         
     | 
| 
      
 21 
     | 
    
         
            +
                    signature = oauth_signature
         
     | 
| 
      
 22 
     | 
    
         
            +
                    "token=#{token},signature=#{signature},timestamp=#{timestamp}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def oauth_signature
         
     | 
| 
      
 26 
     | 
    
         
            +
                    key = [
         
     | 
| 
      
 27 
     | 
    
         
            +
                      paypal_encode(password),
         
     | 
| 
      
 28 
     | 
    
         
            +
                      paypal_encode(token_secret),
         
     | 
| 
      
 29 
     | 
    
         
            +
                    ].join("&").gsub(/%[0-9A-F][0-9A-F]/, &:downcase )
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    digest = OpenSSL::HMAC.digest('sha1', key, base_string)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    Base64.encode64(digest).chomp
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def base_string
         
     | 
| 
      
 36 
     | 
    
         
            +
                    params = {
         
     | 
| 
      
 37 
     | 
    
         
            +
                      "oauth_consumer_key" => username,
         
     | 
| 
      
 38 
     | 
    
         
            +
                      "oauth_version" => "1.0",
         
     | 
| 
      
 39 
     | 
    
         
            +
                      "oauth_signature_method" => "HMAC-SHA1",
         
     | 
| 
      
 40 
     | 
    
         
            +
                      "oauth_token" => token,
         
     | 
| 
      
 41 
     | 
    
         
            +
                      "oauth_timestamp" => timestamp,
         
     | 
| 
      
 42 
     | 
    
         
            +
                    }
         
     | 
| 
      
 43 
     | 
    
         
            +
                    sorted_query_string = params.sort.map{|v| v.join("=") }.join("&")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    base = [
         
     | 
| 
      
 46 
     | 
    
         
            +
                      "POST",
         
     | 
| 
      
 47 
     | 
    
         
            +
                      paypal_encode(url),
         
     | 
| 
      
 48 
     | 
    
         
            +
                      paypal_encode(sorted_query_string)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    ].join("&")
         
     | 
| 
      
 50 
     | 
    
         
            +
                    base = base.gsub(/%[0-9A-F][0-9A-F]/, &:downcase )
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # The PayPalURLEncoder java class percent encodes everything other than 'a-zA-Z0-9 _'.
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # Then it converts ' ' to '+'.
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # Ruby's CGI.encode takes care of the ' ' and '*' to satisfy PayPal
         
     | 
| 
      
 56 
     | 
    
         
            +
                  # (but beware, URI.encode percent encodes spaces, and does nothing with '*').
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # Finally, CGI.encode does not encode '.-', which we need to do here.
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def paypal_encode str
         
     | 
| 
      
 59 
     | 
    
         
            +
                    CGI.escape(str.to_s).gsub('.', '%2E').gsub('-', '%2D')
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,165 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module PayPal::SDK::Core
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 3 
     | 
    
         
            +
                class OrderedHash < ::Hash #:nodoc:
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  def to_yaml_type
         
     | 
| 
      
 6 
     | 
    
         
            +
                    "!tag:yaml.org,2002:map"
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  # Hash is ordered in Ruby 1.9!
         
     | 
| 
      
 10 
     | 
    
         
            +
                  if RUBY_VERSION < '1.9'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    # In MRI the Hash class is core and written in C. In particular, methods are
         
     | 
| 
      
 13 
     | 
    
         
            +
                    # programmed with explicit C function calls and polymorphism is not honored.
         
     | 
| 
      
 14 
     | 
    
         
            +
                    #
         
     | 
| 
      
 15 
     | 
    
         
            +
                    # For example, []= is crucial in this implementation to maintain the @keys
         
     | 
| 
      
 16 
     | 
    
         
            +
                    # array but hash.c invokes rb_hash_aset() originally. This prevents method
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # reuse through inheritance and forces us to reimplement stuff.
         
     | 
| 
      
 18 
     | 
    
         
            +
                    #
         
     | 
| 
      
 19 
     | 
    
         
            +
                    # For instance, we cannot use the inherited #merge! because albeit the algorithm
         
     | 
| 
      
 20 
     | 
    
         
            +
                    # itself would work, our []= is not being called at all by the C code.
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    def initialize(*args, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      super
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @keys = []
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    def self.[](*args)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      ordered_hash = new
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                      if (args.length == 1 && args.first.is_a?(Array))
         
     | 
| 
      
 31 
     | 
    
         
            +
                        args.first.each do |key_value_pair|
         
     | 
| 
      
 32 
     | 
    
         
            +
                          next unless (key_value_pair.is_a?(Array))
         
     | 
| 
      
 33 
     | 
    
         
            +
                          ordered_hash[key_value_pair[0]] = key_value_pair[1]
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                        return ordered_hash
         
     | 
| 
      
 37 
     | 
    
         
            +
                      end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                      unless (args.size % 2 == 0)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        raise ArgumentError.new("odd number of arguments for Hash")
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      args.each_with_index do |val, ind|
         
     | 
| 
      
 44 
     | 
    
         
            +
                        next if (ind % 2 != 0)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        ordered_hash[val] = args[ind + 1]
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                      ordered_hash
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    def initialize_copy(other)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      super
         
     | 
| 
      
 53 
     | 
    
         
            +
                      # make a deep copy of keys
         
     | 
| 
      
 54 
     | 
    
         
            +
                      @keys = other.keys
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    def []=(key, value)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      @keys << key if !has_key?(key)
         
     | 
| 
      
 59 
     | 
    
         
            +
                      super
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    def delete(key)
         
     | 
| 
      
 63 
     | 
    
         
            +
                      if has_key? key
         
     | 
| 
      
 64 
     | 
    
         
            +
                        index = @keys.index(key)
         
     | 
| 
      
 65 
     | 
    
         
            +
                        @keys.delete_at index
         
     | 
| 
      
 66 
     | 
    
         
            +
                      end
         
     | 
| 
      
 67 
     | 
    
         
            +
                      super
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    def delete_if
         
     | 
| 
      
 71 
     | 
    
         
            +
                      super
         
     | 
| 
      
 72 
     | 
    
         
            +
                      sync_keys!
         
     | 
| 
      
 73 
     | 
    
         
            +
                      self
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    def reject!
         
     | 
| 
      
 77 
     | 
    
         
            +
                      super
         
     | 
| 
      
 78 
     | 
    
         
            +
                      sync_keys!
         
     | 
| 
      
 79 
     | 
    
         
            +
                      self
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    def reject(&block)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      dup.reject!(&block)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    def keys
         
     | 
| 
      
 87 
     | 
    
         
            +
                      @keys.dup
         
     | 
| 
      
 88 
     | 
    
         
            +
                    end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    def values
         
     | 
| 
      
 91 
     | 
    
         
            +
                      @keys.collect { |key| self[key] }
         
     | 
| 
      
 92 
     | 
    
         
            +
                    end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    def to_hash
         
     | 
| 
      
 95 
     | 
    
         
            +
                      self
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                    def to_a
         
     | 
| 
      
 99 
     | 
    
         
            +
                      @keys.map { |key| [ key, self[key] ] }
         
     | 
| 
      
 100 
     | 
    
         
            +
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    def each_key
         
     | 
| 
      
 103 
     | 
    
         
            +
                      @keys.each { |key| yield key }
         
     | 
| 
      
 104 
     | 
    
         
            +
                    end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                    def each_value
         
     | 
| 
      
 107 
     | 
    
         
            +
                      @keys.each { |key| yield self[key]}
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                    def each
         
     | 
| 
      
 111 
     | 
    
         
            +
                      @keys.each {|key| yield [key, self[key]]}
         
     | 
| 
      
 112 
     | 
    
         
            +
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    alias_method :each_pair, :each
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    def clear
         
     | 
| 
      
 117 
     | 
    
         
            +
                      super
         
     | 
| 
      
 118 
     | 
    
         
            +
                      @keys.clear
         
     | 
| 
      
 119 
     | 
    
         
            +
                      self
         
     | 
| 
      
 120 
     | 
    
         
            +
                    end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    def shift
         
     | 
| 
      
 123 
     | 
    
         
            +
                      k = @keys.first
         
     | 
| 
      
 124 
     | 
    
         
            +
                      v = delete(k)
         
     | 
| 
      
 125 
     | 
    
         
            +
                      [k, v]
         
     | 
| 
      
 126 
     | 
    
         
            +
                    end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                    def merge!(other_hash)
         
     | 
| 
      
 129 
     | 
    
         
            +
                      if block_given?
         
     | 
| 
      
 130 
     | 
    
         
            +
                        other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
         
     | 
| 
      
 131 
     | 
    
         
            +
                      else
         
     | 
| 
      
 132 
     | 
    
         
            +
                        other_hash.each { |k, v| self[k] = v }
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
      
 134 
     | 
    
         
            +
                      self
         
     | 
| 
      
 135 
     | 
    
         
            +
                    end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                    alias_method :update, :merge!
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                    def merge(other_hash, &block)
         
     | 
| 
      
 140 
     | 
    
         
            +
                      dup.merge!(other_hash, &block)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                    # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
         
     | 
| 
      
 144 
     | 
    
         
            +
                    def replace(other)
         
     | 
| 
      
 145 
     | 
    
         
            +
                      super
         
     | 
| 
      
 146 
     | 
    
         
            +
                      @keys = other.keys
         
     | 
| 
      
 147 
     | 
    
         
            +
                      self
         
     | 
| 
      
 148 
     | 
    
         
            +
                    end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                    def invert
         
     | 
| 
      
 151 
     | 
    
         
            +
                      OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
         
     | 
| 
      
 152 
     | 
    
         
            +
                    end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                    def inspect
         
     | 
| 
      
 155 
     | 
    
         
            +
                      "#<OrderedHash #{super}>"
         
     | 
| 
      
 156 
     | 
    
         
            +
                    end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                    private
         
     | 
| 
      
 159 
     | 
    
         
            +
                      def sync_keys!
         
     | 
| 
      
 160 
     | 
    
         
            +
                        @keys.delete_if {|k| !has_key?(k)}
         
     | 
| 
      
 161 
     | 
    
         
            +
                      end
         
     | 
| 
      
 162 
     | 
    
         
            +
                  end
         
     | 
| 
      
 163 
     | 
    
         
            +
                end
         
     | 
| 
      
 164 
     | 
    
         
            +
              end
         
     | 
| 
      
 165 
     | 
    
         
            +
            end
         
     |