Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: disregard Deleted Objects

Fedora Repository Views

...

The second requirement, and this is very fundamental, is that A does not know it is being viewed. A is just a data object. It cannot be expected to keep up with new ways of accessing the repository, and new ways to view the data. So, A must not store any information that pertain solely to this or any other view angle. The relations of A should only be structural, in regards to the data it contains.

...

But the angle one views the repository might also affect the number of entries seen. The above, recursive approach will always lead to one entry per data object. The remedy for this is to mark some classes as Entries for a certain view angle. This means that to compute the records for a given view angle, the view of all objects of a class that is an Entry should be computed. This is the view of the repository.

Fedora Implementation 

This section describes how the above could be implemented in Fedora. 

...

It is very simple for a content model to declare itself to be an Entry for a view angle. All it has to do is have a literal relation in the RELS-EXT datastream, by the name "isEntryForViewAngle", in the view namespace (see DomsNameSpacesAndSchemas), to the literal name of the view angle.

...

Code Block
languagexml
<view:isEntryForViewAngle xmlns:view="http://doms.statsbiblioteket.dk/types/view/default/0/21/#">GUI</view:isEntryForViewAngle>

...

Code Block
languagexml
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://doms.statsbiblioteket.dk/types/view/default/0/21/#" xmlns="http://doms.statsbiblioteket.dk/types/view/default/0/21/#" elementFormDefault="qualified" attributeFormDefault="unqualified">
 
	<xsd:element name="views" type="viewsType"/>
 
	<xsd:complexType name="viewsType">
		<xsd:sequence>
			<xsd:element name="viewangle" type="viewType" minOccurs="0" maxOccurs="unbounded"/>
		</xsd:sequence>
	</xsd:complexType>
 
	<xsd:complexType name="viewType">
		<xsd:sequence>
			<xsd:element name="relations" type="relationsType" minOccurs="0" maxOccurs="1"/>
			<xsd:element name="inverse-relations" type="inverse-relationsType" minOccurs="0" maxOccurs="1"/>
		</xsd:sequence>
		<xsd:attribute name="name" type="xsd:string" use="required"/>
	</xsd:complexType>
 
	<xsd:complexType name="relationsType">
		<xsd:sequence>
			<xsd:any namespace="##any" processContents="skip" maxOccurs="unbounded"/>
		</xsd:sequence>
	</xsd:complexType>
 
	<xsd:complexType name="inverse-relationsType">
		<xsd:sequence>
			<xsd:any namespace="##any" processContents="skip" maxOccurs="unbounded"/>
		</xsd:sequence>
	</xsd:complexType>
 
</xsd:schema>

...

Code Block
languagexml
<view:views xmlns:view="http://doms.statsbiblioteket.dk/types/views/0/1/#">
	<view:viewangle name="GUI">
		<view:relations>
			<doms:hasFile xmlns:doms="http://doms.statsbiblioteket.dk/relations/default/0/1/#"/>
		</view:relations>
		<view:inverse-relations>
			<doms:isPartOfCollection xmlns:doms="http://doms.statsbiblioteket.dk/relations/default/0/1/#"/>
		</view:inverse-relations>
	</view:viewangle>
</view:views>

...

Code Block
languagejava
Set<Object> visitedObjects;
 
List<Object> CalculateView(Object o) {
	List<Objects> view = new List<Objects>();
 
	if (visitedObjects.contain(o){
		return view;
	}


	visitedObjects.add(o);
 	if (o.isDeleted){
		return view;
	}
	ContentModel c = o.getContentModel();
	List<Relation> view-rels = c.getViewRelations();
	List<Relation> object-rels = o.getRelations();
 
	for (Relation r : object-rels){
		if (view-rels.contain(r)){
			view.addAll(CalculateView(r.getObject());
		}
	}
 
	List<Relation> view-invrels = c.getInverseViewRelations();
	List<Relation> object-invrels = o.getInverseRelations();
	for (Relation r : object-invrels){
		if (view-invrels.contain(r)){
			view.addAll(CalculateView(r.getSubject());
		}
	}
 
	return view;
}

Content Model Inheritance/Multiple Content Models and Views

...

  • When finding the annotated relations for a given view angle for a data object, get the list from each of the content models, merge it to one list and remove the duplicates. These are the view relations of this object. Do the same with the inverse relations.
  • If a content model marks an object as an Entry for a given view angle, the object is an entry. It does not matter if it has other content models that does not mark it as an entry. An object can of course be an entry for several view angles.   

Update Tracking

This document describes how the backend services should use to view to detect changes in records.

Changing an object and marking the view as updated

Whenever one of the components of a View is changed, the whole View count as updated. As such, any services that subscribe to the View in any way need to be notified. If there is a search index for the Views, and one is updated, its state in the index must be recomputed.

The problem arrives when trying to do this. The View system is designed to ease the computing of a View when knowing the Main object. The reverse is finding the Views, ie. the Main objects, that have this data object in their View. Rather than encoding this information in the model, we chose to keep an external record of all the views.

The external record will be SQL based, or something similar. It will have two tables. The first table, MAINS, will have the columns PID, changed and updated. The PID is the pid of a main object, changed is the timestamp the record was changed and updated is the time stamp the objects in the view was recomputed. The second table, OBJECTS, have just one column, PID, the PID of the object. Each entry in MAINS will have 1..* relations to entries in OBJECTS, and each entry in OBJECTS will have 1..* relations to entries in MAINS.

These lists will be made at one time, by computing the view of all main objects in Doms. All Main objects will have been found, and added to MAIN_OBJECTS. When appropriate changes are made to the objects in DOMS, the object in MAIN_OBJECTS will be marked as changed. Periodically, the View of changed main objects will be computed, and the VIEWS list will be updated, and the objects will be marked as not changed.

We expect to hook the fedora API-M functions directly, so that the updating of the VIEW lists are done without any user input.

There are several situations where the list will be used

  • A data object is modified: (ModifyDatastreanBy*) Look up the PID of the object, find the main object(s), and mark them as modified.
  • A non-main data object is added: Do nothing
  • A main data object is added: (ingest/AddRelationship->Contentmodel) Register the PID as a main object, and mark it as changed.
  • A relation is added/deleted in an data object: (AddRelationship/PurgeRelationship) Look up the PIDs of both the object and the subject of the relation, and mark both's main objects as changed.
  • A relation is modified in a data object:(API?) Look up the PIDs of all the object, and the new and old subject, and find the main objects of all three, and mark these as changed.

 

 

 

...