Getting the Data from the PropertyCollector
Now that we have defined ObjectSpec and PropertySpec (the where and what), we need to put them into a FilterSpec that combines the two. An array of FilterSpec elements is passed to the PropertyCollector (the minimum number of elements is one). Two mechanisms can retrieve data from PropertyCollector:
- RetrieveProperties – A one-time request for all of the desired properties. This can involve a lot of data, and has no refresh option. RetrievePropertiesEx has an additional options parameter.
- Update requests – PropertyCollector update requests take two forms: polling and waiting (see below).
Requesting Updates
The update method is the way to keep properties up to date. In either Polling or Waiting, it is first necessary to register your FilterSpec array object with the PropertyCollector. You do this using the CreateFilter method, which sends a copy of your FilterSpec to the server. Unlike the RetrieveProperties method, FilterSpec is retained after CreateFilter operation. The following code shows how to set FilterSpec:
// We already showed examples of creating pspec and ospec in the examples above. // The PropertyCollector wants an array of FilterSpec objects, so: PropertyFilterSpec fs = new PropertyFilterSpec(); fs.setPropSet(pspec); fs.setObjectSet(ospec); PropertyFilterSpec [] fsa = new PropertyFilterSpec [] {fs}; ManagedObjectReference pcRef = serviceContent.getPropertyCollector(); // This next statement sends the filter to the server for reference by the PropertyCollector ManagedObjectReference pFilter = serviceConnection.CreateFilter(pcRef, fsa, Boolean.FALSE);
If you wish to begin polling, you may then call the function CheckForUpdates, which on the first try (when it must contain an empty string for the version number) returns a complete dump of all the requested properties from all the eligible objects, along with a version number. Subsequent calls to CheckForUpdates must contain this version number to indicate to the PropertyCollector that you seek any changes that deviate from this version. The result is either a partial list containing only the changes from the previous version (including a new version number), or a return code indicating no data has changed. The following code sample shows how to check for updates:
String updateVersion = ""; // Start with no version UpdateSet changeData = serviceConnection.CheckForUpdates(pcRef, updateVersion); if (changeData != nil) { updateVersion = changeData.getVersion(); // Extract the version of the data set } // ... // Get changes since the last version was sent. UpdateSet latestData = serviceConnection.CheckForUpdates(pcRef, updateVersion);
If instead you wish to wait for updates to occur, you must create a task thread that blocks on the call WaitForUpdates. This task thread would return changes only as they occur and not at any other time. However if the request times out, you must renew it.
The order of property retrieval is not guaranteed. Multiple update requests may be needed.
Extracting Information from the Change Data
The data returned from CheckForUpdates (or WaitForUpdates) is an array of PropertyFilterUpdate entries. Since a PropertyFilterUpdate entry is very generic, here is some code showing how to extract information from the PropertyFilterUpdate.
// Extract the PropertyFilterUpdate set from the changeData PropertyFilterUpdate [] updateSet = changeData.getFilterSet(); // There is one entry in the updateSet for each filter you registered with the PropertyCollector. // Since we currently have only one filter, the array length should be one. PropertyFilterUpdate myUpdate = updateSet[0]; ObjectUpdate [] changes = myUpdate.getObjectSet(); for (a = 0; a < changes.length; a++) { ObjectUpdate theObject = changes[a]; String objName = theObject.getObj().getMoType().getName(); // Must decide how to handle the value based on the name returned. // The only names returned are names found in the PropertySpec lists. // Get propertyName and value ... }
Getting Specific Data
From time to time, you might need to get data that is relevant to a single item. In that case you can create a simple ObjectSpec including the moRef for the item of interest. The PropertySpec can then be set to obtain the properties you want, and you can use RetrieveProperties to get the data. Hopefully you can deduce moRef from a general examination of the properties, by searching for information from the rootFolder.