public interface RecordTopicData extends PublishingTopicData
Fields are separated by the
field
delimiter byte
and may be organised into records separated by the
record delimiter byte
. Records may be written to and read from Messages
using Record
objects.
An instance of this data has the data format defined by an MMessage
metadata definition of type
RECORD
created using
MetadataFactory
.
The following must be taken into account when defining the Message Metadata:
1) A Message can have one or more Records within it.
2) Each Record can have one or more Fields defined for it.
3) Fields may not exist directly under a Metadata Message, only within a
Record. Even though the Message interface does permit Messages containing
only Fields, a single Record is implied in those cases.
4) Only String data types are permitted for Fields(
STRING
,
DECIMAL_STRING
etc).
5) Repeating Field definitions with fixed multiplicity are permitted anywhere
within Records but a repeating Field definition with variable multiplicity is
only permitted if it is the last field within the last (non repeating) Record
defined for the message.
6) Repeating Record definitions with fixed multiplicity are permitted
anywhere within the Message but a repeating Record definition with variable
multiplicity is permitted only if it is the last Record definition within the
Message.
7) Nested Records are not permitted (i.e. you can not define a Record within
a Record).
Having defined Metadata an instance of this type of data can be created using
TopicDataFactory.newRecordData(MMessage)
.
The data may be initialised in one of the following ways:
1) Assume defaults.
If not otherwise initialised then when the Topic Data is attached to a Topic
it will be initialised to all of the default values indicated by the metadata
definition.
2) Using Record
Definitions
Using initialise(Record, int)
calls the content of specific Record
definitions may be specified instead of assuming defaults.
The initialise(Record...)
option may be used to initialise a message
that comprises a single repeating Record.
3) From a Diffusion Message.
Using
PublishingTopicData.initialise(com.pushtechnology.diffusion.api.message.TopicMessage)
the content of the specified Diffusion message is parsed into records using
the specified metadata. Where the message input is a Topic Load message the
data is totally defined by the input message whereas if the input message is
a Delta the default state of the data is updated by the content of the input
message.
Updates to this data may occur via the
PublishingTopicData.update(com.pushtechnology.diffusion.api.message.TopicMessage)
method
or one or more of the Record specific update methods. In the first case the
Message is expected to contain a full set of Records that match the metadata
definition. In the latter case updates can be done on an individual Record
basis (using update(Record, int)
, using repeating records (
update(Record...)
) or on a field by field basis (
update(String, int, String, Object...)
).
It is also possible to update and publish a delta in a single call of
PublishingTopicData.updateAndPublish(com.pushtechnology.diffusion.api.message.TopicMessage)
which will parse the incoming message using the metadata.
The data that is input on an update is checked against the current data state and a delta with only those fields that are different will be generated. If there are no differences then no delta would need to be sent. If multiple updates are done within the same block then the update effect will be cumulative in that the the newly generated delta is merged with any existing delta.
The nature of Record data means that generated Delta messages (as obtained
using PublishingTopicData.generateDeltaMessage(String...)
) will contain an entry for
every possible field but those that have not changed will be zero length. It
would therefore not be possible for a Client to differentiate between a field
indicating 'no change' and a field that is having its value changed to be a
zero length string. For this reason setEmptyFieldValue(String)
may
be used to specify how empty fields are to be represented.
Modifier and Type | Method and Description |
---|---|
String |
getEmptyFieldValue()
Returns the current empty field value.
|
MMessage |
getMetadata()
Metadata Message describing the TopicData.
|
List<Record> |
getState()
Gets the current state of the data as a List of Records.
|
Record |
getStateRecord(String recordName,
int index)
Gets the current state of a particular Record occurrence within the data.
|
void |
initialise(Collection<Record> records)
Initialises one or more Record occurrences within the data.
|
void |
initialise(Record... records)
Initialises one or more Record occurrences within the data.
|
void |
initialise(Record record,
int index)
Initialises an occurrence of a Record within the data from a Record with
matching metadata.
|
void |
setEmptyFieldValue(String emptyValue)
Sets the value to be used to represent empty fields in messages generated
by the TopicData.
|
boolean |
update(Collection<Record> records)
Update data from records.
|
boolean |
update(Record... records)
Update data from records.
|
boolean |
update(Record record,
int index)
Updates data from a Record.
|
boolean |
update(String recordName,
int recordIndex,
String fieldName,
Object... values)
Updates a specific field within a specified record within the data.
|
abortUpdate, addListener, asString, endUpdate, generateAckDeltaMessage, generateDeltaMessage, getInitialiser, getLastUpdateTimeMillis, getLoadHeaders, getLoadMessage, hasChanges, hasSlaves, initialise, isDeltaAckRequired, isLoadAckRequired, isSlave, publishExclusiveMessage, publishExclusiveMessage, publishMessage, publishMessage, removeListener, setDeltaAckRequired, setInitialiser, setLoadAckRequired, setLoadHeaders, startUpdate, update, updateAndPublish, updateAndPublish, updateAndPublishFromDelta
getDeltaEncoding, getLoadEncoding, getLoadMessage, getTopic, getType, hasSubscribers, isCommand, isLockedByCurrentThread, isPaged, isPublishing, isRouting, isService, lock, setDeltaEncoding, setLoadEncoding, unlock
getMetadataNode, isMetadataMandatory, setMetadataNode
void initialise(Record... records) throws APIException
This may only be called before the data is attached to a Topic.
The Record(s) specified must have metadata that matches the metadata of a Record within the data and all Records must have the same Metadata.
records
- one or more Records, each having the same Metadata
matching one of the Record types within the data. The
minimum
number of Records for the Record type within the data
must be specified and the number of Records must not exceed the
maximum
.APIException
- if unable to initialise.void initialise(Collection<Record> records) throws APIException
This may only be called before the data is attached to a Topic.
The Record(s) specified must have metadata that matches the metadata of a Record within the data and all Records must have the same Metadata.
records
- one or more Records, each having the same Metadata
matching one of the Record types within the data. The
minimum
number of Records for the Record type within the data
must be specified and the number of Records must not exceed the
maximum
.APIException
- if unable to initialise.void initialise(Record record, int index) throws APIException
This may only be called before the data is attached to a Topic.
This may only be used for Records with
fixed
multiplicity.
record
- the record to takes initial values from. This record must
have metadata that matches the metadata of a Record within the
data.index
- the index of the Record occurrence within the data to
initialise. For a Record that occurs only once this should be
specified as 0.APIException
- if unable to initialise the data from the given
Record, possibly because its metadata does not match any within
the data or the index is invalid for the specified Record.boolean update(Record... records) throws APIException
This may only be called from within an update block (see
PublishingTopicData.startUpdate()
).
records
- one or more Records, each having the same Metadata
matching one of the Record types within the data. The
minimum
number of Records for the Record type within the data
must be specified and the number of Records must not exceed the
maximum
.APIException
- if unable to perform the update. After such an
exception the update can not continue and when
PublishingTopicData.endUpdate()
is called the data state will be reverted to
its state before PublishingTopicData.startUpdate()
was called.boolean update(Collection<Record> records) throws APIException
This may only be called from within an update block (see
PublishingTopicData.startUpdate()
).
records
- one or more Records, each having the same Metadata
matching one of the Record types within the data. The
minimum
number of Records for the Record type within the data
must be specified and the number of Records must not exceed the
maximum
.APIException
- if unable to perform the update. After such an
exception the update can not continue and when
PublishingTopicData.endUpdate()
is called the data state will be reverted to
its state before PublishingTopicData.startUpdate()
was called.boolean update(Record record, int index) throws APIException
This is similar to
PublishingTopicData.update(com.pushtechnology.diffusion.api.message.TopicMessage)
except only the part of the data represented by the record is updated.
This may only be called from within an update block (see
PublishingTopicData.startUpdate()
).
This may only be used for Records with
fixed
multiplicity.
record
- a record which has metadata that matches the metadata of a
record within the data.index
- the index of the record occurrence to set. When a record
definition is not repeating then this should be set to 0.APIException
- if unable to perform the update. After such an
exception the update can not continue and when
PublishingTopicData.endUpdate()
is called the data state will be reverted to
its state before PublishingTopicData.startUpdate()
was called.boolean update(String recordName, int recordIndex, String fieldName, Object... values) throws APIException
This is similar to
PublishingTopicData.update(com.pushtechnology.diffusion.api.message.TopicMessage)
except that only the values(s) of a specified field within a specified
record occurrence within the data is updated.
This may only be called from within an update block (see
PublishingTopicData.startUpdate()
).
recordName
- the name of the record that the field to set is in.recordIndex
- the index identifying the occurrence of the record.
For non repeating records this should be 0.fieldName
- the name of the field to set value(s) for.values
- the value(s) for the field. Each value will be parsed to
the appropriate internal type as defined by the metadata. At least
the
minimum
number of values indicated by the metadata for the field
must be supplied and no more than the
Multiplicity.getMaximum()
.APIException
- if unable to perform the update. After such an
exception the update can not continue and when
PublishingTopicData.endUpdate()
is called the data state will be reverted to
its state before PublishingTopicData.startUpdate()
was called.List<Record> getState() throws TimeoutException, APIException
This will return the current committed state. If called before any initialisation has taken place then the state will first be initialised to the default state.
If called during an update block this will return the state as it was at the start of the block and not the current updated state.
Currently this obtains a lock on the topic this data is attached to. It
then creates and returns a new List containing unshared references to
Record objects. Finally it releases the lock. This list and its entries
can be accessed and modified safely but if other threads modify the topic
data it may become out of date. It obtains the same lock as
PublishingTopicData.startUpdate()
.
TimeoutException
- if the lock
timeout
period for the Topic has been exceeded whilst waiting to
obtain a lock on the data.APIException
- if unable to obtain the current state.Record getStateRecord(String recordName, int index) throws TimeoutException, APIException
This will return the current committed state of the Record. If called before any initialisation has taken place then the state will first be initialised to the default state.
If called during an update block this will return the state as it was at the start of the block and not the current updated state.
Currently this obtains a lock on the topic this data is attached to. It
then creates and returns a new Record object. Finally it releases the
lock. This Record can be accessed and modified safely but if other
threads modify the topic data it may become out of date. It obtains the
same lock as PublishingTopicData.startUpdate()
.
recordName
- the name of the record.index
- the index of the record occurrence. For non repeating
Records this must be supplied as 0.TimeoutException
- if the lock
timeout
period for the Topic has been exceeded whilst waiting to
obtain a lock on the data.APIException
- if unable to obtain the current state.MMessage getMetadata()
void setEmptyFieldValue(String emptyValue) throws APIException
This allows it to be possible for a client receiving a delta message to distinguish between a field that had not changed and a field that has changed to become empty.
This will be used in generated deltas.
If not set then empty fields will be rendered as zero length Strings and thus be indistinguishable from unchanged fields.
This must be called before the data is initialised.
emptyValue
- the empty value which can be any String, ideally a
single character. The value should be a value that would not occur
normally in a field, thus a non visible character is ideal. It is
recommended that
Message.EMPTY_FIELD_STRING
is used as it is a special character that is rendered when
messages are displayed. The value may not contain reserved
character values (so avoid 0x00 to 0x09). The value may not be
null.APIException
- if the specified character value is not permitted as
an empty field value or if called after the data has been
initialised.String getEmptyFieldValue()
This returns the String that is used in messages generated by the Topic Data to represent an empty field.
setEmptyFieldValue(String)
Copyright © 2016 Push Technology Ltd. All Rights Reserved.