hydramata-works 0.0.1.prerelease
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.hound.yml +818 -0
- data/.rspec +2 -0
- data/.travis.yml +20 -0
- data/CONTRIBUTING.md +220 -0
- data/Gemfile +36 -0
- data/Guardfile +36 -0
- data/LICENSE +15 -0
- data/README.md +36 -0
- data/Rakefile +47 -0
- data/TODO.md +74 -0
- data/VISION.md +19 -0
- data/app/forms/hydramata/works/entity_form.rb +92 -0
- data/app/forms/hydramata/works/validation_service.rb +78 -0
- data/app/models/hydramata/works/data_definition.rb +57 -0
- data/app/models/hydramata/works/entities.rb +11 -0
- data/app/models/hydramata/works/entity.rb +75 -0
- data/app/models/hydramata/works/predicate.rb +35 -0
- data/app/models/hydramata/works/predicate_presentation_sequences/storage.rb +29 -0
- data/app/models/hydramata/works/predicate_set.rb +44 -0
- data/app/models/hydramata/works/predicate_sets/storage.rb +45 -0
- data/app/models/hydramata/works/predicates.rb +14 -0
- data/app/models/hydramata/works/predicates/storage.rb +33 -0
- data/app/models/hydramata/works/presentation_structure.rb +29 -0
- data/app/models/hydramata/works/property.rb +72 -0
- data/app/models/hydramata/works/property_set.rb +89 -0
- data/app/models/hydramata/works/validations.rb +6 -0
- data/app/models/hydramata/works/value.rb +34 -0
- data/app/models/hydramata/works/work_type.rb +49 -0
- data/app/models/hydramata/works/work_types.rb +14 -0
- data/app/models/hydramata/works/work_types/storage.rb +42 -0
- data/app/parsers/hydramata/works/datastream_parser.rb +36 -0
- data/app/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser.rb +60 -0
- data/app/parsers/hydramata/works/datastream_parsers/simple_xml_parser.rb +27 -0
- data/app/parsers/hydramata/works/predicate_parser.rb +31 -0
- data/app/parsers/hydramata/works/predicate_parsers/simple_parser.rb +13 -0
- data/app/parsers/hydramata/works/validations_parser.rb +22 -0
- data/app/parsers/hydramata/works/value_parser.rb +26 -0
- data/app/parsers/hydramata/works/value_parsers.rb +27 -0
- data/app/parsers/hydramata/works/value_parsers/date_parser.rb +13 -0
- data/app/parsers/hydramata/works/value_parsers/interrogation_parser.rb +18 -0
- data/app/parsers/hydramata/works/value_parsers/simple_parser.rb +14 -0
- data/app/presenters/hydramata/works/base_presenter.rb +146 -0
- data/app/presenters/hydramata/works/dom_attributes_builder.rb +24 -0
- data/app/presenters/hydramata/works/entity_presenter.rb +67 -0
- data/app/presenters/hydramata/works/fieldset_presenter.rb +54 -0
- data/app/presenters/hydramata/works/property_presenter.rb +51 -0
- data/app/presenters/hydramata/works/value_presenter.rb +60 -0
- data/app/renderers/hydramata/works/entity_renderer.rb +45 -0
- data/app/views/hydramata/works/fieldsets/_edit.html.erb +4 -0
- data/app/views/hydramata/works/fieldsets/_show.html.erb +8 -0
- data/app/views/hydramata/works/fieldsets/_show.json.jbuilder +8 -0
- data/app/views/hydramata/works/properties/_edit.html.erb +12 -0
- data/app/views/hydramata/works/properties/_show.html.erb +3 -0
- data/app/views/hydramata/works/properties/_show.json.jbuilder +1 -0
- data/app/views/hydramata/works/works/_edit.html.erb +8 -0
- data/app/views/hydramata/works/works/_new.html.erb +8 -0
- data/app/views/hydramata/works/works/_show.html.erb +3 -0
- data/app/views/hydramata/works/works/_show.json.jbuilder +13 -0
- data/app/wranglers/hydramata/works/fedora_wrangler.rb +66 -0
- data/bin/rails +12 -0
- data/db/migrate/20140606132349_create_hydramata_work_predicates.rb +13 -0
- data/db/migrate/20140606132350_create_hydramata_work_types.rb +9 -0
- data/db/migrate/20140606132351_create_hydramata_work_predicate_sets.rb +13 -0
- data/db/migrate/20140606132352_create_hydramata_work_predicate_presentation_sequences.rb +12 -0
- data/db/migrate/20140623200635_add_validations_to_predicates.rb +5 -0
- data/db/migrate/20140627134133_adding_item_type_schema_dot_org_to_work_type.rb +5 -0
- data/db/migrate/20140627140840_adding_item_prop_schema_dot_org_to_predicate.rb +5 -0
- data/db/seeds.rb +36 -0
- data/documents/administrative-set-strawperson.md +45 -0
- data/documents/diagrams/hydramata-refactor-tasks.dot +88 -0
- data/documents/diagrams/hydramata-sip-dip-aip.dot +88 -0
- data/documents/diagrams/hydramata-work-architecture.dot +129 -0
- data/documents/diagrams/hydramata-work-subcomponents.dot +36 -0
- data/documents/diagrams/map-from-database-to-work-object.dot +44 -0
- data/documents/diagrams/map-from-fedora-to-work-object.dot +51 -0
- data/documents/diagrams/map-from-input-to-work-object.dot +37 -0
- data/documents/diagrams/map-from-work-object-to-database.dot +31 -0
- data/documents/diagrams/work-rendering.dot +53 -0
- data/documents/diagrams/work-structure.dot +32 -0
- data/documents/handling-work.md +224 -0
- data/documents/high-level-stories.md +105 -0
- data/documents/hydramata-components.md +82 -0
- data/documents/interface-between-work-and-permissions.md +131 -0
- data/documents/interface-between-work-and-workflow.md +6 -0
- data/documents/timeline.md +75 -0
- data/fs +3 -0
- data/gemfiles/rails4.1.gemfile +12 -0
- data/gemfiles/rails4.gemfile +13 -0
- data/hydramata-works.gemspec +43 -0
- data/lib/hydramata-works.rb +23 -0
- data/lib/hydramata/works/conversions.rb +21 -0
- data/lib/hydramata/works/conversions/exceptions.rb +18 -0
- data/lib/hydramata/works/conversions/predicate.rb +22 -0
- data/lib/hydramata/works/conversions/predicate_set.rb +28 -0
- data/lib/hydramata/works/conversions/presented_fieldsets.rb +28 -0
- data/lib/hydramata/works/conversions/presenter.rb +13 -0
- data/lib/hydramata/works/conversions/property.rb +31 -0
- data/lib/hydramata/works/conversions/property_set.rb +23 -0
- data/lib/hydramata/works/conversions/translation_key_fragment.rb +20 -0
- data/lib/hydramata/works/conversions/value.rb +20 -0
- data/lib/hydramata/works/conversions/work_type.rb +26 -0
- data/lib/hydramata/works/engine.rb +31 -0
- data/lib/hydramata/works/linters.rb +99 -0
- data/lib/hydramata/works/linters/implement_data_definition_interface_matcher.rb +17 -0
- data/lib/hydramata/works/linters/implement_entity_interface_matcher.rb +16 -0
- data/lib/hydramata/works/linters/implement_predicate_interface_matcher.rb +17 -0
- data/lib/hydramata/works/linters/implement_predicate_set_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_property_set_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_value_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_work_type_interface_matcher.rb +13 -0
- data/lib/hydramata/works/linters/interface_matcher_builder.rb +36 -0
- data/lib/hydramata/works/translator.rb +67 -0
- data/lib/hydramata/works/version.rb +5 -0
- data/lib/hydramata_works.rb +2 -0
- data/lib/tasks/hydramata_work_tasks.rake +4 -0
- data/run_each_spec_in_isolation +16 -0
- data/run_each_spec_in_isolation.txt +110 -0
- data/script/analyzer.rb +124 -0
- data/script/fast_specs +22 -0
- data/spec/features/fedora_to_in_memory_spec.rb +60 -0
- data/spec/features/format_and_view_path_overrides_spec.rb +72 -0
- data/spec/features/in_memory_to_output_buffer_spec.rb +109 -0
- data/spec/features/instantiate_entity_from_persisted_work_type_spec.rb +26 -0
- data/spec/features/new_user_input_to_in_memory_spec.rb +75 -0
- data/spec/features/translation_services_spec.rb +107 -0
- data/spec/features/validate_entity_based_on_work_type_structure_spec.rb +19 -0
- data/spec/fixtures/cassettes/fedora-object.yml +299 -0
- data/spec/fixtures/translations.yml +20 -0
- data/spec/forms/hydramata/works/entity_form_spec.rb +83 -0
- data/spec/forms/hydramata/works/validation_service_spec.rb +32 -0
- data/spec/lib/hydramata-work_spec.rb +14 -0
- data/spec/lib/hydramata/works/conversions/predicate_set_spec.rb +50 -0
- data/spec/lib/hydramata/works/conversions/predicate_spec.rb +43 -0
- data/spec/lib/hydramata/works/conversions/presented_fieldsets_spec.rb +52 -0
- data/spec/lib/hydramata/works/conversions/presenter_spec.rb +22 -0
- data/spec/lib/hydramata/works/conversions/property_set_spec.rb +42 -0
- data/spec/lib/hydramata/works/conversions/property_spec.rb +68 -0
- data/spec/lib/hydramata/works/conversions/translation_key_fragment_spec.rb +45 -0
- data/spec/lib/hydramata/works/conversions/value_spec.rb +36 -0
- data/spec/lib/hydramata/works/conversions/work_type_spec.rb +55 -0
- data/spec/lib/hydramata/works/translator_spec.rb +81 -0
- data/spec/models/hydramata/works/data_definition_spec.rb +53 -0
- data/spec/models/hydramata/works/entity_spec.rb +50 -0
- data/spec/models/hydramata/works/predicate_presentation_sequences/storage_spec.rb +15 -0
- data/spec/models/hydramata/works/predicate_set_spec.rb +63 -0
- data/spec/models/hydramata/works/predicate_sets/storage_spec.rb +37 -0
- data/spec/models/hydramata/works/predicate_spec.rb +16 -0
- data/spec/models/hydramata/works/predicates/storage_spec.rb +78 -0
- data/spec/models/hydramata/works/predicates_spec.rb +18 -0
- data/spec/models/hydramata/works/presentation_structure_spec.rb +27 -0
- data/spec/models/hydramata/works/property_set_spec.rb +135 -0
- data/spec/models/hydramata/works/property_spec.rb +74 -0
- data/spec/models/hydramata/works/value_spec.rb +61 -0
- data/spec/models/hydramata/works/work_type_spec.rb +45 -0
- data/spec/models/hydramata/works/work_types/storage_spec.rb +74 -0
- data/spec/models/hydramata/works/work_types_spec.rb +16 -0
- data/spec/parsers/hydramata/works/datastream_parser_spec.rb +29 -0
- data/spec/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser_spec.rb +65 -0
- data/spec/parsers/hydramata/works/datastream_parsers/simple_xml_parser_spec.rb +37 -0
- data/spec/parsers/hydramata/works/predicate_parser_spec.rb +30 -0
- data/spec/parsers/hydramata/works/predicate_parsers/simple_parser_spec.rb +20 -0
- data/spec/parsers/hydramata/works/validations_parser_spec.rb +31 -0
- data/spec/parsers/hydramata/works/value_parser_spec.rb +22 -0
- data/spec/parsers/hydramata/works/value_parsers/simple_parser_spec.rb +20 -0
- data/spec/parsers/hydramata/works/value_parsers_spec.rb +36 -0
- data/spec/presenters/hydramata/works/base_presenter_spec.rb +111 -0
- data/spec/presenters/hydramata/works/dom_attributes_builder_spec.rb +26 -0
- data/spec/presenters/hydramata/works/entity_presenter_spec.rb +51 -0
- data/spec/presenters/hydramata/works/fieldset_presenter_spec.rb +58 -0
- data/spec/presenters/hydramata/works/property_presenter_spec.rb +42 -0
- data/spec/presenters/hydramata/works/value_presenter_spec.rb +49 -0
- data/spec/renderers/hydramata/works/entity_renderer_spec.rb +25 -0
- data/spec/spec_active_record_helper.rb +30 -0
- data/spec/spec_fast_helper.rb +12 -0
- data/spec/spec_slow_helper.rb +56 -0
- data/spec/spec_view_helper.rb +14 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +21 -0
- data/spec/views/hydramata/works/fieldsets/_edit.html.erb_spec.rb +29 -0
- data/spec/views/hydramata/works/fieldsets/_show.html.erb_spec.rb +25 -0
- data/spec/views/hydramata/works/properties/_edit.html.erb_spec.rb +22 -0
- data/spec/views/hydramata/works/properties/_show.html.erb_spec.rb +22 -0
- data/spec/views/hydramata/works/works/_edit.html.erb_spec.rb +23 -0
- data/spec/views/hydramata/works/works/_new.html.erb_spec.rb +23 -0
- data/spec/views/hydramata/works/works/_show.html.erb_spec.rb +24 -0
- data/spec/wranglers/hydramata/works/fedora_wrangler_spec.rb +26 -0
- metadata +466 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'hydramata/works/predicate_set'
|
3
|
+
require 'hydramata/works/work_types/storage'
|
4
|
+
require 'hydramata/works/predicates/storage'
|
5
|
+
require 'hydramata/works/predicate_presentation_sequences/storage'
|
6
|
+
|
7
|
+
module Hydramata
|
8
|
+
module Works
|
9
|
+
module PredicateSets
|
10
|
+
class Storage < ActiveRecord::Base
|
11
|
+
self.table_name = :hydramata_works_predicate_sets
|
12
|
+
belongs_to(
|
13
|
+
:work_type,
|
14
|
+
class_name: '::Hydramata::Works::WorkTypes::Storage',
|
15
|
+
foreign_key: 'work_type_id'
|
16
|
+
)
|
17
|
+
validates :identity, uniqueness: { scope: :work_type_id }
|
18
|
+
validates :presentation_sequence, uniqueness: { scope: :work_type_id }
|
19
|
+
|
20
|
+
has_many(
|
21
|
+
:predicate_presentation_sequences,
|
22
|
+
class_name: '::Hydramata::Works::PredicatePresentationSequences::Storage',
|
23
|
+
foreign_key: 'predicate_set_id'
|
24
|
+
)
|
25
|
+
|
26
|
+
has_many(
|
27
|
+
:predicates,
|
28
|
+
class_name: '::Hydramata::Works::Predicates::Storage',
|
29
|
+
through: :predicate_presentation_sequences
|
30
|
+
)
|
31
|
+
|
32
|
+
def to_predicate_set
|
33
|
+
PredicateSet.new(predicate_set_attributes)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def predicate_set_attributes
|
39
|
+
attributes.with_indifferent_access.merge(predicates: predicates, work_type: work_type)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'hydramata/works/predicate'
|
2
|
+
require 'hydramata/works/predicates/storage'
|
3
|
+
|
4
|
+
module Hydramata
|
5
|
+
module Works
|
6
|
+
module Predicates
|
7
|
+
module_function
|
8
|
+
def find(identity, attributes = {})
|
9
|
+
predicate_attributes = attributes.merge(Predicates::Storage.existing_attributes_for(identity))
|
10
|
+
Predicate.new(predicate_attributes)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'hydramata/works/predicates'
|
3
|
+
|
4
|
+
module Hydramata
|
5
|
+
module Works
|
6
|
+
module Predicates
|
7
|
+
# I don't want to conflate the idea with the predicate, with the storage
|
8
|
+
# strategy for predicates.
|
9
|
+
class Storage < ActiveRecord::Base
|
10
|
+
self.table_name = :hydramata_works_predicates
|
11
|
+
|
12
|
+
def self.find_by_identity!(identity)
|
13
|
+
where(identity: identity).first!
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.existing_attributes_for(identity)
|
17
|
+
find_by_identity!(identity).attributes
|
18
|
+
rescue ActiveRecord::RecordNotFound
|
19
|
+
{ identity: identity }
|
20
|
+
rescue ActiveRecord::ConnectionNotEstablished
|
21
|
+
# This is a potentially big deal in production.
|
22
|
+
# But for testing, I don't always want to hit the database, so
|
23
|
+
# I'm capturing this exception
|
24
|
+
{ identity: identity }
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_predicate
|
28
|
+
Predicate.new(attributes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Hydramata
|
2
|
+
module Works
|
3
|
+
# This is responsible for defining
|
4
|
+
#
|
5
|
+
# Taking a queue from HTML, a fieldset gives meaning to a group of
|
6
|
+
# attributes. Conceptually it is providing the sequence in which to render
|
7
|
+
# attributes.
|
8
|
+
#
|
9
|
+
# @TODO - Does this class even make sense? Given that I am grabbing the
|
10
|
+
# presentation structure from the work type.
|
11
|
+
class PresentationStructure
|
12
|
+
def self.build_from(object)
|
13
|
+
new do |structure|
|
14
|
+
object.predicate_sets.each do |predicate_set|
|
15
|
+
structure.fieldsets << predicate_set
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
yield(self) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def fieldsets
|
25
|
+
@fieldsets ||= []
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
require 'hydramata/works/conversions'
|
3
|
+
|
4
|
+
module Hydramata
|
5
|
+
module Works
|
6
|
+
# The responsibility of a Property is to be a collection of values for
|
7
|
+
# a given predicate. In other words, this represents the Predicate/Object
|
8
|
+
# components of an RDF Triple.
|
9
|
+
#
|
10
|
+
# Why not use RDF? Because not everything we are working with is in RDF.
|
11
|
+
class Property
|
12
|
+
def self.===(other)
|
13
|
+
super || other.instance_of?(self)
|
14
|
+
end
|
15
|
+
|
16
|
+
include ::Enumerable
|
17
|
+
include Conversions
|
18
|
+
|
19
|
+
attr_reader :predicate, :values, :value_parser
|
20
|
+
def initialize(options = {})
|
21
|
+
self.predicate = options.fetch(:predicate)
|
22
|
+
@value_parser = options.fetch(:value_parser) { default_value_parser }
|
23
|
+
@values = []
|
24
|
+
push(options[:values])
|
25
|
+
push(options[:value])
|
26
|
+
end
|
27
|
+
|
28
|
+
def name
|
29
|
+
predicate
|
30
|
+
end
|
31
|
+
|
32
|
+
# Because who wants to remember which way to access this?
|
33
|
+
alias_method :value, :values
|
34
|
+
|
35
|
+
def to_translation_key_fragment
|
36
|
+
predicate.to_translation_key_fragment
|
37
|
+
end
|
38
|
+
|
39
|
+
def each(&block)
|
40
|
+
values.each(&block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def <<(values)
|
44
|
+
Array.wrap(values).each do |value|
|
45
|
+
value_parser.call(predicate: predicate, value: value) do |response|
|
46
|
+
@values << Value(response)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
alias_method :push, :<<
|
52
|
+
|
53
|
+
def ==(other)
|
54
|
+
super ||
|
55
|
+
other.instance_of?(self.class) &&
|
56
|
+
other.predicate == predicate &&
|
57
|
+
other.values == values
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def predicate=(value)
|
63
|
+
@predicate = Predicate(value)
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_value_parser
|
67
|
+
require 'hydramata/works/value_parser'
|
68
|
+
ValueParser
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
require 'hydramata/works/conversions'
|
3
|
+
module Hydramata
|
4
|
+
module Works
|
5
|
+
# A container for Property objects. It provides ordered access to
|
6
|
+
# property_store. The corresponding specs go into further details on ordering.
|
7
|
+
class PropertySet
|
8
|
+
include Conversions
|
9
|
+
include ::Enumerable
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@property_store = {}
|
13
|
+
self.predicate_set = options.fetch(:predicate_set) { default_predicate_set }
|
14
|
+
end
|
15
|
+
attr_reader :predicate_set
|
16
|
+
|
17
|
+
def name
|
18
|
+
predicate_set
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(input)
|
22
|
+
property = Property(input)
|
23
|
+
if property_store[property.predicate.to_s]
|
24
|
+
property_store[property.predicate.to_s] << property.values
|
25
|
+
else
|
26
|
+
property_store[property.predicate.to_s] = property
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# If the key is missing, return a quasi-null object.
|
31
|
+
def [](key)
|
32
|
+
property_store[key.to_s] || Property(predicate: key)
|
33
|
+
end
|
34
|
+
|
35
|
+
def predicates
|
36
|
+
property_store.keys
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch(key)
|
40
|
+
property_store.fetch(key.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def key?(key)
|
44
|
+
property_store.key?(key.to_s)
|
45
|
+
end
|
46
|
+
|
47
|
+
def ==(other)
|
48
|
+
# Because property_store is a private method.
|
49
|
+
(other.instance_of?(property_store.class) && property_store == other) ||
|
50
|
+
(other.instance_of?(self.class) && other == property_store)
|
51
|
+
end
|
52
|
+
|
53
|
+
def each
|
54
|
+
property_store.each do |_key, property|
|
55
|
+
yield(property)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def properties
|
60
|
+
property_store.collect {|_, property| property }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Conversion::PresentedFieldsets interacts with this.
|
64
|
+
# Consider extracting the shared behavior into that function. Perhaps
|
65
|
+
# making a proper class.
|
66
|
+
def subset(keys, receiver = self.class.new, property_builder = nil)
|
67
|
+
property_builder ||= ->(builder) { builder }
|
68
|
+
Array.wrap(keys).each_with_object(receiver).each do |key, collector|
|
69
|
+
# A concession regarding null property; If you ask for the keys, I'll
|
70
|
+
# give them to you; it just may be an empty value.
|
71
|
+
collector << property_builder.call(self[key])
|
72
|
+
collector
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
attr_reader :property_store
|
79
|
+
|
80
|
+
def default_predicate_set
|
81
|
+
{ identity: 'identity' }
|
82
|
+
end
|
83
|
+
|
84
|
+
def predicate_set=(value)
|
85
|
+
@predicate_set = PredicateSet(value)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Hydramata
|
4
|
+
module Works
|
5
|
+
# Because it may be helpful to see the raw object
|
6
|
+
class Value < SimpleDelegator
|
7
|
+
attr_reader :raw_object
|
8
|
+
def initialize(options = {})
|
9
|
+
value = options.fetch(:value)
|
10
|
+
__setobj__(value)
|
11
|
+
@raw_object = options.fetch(:raw_object) { default_raw_object }
|
12
|
+
yield(self) if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
format('#<%s:%#0x value=%s raw_object=%s>', self.class, __id__, __getobj__.inspect, raw_object.inspect)
|
17
|
+
end
|
18
|
+
|
19
|
+
def instance_of?(klass)
|
20
|
+
super || __getobj__.instance_of?(klass)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
super || other == __getobj__
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def default_raw_object
|
30
|
+
__getobj__
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'hydramata/works/data_definition'
|
2
|
+
require 'hydramata/works/conversions/predicate_set'
|
3
|
+
require 'active_support/core_ext/array/wrap'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
class WorkType < DataDefinition
|
8
|
+
include Conversions
|
9
|
+
|
10
|
+
def initialize(*args, &block)
|
11
|
+
@predicate_sets = []
|
12
|
+
super(*args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :predicate_sets
|
16
|
+
def predicate_sets=(things)
|
17
|
+
@predicate_sets = []
|
18
|
+
Array.wrap(things).each do |thing|
|
19
|
+
@predicate_sets << PredicateSet(thing)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias_method :fieldsets, :predicate_sets
|
23
|
+
alias_method :fieldsets=, :predicate_sets=
|
24
|
+
|
25
|
+
def itemtype_schema_dot_org
|
26
|
+
@itemtype_schema_dot_org || default_itemtype_schema_dot_org
|
27
|
+
end
|
28
|
+
|
29
|
+
def itemtype_schema_dot_org=(value)
|
30
|
+
string = value.to_s.strip
|
31
|
+
if string.size == 0
|
32
|
+
@itemtype_schema_dot_org = nil
|
33
|
+
else
|
34
|
+
if string =~ /\Ahttp/
|
35
|
+
@itemtype_schema_dot_org = string
|
36
|
+
else
|
37
|
+
@itemtype_schema_dot_org = File.join('http://schema.org', string)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def default_itemtype_schema_dot_org
|
45
|
+
'http://schema.org/Thing'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'hydramata/works/work_type'
|
2
|
+
require 'hydramata/works/work_types/storage'
|
3
|
+
|
4
|
+
module Hydramata
|
5
|
+
module Works
|
6
|
+
module WorkTypes
|
7
|
+
module_function
|
8
|
+
def find(identity, attributes = {})
|
9
|
+
work_type_attributes = attributes.merge(WorkTypes::Storage.existing_attributes_for(identity))
|
10
|
+
WorkType.new(work_type_attributes)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'hydramata/works/predicate_sets/storage'
|
3
|
+
require 'hydramata/works/work_type'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
module WorkTypes
|
8
|
+
# I don't want to conflate the idea with the predicate, with the storage
|
9
|
+
# strategy for predicates.
|
10
|
+
class Storage < ActiveRecord::Base
|
11
|
+
self.table_name = :hydramata_works_types
|
12
|
+
has_many :predicate_sets, class_name: '::Hydramata::Works::PredicateSets::Storage', foreign_key: 'work_type_id'
|
13
|
+
validates :identity, uniqueness: true, presence: true
|
14
|
+
|
15
|
+
def self.find_by_identity!(identity)
|
16
|
+
where(identity: identity).first!
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.existing_attributes_for(identity)
|
20
|
+
# @TODO - Is this the pattern I want to pursue? I liked the method
|
21
|
+
# :as_work_type being private
|
22
|
+
find_by_identity!(identity).as_work_type
|
23
|
+
rescue ActiveRecord::RecordNotFound
|
24
|
+
{ identity: identity }
|
25
|
+
rescue ActiveRecord::ConnectionNotEstablished
|
26
|
+
# This is a potentially big deal in production.
|
27
|
+
# But for testing, I don't always want to hit the database, so
|
28
|
+
# I'm capturing this exception
|
29
|
+
{ identity: identity }
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_work_type
|
33
|
+
WorkType.new(as_work_type)
|
34
|
+
end
|
35
|
+
|
36
|
+
def as_work_type
|
37
|
+
attributes.merge(predicate_sets: predicate_sets)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'hydramata/works/datastream_parsers/simple_xml_parser'
|
2
|
+
require 'hydramata/works/datastream_parsers/rdf_ntriples_parser'
|
3
|
+
|
4
|
+
module Hydramata
|
5
|
+
module Works
|
6
|
+
# Responsible for finding the appropriate datastream parser based on the
|
7
|
+
# input context, then calling the found parser.
|
8
|
+
#
|
9
|
+
# See lib/hydramata/works/linters.rb for the interface definition of a
|
10
|
+
# datastream parser.
|
11
|
+
module DatastreamParser
|
12
|
+
module_function
|
13
|
+
|
14
|
+
def call(options = {}, &block)
|
15
|
+
parser = parser_for(options)
|
16
|
+
datastream = options.fetch(:datastream)
|
17
|
+
parser.call(datastream.content, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def parser_for(options = {})
|
21
|
+
parser_finder = options.fetch(:parser_finder) { default_parser_finder }
|
22
|
+
parser_finder.call(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_parser_finder
|
26
|
+
lambda do |options|
|
27
|
+
null_parser = proc {}
|
28
|
+
DatastreamParsers::RdfNtriplesParser.match?(options) ||
|
29
|
+
DatastreamParsers::SimpleXmlParser.match?(options) ||
|
30
|
+
null_parser
|
31
|
+
end
|
32
|
+
end
|
33
|
+
private_class_method :default_parser_finder
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|