aspace_client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/aspace_client.rb +15 -0
- data/lib/aspace_client/archivesspace_json_schema.rb +210 -0
- data/lib/aspace_client/asutils.rb +142 -0
- data/lib/aspace_client/client_enum_source.rb +30 -0
- data/lib/aspace_client/exceptions.rb +15 -0
- data/lib/aspace_client/helpers.rb +0 -0
- data/lib/aspace_client/json_schema_concurrency_fix.rb +52 -0
- data/lib/aspace_client/json_schema_utils.rb +414 -0
- data/lib/aspace_client/jsonmodel.rb +342 -0
- data/lib/aspace_client/jsonmodel_client.rb +528 -0
- data/lib/aspace_client/jsonmodel_i18n_mixin.rb +77 -0
- data/lib/aspace_client/jsonmodel_type.rb +478 -0
- data/lib/aspace_client/memoryleak.rb +59 -0
- data/lib/aspace_client/schemas/abstract_agent.rb +51 -0
- data/lib/aspace_client/schemas/abstract_agent_relationship.rb +12 -0
- data/lib/aspace_client/schemas/abstract_archival_object.rb +96 -0
- data/lib/aspace_client/schemas/abstract_classification.rb +44 -0
- data/lib/aspace_client/schemas/abstract_name.rb +23 -0
- data/lib/aspace_client/schemas/abstract_note.rb +13 -0
- data/lib/aspace_client/schemas/accession.rb +174 -0
- data/lib/aspace_client/schemas/accession_parts_relationship.rb +31 -0
- data/lib/aspace_client/schemas/accession_sibling_relationship.rb +31 -0
- data/lib/aspace_client/schemas/active_edits.rb +23 -0
- data/lib/aspace_client/schemas/advanced_query.rb +12 -0
- data/lib/aspace_client/schemas/agent_contact.rb +25 -0
- data/lib/aspace_client/schemas/agent_corporate_entity.rb +32 -0
- data/lib/aspace_client/schemas/agent_family.rb +29 -0
- data/lib/aspace_client/schemas/agent_person.rb +31 -0
- data/lib/aspace_client/schemas/agent_relationship_associative.rb +28 -0
- data/lib/aspace_client/schemas/agent_relationship_earlierlater.rb +28 -0
- data/lib/aspace_client/schemas/agent_relationship_parentchild.rb +26 -0
- data/lib/aspace_client/schemas/agent_relationship_subordinatesuperior.rb +26 -0
- data/lib/aspace_client/schemas/agent_software.rb +22 -0
- data/lib/aspace_client/schemas/archival_object.rb +60 -0
- data/lib/aspace_client/schemas/archival_record_children.rb +15 -0
- data/lib/aspace_client/schemas/boolean_field_query.rb +13 -0
- data/lib/aspace_client/schemas/boolean_query.rb +13 -0
- data/lib/aspace_client/schemas/classification.rb +10 -0
- data/lib/aspace_client/schemas/classification_term.rb +38 -0
- data/lib/aspace_client/schemas/classification_tree.rb +17 -0
- data/lib/aspace_client/schemas/collection_management.rb +27 -0
- data/lib/aspace_client/schemas/container.rb +29 -0
- data/lib/aspace_client/schemas/container_location.rb +19 -0
- data/lib/aspace_client/schemas/date.rb +19 -0
- data/lib/aspace_client/schemas/date_field_query.rb +14 -0
- data/lib/aspace_client/schemas/deaccession.rb +20 -0
- data/lib/aspace_client/schemas/defaults.rb +104 -0
- data/lib/aspace_client/schemas/digital_object.rb +64 -0
- data/lib/aspace_client/schemas/digital_object_component.rb +53 -0
- data/lib/aspace_client/schemas/digital_object_tree.rb +19 -0
- data/lib/aspace_client/schemas/digital_record_children.rb +15 -0
- data/lib/aspace_client/schemas/enumeration.rb +29 -0
- data/lib/aspace_client/schemas/enumeration_migration.rb +14 -0
- data/lib/aspace_client/schemas/event.rb +88 -0
- data/lib/aspace_client/schemas/extent.rb +17 -0
- data/lib/aspace_client/schemas/external_document.rb +12 -0
- data/lib/aspace_client/schemas/external_id.rb +11 -0
- data/lib/aspace_client/schemas/field_query.rb +15 -0
- data/lib/aspace_client/schemas/file_version.rb +26 -0
- data/lib/aspace_client/schemas/group.rb +17 -0
- data/lib/aspace_client/schemas/instance.rb +27 -0
- data/lib/aspace_client/schemas/job.rb +57 -0
- data/lib/aspace_client/schemas/location.rb +36 -0
- data/lib/aspace_client/schemas/location_batch.rb +45 -0
- data/lib/aspace_client/schemas/merge_request.rb +48 -0
- data/lib/aspace_client/schemas/name_corporate_entity.rb +15 -0
- data/lib/aspace_client/schemas/name_family.rb +13 -0
- data/lib/aspace_client/schemas/name_form.rb +15 -0
- data/lib/aspace_client/schemas/name_person.rb +19 -0
- data/lib/aspace_client/schemas/name_software.rb +14 -0
- data/lib/aspace_client/schemas/note_abstract.rb +17 -0
- data/lib/aspace_client/schemas/note_bibliography.rb +29 -0
- data/lib/aspace_client/schemas/note_bioghist.rb +22 -0
- data/lib/aspace_client/schemas/note_chronology.rb +28 -0
- data/lib/aspace_client/schemas/note_citation.rb +32 -0
- data/lib/aspace_client/schemas/note_definedlist.rb +25 -0
- data/lib/aspace_client/schemas/note_digital_object.rb +23 -0
- data/lib/aspace_client/schemas/note_index.rb +29 -0
- data/lib/aspace_client/schemas/note_index_item.rb +25 -0
- data/lib/aspace_client/schemas/note_multipart.rb +25 -0
- data/lib/aspace_client/schemas/note_orderedlist.rb +27 -0
- data/lib/aspace_client/schemas/note_outline.rb +20 -0
- data/lib/aspace_client/schemas/note_outline_level.rb +21 -0
- data/lib/aspace_client/schemas/note_singlepart.rb +24 -0
- data/lib/aspace_client/schemas/note_text.rb +17 -0
- data/lib/aspace_client/schemas/permission.rb +15 -0
- data/lib/aspace_client/schemas/preference.rb +16 -0
- data/lib/aspace_client/schemas/record_tree.rb +17 -0
- data/lib/aspace_client/schemas/repository.rb +32 -0
- data/lib/aspace_client/schemas/repository_with_agent.rb +14 -0
- data/lib/aspace_client/schemas/resource.rb +112 -0
- data/lib/aspace_client/schemas/resource_tree.rb +20 -0
- data/lib/aspace_client/schemas/rights_statement.rb +35 -0
- data/lib/aspace_client/schemas/subject.rb +30 -0
- data/lib/aspace_client/schemas/term.rb +16 -0
- data/lib/aspace_client/schemas/user.rb +56 -0
- data/lib/aspace_client/schemas/user_defined.rb +42 -0
- data/lib/aspace_client/schemas/vocabulary.rb +15 -0
- data/lib/aspace_client/validations.rb +434 -0
- data/lib/aspace_client/validator_cache.rb +47 -0
- data/lib/aspace_client/version.rb +3 -0
- metadata +244 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ac953db47d3758e451a44a90dbdf570bad1c6d48
|
4
|
+
data.tar.gz: ee196ef429407e4f59cea5190865fd08a70b9c44
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 191e45a120e291974d55e0000073acfd460e6162847d3c891c7b9422e98532b5ad8f8f7861410d4906191bb4d37fbbfe4833c05c5c45328f957152e8880cc1ec
|
7
|
+
data.tar.gz: 34076a7f7f5fb3d8c8d64ac578c66bde17f1c5887da65462af9b76855c94c5ed70bafcf145c4c7b58db9bd121d9fa6ed0015039cf8000705e00b7c5343a8426c
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$: << "#{File.dirname(__FILE__)}" unless $:.include? File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "aspace_client/jsonmodel"
|
4
|
+
require "aspace_client/asutils"
|
5
|
+
require "aspace_client/memoryleak"
|
6
|
+
require "aspace_client/client_enum_source"
|
7
|
+
require "aspace_client/jsonmodel_i18n_mixin"
|
8
|
+
require 'aspace_client/jsonmodel_client'
|
9
|
+
require 'aspace_client/archivesspace_json_schema.rb'
|
10
|
+
|
11
|
+
include JSONModel
|
12
|
+
|
13
|
+
module AspaceClient
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
# Add a new 'ifmissing' attribute which emits either an error or warning
|
4
|
+
# depending on its value.
|
5
|
+
class IfMissingAttribute < JSON::Schema::PropertiesAttribute
|
6
|
+
|
7
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
8
|
+
super
|
9
|
+
|
10
|
+
if data.is_a?(Hash)
|
11
|
+
current_schema.schema['properties'].each do |property, property_schema|
|
12
|
+
if (property_schema['ifmissing'] && !data.has_key?(property))
|
13
|
+
message = nil
|
14
|
+
|
15
|
+
if property_schema['ifmissing'] == 'error'
|
16
|
+
message = "ERROR: The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
|
17
|
+
elsif property_schema['ifmissing'] == 'warn'
|
18
|
+
message = "WARNING: The property '#{build_fragment(fragments)}' did not contain a required property of '#{property}'"
|
19
|
+
end
|
20
|
+
|
21
|
+
if message
|
22
|
+
validation_error(message, fragments, current_schema, self, options[:record_errors])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
class ArchivesSpaceTypeAttribute < JSON::Schema::TypeAttribute
|
33
|
+
extend JSONModel
|
34
|
+
|
35
|
+
|
36
|
+
# This reuse business is a bit of a pain. The story here: JRuby backtraces
|
37
|
+
# are relatively expensive to create (relative to MRI Ruby), and JSON Schema
|
38
|
+
# validation is using exceptions as control flow here (sigh). During imports,
|
39
|
+
# these validation error are hit a *lot*, and calculating a backtrace every
|
40
|
+
# time is expensive.
|
41
|
+
#
|
42
|
+
# So, we recycle.
|
43
|
+
def self.validation_error_for(expected_type, fragments, current_schema)
|
44
|
+
Thread.current[:json_validation_cached_errors] ||= {}
|
45
|
+
if !Thread.current[:json_validation_cached_errors][expected_type]
|
46
|
+
msg = "ERROR: Schema type mismatch. Expected type: #{expected_type}"
|
47
|
+
Thread.current[:json_validation_cached_errors][expected_type] = JSON::Schema::ValidationError.new(msg, fragments, self, current_schema)
|
48
|
+
end
|
49
|
+
|
50
|
+
Thread.current[:json_validation_cached_errors][expected_type].fragments = fragments
|
51
|
+
Thread.current[:json_validation_cached_errors][expected_type]
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
56
|
+
types = current_schema.schema['type']
|
57
|
+
|
58
|
+
if types == 'date'
|
59
|
+
begin
|
60
|
+
Date.parse(data)
|
61
|
+
return
|
62
|
+
rescue
|
63
|
+
validation_error("The property '#{build_fragment(fragments)}' was not " +
|
64
|
+
"a well-formed date (value: #{data})",
|
65
|
+
fragments, current_schema, self, options[:record_errors])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
if types == 'object' && data.is_a?(Hash) && data.has_key?('ref') && current_schema.schema['subtype'] != 'ref'
|
71
|
+
# Provide a helpful warning about potentially missing subtype definitions
|
72
|
+
$stderr.puts("WARNING: Schema #{current_schema.inspect} appears to be missing a subtype definition of 'ref'")
|
73
|
+
end
|
74
|
+
|
75
|
+
# A bit crazy, sorry. If we're being asked to validate a hash whose
|
76
|
+
# jsonmodel_type is marked against a different JSONModel schema, we're
|
77
|
+
# wasting our time. Just stop straight away.
|
78
|
+
if (data.is_a?(Hash) && data["jsonmodel_type"]) &&
|
79
|
+
(current_schema.schema.is_a?(Hash) &&
|
80
|
+
"#{current_schema.schema["type"]}".include?("JSONModel") &&
|
81
|
+
!"#{current_schema.schema["type"]}".include?("JSONModel(:#{data['jsonmodel_type']})"))
|
82
|
+
|
83
|
+
raise validation_error_for(data['jsonmodel_type'], fragments, current_schema)
|
84
|
+
end
|
85
|
+
|
86
|
+
if JSONModel.parse_jsonmodel_ref(types)
|
87
|
+
(model, qualifier) = JSONModel.parse_jsonmodel_ref(types)
|
88
|
+
|
89
|
+
if qualifier == 'uri' || (qualifier == 'uri_or_object' && data.is_a?(String))
|
90
|
+
if JSONModel(model).id_for(data, {}, true).nil?
|
91
|
+
validation_error("The property '#{build_fragment(fragments)}' of type " +
|
92
|
+
"#{data.class} did not match the following type: #{types} in schema",
|
93
|
+
fragments, current_schema, self, options[:record_errors])
|
94
|
+
end
|
95
|
+
|
96
|
+
elsif qualifier == 'uri_or_object' || qualifier == 'object'
|
97
|
+
if data.is_a?(Hash)
|
98
|
+
data["jsonmodel_type"] ||= model.to_s
|
99
|
+
|
100
|
+
ValidatorCache.with_validator_for(JSONModel(model), data) do |subvalidator|
|
101
|
+
# Urk. Validate the subrecord but pass in the fragments of the point
|
102
|
+
# we're at in the parent record.
|
103
|
+
subvalidator.instance_eval do
|
104
|
+
@base_schema.validate(@data, fragments, @validation_options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
else
|
109
|
+
validation_error("The property '#{build_fragment(fragments)}' of type " +
|
110
|
+
"#{data.class} did not match the following type: #{types} in schema",
|
111
|
+
fragments, current_schema, self, options[:record_errors])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
else
|
115
|
+
super
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
class ArchivesSpaceSubTypeAttribute < JSON::Schema::TypeAttribute
|
122
|
+
|
123
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
124
|
+
if data.is_a?(Hash) && !data.has_key?('ref')
|
125
|
+
message = "ERROR: The property '#{build_fragment(fragments)}' did not contain a required property of 'ref'"
|
126
|
+
validation_error(message, fragments, current_schema, self, options[:record_errors])
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
class ArchivesSpaceReadOnlyDynamicEnumAttribute < JSON::Schema::TypeAttribute; end
|
133
|
+
|
134
|
+
class ArchivesSpaceDynamicEnumAttribute < JSON::Schema::TypeAttribute
|
135
|
+
|
136
|
+
def self.validate(current_schema, data, fragments, validator, options = {})
|
137
|
+
enum_name = current_schema.schema['dynamic_enum']
|
138
|
+
|
139
|
+
if !JSONModel.init_args[:enum_source].valid?(enum_name, data)
|
140
|
+
possible_values = JSONModel.init_args[:enum_source].values_for(enum_name)
|
141
|
+
message = ("The property '#{build_fragment(fragments)}' value #{data.inspect} " +
|
142
|
+
"did not match one of the following configurable values: #{possible_values.join(', ')}")
|
143
|
+
|
144
|
+
if JSONModel.init_args[:enum_source].editable?(enum_name)
|
145
|
+
klass = self
|
146
|
+
else
|
147
|
+
klass = ArchivesSpaceReadOnlyDynamicEnumAttribute
|
148
|
+
end
|
149
|
+
|
150
|
+
validation_error(message, fragments, current_schema, klass, options[:record_errors])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
class ArchivesSpaceSchema < JSON::Schema::Validator
|
158
|
+
def initialize
|
159
|
+
super
|
160
|
+
extend_schema_definition("http://json-schema.org/draft-03/schema#")
|
161
|
+
@attributes["type"] = ArchivesSpaceTypeAttribute
|
162
|
+
@attributes["subtype"] = ArchivesSpaceSubTypeAttribute
|
163
|
+
@attributes["dynamic_enum"] = ArchivesSpaceDynamicEnumAttribute
|
164
|
+
@attributes["properties"] = IfMissingAttribute
|
165
|
+
@uri = URI.parse("http://www.archivesspace.org/archivesspace.json")
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
def already_failed?(fragments)
|
170
|
+
JSON::Validator.validation_errors.any? {|error|
|
171
|
+
error.fragments == fragments
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
def validate(current_schema, data, fragments, options = {})
|
177
|
+
super
|
178
|
+
|
179
|
+
# Run any custom validations if we've made it this far with no errors
|
180
|
+
if !already_failed?(fragments) && current_schema.schema.has_key?("validations")
|
181
|
+
current_schema.schema["validations"].each do |level_and_name|
|
182
|
+
level, name = level_and_name
|
183
|
+
|
184
|
+
errors = JSONModel::custom_validations[name].call(data)
|
185
|
+
|
186
|
+
errors.each do |error|
|
187
|
+
error_string = nil
|
188
|
+
|
189
|
+
if error.is_a? Symbol
|
190
|
+
error_string = "Validation error code: #{error}"
|
191
|
+
else
|
192
|
+
field, msg = error
|
193
|
+
prefix = level == :warning ? "Warning generated for" : "Validation failed for"
|
194
|
+
error_string = "#{prefix} '#{field}': #{msg}"
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
err = JSON::Schema::ValidationError.new(error_string,
|
199
|
+
fragments,
|
200
|
+
"custom_validation",
|
201
|
+
current_schema)
|
202
|
+
|
203
|
+
JSON::Validator.validation_error(err)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
JSON::Validator.register_validator(self.new)
|
210
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module ASUtils
|
6
|
+
|
7
|
+
def self.keys_as_strings(hash)
|
8
|
+
result = {}
|
9
|
+
|
10
|
+
hash.each do |key, value|
|
11
|
+
result[key.to_s] = value.is_a?(Date) ? value.to_s : value
|
12
|
+
end
|
13
|
+
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def self.as_array(thing)
|
19
|
+
return [] if thing.nil?
|
20
|
+
thing.kind_of?(Array) ? thing : [thing]
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def self.jsonmodels_to_hashes(elt)
|
25
|
+
|
26
|
+
if elt.is_a?(JSONModelType)
|
27
|
+
elt = elt.to_hash(:raw)
|
28
|
+
end
|
29
|
+
|
30
|
+
if elt.is_a?(Hash)
|
31
|
+
Hash[elt.map {|k, v| [k, self.jsonmodels_to_hashes(v)]}]
|
32
|
+
elsif elt.is_a?(Array)
|
33
|
+
elt.map {|v| self.jsonmodels_to_hashes(v)}
|
34
|
+
else
|
35
|
+
elt
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def self.json_parse(s)
|
41
|
+
JSON.parse(s, :max_nesting => false, :create_additions => false)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
def self.to_json(obj, opts = {})
|
47
|
+
if obj.respond_to?(:jsonize)
|
48
|
+
obj.jsonize(opts.merge(:max_nesting => false))
|
49
|
+
else
|
50
|
+
obj.to_json(opts.merge(:max_nesting => false))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def self.find_base_directory(root = nil)
|
56
|
+
[ File.join(*[File.dirname(__FILE__), "..", root].compact)].find {|dir|
|
57
|
+
Dir.exists?(dir)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def self.find_local_directories(base = nil, *plugins)
|
63
|
+
base_directory = self.find_base_directory
|
64
|
+
Array(plugins).map { |plugin| File.join(*[base_directory, "plugins", plugin, base].compact) }
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def self.find_locales_directories(base = nil)
|
69
|
+
[File.join(*[self.find_base_directory("common"), "locales", base].compact)]
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def self.extract_nested_strings(coll)
|
74
|
+
if coll.is_a?(Hash)
|
75
|
+
coll.values.map {|v| self.extract_nested_strings(v)}.flatten.compact
|
76
|
+
elsif coll.is_a?(Array)
|
77
|
+
coll.map {|v| self.extract_nested_strings(v)}.flatten.compact
|
78
|
+
else
|
79
|
+
coll
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.dump_diagnostics(exception = nil)
|
84
|
+
diagnostics = self.get_diagnostics( exception )
|
85
|
+
tmp = File.join(Dir.tmpdir, "aspaue_diagnostic_#{Time.now.to_i}.txt")
|
86
|
+
File.open(tmp, "w") do |fh|
|
87
|
+
fh.write(JSON.pretty_generate(diagnostics))
|
88
|
+
end
|
89
|
+
|
90
|
+
msg = <<EOF
|
91
|
+
A trace file has been written to the following location: #{tmp}
|
92
|
+
|
93
|
+
This file contains information that will assist developers in diagnosing
|
94
|
+
problems with your ArchivesSpace installation. Please review the file's
|
95
|
+
contents for sensitive information (such as passwords) that you might not
|
96
|
+
want to share.
|
97
|
+
EOF
|
98
|
+
|
99
|
+
$stderr.puts("=" * 72)
|
100
|
+
$stderr.puts(msg)
|
101
|
+
$stderr.puts("=" * 72)
|
102
|
+
|
103
|
+
raise exception if exception
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Recursively overlays hash2 onto hash 1
|
108
|
+
def self.deep_merge(hash1, hash2)
|
109
|
+
target = hash1.dup
|
110
|
+
hash2.keys.each do |key|
|
111
|
+
if hash2[key].is_a? Hash and hash1[key].is_a? Hash
|
112
|
+
target[key] = self.deep_merge(target[key], hash2[key])
|
113
|
+
next
|
114
|
+
end
|
115
|
+
target[key] = hash2[key]
|
116
|
+
end
|
117
|
+
target
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def self.load_plugin_gems(context)
|
122
|
+
ASUtils.find_local_directories.each do |plugin|
|
123
|
+
gemfile = File.join(plugin, 'Gemfile')
|
124
|
+
if File.exists?(gemfile)
|
125
|
+
context.instance_eval(File.read(gemfile))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
# Borrowed from: file activesupport/lib/active_support/core_ext/array/wrap.rb, line 36
|
132
|
+
def self.wrap(object)
|
133
|
+
if object.nil?
|
134
|
+
[]
|
135
|
+
elsif object.respond_to?(:to_ary)
|
136
|
+
object.to_ary || [object]
|
137
|
+
else
|
138
|
+
[object]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "aspace_client/jsonmodel"
|
2
|
+
require "aspace_client/memoryleak"
|
3
|
+
|
4
|
+
class ClientEnumSource
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
MemoryLeak::Resources.define(:enumerations, proc {
|
8
|
+
JSONModel::Client::EnumSource.fetch_enumerations
|
9
|
+
}, 300)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def valid?(name, value)
|
14
|
+
values_for(name).include?(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def editable?(name)
|
18
|
+
MemoryLeak::Resources.get(:enumerations).fetch(name).editable?
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def values_for(name)
|
23
|
+
MemoryLeak::Resources.get(:enumerations).fetch(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_value_for(name)
|
27
|
+
MemoryLeak::Resources.get(:enumerations)[:defaults].fetch(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
File without changes
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Monkey patch against json-schema 1.0.12 to work around
|
2
|
+
# https://github.com/hoxworth/json-schema/issues/24
|
3
|
+
|
4
|
+
|
5
|
+
module JSON
|
6
|
+
class Validator
|
7
|
+
|
8
|
+
# Run a simple true/false validation of data against a schema
|
9
|
+
def validate()
|
10
|
+
begin
|
11
|
+
Validator.clear_errors
|
12
|
+
@base_schema.validate(@data,[],@validation_options)
|
13
|
+
Validator.clear_cache
|
14
|
+
if @options[:errors_as_objects]
|
15
|
+
self.class.validation_errors.map{|e| e.to_hash}
|
16
|
+
else
|
17
|
+
self.class.validation_errors.map{|e| e.to_string}
|
18
|
+
end
|
19
|
+
rescue JSON::Schema::ValidationError
|
20
|
+
Validator.clear_cache
|
21
|
+
raise $!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def clear_errors
|
27
|
+
Thread.current[:jsonschema_errors] = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def validation_error(error)
|
31
|
+
Thread.current[:jsonschema_errors] << error
|
32
|
+
end
|
33
|
+
|
34
|
+
def validation_errors
|
35
|
+
Thread.current[:jsonschema_errors] or []
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# Plus one bonus: don't use MultiJson here.
|
41
|
+
def serialize schema
|
42
|
+
# if defined?(MultiJson)
|
43
|
+
# MultiJson.respond_to?(:dump) ? MultiJson.dump(schema) : MultiJson.encode(schema)
|
44
|
+
# else
|
45
|
+
# @@serializer.call(schema)
|
46
|
+
# end
|
47
|
+
|
48
|
+
ASUtils.to_json(schema)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|