hydramata-works 0.0.1.prerelease

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.hound.yml +818 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +20 -0
  6. data/CONTRIBUTING.md +220 -0
  7. data/Gemfile +36 -0
  8. data/Guardfile +36 -0
  9. data/LICENSE +15 -0
  10. data/README.md +36 -0
  11. data/Rakefile +47 -0
  12. data/TODO.md +74 -0
  13. data/VISION.md +19 -0
  14. data/app/forms/hydramata/works/entity_form.rb +92 -0
  15. data/app/forms/hydramata/works/validation_service.rb +78 -0
  16. data/app/models/hydramata/works/data_definition.rb +57 -0
  17. data/app/models/hydramata/works/entities.rb +11 -0
  18. data/app/models/hydramata/works/entity.rb +75 -0
  19. data/app/models/hydramata/works/predicate.rb +35 -0
  20. data/app/models/hydramata/works/predicate_presentation_sequences/storage.rb +29 -0
  21. data/app/models/hydramata/works/predicate_set.rb +44 -0
  22. data/app/models/hydramata/works/predicate_sets/storage.rb +45 -0
  23. data/app/models/hydramata/works/predicates.rb +14 -0
  24. data/app/models/hydramata/works/predicates/storage.rb +33 -0
  25. data/app/models/hydramata/works/presentation_structure.rb +29 -0
  26. data/app/models/hydramata/works/property.rb +72 -0
  27. data/app/models/hydramata/works/property_set.rb +89 -0
  28. data/app/models/hydramata/works/validations.rb +6 -0
  29. data/app/models/hydramata/works/value.rb +34 -0
  30. data/app/models/hydramata/works/work_type.rb +49 -0
  31. data/app/models/hydramata/works/work_types.rb +14 -0
  32. data/app/models/hydramata/works/work_types/storage.rb +42 -0
  33. data/app/parsers/hydramata/works/datastream_parser.rb +36 -0
  34. data/app/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser.rb +60 -0
  35. data/app/parsers/hydramata/works/datastream_parsers/simple_xml_parser.rb +27 -0
  36. data/app/parsers/hydramata/works/predicate_parser.rb +31 -0
  37. data/app/parsers/hydramata/works/predicate_parsers/simple_parser.rb +13 -0
  38. data/app/parsers/hydramata/works/validations_parser.rb +22 -0
  39. data/app/parsers/hydramata/works/value_parser.rb +26 -0
  40. data/app/parsers/hydramata/works/value_parsers.rb +27 -0
  41. data/app/parsers/hydramata/works/value_parsers/date_parser.rb +13 -0
  42. data/app/parsers/hydramata/works/value_parsers/interrogation_parser.rb +18 -0
  43. data/app/parsers/hydramata/works/value_parsers/simple_parser.rb +14 -0
  44. data/app/presenters/hydramata/works/base_presenter.rb +146 -0
  45. data/app/presenters/hydramata/works/dom_attributes_builder.rb +24 -0
  46. data/app/presenters/hydramata/works/entity_presenter.rb +67 -0
  47. data/app/presenters/hydramata/works/fieldset_presenter.rb +54 -0
  48. data/app/presenters/hydramata/works/property_presenter.rb +51 -0
  49. data/app/presenters/hydramata/works/value_presenter.rb +60 -0
  50. data/app/renderers/hydramata/works/entity_renderer.rb +45 -0
  51. data/app/views/hydramata/works/fieldsets/_edit.html.erb +4 -0
  52. data/app/views/hydramata/works/fieldsets/_show.html.erb +8 -0
  53. data/app/views/hydramata/works/fieldsets/_show.json.jbuilder +8 -0
  54. data/app/views/hydramata/works/properties/_edit.html.erb +12 -0
  55. data/app/views/hydramata/works/properties/_show.html.erb +3 -0
  56. data/app/views/hydramata/works/properties/_show.json.jbuilder +1 -0
  57. data/app/views/hydramata/works/works/_edit.html.erb +8 -0
  58. data/app/views/hydramata/works/works/_new.html.erb +8 -0
  59. data/app/views/hydramata/works/works/_show.html.erb +3 -0
  60. data/app/views/hydramata/works/works/_show.json.jbuilder +13 -0
  61. data/app/wranglers/hydramata/works/fedora_wrangler.rb +66 -0
  62. data/bin/rails +12 -0
  63. data/db/migrate/20140606132349_create_hydramata_work_predicates.rb +13 -0
  64. data/db/migrate/20140606132350_create_hydramata_work_types.rb +9 -0
  65. data/db/migrate/20140606132351_create_hydramata_work_predicate_sets.rb +13 -0
  66. data/db/migrate/20140606132352_create_hydramata_work_predicate_presentation_sequences.rb +12 -0
  67. data/db/migrate/20140623200635_add_validations_to_predicates.rb +5 -0
  68. data/db/migrate/20140627134133_adding_item_type_schema_dot_org_to_work_type.rb +5 -0
  69. data/db/migrate/20140627140840_adding_item_prop_schema_dot_org_to_predicate.rb +5 -0
  70. data/db/seeds.rb +36 -0
  71. data/documents/administrative-set-strawperson.md +45 -0
  72. data/documents/diagrams/hydramata-refactor-tasks.dot +88 -0
  73. data/documents/diagrams/hydramata-sip-dip-aip.dot +88 -0
  74. data/documents/diagrams/hydramata-work-architecture.dot +129 -0
  75. data/documents/diagrams/hydramata-work-subcomponents.dot +36 -0
  76. data/documents/diagrams/map-from-database-to-work-object.dot +44 -0
  77. data/documents/diagrams/map-from-fedora-to-work-object.dot +51 -0
  78. data/documents/diagrams/map-from-input-to-work-object.dot +37 -0
  79. data/documents/diagrams/map-from-work-object-to-database.dot +31 -0
  80. data/documents/diagrams/work-rendering.dot +53 -0
  81. data/documents/diagrams/work-structure.dot +32 -0
  82. data/documents/handling-work.md +224 -0
  83. data/documents/high-level-stories.md +105 -0
  84. data/documents/hydramata-components.md +82 -0
  85. data/documents/interface-between-work-and-permissions.md +131 -0
  86. data/documents/interface-between-work-and-workflow.md +6 -0
  87. data/documents/timeline.md +75 -0
  88. data/fs +3 -0
  89. data/gemfiles/rails4.1.gemfile +12 -0
  90. data/gemfiles/rails4.gemfile +13 -0
  91. data/hydramata-works.gemspec +43 -0
  92. data/lib/hydramata-works.rb +23 -0
  93. data/lib/hydramata/works/conversions.rb +21 -0
  94. data/lib/hydramata/works/conversions/exceptions.rb +18 -0
  95. data/lib/hydramata/works/conversions/predicate.rb +22 -0
  96. data/lib/hydramata/works/conversions/predicate_set.rb +28 -0
  97. data/lib/hydramata/works/conversions/presented_fieldsets.rb +28 -0
  98. data/lib/hydramata/works/conversions/presenter.rb +13 -0
  99. data/lib/hydramata/works/conversions/property.rb +31 -0
  100. data/lib/hydramata/works/conversions/property_set.rb +23 -0
  101. data/lib/hydramata/works/conversions/translation_key_fragment.rb +20 -0
  102. data/lib/hydramata/works/conversions/value.rb +20 -0
  103. data/lib/hydramata/works/conversions/work_type.rb +26 -0
  104. data/lib/hydramata/works/engine.rb +31 -0
  105. data/lib/hydramata/works/linters.rb +99 -0
  106. data/lib/hydramata/works/linters/implement_data_definition_interface_matcher.rb +17 -0
  107. data/lib/hydramata/works/linters/implement_entity_interface_matcher.rb +16 -0
  108. data/lib/hydramata/works/linters/implement_predicate_interface_matcher.rb +17 -0
  109. data/lib/hydramata/works/linters/implement_predicate_set_interface_matcher.rb +8 -0
  110. data/lib/hydramata/works/linters/implement_property_set_interface_matcher.rb +8 -0
  111. data/lib/hydramata/works/linters/implement_value_interface_matcher.rb +8 -0
  112. data/lib/hydramata/works/linters/implement_work_type_interface_matcher.rb +13 -0
  113. data/lib/hydramata/works/linters/interface_matcher_builder.rb +36 -0
  114. data/lib/hydramata/works/translator.rb +67 -0
  115. data/lib/hydramata/works/version.rb +5 -0
  116. data/lib/hydramata_works.rb +2 -0
  117. data/lib/tasks/hydramata_work_tasks.rake +4 -0
  118. data/run_each_spec_in_isolation +16 -0
  119. data/run_each_spec_in_isolation.txt +110 -0
  120. data/script/analyzer.rb +124 -0
  121. data/script/fast_specs +22 -0
  122. data/spec/features/fedora_to_in_memory_spec.rb +60 -0
  123. data/spec/features/format_and_view_path_overrides_spec.rb +72 -0
  124. data/spec/features/in_memory_to_output_buffer_spec.rb +109 -0
  125. data/spec/features/instantiate_entity_from_persisted_work_type_spec.rb +26 -0
  126. data/spec/features/new_user_input_to_in_memory_spec.rb +75 -0
  127. data/spec/features/translation_services_spec.rb +107 -0
  128. data/spec/features/validate_entity_based_on_work_type_structure_spec.rb +19 -0
  129. data/spec/fixtures/cassettes/fedora-object.yml +299 -0
  130. data/spec/fixtures/translations.yml +20 -0
  131. data/spec/forms/hydramata/works/entity_form_spec.rb +83 -0
  132. data/spec/forms/hydramata/works/validation_service_spec.rb +32 -0
  133. data/spec/lib/hydramata-work_spec.rb +14 -0
  134. data/spec/lib/hydramata/works/conversions/predicate_set_spec.rb +50 -0
  135. data/spec/lib/hydramata/works/conversions/predicate_spec.rb +43 -0
  136. data/spec/lib/hydramata/works/conversions/presented_fieldsets_spec.rb +52 -0
  137. data/spec/lib/hydramata/works/conversions/presenter_spec.rb +22 -0
  138. data/spec/lib/hydramata/works/conversions/property_set_spec.rb +42 -0
  139. data/spec/lib/hydramata/works/conversions/property_spec.rb +68 -0
  140. data/spec/lib/hydramata/works/conversions/translation_key_fragment_spec.rb +45 -0
  141. data/spec/lib/hydramata/works/conversions/value_spec.rb +36 -0
  142. data/spec/lib/hydramata/works/conversions/work_type_spec.rb +55 -0
  143. data/spec/lib/hydramata/works/translator_spec.rb +81 -0
  144. data/spec/models/hydramata/works/data_definition_spec.rb +53 -0
  145. data/spec/models/hydramata/works/entity_spec.rb +50 -0
  146. data/spec/models/hydramata/works/predicate_presentation_sequences/storage_spec.rb +15 -0
  147. data/spec/models/hydramata/works/predicate_set_spec.rb +63 -0
  148. data/spec/models/hydramata/works/predicate_sets/storage_spec.rb +37 -0
  149. data/spec/models/hydramata/works/predicate_spec.rb +16 -0
  150. data/spec/models/hydramata/works/predicates/storage_spec.rb +78 -0
  151. data/spec/models/hydramata/works/predicates_spec.rb +18 -0
  152. data/spec/models/hydramata/works/presentation_structure_spec.rb +27 -0
  153. data/spec/models/hydramata/works/property_set_spec.rb +135 -0
  154. data/spec/models/hydramata/works/property_spec.rb +74 -0
  155. data/spec/models/hydramata/works/value_spec.rb +61 -0
  156. data/spec/models/hydramata/works/work_type_spec.rb +45 -0
  157. data/spec/models/hydramata/works/work_types/storage_spec.rb +74 -0
  158. data/spec/models/hydramata/works/work_types_spec.rb +16 -0
  159. data/spec/parsers/hydramata/works/datastream_parser_spec.rb +29 -0
  160. data/spec/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser_spec.rb +65 -0
  161. data/spec/parsers/hydramata/works/datastream_parsers/simple_xml_parser_spec.rb +37 -0
  162. data/spec/parsers/hydramata/works/predicate_parser_spec.rb +30 -0
  163. data/spec/parsers/hydramata/works/predicate_parsers/simple_parser_spec.rb +20 -0
  164. data/spec/parsers/hydramata/works/validations_parser_spec.rb +31 -0
  165. data/spec/parsers/hydramata/works/value_parser_spec.rb +22 -0
  166. data/spec/parsers/hydramata/works/value_parsers/simple_parser_spec.rb +20 -0
  167. data/spec/parsers/hydramata/works/value_parsers_spec.rb +36 -0
  168. data/spec/presenters/hydramata/works/base_presenter_spec.rb +111 -0
  169. data/spec/presenters/hydramata/works/dom_attributes_builder_spec.rb +26 -0
  170. data/spec/presenters/hydramata/works/entity_presenter_spec.rb +51 -0
  171. data/spec/presenters/hydramata/works/fieldset_presenter_spec.rb +58 -0
  172. data/spec/presenters/hydramata/works/property_presenter_spec.rb +42 -0
  173. data/spec/presenters/hydramata/works/value_presenter_spec.rb +49 -0
  174. data/spec/renderers/hydramata/works/entity_renderer_spec.rb +25 -0
  175. data/spec/spec_active_record_helper.rb +30 -0
  176. data/spec/spec_fast_helper.rb +12 -0
  177. data/spec/spec_slow_helper.rb +56 -0
  178. data/spec/spec_view_helper.rb +14 -0
  179. data/spec/test_app_templates/lib/generators/test_app_generator.rb +21 -0
  180. data/spec/views/hydramata/works/fieldsets/_edit.html.erb_spec.rb +29 -0
  181. data/spec/views/hydramata/works/fieldsets/_show.html.erb_spec.rb +25 -0
  182. data/spec/views/hydramata/works/properties/_edit.html.erb_spec.rb +22 -0
  183. data/spec/views/hydramata/works/properties/_show.html.erb_spec.rb +22 -0
  184. data/spec/views/hydramata/works/works/_edit.html.erb_spec.rb +23 -0
  185. data/spec/views/hydramata/works/works/_new.html.erb_spec.rb +23 -0
  186. data/spec/views/hydramata/works/works/_show.html.erb_spec.rb +24 -0
  187. data/spec/wranglers/hydramata/works/fedora_wrangler_spec.rb +26 -0
  188. metadata +466 -0
@@ -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,11 @@
1
+ require 'hydramata/works/entity'
2
+ module Hydramata
3
+ module Works
4
+ module Entities
5
+ module_function
6
+ def find(identifier)
7
+ Entity.new(identifier: identifier)
8
+ end
9
+ end
10
+ end
11
+ 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