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
@@ -0,0 +1,51 @@
|
|
1
|
+
digraph "G" {
|
2
|
+
label="Map from Fedora to Work Object"
|
3
|
+
compound=true;
|
4
|
+
node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
|
5
|
+
|
6
|
+
subgraph 1 {
|
7
|
+
label="Records"
|
8
|
+
node[color="grey" style=filled fillcolor=olivedrab3];
|
9
|
+
fedora[label="Fedora"]
|
10
|
+
work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
|
11
|
+
}
|
12
|
+
|
13
|
+
subgraph cluster_0 {
|
14
|
+
label="Sequence for Transforming\nFedora object to a Work"
|
15
|
+
color="orange"
|
16
|
+
style="filled"
|
17
|
+
node[style=filled fillcolor=white]
|
18
|
+
fedora_request_pid[label="Request PID"]
|
19
|
+
fedora_retrieve_object[label="Retrieve Object"]
|
20
|
+
fedora_instantiate_work[label="Instantiate Work"]
|
21
|
+
fedora_assign_work_type[label="Assign Work Type"]
|
22
|
+
fedora_retrieve_datastreams[label="Retrieve Datastreams"]
|
23
|
+
fedora_for_each_datastream[label="For each Datastream"]
|
24
|
+
fedora_parse_datastream[label="Parse Datastream"]
|
25
|
+
fedora_for_each_property[label="For each Property"]
|
26
|
+
fedora_loop_for_each_property[label="More Properties" shape="diamond"]
|
27
|
+
fedora_loop_for_each_datastream[label="More Datastreams" shape="diamond"]
|
28
|
+
fedora_push_property_to_work_property_set[label="Push Property to Work Property Set"]
|
29
|
+
return_work[label="Return Work object"]
|
30
|
+
|
31
|
+
fedora_request_pid -> fedora_retrieve_object
|
32
|
+
fedora_retrieve_object -> fedora_instantiate_work ->
|
33
|
+
fedora_instantiate_work -> fedora_assign_work_type
|
34
|
+
fedora_assign_work_type -> fedora_retrieve_datastreams
|
35
|
+
fedora_retrieve_datastreams -> fedora_for_each_datastream
|
36
|
+
fedora_for_each_datastream-> fedora_parse_datastream
|
37
|
+
fedora_parse_datastream -> fedora_for_each_property
|
38
|
+
fedora_for_each_property -> fedora_push_property_to_work_property_set
|
39
|
+
fedora_push_property_to_work_property_set -> fedora_loop_for_each_property
|
40
|
+
fedora_loop_for_each_property -> fedora_for_each_property [label="NEXT"]
|
41
|
+
fedora_loop_for_each_property -> fedora_loop_for_each_datastream [label="NO"]
|
42
|
+
fedora_loop_for_each_datastream -> fedora_for_each_datastream [label="NEXT"]
|
43
|
+
fedora_loop_for_each_datastream -> return_work [label="NO"]
|
44
|
+
}
|
45
|
+
|
46
|
+
fedora_instantiate_work -> work[dir=both]
|
47
|
+
fedora_assign_work_type -> work:f2
|
48
|
+
fedora_retrieve_object -> fedora[dir=both]
|
49
|
+
fedora_push_property_to_work_property_set -> work:f3
|
50
|
+
work -> return_work
|
51
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
digraph "G" {
|
2
|
+
label="Map from User Input to Work Object"
|
3
|
+
compound=true;
|
4
|
+
node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
|
5
|
+
|
6
|
+
subgraph 1 {
|
7
|
+
label="Records"
|
8
|
+
node[color="grey" style=filled fillcolor=olivedrab3];
|
9
|
+
input[label="Input"]
|
10
|
+
work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
|
11
|
+
}
|
12
|
+
|
13
|
+
subgraph cluster_0 {
|
14
|
+
label="Sequence for Transforming\nUser Input to a Work"
|
15
|
+
color="orange"
|
16
|
+
style="filled"
|
17
|
+
node[style=filled fillcolor=white]
|
18
|
+
post_user_input[label="Post User Input"]
|
19
|
+
for_each_input_key[label="For each Input Key/Value pair"]
|
20
|
+
determine_predicate_for_key[label="Determine Predicate by Key"]
|
21
|
+
coerce_value[label="Use Predicate to coerce Value into a Property"]
|
22
|
+
push_value_to_onto_work[label="Push Property onto Work"]
|
23
|
+
loop_input_key[label="More input keys?" shape="diamond"]
|
24
|
+
return_work[label="Return Work object"]
|
25
|
+
|
26
|
+
post_user_input -> for_each_input_key
|
27
|
+
for_each_input_key -> determine_predicate_for_key
|
28
|
+
determine_predicate_for_key -> coerce_value
|
29
|
+
coerce_value -> push_value_to_onto_work
|
30
|
+
push_value_to_onto_work -> loop_input_key
|
31
|
+
loop_input_key -> for_each_input_key[label="NEXT"]
|
32
|
+
loop_input_key -> return_work[label="NO"]
|
33
|
+
}
|
34
|
+
coerce_value -> work
|
35
|
+
work -> return_work
|
36
|
+
input -> for_each_input_key
|
37
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
digraph "G" {
|
2
|
+
label="Map from Work Object to Database"
|
3
|
+
compound=true;
|
4
|
+
node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
|
5
|
+
|
6
|
+
subgraph 1 {
|
7
|
+
label="Records"
|
8
|
+
node[color="grey" style=filled fillcolor=olivedrab3];
|
9
|
+
database[label="database"]
|
10
|
+
work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
|
11
|
+
}
|
12
|
+
|
13
|
+
subgraph cluster_0 {
|
14
|
+
label="Sequence for Transforming\nan in Memory Work to the Database"
|
15
|
+
color="orange"
|
16
|
+
style="filled"
|
17
|
+
node[style=filled fillcolor=white]
|
18
|
+
save_work[label="Request to save Work"]
|
19
|
+
validate[label="Validate Work"]
|
20
|
+
request_pid[label="Request PID (if applicable)"]
|
21
|
+
serialize_property_set[label="Serialize PropertySet to JSON"]
|
22
|
+
|
23
|
+
save_work -> validate
|
24
|
+
validate -> work[dir=both]
|
25
|
+
work -> serialize_property_set
|
26
|
+
validate -> request_pid
|
27
|
+
request_pid -> serialize_property_set
|
28
|
+
serialize_property_set -> database
|
29
|
+
}
|
30
|
+
|
31
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
digraph "G" {
|
2
|
+
label="Render a Work"
|
3
|
+
compound=true;
|
4
|
+
node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
|
5
|
+
|
6
|
+
subgraph 1 {
|
7
|
+
label="Records"
|
8
|
+
node[color="grey" style=filled fillcolor=olivedrab3];
|
9
|
+
work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
|
10
|
+
output_buffer[label=" { Rendered output }"]
|
11
|
+
}
|
12
|
+
|
13
|
+
subgraph cluster_0 {
|
14
|
+
label="Sequence for Transforming\nWork to Rendered Output"
|
15
|
+
color="orange"
|
16
|
+
style="filled"
|
17
|
+
node[style=filled fillcolor=white]
|
18
|
+
request_for_content_type[label="Request Work for Content Type (i.e. XML)"]
|
19
|
+
determine_presentation_structure[label="With Presentation Structure"]
|
20
|
+
for_each_fieldset[label="For each Fieldset"]
|
21
|
+
render_fieldset_container[label="Render Fieldset container"]
|
22
|
+
for_each_predicate[label="For each Predicate"]
|
23
|
+
render_predicate_container[label="Render Predicate container"]
|
24
|
+
fetch_work_property_by_predicate[label="Fetch Property from Work by Predicate"]
|
25
|
+
render_work_property[label="Render Work's Property#values"]
|
26
|
+
loop_for_each_predicate[shape="diamond" label="More Predicates?"]
|
27
|
+
loop_for_each_fieldset[shape="diamond" label="More Fieldsets?"]
|
28
|
+
render_remaining_work_properties_in_junk_drawer_fieldset[label="Render remaining Work Properties (if applicable)"]
|
29
|
+
return_output_buffer[label="Return rendered output to requester"]
|
30
|
+
|
31
|
+
request_for_content_type -> determine_presentation_structure
|
32
|
+
determine_presentation_structure -> for_each_fieldset
|
33
|
+
for_each_fieldset -> render_fieldset_container
|
34
|
+
render_fieldset_container -> for_each_predicate
|
35
|
+
for_each_predicate -> render_predicate_container
|
36
|
+
render_predicate_container -> fetch_work_property_by_predicate
|
37
|
+
fetch_work_property_by_predicate -> render_work_property
|
38
|
+
render_work_property -> loop_for_each_predicate
|
39
|
+
loop_for_each_predicate -> for_each_predicate [label="NEXT"]
|
40
|
+
loop_for_each_predicate -> loop_for_each_fieldset [label="NO"]
|
41
|
+
loop_for_each_fieldset -> for_each_fieldset [label="NEXT"]
|
42
|
+
loop_for_each_fieldset -> render_remaining_work_properties_in_junk_drawer_fieldset [label="NO"]
|
43
|
+
render_remaining_work_properties_in_junk_drawer_fieldset -> return_output_buffer
|
44
|
+
}
|
45
|
+
|
46
|
+
fetch_work_property_by_predicate -> work:f3[arrowhead=none]
|
47
|
+
determine_presentation_structure -> work:f2[arrowhead=none]
|
48
|
+
render_fieldset_container -> output_buffer
|
49
|
+
render_predicate_container -> output_buffer
|
50
|
+
render_work_property -> output_buffer
|
51
|
+
render_remaining_work_properties_in_junk_drawer_fieldset -> output_buffer
|
52
|
+
output_buffer -> return_output_buffer
|
53
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
digraph "G" {
|
2
|
+
label="Work Structure"
|
3
|
+
compound=true;
|
4
|
+
node[color="grey15" shape=record penwidth=2 margin="0.15, 0.125"];
|
5
|
+
edge[arrowhead="crowfeet"]
|
6
|
+
|
7
|
+
work[label="{ <f0> Work (in memory) | <f1> #pid | <f2> #work_type | <f3> #property_set }"]
|
8
|
+
work_type [label="{ WorkType | #name | #presentation_structure }"]
|
9
|
+
property [label="{ Property (in memory) | #predicate | #values }"]
|
10
|
+
workflow [label="{ Workflow | #first_task | #task_graph }"]
|
11
|
+
fieldset [label="{ Fieldset | #name | #predicates | #presentation_sequence_number }"]
|
12
|
+
fieldset_predicates [label="{ FieldsetPredicate | #fieldset | #predicate | #presentation_sequence_number }"]
|
13
|
+
predicate [label="{ <f0> Predicate | <f1> #name | <f2> #uri | <f3> #datastream_name | <f4> #predicate_coercer_class_name | <f5> #predicate_parser_class_name | <f6> #indexing_strategy | <f7> #key }"]
|
14
|
+
work_type_datastream_parser [label="{ WorkTypeDatastreamParser | #work_type | #datastream_name | #parser_class_name }"]
|
15
|
+
presentation_structure [label="{ Presentation Structure | #name }"]
|
16
|
+
presentation_context [label="{ PresentationContext | #work_type | #content_type (ie 'solr', 'xml', 'html') | #context (ie 'show', 'edit') | #renderer_class_name }"]
|
17
|
+
work_type_processing_context [label="{ ProcessingContext | #work_type | #context (ie 'create', 'update', 'destroy') }"]
|
18
|
+
property_set [label="{ PropertySet (in memory) | #work | #push(a_property) }"]
|
19
|
+
|
20
|
+
work_type -> work
|
21
|
+
work -> property_set [arrowhead=lcrow]
|
22
|
+
property_set -> property
|
23
|
+
predicate -> property
|
24
|
+
presentation_structure -> fieldset
|
25
|
+
fieldset -> fieldset_predicates
|
26
|
+
predicate -> fieldset_predicates
|
27
|
+
work_type -> presentation_structure
|
28
|
+
work_type -> presentation_context
|
29
|
+
work_type -> work_type_processing_context -> workflow
|
30
|
+
|
31
|
+
work_type -> work_type_datastream_parser
|
32
|
+
}
|
@@ -0,0 +1,224 @@
|
|
1
|
+
The audience for (most of) the specs that verify the feature is a developer.
|
2
|
+
|
3
|
+
RSpec with a statement of target audience for each spec (i.e. product_owner: true).
|
4
|
+
|
5
|
+
# To Render a New Work's SIP Form
|
6
|
+
|
7
|
+
For the requested work_type
|
8
|
+
Instantiate a work with a presentation structure
|
9
|
+
For each fieldset in the instatiated work's presentation structure
|
10
|
+
For each property key (predicate) in the fieldset
|
11
|
+
Render property key with Work's property
|
12
|
+
|
13
|
+
## Done Looks Like
|
14
|
+
|
15
|
+
```gherkin
|
16
|
+
Given work_type 'Article' has the following presentation structure:
|
17
|
+
| fieldset | property_key
|
18
|
+
| :required | [['DC:TITLE', multi_value: true]]
|
19
|
+
| :optional | [['DC:ABSTRACT', multi_value: false]]
|
20
|
+
When I request an HTML form for a new 'Article'
|
21
|
+
Then I should see a well-structured output with CSS selectors:
|
22
|
+
| css_selector
|
23
|
+
| .required .dc-title.multi_value input.value
|
24
|
+
| .optional .dc-abstract input.value
|
25
|
+
And in the response document the .required container preceeds the .optional container.
|
26
|
+
```
|
27
|
+
|
28
|
+
# To Submit a Work's SIP Form
|
29
|
+
|
30
|
+
This is a PO-level feature.
|
31
|
+
|
32
|
+
## Done Looks Like
|
33
|
+
|
34
|
+
```gherkin
|
35
|
+
Given I have a valid form for a work_type
|
36
|
+
When I submit the form
|
37
|
+
Then a SIP is created with a unique PID
|
38
|
+
And the SIP is submitted for processing
|
39
|
+
And a :created response is issued
|
40
|
+
```
|
41
|
+
|
42
|
+
# To Render a Work's SIP
|
43
|
+
|
44
|
+
For the requested PID
|
45
|
+
Find the work in the database and assign the work's properties
|
46
|
+
For each fieldset in the work's presentation structure
|
47
|
+
For each property key (predicate) in the fieldset
|
48
|
+
Render property key with Work's property
|
49
|
+
|
50
|
+
## Done Looks Like
|
51
|
+
|
52
|
+
```gherkin
|
53
|
+
Given a PID that exists in the database
|
54
|
+
And it has the following serialized structure properties:
|
55
|
+
{'DC:TITLE' => ['My Book', 'A Lengthy Treatise'], 'DC:ABSTRACT' => 'Lots of Words'}
|
56
|
+
And its work_type of Article has a presentation structure of:
|
57
|
+
| fieldset | property_key
|
58
|
+
| :required | [['DC:TITLE', multi_value: true]
|
59
|
+
| :optional | ['DC:ABSTRACT']
|
60
|
+
When I request an HTML version of that PID
|
61
|
+
Then I should see a well-structured output with CSS selectors:
|
62
|
+
| css_selector | text_value
|
63
|
+
| .required .dc-title.multi_value .value | "My Book"
|
64
|
+
| .required .dc-title.multi_value .value | "Lengthy Treatise"
|
65
|
+
| .optional .dc-abstract .value | "Lots of Words"
|
66
|
+
And in the response document the .required container preceeds the .optional container.
|
67
|
+
```
|
68
|
+
|
69
|
+
# To Render a Work's AIP
|
70
|
+
|
71
|
+
For the requested PID
|
72
|
+
Find the work in Fedora and assign the work's properties
|
73
|
+
For each fieldset in the work's presentation structure
|
74
|
+
For each property key (predicate) in the fieldset
|
75
|
+
Render property key with Work's property
|
76
|
+
|
77
|
+
## Done Looks Like
|
78
|
+
|
79
|
+
```gherkin
|
80
|
+
Given a PID that exists in Fedora
|
81
|
+
And it has the following RDF properties:
|
82
|
+
| predicate | object
|
83
|
+
| DC:TITLE | My Book
|
84
|
+
| DC:TITLE | A Lengthy Treatise
|
85
|
+
| DC:ABSTRACT | Lots of Words
|
86
|
+
And its work_type of Article has a presentation structure of:
|
87
|
+
| fieldset | property_key
|
88
|
+
| :required | ['DC:TITLE']
|
89
|
+
| :optional | ['DC:ABSTRACT']
|
90
|
+
When I request an HTML version of that PID
|
91
|
+
Then I should see a well-structured output with CSS selectors:
|
92
|
+
| css_selector | text_value
|
93
|
+
| .required .dc-title .value | "My Book"
|
94
|
+
| .required .dc-title .value | "Lengthy Treatise"
|
95
|
+
| .optional .dc-abstract .value | "Lots of Words"
|
96
|
+
And in the response document the .required container preceeds the .optional container.
|
97
|
+
```
|
98
|
+
|
99
|
+
# A workflow processing a SIP
|
100
|
+
|
101
|
+
For queued up SIP Workflow (eg State Machine).
|
102
|
+
A task is a discreet function that can be run in isolation (i.e. characterize all files associated with this SIP).
|
103
|
+
A workflow is composed of a sequence of tasks.
|
104
|
+
|
105
|
+
**Workflow properties**
|
106
|
+
|
107
|
+
A workflow has a unique name
|
108
|
+
A workflow is comprised of tasks definitions
|
109
|
+
A task definition is comprised of a unique name
|
110
|
+
|
111
|
+
**Outstanding questions**
|
112
|
+
|
113
|
+
How is the workflow defined?
|
114
|
+
How each task is defined (i.e. what is the object interface)?
|
115
|
+
How is a workflow processed (i.e. how do we run one task, then respond accordingly and start another task)?
|
116
|
+
How are errors reported/monitored/recovered from?
|
117
|
+
|
118
|
+
*Look to [Heracles](https://github.com/ndlib/heracles) for guidance.*
|
119
|
+
|
120
|
+
## Done Looks Like
|
121
|
+
|
122
|
+
```gherkin
|
123
|
+
Given a workflow with tasks:
|
124
|
+
| task_name | responder
|
125
|
+
| :a | { ok: :b }
|
126
|
+
| :b | { ok: :done }
|
127
|
+
And `first_task :a`
|
128
|
+
When the workflow is started
|
129
|
+
Then task :a is invoked
|
130
|
+
```
|
131
|
+
|
132
|
+
```gherkin
|
133
|
+
Given a workflow with tasks:
|
134
|
+
| task_name | responder
|
135
|
+
| :a | { ok: :b }
|
136
|
+
| :b | { ok: :done }
|
137
|
+
And `first_task :a`
|
138
|
+
When task :a is completed with response :ok
|
139
|
+
Then task :b is invoked
|
140
|
+
```
|
141
|
+
|
142
|
+
```gherkin
|
143
|
+
Given a workflow with tasks:
|
144
|
+
| task_name | responder
|
145
|
+
| :a | { ok: :b }
|
146
|
+
| :b | { ok: :done }
|
147
|
+
And `first_task :a`
|
148
|
+
When task :a throws an exception
|
149
|
+
Then task :b is not invoked
|
150
|
+
And an error is submitted to the monitoring system
|
151
|
+
```
|
152
|
+
|
153
|
+
```gherkin
|
154
|
+
Given a task of :generate_derivatives
|
155
|
+
When the task :generate_derivatives is invoked with a SIP
|
156
|
+
Then derivatives are generated for each of the SIP's associated primary files (i.e. don't generate derivatives for the derivatives)
|
157
|
+
And append the derivatives to the SIP's payload
|
158
|
+
```
|
159
|
+
|
160
|
+
```gherkin
|
161
|
+
Given a task of :run_antivirus
|
162
|
+
When the task :run_antivirus is invoked with a SIP
|
163
|
+
And one of the attached files is a virus
|
164
|
+
Then return a :virus_found
|
165
|
+
```
|
166
|
+
|
167
|
+
```gherkin
|
168
|
+
Given a task of :run_antivirus
|
169
|
+
When the task :run_antivirus is invoked with a SIP
|
170
|
+
And none of the attached files contain a virus
|
171
|
+
Then return :virus_not_found
|
172
|
+
```
|
173
|
+
|
174
|
+
See the [Raw Object Format repository](https://github.com/ndlib/rof).
|
175
|
+
|
176
|
+
```gherkin
|
177
|
+
Given a task :validate_rof
|
178
|
+
And a SIP that is will-formed and ready for ingest
|
179
|
+
When the task :validate_rof is invoked with a SIP
|
180
|
+
Then return :rof_is_valid
|
181
|
+
```
|
182
|
+
|
183
|
+
# To Index a Work's AIP
|
184
|
+
|
185
|
+
SOLR strategy for a given property appears to be the same across work types.
|
186
|
+
Each Property has a SOLR strategy
|
187
|
+
|
188
|
+
# To Represent a Work's Files
|
189
|
+
|
190
|
+
If we ask an object for its datastreams, how do we know which ones are files?
|
191
|
+
Files are attached on children of a Work.
|
192
|
+
There are manifestations of the Work's files in the datastreams.
|
193
|
+
Predicate :realization for the File "Work"
|
194
|
+
|
195
|
+
# Glossary?
|
196
|
+
|
197
|
+
## Work
|
198
|
+
|
199
|
+
Responsible for being a container of the data that is persisted in a data store.
|
200
|
+
|
201
|
+
* Each work has many properties
|
202
|
+
* Each property has a key (predicate) and one or more values
|
203
|
+
|
204
|
+
## Presentation Structure
|
205
|
+
|
206
|
+
Responsible for saying where in the rendering something occurs (eg Title occurs before Author).
|
207
|
+
Provides logical groupings via Fieldsets (eg the "Required fields" occur before the "Optional fields")
|
208
|
+
|
209
|
+
* Each work type has one presentation structure
|
210
|
+
* Each presentation structure has many fieldsets
|
211
|
+
* Each fieldset has many property keys
|
212
|
+
|
213
|
+
## Fieldset
|
214
|
+
|
215
|
+
Responsible for providing logical groupings of properties.
|
216
|
+
Arbitrarily named; use internationalization (I18n) for name and legend.
|
217
|
+
|
218
|
+
## Property Key
|
219
|
+
|
220
|
+
## Work's Property
|
221
|
+
|
222
|
+
## Renderers
|
223
|
+
|
224
|
+
ShowRenderer, EditRenderer, NewRenderer
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# High-level Stories
|
2
|
+
|
3
|
+
Below are stories that are supported in the `./documents` directory.
|
4
|
+
|
5
|
+
## Done
|
6
|
+
|
7
|
+
### (1) Transform in memory Work object to Show JSON Document
|
8
|
+
|
9
|
+
### (2) Transform Fedora object to in memory Work object
|
10
|
+
|
11
|
+
* Done Looks Like: All of the persisted datastreams are in the database are reified in the Work object's #properties.
|
12
|
+
|
13
|
+
### (1) Create an interface for rendering a fieldset
|
14
|
+
|
15
|
+
### (1) Transform in memory Work object to Show HTML Document
|
16
|
+
|
17
|
+
**Done looks like**
|
18
|
+
|
19
|
+
```gherkin
|
20
|
+
Given a work object with the following propety_set:
|
21
|
+
| fieldset | predicate | value |
|
22
|
+
| :required | :title | 'Hello' |
|
23
|
+
| :required | :title | 'World' |
|
24
|
+
| :required | :title | 'Bang!' |
|
25
|
+
| :optional | :abstract | 'Long Text' |
|
26
|
+
| :optional | :abstract | 'Longer Text' |
|
27
|
+
| :optional | :keyword | 'Programming' |
|
28
|
+
When I request an HTML version of the work
|
29
|
+
Then I should have the following css-selectors and text:
|
30
|
+
| css_selector | text |
|
31
|
+
| .required .title .label | Title |
|
32
|
+
| .required .title .value | Hello |
|
33
|
+
| .required .title .value | World |
|
34
|
+
| .required .title .value | Bang! |
|
35
|
+
| .optional .abstract .label | Abstract |
|
36
|
+
| .optional .abstract .value | Long Text |
|
37
|
+
| .optional .abstract .value | Longer Text |
|
38
|
+
| .optional .keyword .label | Keyword |
|
39
|
+
| .optional .keyword .value | Programming |
|
40
|
+
```
|
41
|
+
|
42
|
+
## Must Have
|
43
|
+
|
44
|
+
### (4) Transform in memory Work object to New HTML Document
|
45
|
+
|
46
|
+
**Done looks like**
|
47
|
+
|
48
|
+
```gherkin
|
49
|
+
Given a work object with the following propety_set:
|
50
|
+
| fieldset | predicate | value |
|
51
|
+
| :required | :title | 'Hello' |
|
52
|
+
| :required | :title | '' |
|
53
|
+
| :optional | :abstract | '' |
|
54
|
+
| :optional | :keyword | '' |
|
55
|
+
When I request an HTML version of the work
|
56
|
+
Then I should have the following css-selectors and text:
|
57
|
+
| css_selector | text |
|
58
|
+
| fieldset.required.caption | 'Required' |
|
59
|
+
| .required .title label.label | 'Title' |
|
60
|
+
| .required .title input.value[name=work[title]] | 'Hello' |
|
61
|
+
| .required .title input.value[name=work[title]] | '' |
|
62
|
+
| fieldset.optional.caption | 'Optional' |
|
63
|
+
| .optional .abstract input.value[name=work[abstract]] | '' |
|
64
|
+
| .optional .keyword input.value[name=work[keyword]] | '' |
|
65
|
+
```
|
66
|
+
|
67
|
+
### (3) Create an interface for rendering a property
|
68
|
+
|
69
|
+
* in Edit HTML
|
70
|
+
* in New HTML
|
71
|
+
* in Show HTML
|
72
|
+
* in Solr Document
|
73
|
+
|
74
|
+
### (1) Transform Database object to in memory Work object
|
75
|
+
|
76
|
+
* Done Looks Like: All of the persisted properties in the database are reified in the Work object's #properties.
|
77
|
+
|
78
|
+
### (2) Transform Solr object to in memory Work object
|
79
|
+
|
80
|
+
### (2) Transform in memory Work object to SOLR Document
|
81
|
+
### (3) Transform in memory Work object to Raw Datastreams
|
82
|
+
### (1) Transform in memory Work object to Edit HTML Document
|
83
|
+
### (1) Transform in memory Work object to Database
|
84
|
+
### (3) Transform in memory Work to Fedora object
|
85
|
+
### (1) Transform user input from Edit Form to in memory Work object
|
86
|
+
### (1) Transform user input from New Form to in memory Work object
|
87
|
+
|
88
|
+
#### Components
|
89
|
+
|
90
|
+
* Define a Work type's suggested predicates
|
91
|
+
* Define a Work type's presentation structure
|
92
|
+
* Define an abstract Predicate
|
93
|
+
* Create a presented fieldset
|
94
|
+
* Should render itself for its context
|
95
|
+
* Create a presented property
|
96
|
+
* Should render itself for its context
|
97
|
+
|
98
|
+
## Nice to Have
|
99
|
+
|
100
|
+
* Transform in memory Work object to New JSON Document
|
101
|
+
|
102
|
+
## There are Small Work Items
|
103
|
+
|
104
|
+
* Predicate parsers and coercers
|
105
|
+
* Datastream parsers and coercers
|