|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object ix.util.context.Context
public final class Context
A Context is an object that is used as an additional, often
implicit, parameter when accessing values, such as in a "get"-method.
Instead of a value being stored directly in a field, the field contains
a list of associations from contexts to values, arranged so that they
can be searched efficiently. The conventions used in this implementation
of contexts are that the associations are held in a chain of
ContextLink
s, and the relevant context is obtained from
an implementation of ContextHolder
. So instead of writing
something like this in a class definition:
ValClass field = new FieldValue(); ValClass getField() { return field; } void setField(ValClass value) { field = value; }you would write something like this:
ContextLink field = new ContextLink(new FieldValue()); // Here one holder used with all fields, and the holder // is obtained when this object is created. ContextHolder contextHolder = Context.getContextHolder(); ValClass getField() { Context c = contextHolder.getContext(); return (ValClass)Context.getInContext(field, c); } void setField(ValClass value) { Context c = contextHolder.getContext(); Context.setInContext(field, c, value); }
An alternative is to use objects that hide some of the details.
Here is the same example using a ContextValue
:
// Here one holder used with all fields, and the holder // is obtained when this object is created. ContextHolder contextHolder = Context.getContextHolder(); ContextValue field = new ContextValue(contextHolder, new FieldValue()); ValClass getField() { return (ValClass)field.get(); } void setField(ValClass value) { field.set(value); }Since the defaut holder used when a ContextValue is constructed is the one returned by
Context.getContextHolder()
, which is what
ContextValue uses by default, the example can be simplified further
to:
ContextValue field = new ContextValue(new FieldValue()); ValClass getField() { return (ValClass)field.get(); } void setField(ValClass value) { field.set(value); }
A context has few properties of its own. It is simply an object with which the values obtained by context-relative accessors may be associated. Contexts are arranged in a tree: each context has a single parent and a list of children. When there is no value directly associated with a context, a value is inherited from the nearest ancestor context that does have a directly associated value. However, when a value is assigned in a context, it is always associated directly with that context, and the associations between ancestor contexts and values are not changed. This makes it possible to protect the values associated with a context, while still being able to access them, by moving to a descendent context.
An efficient search for the value associated with a context, or inherited from an ancestor, is accomplished by exploiting context numbers. Every context has a number which is assigned when it is created, and newer contexts have higher numbers than older ones. In particular, a context has a higher number than any of its ancestors. The chain of ContextLinks for a given field has links for higher-numbered (newer) contexts first. The algorithm for finding the right value is therefore as follows:
getInContext
method implements that algorithm.
Context-holders are used for two reasons. First, they make it unnecessary to pass contexts as parameters to "get"- and "set"-methods. This makes "context-layered" objects look much more like ordinary objects. Second, a context-holder may be shared by many objects, so that they all change context at once.
However, there is no single way of managing context-holders that is right for every case. In some applications, a single, global context-holder can be used. In others, a number of more local context-holders will be needed.
These problems are partly addressed by context-holding "strategies". A holding strategy provides a method that returns a context-holder, and the Context class holds a current (global) strategy. The static method Context.getContextHolder() asks the current strategy for a holder.
When using contexts, it is typical to fix the holder used by an object when the object is created (as in the examples above). Otherwise, every access to a context-dependent value would involve asking a strategy for a holder and then asking the holder for its current context, rather than just asking a holder for its current context.
ContextLink
,
ContextHolder
,
ContextHoldingStrategy
,
GlobalHoldingStrategy
,
ThreadLocalHoldingStrategy
,
ContextValue
Field Summary | |
---|---|
(package private) java.util.List<Context> |
children
A collection of this context's children. |
(package private) static ContextHoldingStrategy |
contextHoldingStrategy
The current context-holding strategy. |
(package private) static long |
count
The number of contexts that have been created. |
(package private) long |
number
A number, unique to this context and larger than the number of any context created earlier. |
(package private) static java.util.HashMap |
numberToContextTable
A mapping from context numbers to (weak references to) contexts. |
(package private) Context |
parent
This context's parent context. |
static Context |
rootContext
A context that is an ancestor of all others. |
Constructor Summary | |
---|---|
Context()
Create a context with the root context as its parent. |
|
Context(Context parent)
Create a context with a given parent. |
Method Summary | ||
---|---|---|
static void |
clearContexts()
Removes all contexts except the root context. |
|
void |
discard()
Remove this context and all of its descendents from the context tree and the number-to-context table. |
|
java.util.List<Context> |
getAncestors()
Returns a list containing the path from this context back to the root. |
|
java.util.List<Context> |
getChildren()
Returns an unmodifiable view of this context's children. |
|
static Context |
getContext()
Returns the current context from the ContextHolder returned by the current ContextHoldingStrategy. |
|
static Context |
getContext(long n)
Returns the context that has the indicated number, or null if that context has been discarded or has ceased to exist. |
|
static ContextHolder |
getContextHolder()
Returns the context-holder provided by the current context-holding strategy. |
|
static ContextHoldingStrategy |
getContextHoldingStrategy()
Returns the current context-holding strategy. |
|
static
|
getInContext(ContextLink<T> cl,
Context c)
Searches a chain of ContextLinks to find the value associated with a given context. |
|
static
|
getInContext(ContextLink<T> cl,
Context c,
T defaultValue)
Searches a chain of ContextLinks to find the value associated with a given context and returns a default value if no value can be found. |
|
long |
getNumber()
Returns this context's number. |
|
Context |
getParent()
Returns this context's parent context. |
|
static
|
getValueLinkInContext(ContextLink<T> cl,
Context c)
Searches a chain of ContextLinks to find the link that contains the value associated with a given context. |
|
static void |
inContext(ContextHolder h,
Context c,
java.lang.Runnable r)
Temporarily changes a context-holder's current context around a call to a Runnable's run() method. |
|
static void |
inContext(Context c,
java.lang.Runnable r)
Calls inContext(ContextHolder, Context, Runnable)
on the ContextHolder returned by the current ContextHoldingStrategy. |
|
static Context |
popContext()
Calls popContext(ContextHolder) on the ContextHolder
returned by the current ContextHoldingStrategy |
|
static Context |
popContext(ContextHolder h)
Moves the specified context-holder to the parent of its current context. |
|
static void |
printContextTree()
Prints a description of the current context tree on Debug.out . |
|
static Context |
pushContext()
Calls pushContext(ContextHolder) on the ContextHolder
returned by the current ContextHoldingStrategy. |
|
static Context |
pushContext(ContextHolder h)
Moves the specified context-holder to a new child of its current context and returns that new context. |
|
static void |
setContext(Context c)
Sets the context in the ContextHolder returned by the current ContextHoldingStrategy. |
|
static void |
setContextHoldingStrategy(ContextHoldingStrategy s)
Sets the current context-holding strategy. |
|
static
|
setInContext(ContextLink<T> cl,
Context c,
T value)
Modifies a chain of ContextLinks to associate a value directly with a given context. |
|
java.lang.String |
toString()
|
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
static long count
static java.util.HashMap numberToContextTable
public static final Context rootContext
Unlike any other context, the root context's parent is null.
static ContextHoldingStrategy contextHoldingStrategy
getContextHoldingStrategy()
,
setContextHoldingStrategy(ContextHoldingStrategy s)
,
getContextHolder()
final long number
final Context parent
final java.util.List<Context> children
Constructor Detail |
---|
public Context()
The constructor is also used once to create the root context itself, and then it's arranged for the root context's parent to be null.
public Context(Context parent)
Method Detail |
---|
public long getNumber()
public Context getParent()
public java.util.List<Context> getAncestors()
public java.util.List<Context> getChildren()
public void discard()
public java.lang.String toString()
toString
in class java.lang.Object
public static Context getContext()
ContextHolder.getContext()
public static Context getContext(long n)
public static void setContext(Context c)
ContextHolder.setContext(Context)
public static void clearContexts()
ContextHoldingStrategy.clearContexts()
method of the current ContextHoldingStrategy. The strategy
should set the current context of any holders it knows about
to the root context.
public static ContextHoldingStrategy getContextHoldingStrategy()
Initially, the strategy is one that provides a single, global context holder.
GlobalHoldingStrategy
,
ThreadLocalHoldingStrategy
public static void setContextHoldingStrategy(ContextHoldingStrategy s)
public static ContextHolder getContextHolder()
getContextHoldingStrategy()
public static <T> T getInContext(ContextLink<T> cl, Context c)
public static <T> T getInContext(ContextLink<T> cl, Context c, T defaultValue)
public static <T> ContextLink<T> getValueLinkInContext(ContextLink<T> cl, Context c)
public static <T> void setInContext(ContextLink<T> cl, Context c, T value)
public static void inContext(ContextHolder h, Context c, java.lang.Runnable r)
public static Context pushContext(ContextHolder h)
public static Context popContext(ContextHolder h)
public static Context pushContext()
pushContext(ContextHolder)
on the ContextHolder
returned by the current ContextHoldingStrategy.
public static Context popContext()
popContext(ContextHolder)
on the ContextHolder
returned by the current ContextHoldingStrategy
public static void inContext(Context c, java.lang.Runnable r)
inContext(ContextHolder, Context, Runnable)
on the ContextHolder returned by the current ContextHoldingStrategy.
public static void printContextTree()
Debug.out
. Children appear after their parent,
indented one more level.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |