hydramata-works 0.0.1.prerelease
Sign up to get free protection for your applications and to get access to all the features.
- 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
|