ims-lti 1.2.4 → 2.0.0.beta.1

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 (57) hide show
  1. checksums.yaml +5 -5
  2. data/Changelog.txt +0 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +15 -103
  5. data/lib/ims.rb +3 -1
  6. data/lib/ims/lti.rb +6 -64
  7. data/lib/ims/lti/converters.rb +5 -0
  8. data/lib/ims/lti/converters/time_json_converter.rb +13 -0
  9. data/lib/ims/lti/models.rb +29 -0
  10. data/lib/ims/lti/models/base_url_choice.rb +15 -0
  11. data/lib/ims/lti/models/base_url_selector.rb +5 -0
  12. data/lib/ims/lti/models/contact.rb +5 -0
  13. data/lib/ims/lti/models/icon_endpoint.rb +5 -0
  14. data/lib/ims/lti/models/icon_info.rb +6 -0
  15. data/lib/ims/lti/models/localized_name.rb +11 -0
  16. data/lib/ims/lti/models/localized_text.rb +11 -0
  17. data/lib/ims/lti/models/lti_model.rb +169 -0
  18. data/lib/ims/lti/models/message_handler.rb +6 -0
  19. data/lib/ims/lti/models/messages.rb +6 -0
  20. data/lib/ims/lti/models/messages/basic_lti_launch_request.rb +8 -0
  21. data/lib/ims/lti/models/messages/message.rb +43 -0
  22. data/lib/ims/lti/models/messages/registration_request.rb +17 -0
  23. data/lib/ims/lti/models/parameter.rb +5 -0
  24. data/lib/ims/lti/models/product_family.rb +8 -0
  25. data/lib/ims/lti/models/product_info.rb +19 -0
  26. data/lib/ims/lti/models/product_instance.rb +10 -0
  27. data/lib/ims/lti/models/resource_handler.rb +18 -0
  28. data/lib/ims/lti/models/resource_type.rb +6 -0
  29. data/lib/ims/lti/models/rest_service.rb +14 -0
  30. data/lib/ims/lti/models/rest_service_profile.rb +7 -0
  31. data/lib/ims/lti/models/security_contract.rb +9 -0
  32. data/lib/ims/lti/models/service_owner.rb +8 -0
  33. data/lib/ims/lti/models/service_provider.rb +11 -0
  34. data/lib/ims/lti/models/tool_consumer_profile.rb +20 -0
  35. data/lib/ims/lti/models/tool_profile.rb +22 -0
  36. data/lib/ims/lti/models/tool_proxy.rb +11 -0
  37. data/lib/ims/lti/models/vendor.rb +28 -0
  38. data/lib/ims/lti/services.rb +5 -0
  39. data/lib/ims/lti/services/message_service.rb +40 -0
  40. data/lib/ims/lti/version.rb +5 -0
  41. metadata +68 -52
  42. data/Changelog +0 -54
  43. data/LICENSE +0 -18
  44. data/lib/ims/lti/deprecated_role_checks.rb +0 -52
  45. data/lib/ims/lti/extensions.rb +0 -45
  46. data/lib/ims/lti/extensions/canvas.rb +0 -122
  47. data/lib/ims/lti/extensions/content.rb +0 -209
  48. data/lib/ims/lti/extensions/outcome_data.rb +0 -216
  49. data/lib/ims/lti/launch_params.rb +0 -166
  50. data/lib/ims/lti/outcome_request.rb +0 -225
  51. data/lib/ims/lti/outcome_response.rb +0 -166
  52. data/lib/ims/lti/request_validator.rb +0 -56
  53. data/lib/ims/lti/role_checks.rb +0 -101
  54. data/lib/ims/lti/tool_base.rb +0 -29
  55. data/lib/ims/lti/tool_config.rb +0 -231
  56. data/lib/ims/lti/tool_consumer.rb +0 -86
  57. data/lib/ims/lti/tool_provider.rb +0 -143
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 224820ab40ce08a13bfda880f3107740a2b46cd31f672719b72d1d8e8cf3cc50
4
- data.tar.gz: b0c4c73930312bd6a27c7d6c8ea74b9dd33d83fd8cf8d240db14ea2b3e27e29f
2
+ SHA1:
3
+ metadata.gz: d9a9be3ac5b5acb2c58f5c961cb68be59accfa3f
4
+ data.tar.gz: d5dba5360e965a35e54fe010800735e4d087fe25
5
5
  SHA512:
6
- metadata.gz: 4d787b098d9fe7b9dba586cf77eff9d3a76cb31697685f29d5cd9f8add1d2950a8ac55385d1419a27559e688f1629f11ce33e394bb24191e447d6876a3b692fd
7
- data.tar.gz: 4f0b4d72b52cd2ad3b936da67d64709734194c6dd321f4883b91131a8625e33193b40ed804d3ea1d633bf254fb3c9656829d04450ad26ca250899dfaf43799de
6
+ metadata.gz: 9b45fee316f01a2681c78bc047d7710e3d7ad502afb170407a15e00e2f1f3305742e03024b92d9feca47b650bc93792d1b9ab26176fd92f3ea00137200961350
7
+ data.tar.gz: 947ca33099a7285791b82e5e0b9d1fa92202d1370a36a0fae5fb83f2d35fb84cbb790f40cff88fc57a18b1e2e0525018b5585e26995547ff7108ede73768acb7
File without changes
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Instructure
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,116 +1,28 @@
1
1
  # IMS LTI
2
2
 
3
- This ruby library is to help create Tool Providers and Tool Consumers for the
4
- [IMS LTI standard](http://www.imsglobal.org/lti/index.html).
3
+ #Version 2.x is currently BETA
5
4
 
6
- ## Installation
7
- This is packaged as the `ims-lti` rubygem, so you can just add the dependency to
8
- your Gemfile or install the gem on your system:
9
-
10
- gem install ims-lti
11
-
12
- To require the library in your project:
13
-
14
- require 'ims/lti'
15
-
16
- To validate the OAuth signatures you need to require the appropriate request
17
- proxy for your application. For example:
18
-
19
- # For a Rails 5 (and 2.3) app:
20
- require 'oauth/request_proxy/action_controller_request'
21
-
22
- # For a Sinatra or a Rails 3 or 4 app:
23
- require 'oauth/request_proxy/rack_request'
24
- # You also need to explicitly enable OAuth 1 support in the environment.rb or an initializer:
25
- OAUTH_10_SUPPORT = true
26
-
27
- For further information see the [oauth-ruby](https://github.com/oauth-xx/oauth-ruby) project.
28
-
29
- As a quick debugging note, if you forget that step, you'll get an error like:
30
-
31
- OAuth::RequestProxy::UnknownRequestType
5
+ LTI ruby implementation
32
6
 
33
- ## Usage
34
- This readme won't cover the LTI standard, just how to use the library. It will be
35
- very helpful to read the [LTI documentation](http://www.imsglobal.org/lti/index.html)
36
-
37
- In LTI there are Tool Providers (TP) and Tool Consumers (TC), this library is
38
- useful for implementing both. Here is an overview of the communication process:
39
- [LTI 1.1 Introduction](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560461)
40
-
41
- This library doesn't help you manage the consumer keys and secrets. The POST
42
- headers/parameters will contain the `oauth_consumer_key` and your app can use
43
- that to look up the appropriate `oauth_consumer_secret`.
44
-
45
- Your app will also need to manage the OAuth nonce to make sure the same nonce
46
- isn't used twice with the same timestamp. [Read the LTI documentation on OAuth](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560468).
47
-
48
- ### Tool Provider
49
- As a TP your app will receive a POST request with a bunch of
50
- [LTI launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465)
51
- and it will be signed with OAuth using a key/secret that both the TP and TC share.
52
- This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
53
-
54
- Here is an example of a simple TP Sinatra app using this gem:
55
- [LTI Tool Provider](https://github.com/instructure/lti1_tool_provider_example)
56
-
57
- Once you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in
58
- the request, you can initialize a `ToolProvider` object with them and the post parameters:
59
-
60
- ```ruby
61
- # Initialize TP object with OAuth creds and post parameters
62
- provider = IMS::LTI::ToolProvider.new(consumer_key, consumer_secret, params)
63
-
64
- # Verify OAuth signature by passing the request object
65
- if provider.valid_request?(request)
66
- # success
67
- else
68
- # handle invalid OAuth
69
- end
70
- ```
7
+ ## Installation
71
8
 
72
- Once your TP object is initialized and verified you can load your tool. All of the
73
- [launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465)
74
- is available in the TP object along with some convenience methods like `provider.username`
75
- which will try to find the name from the 3 potential name launch data attributes.
9
+ Add this line to your application's Gemfile:
76
10
 
77
- #### Returning Results of a Quiz/Assignment
78
- If your TP provides some kind of assessment service you can write grades back to
79
- the TC. This is documented in the LTI docs [here](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560471).
11
+ gem 'lti'
80
12
 
81
- You can check whether the TC is expecting a grade write-back:
13
+ And then execute:
82
14
 
83
- ```ruby
84
- if provider.outcome_service?
85
- # ready for grade write-back
86
- else
87
- # normal tool launch without grade write-back
88
- end
89
- ```
15
+ $ bundle
90
16
 
91
- To write the grade back to the TC your tool will do a POST directly back to the
92
- URL the TC passed in the launch data. You can use the TP object to do that for you:
17
+ Or install it yourself as:
93
18
 
94
- ```ruby
95
- # post the score to the TC, score should be a float >= 0.0 and <= 1.0
96
- # this returns an OutcomeResponse object
97
- response = provider.post_replace_result!(score)
98
- if response.success?
99
- # grade write worked
100
- elsif response.processing?
101
- elsif response.unsupported?
102
- else
103
- # failed
104
- end
105
- ```
19
+ $ gem install lti
106
20
 
107
- You can see the error code documentation
108
- [here](http://www.imsglobal.org/gws/gwsv1p0/imsgws_baseProfv1p0.html#1639667).
109
21
 
110
- ### Tool Consumer
111
- As a Tool Consumer your app will POST an OAuth-signed launch requests to TPs with the necessary
112
- [LTI launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465).
113
- This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
22
+ ## Contributing
114
23
 
115
- Here is an example of a simple TC Sinatra app using this gem:
116
- [LTI Tool Consumer](https://github.com/instructure/lti_tool_consumer_example)
24
+ 1. Fork it ( http://github.com/instructure/lti/fork )
25
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
26
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
27
+ 4. Push to the branch (`git push origin my-new-feature`)
28
+ 5. Create new Pull Request
data/lib/ims.rb CHANGED
@@ -1 +1,3 @@
1
- require 'ims/lti'
1
+ module IMS
2
+ require 'ims/lti'
3
+ end
@@ -1,69 +1,11 @@
1
- require 'oauth'
2
- require 'builder'
3
- require "rexml/document"
4
- require 'cgi'
1
+ require 'json'
5
2
  require 'securerandom'
3
+ require 'oauth'
6
4
 
7
- module IMS # :nodoc:
8
-
9
- # :main:IMS::LTI
10
- # LTI is a standard defined by IMS for creating eduction Tool Consumers/Providers.
11
- # LTI documentation: http://www.imsglobal.org/lti/index.html
12
- #
13
- # When creating these tools you will work primarily with the ToolProvider and
14
- # ToolConsumer classes.
15
- #
16
- # For validating OAuth request be sure to require the necessary proxy request
17
- # object. See IMS::LTI::RequestValidator#valid_request? for more documentation.
18
- #
19
- # == Installation
20
- # This is packaged as the `ims-lti` rubygem, so you can just add the dependency to
21
- # your Gemfile or install the gem on your system:
22
- #
23
- # gem install ims-lti
24
- #
25
- # To require the library in your project:
26
- #
27
- # require 'ims/lti'
5
+ module IMS
28
6
  module LTI
29
-
30
- # The versions of LTI this library supports
31
- VERSIONS = %w{1.0 1.1}
32
-
33
- class InvalidLTIConfigError < StandardError
34
- end
35
-
36
- class XMLParseError < StandardError
37
- end
38
-
39
- # POST a signed oauth request with the given key/secret/data
40
- def self.post_service_request(key, secret, url, content_type, body)
41
- raise IMS::LTI::InvalidLTIConfigError, "" unless key && secret
42
-
43
- consumer = OAuth::Consumer.new(key, secret)
44
- token = OAuth::AccessToken.new(consumer)
45
- token.post(
46
- url,
47
- body,
48
- 'Content-Type' => content_type
49
- )
50
- end
51
-
52
- # Generates a unique identifier
53
- def self.generate_identifier
54
- SecureRandom.uuid
55
- end
7
+ require_relative 'lti/models'
8
+ require_relative 'lti/converters'
9
+ require_relative 'lti/services'
56
10
  end
57
11
  end
58
-
59
- require 'ims/lti/extensions'
60
- require 'ims/lti/launch_params'
61
- require 'ims/lti/request_validator'
62
- require 'ims/lti/tool_base'
63
- require 'ims/lti/deprecated_role_checks'
64
- require 'ims/lti/role_checks'
65
- require 'ims/lti/tool_provider'
66
- require 'ims/lti/tool_consumer'
67
- require 'ims/lti/outcome_request'
68
- require 'ims/lti/outcome_response'
69
- require 'ims/lti/tool_config'
@@ -0,0 +1,5 @@
1
+ module IMS::LTI
2
+ module Converters
3
+ require_relative 'converters/time_json_converter'
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module IMS::LTI::Converters
2
+ class TimeJSONConverter
3
+
4
+ def self.to_json_value(time)
5
+ time
6
+ end
7
+
8
+ def self.from_json_value(json_val)
9
+ Time.parse(json_val)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ module IMS::LTI
2
+ module Models
3
+ require_relative 'models/lti_model'
4
+ require_relative 'models/contact'
5
+ require_relative 'models/localized_name'
6
+ require_relative 'models/localized_text'
7
+ require_relative 'models/product_family'
8
+ require_relative 'models/product_info'
9
+ require_relative 'models/product_instance'
10
+ require_relative 'models/rest_service'
11
+ require_relative 'models/service_owner'
12
+ require_relative 'models/service_provider'
13
+ require_relative 'models/tool_consumer_profile'
14
+ require_relative 'models/vendor'
15
+ require_relative 'models/messages'
16
+ require_relative 'models/tool_proxy'
17
+ require_relative 'models/tool_profile'
18
+ require_relative 'models/resource_handler'
19
+ require_relative 'models/resource_type'
20
+ require_relative 'models/message_handler'
21
+ require_relative 'models/parameter'
22
+ require_relative 'models/icon_info'
23
+ require_relative 'models/icon_endpoint'
24
+ require_relative 'models/security_contract'
25
+ require_relative 'models/rest_service_profile'
26
+ require_relative 'models/base_url_choice'
27
+ require_relative 'models/base_url_selector'
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module IMS::LTI::Models
2
+ class BaseUrlChoice < LTIModel
3
+ add_attributes :default_base_url, :secure_base_url
4
+ add_attribute :selector, relation:'IMS::LTI::Models::BaseUrlSelector'
5
+
6
+ def default_message_url
7
+ if selector && selector.applies_to && selector.applies_to.include?('MessageHandler')
8
+ secure_base_url || default_base_url
9
+ else
10
+ ''
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class BaseUrlSelector < LTIModel
3
+ add_attribute :applies_to
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class Contact < LTIModel
3
+ add_attributes :email
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module IMS::LTI::Models
2
+ class IconEndpoint < LTIModel
3
+ add_attribute :path
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module IMS::LTI::Models
2
+ class IconInfo < LTIModel
3
+ add_attributes :key, :icon_style
4
+ add_attribute :default_location, relation: 'IMS::LTI::Models::IconEndpoint'
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module IMS::LTI::Models
2
+ class LocalizedName < LTIModel
3
+ add_attributes :default_value, :key
4
+
5
+ def initialize(default_value = nil, key = nil)
6
+ @default_value = default_value
7
+ @key = key
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module IMS::LTI::Models
2
+ class LocalizedText < LTIModel
3
+ add_attributes :default_value, :key
4
+
5
+ def initialize(default_value = nil, key = nil)
6
+ @default_value = default_value
7
+ @key = key
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,169 @@
1
+ module IMS::LTI::Models
2
+ class LTIModel
3
+ LTI_VERSION_2P0 = 'LTI-2p0'
4
+
5
+ def initialize(attributes = {})
6
+ self.attributes = attributes
7
+ end
8
+
9
+ def self.add_attributes(attribute, *attrs)
10
+ attrs.unshift(attribute)
11
+ self.attributes += attrs
12
+ attr_accessor(attrs.shift, *attrs)
13
+ end
14
+
15
+ def self.add_attribute(attribute, options = {})
16
+ @serialization_options ||= {}
17
+ options.each do |k, v|
18
+ @serialization_options[k] ||= {}
19
+ @serialization_options[k][attribute] = v
20
+ end
21
+ self.attributes += [attribute]
22
+ attr_accessor(attribute)
23
+ end
24
+
25
+ def self.inherit_attributes(attrs)
26
+ attributes ||= []
27
+ self.attributes += attrs
28
+ end
29
+
30
+ def self.inherited(subclass)
31
+ subclass.inherit_attributes(self.attributes)
32
+ end
33
+
34
+ def attributes
35
+ attrs = {}
36
+ self.class.attributes.each do |a|
37
+ value = instance_variable_get("@#{a.to_s}")
38
+ attrs[a.to_s] = value unless value == nil
39
+ end
40
+ attrs
41
+ end
42
+
43
+ def attributes=(attrs)
44
+ attrs.each do |k, v|
45
+ instance_variable_set("@#{k.to_s}", v)
46
+ end
47
+ end
48
+
49
+ def as_json(options = {})
50
+ json_hash = attributes
51
+ serialization_attrs_for(:json_key).each { |attr| json_hash.delete(attr.to_s) }
52
+ serialization_attrs_for(:relation).each do |attr|
53
+ val = attributes[attr.to_s]
54
+ json_hash[json_key(attr)] = val.as_json if val
55
+ end
56
+ json_hash.merge! to_json_conversions
57
+ json_hash.merge! to_json_keys
58
+ json_hash
59
+ end
60
+
61
+ def to_json
62
+ self.as_json.to_json
63
+ end
64
+
65
+ def from_json(json)
66
+ data = JSON.parse(json)
67
+ if data.is_a? Array
68
+ data.map { |hash| self.class.new.from_json(hash.to_json) }
69
+ else
70
+ process_json_hash(data)
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def process_json_hash(hash)
77
+ change_json_keys_to_attrs!(hash)
78
+ hash.merge! from_json_conversions(hash)
79
+ deserialize_json_relations!(hash)
80
+ self.attributes=(hash)
81
+ self
82
+ end
83
+
84
+ def serialization_attrs_for(*keys)
85
+ Array.new(serialization_options.keys & keys).map { |opt| serialization_options[opt].keys }.flatten.uniq
86
+ end
87
+
88
+ def to_json_conversions
89
+ result = {}
90
+ if converters = serialization_options[:json_converter]
91
+ converters.each do |attr, converter|
92
+ value = attributes[attr.to_s]
93
+ result[json_key(attr)] = get_constant(converter).to_json_value(value) if value
94
+ end
95
+ end
96
+ result
97
+ end
98
+
99
+ def to_json_keys
100
+ result = {}
101
+ if attrs = serialization_attrs_for(:json_key)
102
+ conversion_attrs = serialization_attrs_for(:json_converter)
103
+ attrs.each { |attr| result[json_key(attr)] = attributes[attr.to_s] unless conversion_attrs.include?(attr) || attributes[attr.to_s].nil? }
104
+ end
105
+ result
106
+ end
107
+
108
+ def change_json_keys_to_attrs!(json_hash)
109
+ if attrs = serialization_attrs_for(:json_key)
110
+ attrs.each do |attr|
111
+ key = json_key(attr)
112
+ json_hash[attr.to_s] = json_hash.delete(key) if json_hash.has_key?(key)
113
+ end
114
+ end
115
+ end
116
+
117
+ def from_json_conversions(hash)
118
+ result = {}
119
+ if converters = serialization_options[:json_converter]
120
+ converters.each do |attr, converter|
121
+ result[attr] = get_constant(converter).from_json_value(hash[attr.to_s]) if hash[attr.to_s]
122
+ end
123
+ end
124
+ result
125
+ end
126
+
127
+ def deserialize_json_relations!(hash)
128
+ if relations = serialization_options[:relation]
129
+ attrs = {}
130
+ relations.each do |attr, relation|
131
+ hash_val = hash.delete(attr.to_s)
132
+ attrs[attr.to_s] = get_constant(relation).new.from_json(hash_val.to_json) if hash_val
133
+ end
134
+ self.attributes = attrs
135
+ end
136
+ end
137
+
138
+ def json_key(attr)
139
+ if json_keys = serialization_options[:json_key]
140
+ json_keys[attr] || attr
141
+ else
142
+ attr
143
+ end.to_s
144
+ end
145
+
146
+ def self.attributes
147
+ @attributes || []
148
+ end
149
+
150
+ def self.attributes=(attribs)
151
+ @attributes = attribs
152
+ end
153
+
154
+ def self.serialization_options
155
+ @serialization_options ||= {}
156
+ end
157
+
158
+ def serialization_options
159
+ self.class.serialization_options
160
+ end
161
+
162
+ def get_constant(constant)
163
+ obj = Object
164
+ constant.split('::').each { |c| obj = obj.const_get(c) }
165
+ obj
166
+ end
167
+
168
+ end
169
+ end