net.degreedays.api.data
Class DataSpecs

java.lang.Object
  extended by net.degreedays.api.data.DataSpecs
All Implemented Interfaces:
java.io.Serializable

public final class DataSpecs
extends java.lang.Object
implements java.io.Serializable

Defines up to 100 sets of data that should be generated to fulfil a LocationDataRequest.

When requesting multiple sets of data for a particular location, it makes sense to use multiple DataSpec objects to retrieve as much data as possible in a single request. This is cheaper and faster than fetching the same data across multiple requests. For example, for a particular location you might want to request heating and cooling degree days at 5 different base temperatures each. This would require 10 different DataSpec objects in total. By putting all 10 DataSpec objects in a single DataSpecs object, you could fetch all 10 sets of data in a single request.

For most use cases, all you will ever need to do with this class is use the constructors to create instances to pass into LocationDataRequest objects. However, if you are customizing this framework (e.g. using it to construct requests but handling the response XML using your own system entirely), you will probably find it useful to understand about keys and the uniqueness of DataSpec objects.

Keys

The XML request (which this Java framework generates internally) requires that each DataSpec be assigned a unique string key attribute so that its corresponding DataSet can be found in the XML response (which this Java framework parses internally). This DataSpecs class is central to the way that the keys are created and managed. It essentially gives you two options for key management:

  1. You can let this DataSpecs class generate and manage the keys entirely, such that you never have to see them or use them directly. This is the sensible option if you're sticking with the defaults and letting the Java framework parse the XML response. With this option you do not need to deal with keys at all - you can fetch your DataSet objects out of the LocationDataResponse using the DataSpec objects that you created for the request (and kept on hand for this purpose).
  2. You can specify your own keys explicitly. The only reason we can think of for doing this is if, for whatever reason, you are parsing or transforming the XML response yourself and your parsing/transforming code expects the keys to have specific values or a specific format (e.g. matching keys in a database of yours). If this is the case, use the DataSpecs.CustomKeyBuilder class to create a DataSpecs object with your own custom key-to-DataSpec mappings.

Uniqueness of DataSpec objects

There is no point in submitting a request containing multiple identical DataSpec objects, as it would lead to unnecessary duplication in the results and unnecessary bandwidth usage for the communication between the client and API servers.

Unless you are specifying your own keys (using DataSpecs.CustomKeyBuilder), this class is set up to prevent duplicate DataSpec objects from being submitted as part of a request. It does this by filtering and discarding all duplicate DataSpec objects passed in to the constructors of this class. So, if you pass 10 DataSpec objects to one of the constructors, and only 5 of those are unique, then only the 5 unique DataSpec objects will be stored internally and sent as part of the XML request.

Because discarded duplicate DataSpec objects are identical to their retained counterparts, you can still use the duplicates to retrieve fetched data out of the LocationDataResponse. In other words, the internal process of filtering and discarding duplicate DataSpec objects should not affect the way in which you use this API.

If you create your own keys using DataSpecs.CustomKeyBuilder, then duplicate DataSpec objects are not filtered. Filtering duplicate DataSpec objects would also involve filtering the keys associated with the duplicates, and this could cause problems for code of yours that was expecting those keys in the XML response. You can rely on the fact that, if you define your own DataSpec keys using CustomKeyBuilder, your XML response will contain entries for all of your keys, irrespective of whether some of the data associated with those keys is duplicated.

Instances of this class are immutable. You can safely reuse them and call them from multiple threads at once.


Nested Class Summary
static class DataSpecs.CustomKeyBuilder
          For advanced use, this provides a way to create a DataSpecs object with custom keys.
 
Constructor Summary
DataSpecs(java.util.Collection dataSpecObjects)
          Constructs a DataSpecs object containing the specified DataSpec objects.
DataSpecs(DataSpec dataSpecObject)
          Constructs a DataSpecs object containing just the one specified DataSpec object.
DataSpecs(DataSpec[] dataSpecObjects)
          Constructs a DataSpecs object containing the specified DataSpec objects.
 
Method Summary
 int count()
          Returns the number of DataSpec objects held by this DataSpecs - always greater than zero.
 boolean equals(java.lang.Object o)
          Two DataSpecs objects are equal if they contain the same set of unique DataSpec objects - neither keys nor the order of keys make any difference.
 DataSpec get(java.lang.String key)
          Returns the non-null DataSpec that has been assigned the specified string key.
 DayRange getFullRangeOrNull(DayRange availableDataRange)
          Returns the full range of days that this set of DataSpec objects would cover given temperature data covering availableDataRange, or null if availableDataRange is not of use to any of the DataSpec objects.
 java.lang.String getKey(DataSpec dataSpec)
          Returns the non-null, non-empty string key associated with dataSpec.
 java.lang.String[] getKeys()
          Gives access to the string keys that are assigned to the DataSpec objects stored within this DataSpecs.
 int hashCode()
          Overridden to ensure consistency with equals.
 java.lang.String toString()
          Returns a non-null, non-empty string representation of this object for logging and debugging purposes.
 
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
 

Constructor Detail

DataSpecs

public DataSpecs(DataSpec[] dataSpecObjects)
Constructs a DataSpecs object containing the specified DataSpec objects. Keys will be auto-generated, and duplicates will be filtered.

Although the immutable DataSpec objects contained within dataSpecObjects will be stored inside this DataSpecs object, the array itself will neither be stored nor modified. So you can continue using dataSpecObjects without concern for side effects.

Parameters:
dataSpecObjects - the DataSpec objects that you want this DataSpecs to contain. Cannot contain any null values, cannot be empty, and cannot have length > 100.
Throws:
java.lang.NullPointerException - if dataSpecObjects is null, or if it contains a null value.
java.lang.IllegalArgumentException - if dataSpecObjects contains an Object that isn't a DataSpec, or if it is empty, or has length > 100.

DataSpecs

public DataSpecs(java.util.Collection dataSpecObjects)
Constructs a DataSpecs object containing the specified DataSpec objects. Keys will be auto-generated, and duplicates will be filtered.

Although the immutable DataSpec objects contained within dataSpecObjects will be stored inside this DataSpecs object, the Collection itself will neither be stored nor modified. So you can continue using dataSpecObjects without concern for side effects.

Parameters:
dataSpecObjects - the Collection of DataSpec objects (i.e. Collection<DataSpec>) that you want this DataSpecs to contain. Cannot contain any null values, cannot be empty, and cannot have size() > 100.
Throws:
java.lang.NullPointerException - if dataSpecObjects is null, or if it contains a null value.
java.lang.IllegalArgumentException - if dataSpecObjects contains an Object that isn't a DataSpec, or if it is empty, or has size() > 100.

DataSpecs

public DataSpecs(DataSpec dataSpecObject)
Constructs a DataSpecs object containing just the one specified DataSpec object. The single DataSpec will be assigned an auto-generated key.

Parameters:
dataSpecObject - the DataSpec object that you want this DataSpecs to contain. Cannot be null.
Throws:
java.lang.NullPointerException - if dataSpecObject is null.
Method Detail

count

public int count()
Returns the number of DataSpec objects held by this DataSpecs - always greater than zero.

The returned value will also give the number of keys held by this DataSpecs, since each DataSpec object has a unique key.

Assuming you didn't create this DataSpecs object using custom keys (option 2 here), then the number returned by this method may be smaller than the number of DataSpec objects that you passed into the constructor. This is because, when keys are being assigned and managed internally (the normal usage scenario), the constructors filter out duplicate DataSpec objects, as explained here.


getKeys

public java.lang.String[] getKeys()
Gives access to the string keys that are assigned to the DataSpec objects stored within this DataSpecs.

Note that this method returns a defensive copy of the array stored internally, to protect the immutability of the DataSpecs object. Bear this in mind if you're iterating over all values: use for (String key : dataSpecs.keys()), which will call this method only once, or, if you're using indexed iteration, make sure to iterate over a local copy of the array rather than calling this method repeatedly from within your loop.

See Also:
Keys

getKey

public java.lang.String getKey(DataSpec dataSpec)
Returns the non-null, non-empty string key associated with dataSpec.

Parameters:
dataSpec - a data specification held by this DataSpecs. Cannot be null.
Throws:
java.lang.NullPointerException - if dataSpec is null.
java.lang.IllegalArgumentException - if dataSpec isn't equal to one stored in this object.
See Also:
Keys

get

public DataSpec get(java.lang.String key)
Returns the non-null DataSpec that has been assigned the specified string key.

Parameters:
key - a non-null, non-empty string key.
Throws:
java.lang.NullPointerException - if key is null.
java.lang.IllegalArgumentException - if key isn't one of the keys stored in this object.
See Also:
Keys

getFullRangeOrNull

public DayRange getFullRangeOrNull(DayRange availableDataRange)
Returns the full range of days that this set of DataSpec objects would cover given temperature data covering availableDataRange, or null if availableDataRange is not of use to any of the DataSpec objects.

Parameters:
availableDataRange - the non-null range of temperature data available.
Throws:
java.lang.NullPointerException - if availableDataRange is null.
See Also:
Breakdown.getFullRangeOrNull(net.degreedays.time.DayRange)

toString

public java.lang.String toString()
Returns a non-null, non-empty string representation of this object for logging and debugging purposes.

The exact details of the representation are unspecified and subject to change.

Overrides:
toString in class java.lang.Object

equals

public boolean equals(java.lang.Object o)
Two DataSpecs objects are equal if they contain the same set of unique DataSpec objects - neither keys nor the order of keys make any difference.

If you're using this framework end to end (the typical usage pattern), then keys are managed internally, and the ordering of keys makes no difference to anything, so this key-blind equality comparison is ideal for testing whether one DataSpecs is equivalent to another in terms of the data it is specifying.

If, however, you are using DataSpecs.CustomKeyBuilder to create DataSpecs objects with custom keys, then presumably the keys, and maybe the ordering of those keys, are no longer insignificant internal details. So bear in mind that they won't be considered in tests of DataSpecs object equality - this could still be exactly what you'd want, but it might cause problems for you if you're using your custom-keyed DataSpecs objects in equality tests and expecting the keys to be part of the comparison.

Overrides:
equals in class java.lang.Object

hashCode

public int hashCode()
Overridden to ensure consistency with equals.

Overrides:
hashCode in class java.lang.Object


www.degreedays.net/api/