public final class DataSpecs
extends java.lang.Object
implements java.io.Serializable
Defines up to 120 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.
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:
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).DataSpecs.CustomKeyBuilder
class to create a DataSpecs
object with your own custom key-to-DataSpec
mappings.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.
DataApi
Instances of this class are immutable. You can safely reuse them and call them from multiple threads at once.
Modifier and Type | Class and Description |
---|---|
static class |
DataSpecs.CustomKeyBuilder
For advanced use, this provides a way to create a
DataSpecs
object with custom keys. |
Constructor and Description |
---|
DataSpecs(java.util.Collection<? extends DataSpec> dataSpecObjects)
Constructs a
DataSpecs object containing the specified
DataSpec objects. |
DataSpecs(DataSpec dataSpecObject)
Constructs a
DataSpecs object containing the specified
DataSpec object. |
DataSpecs(DataSpec[] dataSpecObjects)
Constructs a
DataSpecs object containing the specified
DataSpec objects. |
DataSpecs(DataSpec dataSpecObject,
DataSpec... additionalDataSpecObjects)
Constructs a
DataSpecs object containing the specified
DataSpec objects. |
DataSpecs(java.lang.Iterable<? extends DataSpec> dataSpecObjects)
Constructs a
DataSpecs object containing the specified
DataSpec objects. |
Modifier and Type | Method and Description |
---|---|
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.
|
public DataSpecs(DataSpec[] dataSpecObjects)
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.
dataSpecObjects
- the DataSpec
objects that you want this
DataSpecs
to contain. Cannot contain any null values,
cannot be empty, and cannot have length > 120.java.lang.NullPointerException
- if dataSpecObjects
is
null
, or if it contains a null
value.java.lang.IllegalArgumentException
- if dataSpecObjects
is
empty, or has length > 120.DataSpecs(DataSpec, DataSpec...)
,
DataSpecs(Iterable)
public DataSpecs(DataSpec dataSpecObject, DataSpec... additionalDataSpecObjects)
DataSpecs
object containing the specified
DataSpec
objects. Keys will be
auto-generated, and duplicates will be
filtered.dataSpecObject
- a DataSpec
object that you want this
DataSpecs
to contain. Cannot be null
.additionalDataSpecObjects
- additional DataSpec
objects that
you want this DataSpecs
to contain. Cannot contain
any null
values, and cannot have length > 99.java.lang.NullPointerException
- if dataSpecObject
or
additionalDataSpecObjects
is null
, or
if additionalDataSpecObjects
contains a
null
value.java.lang.IllegalArgumentException
- if more than 120 DataSpec
objects are passed in.DataSpecs(Iterable)
,
DataSpecs(DataSpec[])
public DataSpecs(java.lang.Iterable<? extends DataSpec> dataSpecObjects)
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 Iterable
itself will
neither be stored nor modified. So you can continue using
dataSpecObjects
without concern for side effects.
dataSpecObjects
- the Iterable
of DataSpec
objects that you want this DataSpecs
to contain.
Cannot contain any null
values, cannot be empty, and
cannot contain more than 120 items.java.lang.NullPointerException
- if dataSpecObjects
is
null
or contains a null
value.java.lang.IllegalArgumentException
- if dataSpecObjects
is
empty or contains more than 120 items.DataSpecs(DataSpec, DataSpec...)
,
DataSpecs(DataSpec[])
public DataSpecs(java.util.Collection<? extends DataSpec> dataSpecObjects)
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.
dataSpecObjects
- the Collection
of DataSpec
objects that you want this DataSpecs
to contain.
Cannot contain any null
values, cannot be empty, and
cannot have size()
> 120.java.lang.NullPointerException
- if dataSpecObjects
is
null
or contains a null
value.java.lang.IllegalArgumentException
- if dataSpecObjects
is
empty or has size()
> 120.DataSpecs(DataSpec, DataSpec...)
,
DataSpecs(DataSpec[])
public DataSpecs(DataSpec dataSpecObject)
DataSpecs
object containing the specified
DataSpec
object. The single DataSpec
will be
assigned an auto-generated key.dataSpecObject
- the DataSpec
object that you want this
DataSpecs
to contain. Cannot be null
.java.lang.NullPointerException
- if dataSpecObject
is
null
.DataSpecs(DataSpec, DataSpec...)
,
DataSpecs(DataSpec[])
,
DataSpecs(Iterable)
public int count()
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.
public java.lang.String[] getKeys()
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.
public java.lang.String getKey(DataSpec dataSpec)
dataSpec
.dataSpec
- a data specification held by this DataSpecs
.
Cannot be null
.java.lang.NullPointerException
- if dataSpec
is
null
.java.lang.IllegalArgumentException
- if dataSpec
isn't equal to
one stored in this object.public DataSpec get(java.lang.String key)
DataSpec
that has been assigned the
specified string key
.key
- a non-null, non-empty string key.java.lang.NullPointerException
- if key
is null
.java.lang.IllegalArgumentException
- if key
isn't one of the
keys stored in this object.public DayRange getFullRangeOrNull(DayRange availableDataRange)
DataSpec
objects would cover given temperature data covering
availableDataRange
, or null
if
availableDataRange
is not of use to any of the
DataSpec
objects.availableDataRange
- the non-null range of temperature data
available.java.lang.NullPointerException
- if availableDataRange
is
null
.Breakdown.getFullRangeOrNull(net.degreedays.time.DayRange)
public java.lang.String toString()
The exact details of the representation are unspecified and subject to change.
toString
in class java.lang.Object
public boolean equals(java.lang.Object o)
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.
equals
in class java.lang.Object
public int hashCode()
equals
.hashCode
in class java.lang.Object
See www.degreedays.net/api/ for more about the Degree Days.net API.
You can sign up for a Degree Days.net API account and read the integration guide that is useful and applicable whether you are using Java or not.