hydramata-works 0.0.1.prerelease
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 +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
data/VISION.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
## Hydramata::Works's Vision
|
2
|
+
|
3
|
+
[CurateND](http://curate.nd.edu) allows for the uploading five Work types: Article, Dataset, Document, Image, and Senior Thesis.
|
4
|
+
Four of the five Work Types (not including Senior Thesis) have their metadata attributes defined in an [application profile](http://ndlib.github.io/metadata_application_profile/templates/). There is a lot of overlap regarding the metadata elements that are rendered.
|
5
|
+
|
6
|
+
One of the goals of the Hydramata::Works project is to allow institutions to create arbitrary Work types that are somewhat arbitrarily comprised of well-defined metadata element predicates.
|
7
|
+
These predicates can be defined in [various ontologies](http://en.wikipedia.org/wiki/Ontology_(information_science)). Examples include [Dublin Core](http://dublincore.org/documents/dcmi-terms/), [Friend of a Friend](http://www.foaf-project.org/), [schema.org](http://schema.org/docs/schemas.html), etc.
|
8
|
+
|
9
|
+
Predicates can be complex in nature. Consider a "name" predicate. It could be comprised of "given_name", "surname", and several other elements [see Personal Names Around the World](http://www.w3.org/International/questions/qa-personal-names).
|
10
|
+
|
11
|
+
The Hydramata::Works project is positioning to allow for:
|
12
|
+
|
13
|
+
* The dynamic creation of different work types
|
14
|
+
* Assigning suggested predicates to the work types
|
15
|
+
* And declaring a recommended presentation structure for the work types
|
16
|
+
* Expose defaults for predicate values within a work type context
|
17
|
+
* Expose validation for predicate values
|
18
|
+
|
19
|
+
At present, the core functionality is being built out.
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'active_model/naming'
|
5
|
+
require 'hydramata/works/conversions/translation_key_fragment'
|
6
|
+
|
7
|
+
module Hydramata
|
8
|
+
module Works
|
9
|
+
class EntityForm < SimpleDelegator
|
10
|
+
include Conversions
|
11
|
+
def initialize(entity, collaborators = {})
|
12
|
+
__setobj__(entity)
|
13
|
+
@errors = collaborators.fetch(:error_container) { default_error_container }
|
14
|
+
@validation_service = collaborators.fetch(:validation_service) { default_validation_service }
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :errors, :validation_service
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
validate
|
21
|
+
errors.size == 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_key
|
25
|
+
persisted? ? [identity] : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_param
|
29
|
+
persisted? ? identity : nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_partial_path
|
33
|
+
# @TODO - need to figure out what this should be
|
34
|
+
''
|
35
|
+
end
|
36
|
+
|
37
|
+
def persisted?
|
38
|
+
identity.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Needed for Validator interaction
|
42
|
+
def self.human_attribute_name(attr, options = {})
|
43
|
+
attr
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.model_name
|
47
|
+
# @TODO - allow overwrite of the ActiveModel::Name, which may require
|
48
|
+
# overwriting #class to be something else.
|
49
|
+
@_model_name ||= ActiveModel::Name.new(self, Hydramata::Works)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Needed for Validator interaction
|
53
|
+
def read_attribute_for_validation(attribute_name)
|
54
|
+
send(TranslationKeyFragment(attribute_name))
|
55
|
+
end
|
56
|
+
|
57
|
+
def inspect
|
58
|
+
format('#<%s:%#0x entity=%s>', EntityForm, __id__, __getobj__.inspect)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def respond_to_missing?(method_name, include_all = false)
|
64
|
+
super || __getobj__.has_property?(method_name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_missing(method_name, *args, &block)
|
68
|
+
if __getobj__.has_property?(method_name)
|
69
|
+
# @TODO - The Law of Demeter is being violated.
|
70
|
+
__getobj__.properties.fetch(method_name).values
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def default_error_container
|
77
|
+
require 'active_model/errors'
|
78
|
+
ActiveModel::Errors.new(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def default_validation_service
|
82
|
+
require 'hydramata/works/validation_service'
|
83
|
+
ValidationService
|
84
|
+
end
|
85
|
+
|
86
|
+
def validate
|
87
|
+
validation_service.call(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
|
3
|
+
module Hydramata
|
4
|
+
module Works
|
5
|
+
class ValidationService
|
6
|
+
def self.call(entity)
|
7
|
+
new(entity).call
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :entity, :validator_namespaces
|
11
|
+
def initialize(entity, collaborators = {})
|
12
|
+
@entity = entity
|
13
|
+
self.validator_namespaces = collaborators.fetch(:validator_namespaces) { default_validator_namespaces }
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
# @TODO - This is an awful lot of information about the validation
|
18
|
+
# structure.
|
19
|
+
entity.properties.each do |property|
|
20
|
+
predicate = property.predicate
|
21
|
+
predicate.validations.each do |validator_name, options|
|
22
|
+
validate(predicate, validator_name, options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def validate(predicate, validator_name, options)
|
31
|
+
return unless options
|
32
|
+
validator = validator_for(validator_name)
|
33
|
+
validation_options = parse_validates_options(options)
|
34
|
+
validation_options[:attributes] = predicate
|
35
|
+
validator.new(validation_options).validate(entity)
|
36
|
+
end
|
37
|
+
|
38
|
+
def validator_for(validator_name)
|
39
|
+
validator_class_name = "#{validator_name.to_s.camelize}Validator"
|
40
|
+
validator = nil
|
41
|
+
validator_namespaces.each do |namespace|
|
42
|
+
begin
|
43
|
+
validator = "#{namespace}::#{validator_class_name}".constantize
|
44
|
+
break
|
45
|
+
rescue NameError
|
46
|
+
next
|
47
|
+
end
|
48
|
+
end
|
49
|
+
validator || validator_class_name.constantize
|
50
|
+
end
|
51
|
+
|
52
|
+
# Cribbed from ActiveModel::Validations#_parse_validates_options
|
53
|
+
# in Rails 4.0.x and 4.1.x
|
54
|
+
def parse_validates_options(options)
|
55
|
+
case options
|
56
|
+
when TrueClass
|
57
|
+
{}
|
58
|
+
when Hash
|
59
|
+
options
|
60
|
+
when Range, Array
|
61
|
+
{ :in => options }
|
62
|
+
else
|
63
|
+
{ :with => options }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_validator_namespaces
|
68
|
+
require 'active_model/validations'
|
69
|
+
ActiveModel::Validations
|
70
|
+
end
|
71
|
+
|
72
|
+
def validator_namespaces=(names)
|
73
|
+
@validator_namespaces = Array.wrap(names)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Hydramata
|
2
|
+
module Works
|
3
|
+
|
4
|
+
# DataDefinition is an abstract class for the Plain Old Ruby Objects (PORO)
|
5
|
+
# that are loaded from the database storage. The irony that I am using
|
6
|
+
# inheritance for these POROs is not lost on me.
|
7
|
+
class DataDefinition
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(attributes = {})
|
12
|
+
attributes.each do |key, value|
|
13
|
+
self.send("#{key}=", value.freeze) if respond_to?("#{key}=")
|
14
|
+
end
|
15
|
+
yield self if block_given?
|
16
|
+
validate!
|
17
|
+
self.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_writer :name_for_application_usage
|
21
|
+
def name_for_application_usage
|
22
|
+
@name_for_application_usage || identity
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_translation_key_fragment
|
26
|
+
name_for_application_usage
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :identity
|
30
|
+
def identity=(value)
|
31
|
+
@identity = value.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
identity
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_sym
|
39
|
+
to_translation_key_fragment.to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def <=>(other)
|
43
|
+
if other.instance_of?(self.class)
|
44
|
+
identity <=> other.identity
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def validate!
|
53
|
+
true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'hydramata/works/conversions'
|
2
|
+
module Hydramata
|
3
|
+
module Works
|
4
|
+
# Responsible for being the in ruby representation of a set of Properties.
|
5
|
+
#
|
6
|
+
# Unlike the [ActiveRecord pattern](http://www.martinfowler.com/eaaCatalog/activeRecord.html),
|
7
|
+
# there is no direct connection to a data storage. This is instead analogous
|
8
|
+
# to the Entity of the [DataMapper pattern](http://www.martinfowler.com/eaaCatalog/dataMapper.html)
|
9
|
+
# as implemented in [Lotus::Models](https://github.com/lotus/model#entities).
|
10
|
+
#
|
11
|
+
# Unlike a Lotus::Model, the Work is an arbitrary collection of Property
|
12
|
+
# objects, as defined in the PropertySet.
|
13
|
+
class Entity
|
14
|
+
include Conversions
|
15
|
+
|
16
|
+
def initialize(collaborators = {}, &block)
|
17
|
+
self.work_type = collaborators[:work_type] if collaborators.key?(:work_type)
|
18
|
+
self.identity = collaborators[:identity] if collaborators.key?(:identity)
|
19
|
+
@properties = collaborators.fetch(:properties_container) { default_properties_container }
|
20
|
+
@presenter_builder = collaborators.fetch(:presenter_builder) { default_presenter_builder }
|
21
|
+
block.call(self) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def work_type=(value)
|
25
|
+
@work_type = WorkType(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def work_type
|
29
|
+
@work_type ||= WorkType()
|
30
|
+
end
|
31
|
+
|
32
|
+
def identity=(value)
|
33
|
+
@identity = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_property?(predicate)
|
37
|
+
properties.key?(predicate)
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :properties, :identity
|
41
|
+
|
42
|
+
def to_translation_key_fragment
|
43
|
+
work_type.to_translation_key_fragment
|
44
|
+
end
|
45
|
+
|
46
|
+
def name_for_application_usage
|
47
|
+
work_type.name_for_application_usage
|
48
|
+
end
|
49
|
+
|
50
|
+
def itemtype_schema_dot_org
|
51
|
+
work_type.itemtype_schema_dot_org
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :presenter_builder
|
55
|
+
private :presenter_builder
|
56
|
+
|
57
|
+
def to_presenter
|
58
|
+
presenter_builder.call(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
|
64
|
+
def default_properties_container
|
65
|
+
require 'hydramata/works/property_set'
|
66
|
+
PropertySet.new(entity: self)
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_presenter_builder
|
70
|
+
require 'hydramata/works/entity_presenter'
|
71
|
+
->(entity) { EntityPresenter.new(entity: entity) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'hydramata/works/data_definition'
|
2
|
+
require 'hydramata/works/validations_parser'
|
3
|
+
require 'active_support/core_ext/array/wrap'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
class Predicate < DataDefinition
|
8
|
+
|
9
|
+
def initialize(*args, &block)
|
10
|
+
@validations = []
|
11
|
+
super(*args, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_accessor :datastream_name
|
15
|
+
attr_accessor :value_coercer_name
|
16
|
+
attr_accessor :value_parser_name
|
17
|
+
attr_accessor :indexing_strategy
|
18
|
+
attr_reader :validations
|
19
|
+
|
20
|
+
def validations=(value)
|
21
|
+
@validations = ValidationsParser.call(value)
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :itemprop_schema_dot_org
|
25
|
+
def itemprop_schema_dot_org=(value)
|
26
|
+
string = value.to_s.strip
|
27
|
+
if string.size == 0
|
28
|
+
@itemprop_schema_dot_org = nil
|
29
|
+
else
|
30
|
+
@itemprop_schema_dot_org = string
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'hydramata/works/predicates/storage'
|
3
|
+
require 'hydramata/works/predicate_sets/storage'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
# Defines the order in which predicates are presented.
|
8
|
+
module PredicatePresentationSequences
|
9
|
+
class Storage < ActiveRecord::Base
|
10
|
+
self.table_name = :hydramata_works_predicate_presentation_sequences
|
11
|
+
|
12
|
+
validates :predicate_set_id, { presence: true }
|
13
|
+
validates :predicate_id, { presence: true, uniqueness: { scope: :predicate_set_id } }
|
14
|
+
validates :presentation_sequence, { presence: true, uniqueness: { scope: :predicate_set_id } }
|
15
|
+
|
16
|
+
belongs_to(
|
17
|
+
:predicate_set,
|
18
|
+
class_name: 'Hydramata::Works::PredicateSets::Storage',
|
19
|
+
foreign_key: 'predicate_set_id'
|
20
|
+
)
|
21
|
+
belongs_to(
|
22
|
+
:predicate,
|
23
|
+
class_name: 'Hydramata::Works::Predicates::Storage',
|
24
|
+
foreign_key: 'predicate_id'
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
require 'hydramata/works/conversions/predicate'
|
3
|
+
require 'hydramata/works/data_definition'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
|
8
|
+
# A PredicateSet is analogous to a PropertySet, except it does not include
|
9
|
+
# values.
|
10
|
+
class PredicateSet < DataDefinition
|
11
|
+
include Conversions
|
12
|
+
|
13
|
+
attr_accessor :work_type
|
14
|
+
attr_accessor :presentation_sequence
|
15
|
+
attr_reader :predicates
|
16
|
+
|
17
|
+
def <=>(other)
|
18
|
+
if other.instance_of?(self.class)
|
19
|
+
[work_type, identity, presentation_sequence] <=>
|
20
|
+
[other.work_type, other.identity, other.presentation_sequence]
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def predicates=(items)
|
27
|
+
@predicates = []
|
28
|
+
Array.wrap(items).each do |item|
|
29
|
+
@predicates << Predicate(item)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def validate!
|
36
|
+
if identity.nil?
|
37
|
+
raise RuntimeError, "#{self.class}(#{inspect}) is invalid"
|
38
|
+
else
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|