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,82 @@
1
+ # Hydramata Components
2
+
3
+ In terms of dependencies, the Work component should happen first.
4
+ Then the Permissions and Workflow components can happen independently.
5
+
6
+ We can begin working on Permissions and Workflow as the Work component is in process.
7
+ Permissions will be easier to do in isolation whereas Workflow will require greater coordination with the Work component effort.
8
+
9
+ Once the Work, Permissions, and Workflow components are complete, most other components could proceed.
10
+
11
+ ## Hydramata::Works
12
+
13
+ A way to suggest the properties and structure of different work types (ie Article, Dataset, etc) while allowing the persisted work to be the authority of its properties.
14
+
15
+ Responsible for defining how a work is:
16
+
17
+ * Represented at three different levels (ie Persistence, Application Object, and User Output).
18
+ * Transformed from one level to another (ie Persistence -> Application Object; Application Object -> User Output).
19
+
20
+ ### What pain points is Hydramata::Works addressing?
21
+
22
+ * Remove duplication of knowledge of a work's data and structure.
23
+ Presently knowledge of a work's data is in the ActiveFedora model, datastreams, show page, and edit page.
24
+ * Allow institutions to define their own work types.
25
+ * Improve the sharability of components that interact with a well-defined narrow interface for a work.
26
+ * Allow institutions to add new work types without requiring deploys.
27
+ * Allow institutions to modify existing work types without always requiring data migrations.
28
+ * Acknowledge that our understanding of the suggested structure and properties of a work is changing over time, but this shouldn't mandate a migration.
29
+
30
+ ## Hydramata::Permissions
31
+
32
+ A common interface for application level permissions. That is to say "Can I view this work?" or perhaps more specifically, "When I view this work, what do I see?"
33
+
34
+ Responsible for defining what an agent interacting with the application can do.
35
+
36
+ The scope of the permissions system is beyond just works.
37
+ Can this person, because they are a member of these groups take this specific action.
38
+ And the action could be:
39
+
40
+ * "Show the Resque worker queue."
41
+ * "Masquerade as another user."
42
+ * "Edit a given work."
43
+
44
+ ### What pain points is Hydramata::Permissions addressing?
45
+
46
+ * Normalize the application permissions (i.e. Repository Manager and System Manager are handled differently from a Work's editor)
47
+ * Expose a well-defined narrow interface for Groups, so that each institution could create an adaptor that suits them.
48
+ * Allow institutions to add new roles to represent a set of abilities (ie a "Librarian" role could edit all AIPs)
49
+
50
+ ## Hydramata::Worksflow
51
+
52
+ A common processing architecture for running tasks that need not be run within a request cycle.
53
+
54
+ Responsible for providing a asynchronous processing capabilities.
55
+ This could be ingesting SIPs, sending emails to depositors, running characterizations, and generating derivatives.
56
+
57
+ ### What pain points is Hydramata::Permissions addressing?
58
+
59
+ * Acknowledging the fragility of deposit when handled within request queue ([See Google Doc](https://docs.google.com/document/d/1AyEFK0PTIt4STFcsNw2x5zeJthP0rRxKX7K0Yv5O_hM/edit)).
60
+ * Acknowledging the transactional challenges of coordinating updates to Fedora and SOLR so as to deliver on the promise of preservation.
61
+ * Teasing apart numerous small tasks that can be run and tested in isolation.
62
+ * Speeding up the responsiveness and scalability of user deposit.
63
+
64
+ ## Hydramata::AdministrativeSet
65
+
66
+ A conceptual place where Works are put.
67
+
68
+ As it relates to the Hydramata::Permissions component, the AdministrativeSet is a Resource.
69
+ An AdministrativeSetMembership is also a Resource.
70
+
71
+ If I want to create a Work, I need to declare which AdministrativeSet I want to put it in.
72
+ "Can I create AdministrativeSetMembership (an Article in this AdministrativeSet)?"
73
+
74
+ ### @TODO
75
+
76
+ Consider how we persist a Work's AdministrativeSet.
77
+ Is this uneditable?
78
+ Is the attribute shown on the page?
79
+ How to enforce that?
80
+
81
+ The reification strategy.
82
+ If a property is present but not editable, discard any value associated with the property when we attempt to.
@@ -0,0 +1,131 @@
1
+ # DRAFT - Interface between Work and Permissions component - DRAFT
2
+
3
+ ## Initial Interface
4
+
5
+ For a Work to assert its available predicates, the Permissions subsystem should:
6
+
7
+ * Provide a `Hydramata::Permissions.roles_for(agent)` service. Responsible for getting all of the roles of an agent.
8
+ * Each of the returned objects from `Hydramata::Permissions.roles_for` should:
9
+ * have a unique identifying symbol from which the Work subsystem can craft the appropriate Work Reification Strategy (which properties go on the work value object that is being passed through the system).
10
+
11
+ The Permissions subsystem is concerned with these three concepts:
12
+
13
+ * Resource - exposes the following methods `#persisted?`, `#to_key`, `#class#model_name` (a subset of the [ActiveModel::Lint::Test](http://api.rubyonrails.org/classes/ActiveModel/Lint/Tests.html))
14
+ * Action - what is the agent trying to do with the resource? This would likely be the Controller#action_name
15
+ * Agent - who (or what) is attempting to take action on the resource
16
+
17
+ For the Permissions subsystem to interact with a Work, the Work object should implement a Resource interface.
18
+
19
+ ### Searching for Resources
20
+
21
+ This is a more complicated case. When searching for Works there are two permission checks:
22
+
23
+ 1. "Can I create a Search?" - In other words, can I perform a search?
24
+ 1. "Can I show a given Search result?" - In other words, what are the documents returned in the search?
25
+
26
+ The Permission system is responsible for appending additional restrictions to Search object/query.
27
+ The additional restrictions would modify the Search by in effect adding "AND I can Show" to the search query.
28
+
29
+ For a search request, we will search across all indexed properties of the solr documents, regardless of permissions.
30
+ When we render a search result document, only properties that the user can access will be available for rendering to the output buffer.
31
+
32
+ Said another way:
33
+
34
+ ```gherkin
35
+ Feature: I can search amongst properties that I may not be able to access
36
+ As patron of the library
37
+ I want to...
38
+ So that I...
39
+
40
+ Scenario:
41
+ Given an Agent
42
+ And there exists the following indexed Works:
43
+ | work_type | properties |
44
+ | Article | { title: 'Hello', secret: 'Dog' } |
45
+ | Book | { title: 'Dog' } |
46
+ | Article | { title: 'World' } |
47
+ And I can accessess the following predicates by Work Type:
48
+ | work_type | predicates |
49
+ | Article | [:title] |
50
+ | Book | [:title] |
51
+ When the Agent searches for "Dog"
52
+ Then they will find two Works with the following properties:
53
+ | work_type | properties |
54
+ | Article | { title: 'Hello' } |
55
+ | Book | { title: 'Dog' } |
56
+ ```
57
+
58
+ ## Initial Scenarios
59
+
60
+ ```gherkin
61
+ Feature: Role-based access to Predicates
62
+ As the steward of repository content
63
+ I want to ensure that the appropriate content is available based on the requesting Agent.
64
+ And that some content is not available.
65
+ So that I am upholding any institutional policies and protocols regarding content.
66
+
67
+ As the Work component is responsible for wrangling the Work from persistence to memory to output buffer,
68
+ it would be the responsibility of the Work component to negotiate any predicate level access.
69
+
70
+ Scenario Outline:
71
+
72
+ Given an Agent with role <role>
73
+ And a Work of work type <work_type> with predicates <predicates>
74
+ And the role <role> can only access the following predicates <accessible_predicates>
75
+ When the Agent requests the Work
76
+ Then the Work asserts that the Agent only accesses the following predicates <accessible_predicates>
77
+
78
+ Examples:
79
+ | role | work_type | predicates | accessible_predicates |
80
+ | Anonymous | Article | :identifier, :title | :identifier |
81
+ | Librarian | Article | :identifier, :title | :identifier, :title |
82
+ | Librarian | Article | :identifier, :title | :identifier, :title |
83
+ ```
84
+
85
+ ```gherkin
86
+ Feature: Work object interacting with Permissions
87
+ As the steward of repository content
88
+ I want to ensure that the appropriate content is available based on the requesting Agent.
89
+ And that some content is not available.
90
+ So that I am upholding any institutional policies and protocols regarding content.
91
+
92
+ Scenario Outline:
93
+
94
+ Given an Agent with role <role>
95
+ And a Work of work type <work_type>
96
+ When the Agent requests the Work
97
+ Then the Permissions subsystem asserts that the Agent is <access_state> access to the Work.
98
+
99
+ Examples:
100
+ | role | work_type | access_state |
101
+ | Anonymous | Article | not allowed |
102
+ | Librarian | Article | allowed |
103
+
104
+ Scenario:
105
+
106
+ Given an Agent with roles:
107
+ | role |
108
+ | Professor |
109
+ | Librarian |
110
+ And a Work of work type Article
111
+ And an Article has the following role-based permissions:
112
+ | role | access_state |
113
+ | Professor | not allowed |
114
+ | Librarian | allowed |
115
+ When the Agent requests the Work
116
+ Then the Permissions subsystem asserts that the Agent is allowed access to the Work.
117
+
118
+ Scenario:
119
+
120
+ Given an Agent with roles:
121
+ | role |
122
+ | Professor |
123
+ | Librarian |
124
+ And a Work of work type Article
125
+ And an Article has the following role-based permissions:
126
+ | role | access_state |
127
+ | Professor | not allowed |
128
+ | Librarian | allowed |
129
+ When the Agent requests the Work
130
+ Then the Permissions subsystem asserts that the Agent is allowed access to the Work.
131
+ ```
@@ -0,0 +1,6 @@
1
+ # DRAFT - Interface between Work and Workflow component - DRAFT
2
+
3
+ ## Initial Interface
4
+
5
+
6
+ ## Initial Scenarios
@@ -0,0 +1,75 @@
1
+ # Proposed Hydramata Timeline
2
+
3
+ ## Work
4
+
5
+ ### Where does this exist in Curate?
6
+
7
+ Presently the definition of a Work is spread across six major concerns:
8
+
9
+ * Model - exposes attributes, validations, defines model level indexing strategy
10
+ * Datastream - exposes attributes and indexing strategy
11
+ * Actor - handles input interactions, DOI minting, file uploading
12
+ * Show page - renders attributes
13
+ * Edit page - renders attributes (and values)
14
+ * Index/search result - renders attributes and values
15
+
16
+ The sequence of rendered attributes is not kept in sync between the different view contexts.
17
+
18
+ ### Replacement Strategy
19
+
20
+
21
+ 1. Define the narrow public interface for a Work's expected methods and their behavior.
22
+ This involves providing object linters to verify the API.
23
+ 1. Establish application plugin structure.
24
+ 1. Data-driven presentation structure for Work Types
25
+ This addresses the rendering aspect of the Show/New/Edit page.
26
+ 1. Splice in a shim for rendering existing Curate work types via data-driven methods
27
+ 1. Data-driven predicate definition for Work Types
28
+ This addresses indexing strategy, validation, and configurablity of work types.
29
+ 1. Splice in the Work Wrangler to reify Fedora objects
30
+ 1. Splice in WorkActorShim to preserve existing Curate Actor behaviors
31
+
32
+ ## Workflow
33
+
34
+ ### Where does this exist in Curate?
35
+
36
+ Presently this exists in the Actor and spread across numerous callbacks for Hydra components
37
+
38
+ * Creating child GenericFiles under a Work
39
+ * Derivatives
40
+ * Remote Identifiers (DOIs)
41
+ * Generate checksums
42
+ * Characterization
43
+ * Assigning a representative image
44
+ * Running anti-virus
45
+ * Establish provenance of attachments
46
+
47
+ ### Replacement Strategy
48
+
49
+ 1. Create or leverage existing Workflow project (i.e. push Heracles over the hump) to implement an asynchronous messaging system.
50
+ 1. Create single-focus tasks (i.e. hydramata/works/tasks/generate_derivatives) that behave well within the Workflow subsystems
51
+ 1. Replace existing Curate actors with data-driven Workflows.
52
+ This will obviate the need for the WorkActorShim as the Workflows expect to interact with objects that implement the Work interface.
53
+
54
+ ## Permissions
55
+
56
+ ### Where does this exist in Curate?
57
+
58
+ This information is spread across:
59
+
60
+ * Hydra::AccessControls
61
+ * The repository manager YML file
62
+ * The application manager YML file
63
+
64
+ The concerns are partially merged into CanCan's expected [Ability class](https://github.com/projecthydra-labs/curate/blob/master/app/models/concerns/curate/ability.rb)
65
+
66
+ The enforcement is spread across controllers and views, leveraging both CanCan queries (i.e. `can?(:edit, @work)`)
67
+ and inline `if current_user.repository_manager?`.
68
+
69
+ ### How to replace these interactions
70
+
71
+ ## Administrative Context
72
+
73
+ ### Where does this exist in Curate?
74
+
75
+ No where. This is a yet to be defined concept.
data/fs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ script/fast_specs
@@ -0,0 +1,12 @@
1
+ source 'http://rubygems.org'
2
+
3
+ file = File.expand_path("../../Gemfile", __FILE__)
4
+
5
+ if File.exists?(file)
6
+ puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
7
+ instance_eval File.read(file)
8
+ end
9
+ gem 'sass', '~> 3.2.15'
10
+ gem 'sprockets', '~> 2.11.0'
11
+
12
+ gem 'rails', '4.1.0'
@@ -0,0 +1,13 @@
1
+ source 'http://rubygems.org'
2
+
3
+ file = File.expand_path("../../Gemfile", __FILE__)
4
+
5
+ if File.exists?(file)
6
+ puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
7
+ instance_eval File.read(file)
8
+ end
9
+
10
+ gem 'sass', '~> 3.2.15'
11
+ gem 'sprockets', '~> 2.11.0'
12
+
13
+ gem 'rails', '4.0.3'
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require 'hydramata/works/version'
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = 'hydramata-works'
9
+ s.version = Hydramata::Works::VERSION
10
+ s.authors = [
11
+ 'Jeremy Friesen'
12
+ ]
13
+ s.email = [
14
+ 'jeremy.n.friesen@gmail.com'
15
+ ]
16
+ s.homepage = 'https://github.com/jeremyf/hydramata-work'
17
+ s.summary = 'Provide a well defined data-structure to ease the interaction between differing layers of a Hydra application.'
18
+ s.description = 'Provide a well defined data-structure to ease the interaction between differing layers of a Hydra application.'
19
+ s.required_ruby_version = '~> 2.0'
20
+
21
+ s.license = 'APACHE2'
22
+
23
+ s.files = `git ls-files -z`.split("\x0")
24
+ s.executables = s.files.grep(%r{^bin/}) do |f|
25
+ f == 'bin/rails' ? nil : File.basename(f)
26
+ end.compact
27
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
28
+ s.require_paths = ['lib']
29
+
30
+ s.add_dependency "rails", "~> 4.0"
31
+ s.add_dependency 'rdf', '~> 1.1'
32
+ s.add_dependency 'psych', '~> 2.0.5'
33
+
34
+ s.add_development_dependency 'engine_cart', '~> 0.3'
35
+ s.add_development_dependency 'rspec', '~> 3.0'
36
+ s.add_development_dependency 'rspec-rails', '~> 3.0'
37
+ s.add_development_dependency 'rspec-html-matchers', '~>0.6'
38
+ s.add_development_dependency 'sqlite3', '~> 1.3'
39
+ s.add_development_dependency 'rubydora', '~> 1.7'
40
+ s.add_development_dependency 'vcr', '~> 2.9'
41
+ s.add_development_dependency 'webmock', '~> 1.18'
42
+ s.add_development_dependency 'database_cleaner', '~> 1.3'
43
+ end
@@ -0,0 +1,23 @@
1
+ require 'hydramata/works/engine' if defined?(Rails)
2
+ module Hydramata
3
+ # Responsible for providing a well defined data-structure to ease the
4
+ # interaction between differing layers of an application.
5
+ #
6
+ # * Persistence Layer
7
+ # * In Memory
8
+ # * Rendering/Output Buffer
9
+ module Works
10
+ module_function
11
+ def table_name_prefix
12
+ 'hydramata_works_'
13
+ end
14
+
15
+ # Because I am not using isolate_namespace for Hydramata::Works::Engine
16
+ # I need this for the application router to find the appropriate routes.
17
+ # @api private
18
+ def use_relative_model_naming?
19
+ true
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ require 'hydramata/works/conversions/predicate'
2
+ require 'hydramata/works/conversions/predicate_set'
3
+ require 'hydramata/works/conversions/presented_fieldsets'
4
+ require 'hydramata/works/conversions/presenter'
5
+ require 'hydramata/works/conversions/property'
6
+ require 'hydramata/works/conversions/property_set'
7
+ require 'hydramata/works/conversions/translation_key_fragment'
8
+ require 'hydramata/works/conversions/value'
9
+ require 'hydramata/works/conversions/work_type'
10
+
11
+ module Hydramata
12
+ module Works
13
+ # Taking a que from Avdi Grimm's "Confident Ruby", the Conversion module
14
+ # is responsible for coercing the inputs to another format.
15
+ #
16
+ # This is somewhat experimental, though analogous to the Array() method in
17
+ # base ruby.
18
+ module Conversions
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'hydramata/works/conversions/exceptions'
2
+
3
+ module Hydramata
4
+ module Works
5
+ # Taking a que from Avdi Grimm's "Confident Ruby", the Conversion module
6
+ # is responsible for coercing the inputs to another format.
7
+ #
8
+ # This is somewhat experimental, though analogous to the Array() method in
9
+ # base ruby.
10
+ module Conversions
11
+ class ConversionError < RuntimeError
12
+ def initialize(class_name, input)
13
+ super("Could not convert #{input.inspect} to #{class_name}")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'hydramata/works/conversions/exceptions'
2
+ require 'hydramata/works/predicate'
3
+ require 'hydramata/works/predicates'
4
+
5
+ module Hydramata
6
+ module Works
7
+ module Conversions
8
+ private
9
+ def Predicate(input)
10
+ return input.to_predicate if input.respond_to?(:to_predicate)
11
+
12
+ case input
13
+ when Predicate then input
14
+ when String, Symbol then Predicates.find(input)
15
+ when Hash then Predicates.find(input.fetch(:identity), input)
16
+ else
17
+ raise ConversionError.new(:Predicate, input)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end