Dataquay 0.8
Dataquay::ObjectLoader Class Reference

ObjectLoader constructs objects corresponding to nodes in the RDF store and sets properties on those objects corresponding to the node's RDF properties. More...

#include <dataquay/objectmapper/ObjectLoader.h>

Classes

struct  LoadCallback
 

Public Types

enum  FollowOption {
  FollowNone = 0 , FollowObjectProperties = 1 , FollowParent = 2 , FollowSiblings = 4 ,
  FollowChildren = 8
}
 !! document this (after ObjectStorer) – or pull it into ObjectMapperDefs More...
 
enum  AbsentPropertyPolicy { IgnoreAbsentProperties , ResetAbsentProperties }
 
enum  LoadCallbackType { ImmediateCallback , FinalCallback }
 Type of a load callback. More...
 
typedef QHash< Node, QPointer< QObject > > NodeObjectMap
 Map from RDF node to object.
 
typedef int FollowPolicy
 

Public Member Functions

 ObjectLoader (Store *s)
 Create an ObjectLoader ready to load objects from the given RDF store.
 
 ~ObjectLoader ()
 
StoregetStore ()
 
void setTypeMapping (const TypeMapping &)
 
const TypeMappinggetTypeMapping () const
 
void setFollowPolicy (FollowPolicy policy)
 
FollowPolicy getFollowPolicy () const
 
void setAbsentPropertyPolicy (AbsentPropertyPolicy policy)
 
AbsentPropertyPolicy getAbsentPropertyPolicy () const
 
QObject * load (Node node)
 Construct a QObject based on the properties of the given object URI in the object mapper's store.
 
QObjectList loadType (Uri type)
 For each node of the given RDF type found in the store, construct a corresponding QObject, returning the objects.
 
QObjectList loadType (Uri type, NodeObjectMap &map)
 For each node of the given RDF type found in the store, construct a corresponding QObject, updating the map with all resulting node-object correspondences and returning the objects.
 
void reload (Nodes nodes, NodeObjectMap &map)
 Examine each of the nodes passed in, and if there is no corresponding object in the node-object map, load the node as a new QObject and place it in the map; if there is a corresponding object in the node-object map, update it with current properties from the store.
 
QObjectList loadAll ()
 Load and return an object for each node in the store that can be loaded.
 
QObjectList loadAll (NodeObjectMap &map)
 Load and return an object for each node in the store that can be loaded, updating the map with all resulting node-object correspondences.
 
void addLoadCallback (LoadCallback *callback, LoadCallbackType type)
 Register the given callback (a subclass of the abstract LoadCallback class) as providing a "loaded" callback method which will be called after each object is loaded.
 

Detailed Description

ObjectLoader constructs objects corresponding to nodes in the RDF store and sets properties on those objects corresponding to the node's RDF properties.

The class of each object is based on the node's RDF type. TypeMapping is used to relate node types to object classes, and ObjectBuilder is used to construct the objects (which must be subclasses of QObject).

In addition to some specification of which nodes to load, ObjectLoader methods may also take a reference to a NodeObjectMap in which is stored the object corresponding to each loaded node. This map may be used by the caller as a persistent record of node-object relationships, as it is updated on each new ObjectLoader call with any unaffected nodes remaining unchanged in the map.

By default, ObjectLoader loads only those objects passed in to each load() or reload() call. ObjectLoader sets as many QObject properties on each object as possible, given the information available to it:

  • Properties with non-object-type values will be assigned from RDF properties with literal value nodes, provided Node::toVariant is able to carry out the conversion from literal;
  • Properties with object-type values will be assigned from RDF properties with URI value nodes, provided those URI nodes have corresponding objects available to ObjectLoader, i.e. also in the set being loaded or in the NodeObjectMap. (However, see also FollowObjectProperties below.)
  • Properties whose value types are sequenced containers such as QList or std::vector will be assigned from RDF properties with sequence values, provided their container types have been registered with ContainerBuilder;
  • Properties whose value types are set containers such as QSet will be assigned from the aggregation of all RDF properties with the appropriate subject and predicate, provided their container types have been registered with ContainerBuilder.

Some behaviour can be adjusted using setFollowPolicy and setAbsentPropertyPolicy, as follows:

  • FollowPolicy is a set of flags describing how ObjectLoader should recurse from each object to those related to it. It can be used to cause ObjectLoader to load more objects than are explicitly requested. The flag FollowObjectProperties causes objects to be loaded whenever they are required as the values of properties on other objects in the loaded set. The flags FollowParent, FollowSiblings and FollowChildren cause object tree relationships to be followed up, using the "parent" and "follow" properties with the TypeMapping's relationship prefix to determine family relationships.
  • AbsentPropertyPolicy determines how ObjectLoader handles properties of an object that have no definition in the RDF store. These properties are ignored if IgnoreAbsentProperties (the default) is set, but if ResetAbsentProperties is set ObjectLoader will attempt to reset each property to its default value based on the value found in a freshly-constructed default instance of the object class in question.

The load procedure follows a defined order:

  • The requested objects, and any relatives required by the FollowPolicy, are constructed with their default properties (no properties assigned from RDF yet). If the FollowPolicy includes FollowParents or FollowSiblings, these will be followed before the current object is loaded; if FollowChildren, they will be followed afterwards;
  • After all objects have been constructed, those properties that have "simple" RDF literal values are assigned for each object;
  • Next any immediate callbacks registered with addLoadCallback are called for each object that has been loaded (i.e. any object that was either constructed or assigned to). Use immediate callbacks if you need to do any further initialisation work on an object before its neighbours or property objects are loaded.
  • After all "simple" properties have been assigned, any further properties are set (those with container and object types);
  • Finally, any final callbacks registered with addLoadCallback are called for each object that has been loaded (i.e. any object that was either constructed or assigned to).

Note that ObjectLoader always maintains a one-to-one correspondence between QObjects and the RDF nodes that it loads as QObjects. In particular, where multiple objects have properties that refer to the same URI, no more than a single value object will be constructed and the same value object will be assigned to all of those objects' properties. This implies that objects to be loaded using ObjectLoader should be designed so that they do not attempt to "own" (control lifecycle for) any other QObjects that appear as their properties. Ownership must be maintained separately from the property relationship.

ObjectLoader is re-entrant, but not thread-safe.

Definition at line 154 of file ObjectLoader.h.

Member Typedef Documentation

◆ NodeObjectMap

QHash<Node, QPointer<QObject> > Dataquay::ObjectLoader::NodeObjectMap

Map from RDF node to object.

Definition at line 158 of file ObjectLoader.h.

◆ FollowPolicy

Definition at line 180 of file ObjectLoader.h.

Member Enumeration Documentation

◆ FollowOption

!! document this (after ObjectStorer) – or pull it into ObjectMapperDefs

Enumerator
FollowNone 
FollowObjectProperties 
FollowParent 
FollowSiblings 
FollowChildren 

Definition at line 173 of file ObjectLoader.h.

◆ AbsentPropertyPolicy

Enumerator
IgnoreAbsentProperties 
ResetAbsentProperties 

Definition at line 185 of file ObjectLoader.h.

◆ LoadCallbackType

Type of a load callback.

Immediate callbacks are called after each node's literal properties have been assigned but before any child, sibling, property etc relationships are followed. Final callbacks are called after all work has been done on all nodes and the graph is complete.

Enumerator
ImmediateCallback 
FinalCallback 

Definition at line 271 of file ObjectLoader.h.

Constructor & Destructor Documentation

◆ ObjectLoader()

Dataquay::ObjectLoader::ObjectLoader ( Store * s)

Create an ObjectLoader ready to load objects from the given RDF store.

◆ ~ObjectLoader()

Dataquay::ObjectLoader::~ObjectLoader ( )

Member Function Documentation

◆ getStore()

Store * Dataquay::ObjectLoader::getStore ( )

◆ setTypeMapping()

void Dataquay::ObjectLoader::setTypeMapping ( const TypeMapping & )

◆ getTypeMapping()

const TypeMapping & Dataquay::ObjectLoader::getTypeMapping ( ) const

◆ setFollowPolicy()

void Dataquay::ObjectLoader::setFollowPolicy ( FollowPolicy policy)

◆ getFollowPolicy()

FollowPolicy Dataquay::ObjectLoader::getFollowPolicy ( ) const

◆ setAbsentPropertyPolicy()

void Dataquay::ObjectLoader::setAbsentPropertyPolicy ( AbsentPropertyPolicy policy)

◆ getAbsentPropertyPolicy()

AbsentPropertyPolicy Dataquay::ObjectLoader::getAbsentPropertyPolicy ( ) const

◆ load()

QObject * Dataquay::ObjectLoader::load ( Node node)

Construct a QObject based on the properties of the given object URI in the object mapper's store.

The type of class created will be calculated from the rdf:type for the URI, using the current TypeMapping (see TypeMapping::getClassForTypeUri).

Use caution in calling this method when the FollowPolicy is set to anything other than FollowNone. Other objects may be loaded when following connections from the given node according to the current FollowPolicy, but only the object initially requested is actually returned from the function – other objects loaded may be only accessible as parent/child or properties of this node, or in some cases (e.g. FollowSiblings) may even be inaccessible to the caller and be leaked.

◆ loadType() [1/2]

QObjectList Dataquay::ObjectLoader::loadType ( Uri type)

For each node of the given RDF type found in the store, construct a corresponding QObject, returning the objects.

◆ loadType() [2/2]

QObjectList Dataquay::ObjectLoader::loadType ( Uri type,
NodeObjectMap & map )

For each node of the given RDF type found in the store, construct a corresponding QObject, updating the map with all resulting node-object correspondences and returning the objects.

◆ reload()

void Dataquay::ObjectLoader::reload ( Nodes nodes,
NodeObjectMap & map )

Examine each of the nodes passed in, and if there is no corresponding object in the node-object map, load the node as a new QObject and place it in the map; if there is a corresponding object in the node-object map, update it with current properties from the store.

If a node is passed in that does not exist in the store, delete any object associated with it from the map.

◆ loadAll() [1/2]

QObjectList Dataquay::ObjectLoader::loadAll ( )

Load and return an object for each node in the store that can be loaded.

◆ loadAll() [2/2]

QObjectList Dataquay::ObjectLoader::loadAll ( NodeObjectMap & map)

Load and return an object for each node in the store that can be loaded, updating the map with all resulting node-object correspondences.

Note that this loads all suitably-typed nodes found in the store, not the objects found in the map. If there are nodes in the map which are not found in the store, they will be ignored (and not deleted from the map).

◆ addLoadCallback()

void Dataquay::ObjectLoader::addLoadCallback ( LoadCallback * callback,
LoadCallbackType type )

Register the given callback (a subclass of the abstract LoadCallback class) as providing a "loaded" callback method which will be called after each object is loaded.


The documentation for this class was generated from the following file: