public abstract class HashStructure extends Structure
URL
ListStructure
hashStructure.getString("a/b/c")
, this is semantically
equivalent to "first look in hashStructure for a sub-HashStructure
named a, and if found look in a for a sub-HashStructure
named b, and if found look in b for a String named
c and return it; otherwise, return null."HashStructure provides support for tracking a dirty flag, performing a deep equals comparison, and performing a deep copy operation.
Modifying values in a chained HashStructure is more complicated, since it depends on whether an overridden value exists and whether the chain is biased toward overriding or toward preserving the status quo, by modifying the layer in which a lookup would currently resolve.
In general, callers should not have to distinguish whether the
HashStructure is chained or not, or if chained, what kind of chain.
In fact, the HashStructure API does not provide a mechanism for
detecting this. Usually, the distinction is only important for UI
that modifies the properties.
Placeholder Values
When a caller looks up a property in the HashStructure, the caller
often needs to get a sensible default value back when the property
doesn't exist in the HashStructure and for subsequent lookups to
continue returning the same defaulted value until it is explicitly
changed. At the same time however, specifying the default value and
having the HashStructure hold it shouldn't cause the HashStructure
to become dirty and adversely affect equals comparison.
To address these requirements, HashStructure supports the notion of 'placeholder' values. In this context, the opposite of 'placeholder' is 'persistent'. A placeholder is a default value specified by a caller through one of the following placeholder-enabled methods:
getString(java.lang.String, java.lang.String)
getBoolean(java.lang.String, boolean)
getInt(java.lang.String, int)
getLong(java.lang.String, long)
getFloat(java.lang.String, float)
getDouble(java.lang.String, double)
getURL(java.lang.String, java.net.URL)
putPlaceholderURL(java.lang.String, java.net.URL)
getOrCreateHashStructure(java.lang.String)
putPlaceholderHashStructure(java.lang.String, oracle.javatools.data.HashStructure)
getOrCreateListStructure(java.lang.String)
putPlaceholderListStructure(java.lang.String, oracle.javatools.data.ListStructure)
To be consistent with how a HashStructure is persisted, the equals comparison of two HashStructure instances when placeholders are involved is somewhat more complicated. Suppose we have two HashStructure instances, H1 and H2, which may either have a single property named "a" or no property at all. When comparing H1 and H2:
copyTo(oracle.javatools.data.HashStructure)
and copyTo(oracle.javatools.data.HashStructure, java.lang.String[])
will copy placeholder values from the origin to destination. The copy
operation will convert a placeholder value to a persistent value and
vice versa if necessary to make the destination a copy of the
original.
Structure.addStructureChangeListener(oracle.javatools.data.StructureChangeListener)
.
Normally, a change event is fired on every change made to the
HashStructure. However, change events can be batched into groups if
the caller uses the Structure.applyBatchChanges(java.lang.Runnable)
method and applies changes to the HashStructure within the specified
Runnable. When using applyBatchChanges, events are buffered until the
Runnable finishes, at which time a single event is fired for all the
changes that occurred. The single event contains details on each
individual change that occurred.
HashStructureIO
.HashStructureIO
Modifier and Type | Field and Description |
---|---|
static int |
NONEXISTENT
Return value from
keyStatus(java.lang.String) to indicate
that the key is nonexistent. |
static int |
PERSISTENT
Return value from
keyStatus(java.lang.String) and
parameter option to setKeyStatus(java.lang.String,int)
to indicate that the key is for a persistent value. |
static int |
PLACEHOLDER
Return value from
keyStatus(java.lang.String) and
parameter option to setKeyStatus(java.lang.String,int)
to indicate that the key is for a
placeholder value. |
Modifier and Type | Method and Description |
---|---|
void |
applyChange(ChangeInfo change)
Applies the change described by the specified
ChangeInfo
to this HashStructure. |
void |
applyChanges(ChangeInfo[] changes)
Applies the changes described by the specified
ChangeInfo
array to this HashStructure. |
HashStructure |
asReadOnly()
Returns a HashStructure that provides read-only access to
this HashStructure's properties.
|
void |
clear()
Removes all data from this HashStructure.
|
abstract boolean |
containsKey(java.lang.String name) |
HashStructure |
copyTo(HashStructure target)
Copies all properties recursively from this HashStructure to
the specified
target HashStructure. |
HashStructure |
copyTo(HashStructure target,
java.lang.String[] names)
Copies the properties specified by the
names parameter
from this HashStructure to the specified target
HashStructure. |
boolean |
equals(java.lang.Object obj) |
java.util.List |
getAsList(java.lang.String name)
Returns the property at the specified name as an unmodifiable
List , whether or not the property name actually points to
a ListStructure . |
boolean |
getBoolean(java.lang.String name)
Returns the
boolean equivalent value of the object
bound at the specified name. |
boolean |
getBoolean(java.lang.String name,
boolean defaultValue)
Returns the
boolean equivalent value of the object
bound at the specified name. |
double |
getDouble(java.lang.String name)
Returns the
double equivalent value of the object bound
at the specified name. |
double |
getDouble(java.lang.String name,
double defaultValue)
Returns the
double equivalent value of the object bound
at the specified name. |
float |
getFloat(java.lang.String name)
Returns the
float equivalent value of the object bound
at the specified name. |
float |
getFloat(java.lang.String name,
float defaultValue)
Returns the
float equivalent value of the object bound
at the specified name. |
HashStructure |
getHashStructure(java.lang.String name) |
int |
getInt(java.lang.String name)
Returns the
int equivalent value of the object bound
at the specified name. |
int |
getInt(java.lang.String name,
int defaultValue)
Returns the
int equivalent value of the object bound
at the specified name. |
ListStructure |
getListStructure(java.lang.String name)
Returns the
ListStructure bound at the specified
name or null of no object is bound. |
long |
getLong(java.lang.String name)
Returns the
long equivalent value of the object bound
at the specified name. |
long |
getLong(java.lang.String name,
long defaultValue)
Returns the
long equivalent value of the object bound
at the specified name. |
abstract java.lang.Object |
getObject(java.lang.String name)
Returns the Object stored at the specified name.
|
HashStructure |
getOrCreateHashStructure(java.lang.String name)
Returns the
HashStructure bound at the specified name
or if no object is currently bound to that name creates a new, empty
HashStructure object and binds it to the specified name as a
placeholder. |
ListStructure |
getOrCreateListStructure(java.lang.String name)
Returns the
ListStructure bound at the specified name
or if no object is currently bound to that name creates a new, empty
ListStructure object and binds it to the specified name as a
placeholder. |
java.lang.String |
getString(java.lang.String name)
Returns the String value that is bound at the specified name.
|
java.lang.String |
getString(java.lang.String name,
java.lang.String defaultValue)
Returns the String value that is bound at the specified name.
|
java.net.URL |
getURL(java.lang.String name)
Returns the
URL bound at the specified name or null
if no object is bound. |
java.net.URL |
getURL(java.lang.String name,
java.net.URL defaultValue)
Returns the
URL bound at the specified name. |
abstract void |
hideValues(java.lang.String[] names)
Moves all of the specified properties into a "dormant" state,
which means the values are still saved, but they will not
participate in any HashStructure operations (get, put,
containsKey, etc) until recovered by recoverValues(..).
|
boolean |
isAnyValueOverridden(java.lang.String[] names)
For a chained HashStructure, this method will return true
if any of the specified properties has its value defined
anywhere other than the last HashStructure in the chain.
|
boolean |
isReadOnly()
Returns
true if this HashStructure is in a
read-only mode or false if this HashStructure is modifiable. |
abstract java.util.Set<java.lang.String> |
keySet()
Returns the keys of this HashStructure as an unmodifiable Set.
|
abstract int |
keyStatus(java.lang.String key)
For the specified key, returns whether the key exists, is
persistent, or is a placeholder.
|
static HashStructure |
newChainForOverriding(HashStructure[] hashes)
Returns a composite HashStructure that is backed by the specified
array of HashStructures, treating the array as a lookup queue.
|
static HashStructure |
newChainForStatusQuo(HashStructure[] hashes)
Returns a composite HashStructure that is backed by the specified
array of HashStructures, treating the array as a lookup queue.
|
static HashStructure |
newInstance() |
abstract java.util.Set<java.lang.String> |
persistentKeySet()
Returns the persistent keys of this HashStructure as an unmodifiable
Set.
|
void |
putBoolean(java.lang.String name,
boolean value)
Binds the specified name to the specified value.
|
void |
putDouble(java.lang.String name,
double value)
Binds the specified name to the specified value.
|
void |
putFloat(java.lang.String name,
float value)
Binds the specified name to the specified value.
|
void |
putHashStructure(java.lang.String name,
HashStructure hash)
Binds the specified name to the specified HashStructure.
|
void |
putInt(java.lang.String name,
int value)
Binds the specified name to the specified value.
|
void |
putListStructure(java.lang.String name,
ListStructure list)
Binds the specified name to the specified ListStructure.
|
void |
putLong(java.lang.String name,
long value)
Binds the specified name to the specified value.
|
void |
putPlaceholderHashStructure(java.lang.String name,
HashStructure hash)
Binds the specified name to the specified HashStructure as a
placeholder.
|
void |
putPlaceholderListStructure(java.lang.String name,
ListStructure list)
Binds the specified name to the specified ListStructure as a
placeholder.
|
void |
putPlaceholderURL(java.lang.String name,
java.net.URL placeholderValue)
Puts the specified URL as a placeholder into this HashStructure.
|
void |
putString(java.lang.String name,
java.lang.String value)
Binds the specified name to the specified value.
|
void |
putString(java.lang.String name,
java.lang.String value,
boolean removeIfNullValue)
Binds the specified name to the specified value.
|
void |
putURL(java.lang.String name,
java.net.URL value)
Binds the specified name to the specified value.
|
void |
putURL(java.lang.String name,
java.net.URL value,
boolean removeIfNullValue)
Binds the specified name to the specified value.
|
abstract void |
recoverValues(java.lang.String[] names)
Recovers the specified properties from the "dormant" state,
so that they again participate in all HashStructure
operations.
|
abstract void |
remove(java.lang.String name)
Removes the object bound to the specified name from this Structure.
|
abstract void |
setKeyStatus(java.lang.String key,
int status)
For the specified key, if it exists in any form in this
HashStructure, the key status is changed to the specified
state, which must be either
PERSISTENT or
PLACEHOLDER . |
abstract void |
setParentDirtyable(Dirtyable parentDirtyable)
Sets the
Dirtyable that will be used as the delegate
for tracking the dirty flag. |
abstract int |
size()
Returns the number of keys that are bound in this HashStructure.
|
addStructureChangeListener, applyBatchChanges, getFullName, getStructName, intern, intern, intern, isDirty, markDirty, removeStructureChangeListener
public static final int NONEXISTENT
keyStatus(java.lang.String)
to indicate
that the key is nonexistent.public static final int PERSISTENT
keyStatus(java.lang.String)
and
parameter option to setKeyStatus(java.lang.String,int)
to indicate that the key is for a persistent value.public static final int PLACEHOLDER
keyStatus(java.lang.String)
and
parameter option to setKeyStatus(java.lang.String,int)
to indicate that the key is for a
placeholder value.public static final HashStructure newInstance()
public static final HashStructure newChainForStatusQuo(HashStructure[] hashes)
public static final HashStructure newChainForOverriding(HashStructure[] hashes)
public final java.lang.String getString(java.lang.String name)
java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
or if a leaf object is encountered when
a substructure is expected.public final java.lang.String getString(java.lang.String name, java.lang.String defaultValue)
java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
or if a leaf object is encountered when
a substructure is expected.public final void putString(java.lang.String name, java.lang.String value)
putString(String, String, boolean)
or
remove(String)
.java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putString("a/b","c") would throw ClassCastException.public final void putString(java.lang.String name, java.lang.String value, boolean removeIfNullValue)
When the value is null, the behavior depends on the value of the removeIfNullValue parameter. If removeIfNullValue is true, the name is unbound from the HashStructure. If removeIfNullValue is false, then the name is bound to null.
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putString("a/b","c") would throw ClassCastException.public final boolean getBoolean(java.lang.String name)
boolean
equivalent value of the object
bound at the specified name. If null is bound or there is no
value bound, this method returns false
.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
boolean) or if a leaf object is encountered when a substructure is
expected.public final boolean getBoolean(java.lang.String name, boolean defaultValue)
boolean
equivalent value of the object
bound at the specified name. If null is bound or there is no
bound value, the value of the defaultValue
parameter
is returned, and the defaultValue boolean is put into the
HashStructure as a placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
boolean) or if a leaf object is encountered when a substructure is
expected.public final void putBoolean(java.lang.String name, boolean value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putBoolean("a/b",true) would throw ClassCastException.public final int getInt(java.lang.String name)
int
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, this method returns 0
.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to an
int) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into an int.public final int getInt(java.lang.String name, int defaultValue)
int
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, the value of the defaultValue
parameter is
returned, and the defaultValue int is put into the HashStructure
as a placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to an
int) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into an int.public final void putInt(java.lang.String name, int value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putInt("a/b",17) would throw ClassCastException.public final long getLong(java.lang.String name)
long
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, this method returns 0
.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
long) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a long.public final long getLong(java.lang.String name, long defaultValue)
long
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, the value of the defaultValue
parameter is
returned, and the defaultValue long is put into the HashStructure
as a placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
long) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a long.public final void putLong(java.lang.String name, long value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putLong("a/b",17L) would throw ClassCastException.public final float getFloat(java.lang.String name)
float
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, this method returns 0.0
.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
float) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a float.public final float getFloat(java.lang.String name, float defaultValue)
float
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, the value of the defaultValue
parameter is
returned, and the defaultValue float is put into the HashStructure
as a placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
float) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a float.public final void putFloat(java.lang.String name, float value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putFloat("a/b",3.14159f) would throw ClassCastException.public final double getDouble(java.lang.String name)
double
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, this method returns 0.0
.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
double) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a double.public final double getDouble(java.lang.String name, double defaultValue)
double
equivalent value of the object bound
at the specified name. If null is bound or there is no bound
value, the value of the defaultValue
parameter is
returned, and the defaultValue double is put into the HashStructure
as a placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to String
(which is subsequently converted to a
double) or if a leaf object is encountered when a substructure is
expected.java.lang.NumberFormatException
- if the object bound at the name
cannot be converted into a double.public final void putDouble(java.lang.String name, double value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putDouble("a/b",2.718281828d) would throw ClassCastException.public final java.net.URL getURL(java.lang.String name)
URL
bound at the specified name or null
if no object is bound.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to URL
or if a leaf object is encountered when a
substructure is expected.public final java.net.URL getURL(java.lang.String name, java.net.URL defaultValue)
URL
bound at the specified name. Null
is a possible value. If there is no bound value, the value of
the defaultValue
parameter is returned, and the
defaultValue URL is put into the HashStructure as a
placeholder.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to URL
or if a leaf object is encountered when a
substructure is expected.public final void putPlaceholderURL(java.lang.String name, java.net.URL placeholderValue)
putURL(java.lang.String,java.net.URL)
, replacing the
existing value with the specified value and making the
HashStructure dirty.java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putPlaceholderURL("a/b",url) would throw ClassCastException.public final void putURL(java.lang.String name, java.net.URL value)
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putURL("a/b",url) would throw ClassCastException.public final void putURL(java.lang.String name, java.net.URL value, boolean removeIfNullValue)
When the value is null, the behavior depends on the value of the removeIfNullValue parameter. If removeIfNullValue is true, the name is unbound from the HashStructure. If removeIfNullValue is false, then the name is bound to null.
java.lang.ClassCastException
- if the name specifies a substructure
but a leaf object is encountered instead. For example, if
hash.getObject("a") would return a String, then calling
hash.putURL("a/b",url,true) would throw ClassCastException.public abstract java.lang.Object getObject(java.lang.String name)
HashStructure
ListStructure
public abstract java.util.Set<java.lang.String> keySet()
java.lang.UnsupportedOperationException
- if any attempt is made to
modify the returned Set.public final void applyChange(ChangeInfo change)
ChangeInfo
to this HashStructure. This method is most often used to apply
deltas accumulated through a ChangeBuffer
from a copy
of the HashStructure back to the original.public final void applyChanges(ChangeInfo[] changes)
ChangeInfo
array to this HashStructure. This method is most often used to
apply deltas accumulated through a ChangeBuffer
from a
copy of the HashStructure back to the original.public abstract java.util.Set<java.lang.String> persistentKeySet()
public abstract int keyStatus(java.lang.String key)
NONEXISTENT
, PERSISTENT
,
or PLACEHOLDER
.public abstract void setKeyStatus(java.lang.String key, int status)
PERSISTENT
or
PLACEHOLDER
.public final HashStructure getHashStructure(java.lang.String name)
name
- The name of the HashStructure
to retrieve.HashStructure
bound at the specified
name or null of no object is bound. However, if this
HashStructure is a chained HashStructure, this method will never
return null; use containsKey(java.lang.String)
to test
for existence instead of checking if getHashStructure
returns null.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to HashStructure
.public final HashStructure getOrCreateHashStructure(java.lang.String name)
HashStructure
bound at the specified name
or if no object is currently bound to that name creates a new, empty
HashStructure object and binds it to the specified name as a
placeholder.java.lang.ClassCastException
- if there is already a non-null object
bound at the name, and it cannot be cast to HashStructure
.public final void putHashStructure(java.lang.String name, HashStructure hash)
java.lang.IllegalArgumentException
- if either the name or the
structure parameter is null.java.lang.IllegalStateException
- if a cyclical reference is detected.
Cycles are not allowed in a graph of HashStructure and
ListStructure objects.public final void putPlaceholderHashStructure(java.lang.String name, HashStructure hash)
java.lang.IllegalArgumentException
- if either the name or the
structure parameter is null.java.lang.IllegalStateException
- if a cyclical reference is detected.
Cycles are not allowed in a graph of HashStructure and
ListStructure objects.public final java.util.List getAsList(java.lang.String name)
List
, whether or not the property name actually points to
a ListStructure
. If the named property is defined but is
not a List, it is returned wrapped in an unmodifiable List; that
will happen even if the defined property has a null value. If the
named property is already a ListStructure, it is simply wrapped by
Collections.unmodifiableList(..) and then returned. If the named
property is not defined (i.e. containsKey is false
for
the name), then this method returns null.public final ListStructure getListStructure(java.lang.String name)
ListStructure
bound at the specified
name or null of no object is bound.java.lang.ClassCastException
- if the object bound at the name cannot
be cast to ListStructure
.public final ListStructure getOrCreateListStructure(java.lang.String name)
ListStructure
bound at the specified name
or if no object is currently bound to that name creates a new, empty
ListStructure object and binds it to the specified name as a
placeholder.java.lang.ClassCastException
- if there is already a non-null object
bound at the name, and it cannot be cast to ListStructure
.public final void putListStructure(java.lang.String name, ListStructure list)
java.lang.IllegalArgumentException
- if either the name or the
structure parameter is null.java.lang.IllegalStateException
- if a cyclical reference is detected.
Cycles are not allowed in a graph of HashStructure and
ListStructure objects.public final void putPlaceholderListStructure(java.lang.String name, ListStructure list)
java.lang.IllegalArgumentException
- if either the name or the
structure parameter is null.java.lang.IllegalStateException
- if a cyclical reference is detected.
Cycles are not allowed in a graph of HashStructure and
ListStructure objects.public void clear()
public abstract boolean containsKey(java.lang.String name)
keyStatus(java.lang.String)
if the distinction between
persistent and placeholder is important.public abstract void remove(java.lang.String name)
public abstract int size()
public abstract void setParentDirtyable(Dirtyable parentDirtyable)
Dirtyable
that will be used as the delegate
for tracking the dirty flag. When no parent Dirtyable is set
(or when null is explicitly set), this HashStructure will
track the dirty state directly.public boolean isAnyValueOverridden(java.lang.String[] names)
public abstract void hideValues(java.lang.String[] names)
recoverValues(java.lang.String[])
public abstract void recoverValues(java.lang.String[] names)
hideValues(java.lang.String[])
public boolean isReadOnly()
true
if this HashStructure is in a
read-only mode or false if this HashStructure is modifiable.
See asReadOnly()
for details.public HashStructure asReadOnly()
public HashStructure copyTo(HashStructure target, java.lang.String[] names)
names
parameter
from this HashStructure to the specified target
HashStructure. The names may use slash
notation to indicate properties located in a substructure.public HashStructure copyTo(HashStructure target)
target
HashStructure. The copy
operation buffers change events so that only a single
StructureChangeEvent
is fired on the target HashStructure
as a result of invoking copyTo.public boolean equals(java.lang.Object obj)
equals
in class java.lang.Object