Adaptive Objects
Throughout these guides, we will refer to objects, many of which were initially created in JSON format before being generated into native C structures and stored in physical memory. For convenience, we will often represent objects in the guides in JSON format. To learn more about the JSON format, please visit http://www.json.org.
Adaptive Object Model
    
            Adaptive Objects are similar to many Object 
            paradigms you may have been introduced to in a programming or data 
            structure lessons. They contain data in a structured way, just as 
            key/values, dictionaries or hashes encapsulate data in other popular 
            languages. With Adaptive Objects, the object 
            that contains data is described by another object, called its 
            Object Type. The keys and values on the Adaptive 
            Object are referred to as Adaptive Properties 
            and the definitions of those properties, which are contained within 
            the Object Type definition, are called Property 
            Types. These definitions provide us with useful metadata 
            that can be used for data validation, user interface representation, 
            authorization controls, and even data transformation and generation.  
            The following diagram illustrates these relationships, and is 
            commonly referred to as the Type Square Pattern:
        
An Adaptive Object may have one or more Adaptive Properties. Likewise, an Object Type may have one or more Property Types. Moreover, an Object Type describes one or more Adaptive Object instances, just as an Adaptive Property Type may describe one or more Adaptive Properties. Let's examine these objects, in detail, in order to get a better sense of how they are related.
    
            Let's define an Adaptive Object of interest with something that is 
            familiar. As a Person, I have some properties 
            that describe me. For example, I have a First Name, 
            a Last Name and an Age.
        
{
    "First Name": "Kevin",
    "Last Name": "Smith",
    "Age": 40
}
    
            Other people also have names and ages. Therefore, we can describe a
            Person using an Object Type. This Object Type contains Property 
            Types, declared under a special name, 
            propertyTypes, for "First Name", "Last Name" and 
            "Age". In this example, you will find "First Name", "Last Name" and 
            "Age" all have Property Type values of structured objects that 
            contain information about them. "First Name" and "Last Name" have a 
            dataType of string and 
            Age is described as an 
            integer. Both have additional 
            description properties that provide additional:
        
{
    "propertyTypes": {
        "First Name": {
            "dataType": "string",
            "description" "This is a person's first name."
        },
        "Last Name": {
            "dataType": "string",
            "description": "This is a person's last name."
        },
        "Age": {
            "dataType": "integer",
            "description": "This is a person's age, in years."
        }
    }
}
    
            This very simple example also demonstrates an aspect of Adaptive 
            Objects that may not seem obvious on the surface. "Object Type" 
            Person is also an Adaptive Object, and "propertyTypes" here is 
            also an Adaptive Property, whose value is an object containing
            "First Name", "Last Name" and "Age". It's only when we establish 
            the Object Type relationship between these two that we apply 
            semantic meaning to this object. In fact, the Person Object Type in 
            this example also has an Object Type, called 
            _AdaptiveObjectType_, which describes how an
            Adaptive Object Type is structured. Likewise, the object type 
            _AdaptivePropertyType_, is used to describe how 
            an Adaptive Property Type is structured. These two special objects
            are defined by Core as compiled object definitions. We can change
            the Person Object Type, because it's an object not defined to core,
            but we cannot change "_AdaptiveObjectType_" or
            "_AdaptivePropertyType_" without recompiling Adaptive Framework.
        
Object Types and Property Types
In the previous section, we demonstrated how an Object Type and its Property Types can describe an instance of an Object. We also introduced the idea that Object Types and Property Types are also objects, themselves, described by "_AdaptiveObjectType_" and "_AdaptivePropertyType_" and defined as compiled-in objects to Adaptive Framework Core. Let's first look at what makes an Adaptive Property Type, using the example from the previous section. The Adaptive Property "First Name" had a Property Type definition that included a property called "dataType". The dataType property is an important one that we will get into more details later. Here is a more complete list of properties that define a Property Type:
| Property | Description | 
|---|---|
additionalConstraints | Additional constraint for the value. | 
allowQuery | If false, this value can NEVER be queried. If true, this value can be queried if allowed by authorization policy. | 
allowWrite | If true, the value can be written if allowed by authorization policy as long as allowChange for the instance is also true. If false, the value can only be written if required is true when adding a new object. | 
allowedValues | This is a list of the allowed values for this adaptive value. The dataType and dataTypeParameter of these values is the same as for the adaptive value itself. | 
brief | This is a predicate for this value, with the first letter capitalized and without a trailing period. | 
collectionURIs | This is the URIs of the collections that this value is a part of and preferably a URIs that can be used to locate an object with objects type _AdaptiveCollection_ that describes the collections. If a collection is used outside of the local instance, it should be a full URI. The URI can also be a local path of the collection object or just the collection's objectId if it resides in the in the same adaptor. | 
contextType | For data types that are evaluated (evaluate property true), this is the context type used for the evaluation. | 
dataType | Data type of this value. | 
dataTypeParameter | See the data type's dataTypeParameterType property to determine how to interpret this. | 
dataTypeParameterFormatted | This is the same as dataTypeParameter with possible comments and whitespace. This is especially useful for data type function to document its signature. If this property is not present, dataTypeParameter can be used in its place. | 
defaultValue | This is the default value. The dataType and dataTypeParameter properties apply to this value. If needed, this value will be normalized. | 
description | The description of this value. | 
hints | Hints that can optionally be used by UI to render this value. | 
label | Label used to identify this value. | 
maxLength | This is maximum length of the to_string() for this value. If not specified, there is no maximum length. | 
maxNormalLength | This is maximum normal length of the to_string() for this value. If not specified, maxLength is used. | 
maxValue | This is the maximum for this value. If not specified, there is no maximum value. The dataType and dataTypeParameter of this value is the same as for the value. | 
minLength | This is minimum length of the to_string() for this value. If not specified, there is no minimum length. | 
minValue | This is the minimum for this. If not specified, there is no minimum value. The dataType and dataTypeParameter of this value is the same as for the value. | 
originURI | The origin URI of this value meta. Descendant object types should be used for any deviations. This URI may be different from the URI within this instance of Adaptive Framework. | 
possibleValues | Possible values of this value. This can be the typed value or the string value. | 
referenceURI | URI of more reference information about this value meta. | 
required | Indicates that value is required. | 
runtime | This is only valid for runtime object types. These are objects that are accessed with adaptorId afw. See afw_runtime.h for more information. | 
skeleton | This is a skeleton example that can optionally be used by an application as an initial value. For example, if this is a new data type hybrid value, this can be the text used to prime the edit window with sample Adaptive Script code including comments. | 
tags | This is a list of keywords and terms associated with values with the meta. An instance of _AdaptiveTag_ can be used to define and document the purpose of a tag. Adaptive Framework reserves the definition of all tags that begin with "_Adaptive". | 
testDataParameter | This contains additional information about values with this meta that is used to produce test data. | 
unique | Value of property must be unique within object type. | 
valueInfId | This is a runtime property that is the implementation id of the value interface. | 
Object Meta
    
            We've now covered Object Types and Property Types and how 
            useful they are in describing an object or collection of objects by 
            extracting their "metadata" and storing it in a common place. In 
            addition to Object Types and Property Types, all objects contain 
            some additional metadata that is useful for Adaptive Framework 
            Core, Adaptors, and even clients. As you may have already guessed, 
            these too are documented and stored in a special Object Type called 
            _AdaptiveMeta_, which looks like the following:
        
| Property | Description | 
|---|---|
allowChange | If false this object is read only. If true, the object can be changed unless denied by authorization policy or by the adaptor. | 
allowDelete | If false this object can not be deleted. If true, the object can be deleted unless denied by authorization policy or by the adaptor. | 
ancestorPaths | This is all of the associated object's ancestor paths. | 
description | The optional description of the object. | 
errors | Object errors. | 
hasErrors | Indicates that at least one errors property exists in the meta. | 
objectId | This the id that uniquely defines the associated object when combined with its adaptor id and object type id within an Adaptive Framework environment. The objectId should be considered opaque unless the associated adaptor or mapping specifies otherwise. | 
objectType | This the id of the associated object's object type within the object's adaptor. | 
objectTypes | This is a object with a property with a name of the objectType for each _AdaptiveObjectType_ used by this object and all of its embedded objects. | 
parentPaths | This is the associated object's direct parent paths. | 
path | This is the associated object's path within an Adaptive Framework environment. The path is of the form "/adaptorId/objectType/objectId". | 
propertyTypes | This is additional meta information that overrides and supplements property type information for specific associated object's properties. The property name of properties in this object corresponds to properties with the same name in the associated object. | 
reconcilable | This strings represents a stateful token, used by the reconcile_object() method, to perform a reconcile request on an object that has been obtained in reconcilable mode. | 
resolvedParentPaths | This is the associated object's direct parent paths before they were resolved by object option composite. | 
Absolute Object Paths
Object Paths
    
            Every Adaptive Object in Adaptive Framework is uniquely identified
            by an Object Path of the form: 
        
/<adaptorId>/<objectTypeId>/<objectId>
    
            An objectId is the unique object identifier of
            the entity, optionally followed by a slash-separated representation
            of embedded properties.
        
/<adaptorId</<objectType</objectId
/<adaptorId</<objectType</objectId/propertyName
/<adaptorId</<objectType</objectId/propertyNameA/propertyNameB
    
            If the property value is a list, a property name can be followed 
            with a zero based integer index enclosed in square brackets 
            ([n]).
        
/<adaptorId>/<objectTypeId>/<objectId>/<propertyNameA>[<index>]
/<adaptorId>/<objectTypeId>/<objectId>/<propertyNameA>[<index>]/<property name>
/<adaptorId>/<objectTypeId>/<objectId>/<propertyNameA>/<propertyNameB>[<index>]
/<adaptorId>/<objectTypeId>/<objectId>/<propertyNameA>[<index>]/<propertyNameB>[<index>]Relative Adaptive Object Path
    
            An Object URI can contain a path as defined
            above, a full URI with scheme, or a relative path. If a path is
            relative, it must be resolved relative to a supplied path.
        
    
            If a relative path begins with a /, its structure
            is the same as an absolute path with * used in 
            place of <adaptorId>, <objectTypeId>, 
            and each shashed part of <objectId> to use the
            corresponding value from the supplied path. The
            <objectId> can also be
            ** to indicate that the entire
            <objectId> including all slash-separated properties
            should be used.
        
    
            If a relative path does not begin with a /, the
            <adaptorId> and
            <objectTypeId> from the supplied path
            will be used and the relative path will be used as the
            /<objectId>. The character sequence 
            /* can be used as a corresponding part from the
            supplied path's /<objectId>.
        
    
            The following are some examples of relative references using the
            given path: 
            /adaptorId/objectTypeId/objectId/prop1/prop2:
        
| Relative Path | Resolved Path | 
|---|---|
objectId2 | /adaptorId/objectTypeId/objectId2 | 
objectId2/prop4 | /adaptorId/objectTypeId/objectId2/prop4 | 
/*/objectTypeId2/objectId3/prop5 | /adaptorId/objectTypeId2/objectId3/prop5 | 
/*/objectTypeId2/*/prop5 | /adaptorId/objectTypeId2/objectId/prop5 | 
*/prop6 | /adaptorId/objectTypeId/objectId/prop6 | 
*/*/prop7 | /adaptorId/objectTypeId/objectId/prop1/prop7 | 
/adaptorId2/*/** | /adaptorId2/objectTypeId/objectId/prop1/prop2 | 
/*/*/** | /adaptorId/objectTypeId/objectId/prop1/prop2 | 
/*/*/* | /adaptorId/objectTypeId/objectId | 
Embedded Objects
    
            Some Adaptive Objects may have properties that also contain 
            objects. We call these objects Embedded Objects.
            The following object illustrates an example of an Embedded Object, 
            referenced by the Embedding Property address:
        
{
    "name": "John Doe",
    "address": {
        "street": "123 Main St.",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    }
}
Inheritance
    
            Adaptive Objects also allow for inheritance, so that Adaptive Objects 
            can borrow properties from other Adaptive Objects. This is done 
            through a special "meta" property called parentPaths:
        
{
    "_meta_": {
        "parentPaths": [
            "/registry/_AdaptiveObjectType_/Person"
        ]
    },
    "employeeId": "12345",
    "officeAddress": {
        "street": "123 Main St.",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    }
}
    
            When observing an Adaptive Object that contains a parent path, the 
            Object Option composite can be specified to 
            resolve the parent and include their properties in the returned 
            object. The following is an example of the same object with the
            composite option specified:
        
{    
    "first": "John",
    "last": "Doe",
    "age": 42,
    "employeeId": "12345",
    "officeAddress": {
        "street": "123 Main St.",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    }
}
Object Options
    
            Adaptive Objects can be provided with Object
            Options that influence how an object should be displayed,
            including what metadata should be provided, or how Adaptive Property
            values should be interpreted or represented. The options that one
            uses is up to the application or client that is consuming or
            providing the objects. For example, a UI may require a lot of
            metadata to understand how to render properties on a screen, while a
            programmatic parser may request property values to be encoded in a
            way that's convenient for the client. Below is a table of the
            object options that are available.
        
| Property | Description | 
|---|---|
checkRequired | Indicates that object should be checked for missing required properties. This option implies the normalize option. | 
composite | Indicates that both direct and embedded inheritance should be performed. | 
debug | This will cause the errors in object meta to include additional debug information. If not specified, only the message will be included. | 
includeDefaultValues | This indicates that default property values should be included. This option implies the normalize option. | 
includeDescendentObjectTypes | This only applies to retrieve objects requests and indicates that objects with the supplied object type along with objects with any of its descendent object types should be included in the search. | 
inheritedFrom | Indicates that the inheritedFrom property in meta propertyTypes.<propertyName>, where <propertyName> is the associated property name, should be set. This option is ignored unless composite option is also set. | 
integersAsString | This overrides the largeIntegersAsString option. If neither the integersAsString or large_integer_as_string is specified, integers will remain integers. If this option is specified, all data type integer values will be converted to the string data type.\n\nThis options is useful if a content type is used that represents integers as double (floating point) values. | 
largeIntegersAsString | This option is overridden by the integersAsString option.\n\nIf this option is specified, all integers that have a magnitude that exceeds plus or minus 9007199254740991 (2^53-1) will be converted to the string data type.\n\nThis options is useful if integers of a content type are interpreted as double (floating point) values, but integers are normally small enough to be represented properly. An example is Javascript's use of JSON. | 
metaFull | This indicates that all meta, including properties that are not part of delta from object type, are to be included. This overrides metaLimited. | 
metaLimited | Indicates that only requested and essential (parentPaths) meta is returned. | 
normalize | Indicates that each object's object type should be processed, assigned each embedded object's object type, converting any properties to their correct data type, plus computing values when needed. If there is dataType or dataTypeParameter information available during normalization that is not in the associated _AdaptiveObjectType_, it will be added at the appropriate place in the object's meta.\n\nUse the includeDefaultValues option to include default values. | 
objectId | Indicates that objectId property should be included in the meta for entity objects. | 
objectType | Indicates that objectType property should be included in the meta for entity and embedded objects, if assigned. | 
objectTypes | Indicates that the objectTypes property should be added to the meta of the entity containing a property of each object type used by the entity and all of its embedded objects. This option implies normalize. | 
path | Indicates that meta path should be included for entity objects. | 
pathEmbedded | Indicates that meta path should be included for embedded objects. | 
reconcilable | Indicates that meta reconcilable should be included in entity's meta. If this is specified on a get_object or retrieve_objects request and a retrieved object is changed, calling reconcile_object() with the changed object will use the information in meta reconcilable to produce a modify request for only the changes. The reconcilable option assumes the path option and possibly other options as needed. | 
resolvedParentPaths | Indicates that meta resolvedParentPaths should be included with a list of parent paths that have been resolved by the composite option. | 
typedValues | *** EXPERIMENTAL *** This option indicates that a value's type information (valueType, dataType, and objectType) should be included with each value. See the content type to determines how this is represented. | 
whitespace | This option can be optionally supported by a content type implementation. In the case of JSON, this indicates that newline, space, and tab characters should be included to make the output more readable. |