Living Without Nulls

Summary

OSID Providers may not return null values. This may restrict implementors accustomed to implementing data transfer objects against databases. We need to look at the role of the OsidObject and the OsidForm as independent interfaces to solve this dilemma. 

 

OsidObjects

OsidObjects are consumable interfaces which provide a view into a provider-owned entity. An OSID Provider may or may not provide direct administrative management of the entity. All or part of an OsidObject may be pulled from a data store, the result of data transformation, a representation of a different OsidObject, or completely made up. 

In the case of a null value in a database, it is the responsibility of the OSID Provider to determine the value of a return from a mandatory method. In the OSID world, OSID Consumers get no hint from an OsidObject that a null value exists any more than OSID Consumers can understand that the OSID Provider is using a database.

So, what to do when there is no data to satisfy a mandatory method? That all depends on what it means to the OSID Provider.

Let's use osid.org.resource.ResourceRelationship as an example and try to pretend absolutely no data exists in a database used by an OSID Resource Provider. This ResourceRelationship is broken, but it demonstrates how to be compliant with the specification. 

MethodReturn SyntaxReturn Value or ErrorComments
getId()osid.id.IdUnknownId

This is an implementation of osid.id.Id that identifies "I don't know." However, since every OsidObject is uniquely identified by its Id, there can only be one of these.

One should be able to: ResourceRelationshipLookupSession.getResourceRelationship(brokenResourceRelationship.getId())

If that works, then all is well as far as the OSIDs are concerned. But you have serious design issues if you can't figure out the identifier from your data store.

isCurrent()booleanfalseThis is connected to the nature of the implementation. Unless it is a real-time implementation where the information is current, the answer is always false.
getRecordTypes()osid.type.TypeListEmptyTypeListAn osid.type.TypeList with no Types.
hasRecordType(osid.type.Type)booleanfalseAlways false if getRecordTypes() is empty.
getProperties()osid.PropertyListempty listAn osid.PropertyList with no properties.
getPropertiesByRecordType(osid.type.Type)osid.PropertyListUNSUPPORTEDgetRecordTypes() is empty.
getDisplayNameosid.locale.DisplayTextEmptyDisplayTextAn osid.locale.DisplayText with an empty string.
getDescriptionosid.locale.DisplayTextEmptyDisplayTextAn osid.locale.DisplayText with an empty string.
getGenusTypeosid.type.TypeUnknownTypeAn osid.type.Type that identifies nothing.
isOfGenusTypebooleantrue if the given Type matches getGenusType() 
isEffective()booleanfalse 
getStartDate()osid.calendaring.DateTimeUnknownDateTimeAn implementation of osid.calendaring.DateTime that has an infinite uncertainty. We could have gone another way and implemented the concept of "always" by using an infinite granularity. In this case, isEffective() would always be true. This is an example where the lack of a value may mean two different things – "I don't know" or "forever."
getEndDate()osid.calendaring.DateTimeUnknownDateTime 
hasEndReason()booleanfalse 
getEndReasonId()osid.id.IdILLEGAL_STATEThe end reason state is only available if hasEndReason is true.
getEndReason()osid.process.StateILLEGAL_STATEThe end reason state is only available if hasEndReason is true.
getSourceResourceId()osid.id.IdUnknownResource.getId()We don't know what this is, so let's make up a Resource and return that.
getSourceResource()osid.resource.ResourceUnknownResource 
getDestinationResourceId()osid.id.IdUnknownResource.getId() 
getDestinationResource()osid.resource.ResourceUnknownResource() 
getResourceRelationshipRecord(osid.type.Type)osid.resource.records.ResourceRelationshipRecordUNSUPPORTEDgetRecordTypes() is empty, so we don't support any.

This may seem silly, but many of these Unknown and Empty implementations in the Okapia jamocha package. They are handy for stubbing things in during development.

 

 

Copyright © 2014 Okapia.