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.
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,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,6 @@
1
+ module Hydramata
2
+ module Works
3
+ class Validations
4
+ end
5
+ end
6
+ 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