Size: 3648
Comment:
|
Size: 10536
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= Fedora View Blobs = DOMS employs an overall atomistic data model. Atomistic data models are much more flexible than traditional compound data models, but they have one big (and largely unmet) challenge. When working with data objects you will frequently need to operate on a number of objects as if they were a common whole. The easiest usecase for this is the public dissemination of data. If the data that should go into one Dissemination Information Package is distributed over several objects, the system needs to understand this. The DOMS team has laboured long and hard to find a nice way to model this in a Fedora context. This is their product. == Views == A view is a way of combining objects in the DOMS into a domain-relevant group. It is a way of seeing a number of objects as related - as a whole. Each view contains an object the view is centered around. We call this the main object, and the ID of the View is the ID of the main object. All the other objects in the View are related to the main object by some chain of relations. Therein lies a crucial feature of this View system; '''Rather than having special relations from the main object to all objects in the view, some of the structural relations are annotated to be view relations.''' Or rather, we list the relations that should be followed to find the objects in the view, rather than define view-relations. Actually, we annotate both relations to and from a given object as view relations. The view nessesary for a proper public dissemination of the objects might not be the same as what is required for a useful GUI access, through. The way around this is to define multiple views on the same objects. Each named view has its own main objects and set of annotated relations to follow from these main objects. In no way do they interact, and we can therefore have radically different ways of viewing the same data. |
|
Line 3: | Line 16: |
=== VIEW === | |
Line 5: | Line 17: |
A view is a way of combining objects in the DOMS into a domain-relevant group. It is a way of seeing a number of objects as related - as a whole; information that can be useful for the GUI-generator when generating GUI-windows. | == The VIEW datastream == |
Line 7: | Line 19: |
Those views that we imagine as being suitable for a screen or window in the GUI, are called main views. Each main view contains an object that the main view is centered around. We call this the main object, and the ID of this view is the ID of the main object. Views of other objects are simply called views. The main object is the object that represents the main view - other objects in that view are related to the main object and would presumably be relevant to edit in the GUI at the same time. For a CD modelled in DOMS, for example, a CD object would be the main object, and objects for tracks, cover, lyrics and so on would constitute the rest of the main view. |
Now we come to another crucial feature of this view system; '''Views are defined on the content model level.''' A data object does not identify itself as a main object. The content model for this object tells that all objects of this class are main objects. Everything is defined in the classes of objects, never in the actual data objects. As such, it is easy to change and add views on a collection-wide basis. |
Line 10: | Line 21: |
We imagine that results appearing in searches in the GUI will all be main views. In fact every view that will be the basis for a screen/window will be a main view. | To facilitate this, the "VIEW" datastream in content models have been designated as Reserved and Required. The "VIEW" datastream is, basicaly, a sequence of named views, each with their designated relations. |
Line 12: | Line 23: |
A view for an object O is represented by a Datastream VIEW on the Content Model object for O. This Datastream also mark the object as Main, if this is the case. Please note that the view is defined on Content Model level, so the same rules are used to generate the view for all objects using that Content Model. When creating totally new objects in the GUI, they should subscribe to main view content models from the current collection. | The schema for the VIEW datastream is as follows: {{{ <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/0/1/#" xmlns="http://doms.statsbiblioteket.dk/types/view/0/1/#" elementFormDefault="qualified" attributeFormDefault="unqualified"> |
Line 14: | Line 32: |
The datastream will just contain a list of relation names and reverse relation names. Following these relations will give you the view. | <xsd:element name="views" type="viewsType"/> <xsd:complexType name="viewsType"> <xsd:sequence> <xsd:element name="view" 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:attribute name="mainobject" type="xsd:boolean" default="false"/> </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> }}} |
Line 17: | Line 65: |
Definitions: | === Multilevel Views === |
Line 19: | Line 67: |
* 1-step relations (relations on a content model c of the form "x rel y", meaning that if an object x with content model c has relation rel to another object y, then y will be part the view too. Examples of rel for a CD modelled in DOMS could be hasTrack, hasLyrics,..) | TODO: THIS HSOULD REALLY BE REFORMULATED |
Line 21: | Line 69: |
## * x-step relations. These are relations of the form mentioned above, but they will be followed from an object an arbitrary number of times, as long as the relations match. | |
Line 23: | Line 70: |
* reverse relations (relations of the type "y rel x" on a content model c, where x has model c and y therefore will be included in the view for x) | The system described above works as follows. 1. Start with a main object. 1. Read the list of view relations from its content model 1. Follow these relations to other objects. 1. Keep following these relations until no new objects are found. |
Line 25: | Line 76: |
In addition, we suggest to augment the 1-step approach with the idea of "includes". What this means is that when object O has a view defined by following relations from O once, and an object P is in the view of O, then the view of P will be included in the view of O. ## Note that this is different from x-step relations, where objects in the view of P would not necessarily be included in the view of O. |
The implementation of the view system detailed above does have one lack, which the clever reader might have spotted. It is not local. One of the fundamental design requirements for expansions to Fedora is that data objects should only be described by content models they subscribe to, and content models should only describe the objects that subscribe to them. |
Line 28: | Line 78: |
View datastream contain xml of the form | For that reason, the meaining of the relations mentioned in the "VIEW" datastream is changed somewhat: '''Each data object has a view, encompassing the object and the views of other directly related data objects'''. So, if the VIEW datastream in a main object was |
Line 30: | Line 80: |
<?xml version="1.0" encoding="UTF-8"?> | |
Line 39: | Line 88: |
<view:datastreams> <view:datastream>DC</view:datastream> </view:datastreams> |
|
Line 45: | Line 91: |
then the View of this main object encompass the main object itself, and the View of any objects that the main object has a "doms:hasFile" relation to and any object that has a "doms:isPartOfCollection" relation to this object. | |
Line 46: | Line 93: |
As can be seen, it describes all relations to be followed outwards, both directly and reverse. When including the object, only the named datastreams from the datastreams tag should be used. There can be several views, with different views in an object. The GUI should use the view with the name "GUI". |
The procedure to calculate the total view of a main object is detailed in this bit of pseudo code. It basicly performs a depthfirst search of the objects. The order of the objects in the View does not carry any sort of meaning, and will be random. {{{ Set<Object> visitedObjects; List<Object> CalculateView(Object o) { List<Objects> view = new List<Objects>(); if (visitedObjects.contain(o){ return view; } visitedObjects.add(o); ContentModel c = o.getContentModel(); List<Relations> view-rels = c.getViewRelations(); for (Relation r : view-rels){ view.addAll(CalculateView(r.getObject()); } List<Relations> view-invrels = c.getInverseViewRelations(); for (Relation r : view-invrels){ view.addAll(CalculateView(r.getSubject()); } return view; } }}} == Datastream View == The described view system can designate exactly which objects are part of a view. But it is not always enough to know just the objects. For the GUI, it is nessesary to know exactly which datastreams should be presented, and how. For this purpose we have designed an DS-COMPOSITE extension, which follows the system laid down in FedoraTypeChecking. {{{ <xsd:schema targetNamespace="http://doms.statsbiblioteket.dk/types/dscompositeschema/guirepresentation/0/1/#" xmlns="http://doms.statsbiblioteket.dk/types/dscompositeschema/guirepresentation/0/1/#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="guirepresentation"> <xsd:complexType> <xsd:attribute name="presentAs" use="required"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="importable"/> <xsd:enumeration value="editable"/> <xsd:enumeration value="uploadable"/> <xsd:enumeration value="readonly"/> <xsd:enumeration value="invisible"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema> }}} The semantic meaning of the five types are really decided by the GUI, but the approximate meaning is as follows * importable: The content is inline xml, and should be the result of an import function. Once written, the datastream count as "readonly" * editable: The contents is inline xml, and should be parsed according to their schema, and presented in the GUI. * uploadable: The contents is a link to a file in bitstorage. If the datastream does not exist, the GUI should present a way to upload a file. Otherwise the link to Bitstorage should appear, readonly. * readonly: The contents is inline xml, generated by some other means. The user should be able to read the contents in the GUI, but not change them. The GUI might hide the contents by default, but they must be accessible. * invisible: The GUI should totally disregard this datastream, and behave as if it is not there. This is the default, if no guirepresentation is defined for a datastream. So, an example of a datastream entry in DS-COMPOSITE would now be: {{{ <dsTypeModel ID="DC"> <form MIME="text/xml"/> <extensions name="DOMS"> <schema:schema type="xsd" datastream="DC_SCHEMA" object="doms:DublinCore_Schema"/> <gui:guirepresentation presentAs="editable"/> </extensions> </dsTypeModel> }}} == Content Model Inheritance and Views == DOMS employ inheritance for content models, as detailed in FedoraOntology. This interferes with the View system. As you cannot mark something as NOT being in the view, there are few potential conflicts. For a data object, just take the list of view relations from each of its content models and their ancestors and concatenate and remove duplicates. This is the view relations for this object. Same with the inverse view relations. Previously we required that you could only mark (as view relations) relations that had been defined in the same content model. This will now be problematic. Rather, the rule now is: '''In the VIEW datastream, you can only mention relations that are defined in this content model or one of its parents.''' The inverse relations can still be freely mentioned. The inheritance rules for datastream views is the same as for datastream definitions. So, like the schema extension, where it is only the last schema that takes effect, it is also only the last guirepresentation that should be considered by the gui. |
Fedora View Blobs
DOMS employs an overall atomistic data model. Atomistic data models are much more flexible than traditional compound data models, but they have one big (and largely unmet) challenge. When working with data objects you will frequently need to operate on a number of objects as if they were a common whole. The easiest usecase for this is the public dissemination of data. If the data that should go into one Dissemination Information Package is distributed over several objects, the system needs to understand this.
The DOMS team has laboured long and hard to find a nice way to model this in a Fedora context. This is their product.
Views
A view is a way of combining objects in the DOMS into a domain-relevant group. It is a way of seeing a number of objects as related - as a whole.
Each view contains an object the view is centered around. We call this the main object, and the ID of the View is the ID of the main object. All the other objects in the View are related to the main object by some chain of relations. Therein lies a crucial feature of this View system; Rather than having special relations from the main object to all objects in the view, some of the structural relations are annotated to be view relations. Or rather, we list the relations that should be followed to find the objects in the view, rather than define view-relations. Actually, we annotate both relations to and from a given object as view relations.
The view nessesary for a proper public dissemination of the objects might not be the same as what is required for a useful GUI access, through. The way around this is to define multiple views on the same objects. Each named view has its own main objects and set of annotated relations to follow from these main objects. In no way do they interact, and we can therefore have radically different ways of viewing the same data.
The VIEW datastream
Now we come to another crucial feature of this view system; Views are defined on the content model level. A data object does not identify itself as a main object. The content model for this object tells that all objects of this class are main objects. Everything is defined in the classes of objects, never in the actual data objects. As such, it is easy to change and add views on a collection-wide basis.
To facilitate this, the "VIEW" datastream in content models have been designated as Reserved and Required. The "VIEW" datastream is, basicaly, a sequence of named views, each with their designated relations.
The schema for the VIEW datastream is as follows:
<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/0/1/#" xmlns="http://doms.statsbiblioteket.dk/types/view/0/1/#" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="views" type="viewsType"/> <xsd:complexType name="viewsType"> <xsd:sequence> <xsd:element name="view" 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:attribute name="mainobject" type="xsd:boolean" default="false"/> </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>
Multilevel Views
TODO: THIS HSOULD REALLY BE REFORMULATED
The system described above works as follows.
- Start with a main object.
- Read the list of view relations from its content model
- Follow these relations to other objects.
- Keep following these relations until no new objects are found.
The implementation of the view system detailed above does have one lack, which the clever reader might have spotted. It is not local. One of the fundamental design requirements for expansions to Fedora is that data objects should only be described by content models they subscribe to, and content models should only describe the objects that subscribe to them.
For that reason, the meaining of the relations mentioned in the "VIEW" datastream is changed somewhat: Each data object has a view, encompassing the object and the views of other directly related data objects. So, if the VIEW datastream in a main object was
<view:views xmlns:view="http://doms.statsbiblioteket.dk/types/views/0/1/#"> <view:view name="GUI" mainobject="true"> <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:view> </view:views>
then the View of this main object encompass the main object itself, and the View of any objects that the main object has a "doms:hasFile" relation to and any object that has a "doms:isPartOfCollection" relation to this object.
The procedure to calculate the total view of a main object is detailed in this bit of pseudo code. It basicly performs a depthfirst search of the objects. The order of the objects in the View does not carry any sort of meaning, and will be random.
Set<Object> visitedObjects; List<Object> CalculateView(Object o) { List<Objects> view = new List<Objects>(); if (visitedObjects.contain(o){ return view; } visitedObjects.add(o); ContentModel c = o.getContentModel(); List<Relations> view-rels = c.getViewRelations(); for (Relation r : view-rels){ view.addAll(CalculateView(r.getObject()); } List<Relations> view-invrels = c.getInverseViewRelations(); for (Relation r : view-invrels){ view.addAll(CalculateView(r.getSubject()); } return view; }
Datastream View
The described view system can designate exactly which objects are part of a view. But it is not always enough to know just the objects. For the GUI, it is nessesary to know exactly which datastreams should be presented, and how. For this purpose we have designed an DS-COMPOSITE extension, which follows the system laid down in FedoraTypeChecking.
<xsd:schema targetNamespace="http://doms.statsbiblioteket.dk/types/dscompositeschema/guirepresentation/0/1/#" xmlns="http://doms.statsbiblioteket.dk/types/dscompositeschema/guirepresentation/0/1/#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="guirepresentation"> <xsd:complexType> <xsd:attribute name="presentAs" use="required"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="importable"/> <xsd:enumeration value="editable"/> <xsd:enumeration value="uploadable"/> <xsd:enumeration value="readonly"/> <xsd:enumeration value="invisible"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>
The semantic meaning of the five types are really decided by the GUI, but the approximate meaning is as follows
- importable: The content is inline xml, and should be the result of an import function. Once written, the datastream count as "readonly"
- editable: The contents is inline xml, and should be parsed according to their schema, and presented in the GUI.
- uploadable: The contents is a link to a file in bitstorage. If the datastream does not exist, the GUI should present a way to upload a file. Otherwise the link to Bitstorage should appear, readonly.
- readonly: The contents is inline xml, generated by some other means. The user should be able to read the contents in the GUI, but not change them. The GUI might hide the contents by default, but they must be accessible.
- invisible: The GUI should totally disregard this datastream, and behave as if it is not there. This is the default, if no guirepresentation is defined for a datastream.
So, an example of a datastream entry in DS-COMPOSITE would now be:
<dsTypeModel ID="DC"> <form MIME="text/xml"/> <extensions name="DOMS"> <schema:schema type="xsd" datastream="DC_SCHEMA" object="doms:DublinCore_Schema"/> <gui:guirepresentation presentAs="editable"/> </extensions> </dsTypeModel>
Content Model Inheritance and Views
DOMS employ inheritance for content models, as detailed in FedoraOntology. This interferes with the View system.
As you cannot mark something as NOT being in the view, there are few potential conflicts. For a data object, just take the list of view relations from each of its content models and their ancestors and concatenate and remove duplicates. This is the view relations for this object. Same with the inverse view relations.
Previously we required that you could only mark (as view relations) relations that had been defined in the same content model. This will now be problematic. Rather, the rule now is: In the VIEW datastream, you can only mention relations that are defined in this content model or one of its parents. The inverse relations can still be freely mentioned.
The inheritance rules for datastream views is the same as for datastream definitions. So, like the schema extension, where it is only the last schema that takes effect, it is also only the last guirepresentation that should be considered by the gui.