samvera / hyrax

Hyrax is a Ruby on Rails Engine built by the Samvera community. Hyrax provides a foundation for creating many different digital repository applications.
http://hyrax.samvera.org/
Apache License 2.0
184 stars 124 forks source link

wings persister: ordered properties #3674

Closed hackartisan closed 1 year ago

hackartisan commented 5 years ago

make these pending specs pass

jrgriffiniii commented 5 years ago

Some of the tests for this may remain unresolved given the mechanisms through which the rdf Gem provides a client API for inserting tuples into RDF graph stores:

> graph
=> #<RDF::Graph:0x3fdb360351c8(default)>
> subject
=> #<RDF::URI:0x3fdb34d7adbc URI:>
> predicate
=> #<RDF::Vocabulary::Term:0x3fdb32a58190 ID:http://purl.org/dc/terms/creator>
> stmt = RDF::Statement(subject, predicate, 0.1)
=> #<RDF::Statement:0x3fdb34f707e8(<> <http://purl.org/dc/terms/creator> "0.1"^^<http://www.w3.org/2001/XMLSchema#double> .)>
> graph.send(:insert_statement, stmt)
=> #<RDF::Repository:0x3fdb36035b00()>
> puts graph.dump(:ttl)

<> a <http://pcdm.org/models#Object>,
    <http://projecthydra.org/works/models#Work>;
  <http://purl.org/dc/terms/creator> 1.0e-1 .

...in this case, one is able to successfully insert an xsd:double value for a PCDM Object attribute. However, when attempting to insert a second, duplicate value:

> stmt2 = RDF::Statement(subject, predicate, 0.1)
=> #<RDF::Statement:0x3fdb36316590(<> <http://purl.org/dc/terms/creator> "0.1"^^<http://www.w3.org/2001/XMLSchema#double> .)>
> graph.send(:insert_statement, stmt2)
=> #<RDF::Repository:0x3fdb36035b00()>
> puts graph.dump(:ttl)

<> a <http://pcdm.org/models#Object>,
    <http://projecthydra.org/works/models#Work>;
  <http://purl.org/dc/terms/creator> 1.0e-1 .

...this seems to attempt to just reinsert the same tuple. If a sequence of different tuples is attempted, this does not resolve the issue:

> stmt3 = RDF::Statement(subject, predicate, 0.2)
=> #<RDF::Statement:0x3fdb33360f80(<> <http://purl.org/dc/terms/creator> "0.2"^^<http://www.w3.org/2001/XMLSchema#double> .)>
> graph.send(:insert_statement, stmt3)
=> #<RDF::Repository:0x3fdb36035b00()>
> graph.send(:insert_statement, stmt2)
=> #<RDF::Repository:0x3fdb36035b00()>
> puts graph.dump(:ttl)

<> a <http://pcdm.org/models#Object>,
    <http://projecthydra.org/works/models#Work>;
  <http://purl.org/dc/terms/creator> 1.0e-1,
    2.0e-1 .

Please note that this will prevent tests such as https://github.com/samvera/hyrax/blob/master/spec/wings/valkyrie/persister_spec.rb#L468 from passing.

jrgriffiniii commented 5 years ago

Given that one is going to need to use ActiveFedora::Base#ordered_member_proxies to address some of the other cases, I can still attempt to address the aforementioned problems also using the linked list pattern.

jrgriffiniii commented 5 years ago

https://github.com/samvera/hydra-pcdm/blob/master/lib/hydra/pcdm/models/concerns/pcdm_behavior.rb#L31 offers a valid pattern for dynamic property declarations.

jrgriffiniii commented 5 years ago

https://github.com/samvera/hyrax/commit/7fdba40bffc9d8f910a14e0b50d09970a8dc4922 works for this, but ActiveFedora::Base needs to be switched for a more generic Class.

jrgriffiniii commented 5 years ago

Trying to dynamically cast ordered data values into RDF::Literals results in the following error (when trying to stored an ordered array of Floats):

ActiveFedora::AssociationTypeMismatch:
  1.123 is not a PCDM object.
jrgriffiniii commented 5 years ago

https://github.com/samvera/hyrax/commit/74e257302319daceb9f6bb43d9e938a7ff05f02b gets this passing, but introduces some conflicts with :member_ids, :ordered_nested.

jrgriffiniii commented 5 years ago

Currently, the graph generated for the converted ActiveFedora Model is structured as the following:

<http://127.0.0.1:8986/rest/test/70/1f/7e/e4/701f7ee4-2ae8-41a9-876b-5c8ec1f7239d> a <http://fedora.info/definitions/v4/repository#Container>,
    <http://www.w3.org/ns/ldp#Container>,
    <http://projecthydra.org/works/models#Work>,
...
    <http://www.w3.org/ns/ldp#contains> <http://127.0.0.1:8986/rest/test/70/1f/7e/e4/701f7ee4-2ae8-41a9-876b-5c8ec1f7239d/ordered_authors>;
...

where the contained proxy is the following:

<http://127.0.0.1:8986/rest/test/70/1f/7e/e4/701f7ee4-2ae8-41a9-876b-5c8ec1f7239d/ordered_authors>
        rdf:type                     fedora:Container ;
        rdf:type                     fedora:Resource ;
        rdf:type                     ldp:IndirectContainer ;
...
        ldp:contains                 <http://127.0.0.1:8986/rest/test/70/1f/7e/e4/701f7ee4-2ae8-41a9-876b-5c8ec1f7239d/ordered_authors/737b467c-24bc-466b-a6c8-61ecb863dfae> ;
...

with the contained proxy reference:

<http://127.0.0.1:8986/rest/test/70/1f/7e/e4/701f7ee4-2ae8-41a9-876b-5c8ec1f7239d/ordered_authors/737b467c-24bc-466b-a6c8-61ecb863dfae>
        rdf:type               fedora:Container ;
        rdf:type               ns008:Proxy ;
...
        ns008:proxyFor         <http://127.0.0.1:8986/rest/test/cd/bc/06/52/cdbc0652-c52c-437a-b44f-520bea278975> ;
...

with the proxied resource being:

...
@prefix ns006:  <http://pcdm.org/models#> .
@prefix ns007:  <http://example.com/> .
...
<http://127.0.0.1:8986/rest/test/cd/bc/06/52/cdbc0652-c52c-437a-b44f-520bea278975>
        rdf:type               fedora:Container ;
        rdf:type               ns006:Object ;
...
        ns007:value            "b"^^<http://www.w3.org/2001/XMLSchema#string> ;

This does not consistently seem to preserve the order of the proxied nodes, so I must not quite understand how ordering has been supported using the head and tail properties for the ORE proxies.

jrgriffiniii commented 5 years ago

Where I think that I was mistaken was that I had assumed that active-fedora provides the head/tail behavior for linked lists (separately implemented in https://github.com/samvera/valkyrie/blob/master/lib/valkyrie/persistence/fedora/ordered_list.rb for the Valkyrie Fedora adapter). This will need to be ported into the work on my branch.

jrgriffiniii commented 5 years ago

Attempting to directly use ActiveFedora::Associations::Builder::Orders (https://github.com/samvera/active_fedora/blob/master/lib/active_fedora/associations/builder/orders.rb) just led me towards attempting to rebuild what was already in ActiveFedora::Orders::OrderedList (https://github.com/samvera/active_fedora/blob/master/lib/active_fedora/orders/ordered_list.rb).

jrgriffiniii commented 5 years ago

My previous approach might be the only way in which I proceed. Checking the ActiveFedora::Base Model retrieved from https://github.com/samvera/hyrax/blob/master/lib/wings/valkyrie/query_service.rb#L82 after using the ordered_aggregration mixin does not seem to ensure that the order is preserved.

jrgriffiniii commented 5 years ago

Using the order mixin now indeed does work, but it requires an additional order_aggregates:

@klass.ordered_aggregation(key,
                           class_name: attribute_value_class,
                           type_validator: type_validator,
                           through: :list_source)
@klass.orders(key,
              class_name: attribute_value_class,
              type_validator: type_validator,
              through: :list_source)

The graph yielded by this is now a proper linked list, but this is still not preserving ordering through the ordered_authors method:

## For the linked list
<http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320485483300> <http://www.iana.org/assignments/relation/next> <http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320554802480>;
  <http://www.openarchives.org/ore/terms/proxyFor> <http://127.0.0.1:8986/rest/test/f0/5a/55/e6/f05a55e6-04aa-41fe-a884-9be522a0e383> .

<http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320554802480> <http://www.iana.org/assignments/relation/prev> <http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320485483300>;
  <http://www.openarchives.org/ore/terms/proxyFor> <http://127.0.0.1:8986/rest/test/69/fe/74/66/69fe7466-29b6-4904-b20c-1c88df78ce42> .

## For the proxied first/"head" element in the list
<http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320485483300> <http://www.iana.org/assignments/relation/next> <http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320554802480>;
  <http://www.openarchives.org/ore/terms/proxyFor> <http://127.0.0.1:8986/rest/test/f0/5a/55/e6/f05a55e6-04aa-41fe-a884-9be522a0e383> .

## For the proxied last/"tail" element in the list
<http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320554802480> <http://www.iana.org/assignments/relation/prev> <http://127.0.0.1:8986/rest/test/3d/3b/66/75/3d3b6675-969f-4bce-8787-b44f25f114b3/list_source#g70320485483300>;
  <http://www.openarchives.org/ore/terms/proxyFor> <http://127.0.0.1:8986/rest/test/69/fe/74/66/69fe7466-29b6-4904-b20c-1c88df78ce42> .
jrgriffiniii commented 5 years ago

I've confirmed through testing that the ordering is correct during persistence (the head and tail of the ListSource both point to the expected value). The errors must be arising when the graph is retrieved from the LDP server.

jrgriffiniii commented 5 years ago

Ordering for values is now passing consistently with the changes introduced in https://github.com/samvera/hyrax/commit/962f294a1528931c5e66ce4ad7ca2fb14f6c226a#diff-840493f4e4717280803a72f41b189f4aR77. There are remaining issues affecting the support for other data types.

jrgriffiniii commented 5 years ago

https://github.com/samvera/hyrax/commit/101d11d21421963e25625a7ea61c277617830ede provides ordering successfully, but Wings::NestedResource is derived from ActiveTriples::Resource. Currently these are cast into URIs to support serialization, and I'll need to take a slightly different approach to support these instead.

hackartisan commented 1 year ago

Hyrax on active fedora has never supported ordered properties, so it doesn't make sense for wings to support it. Once downstream applications are fully migrated to another Valkyrie adapter the feature will be available. wontfix.