Gracelets is designed to be easily integrated into different frameworks. Many frameworks (like JBoss Seam) extend the concept of the basic JSF scopes (request,
session, application) and thus have different implementations. Gracelets scripts need to be able to easily access variables and set variables in these scopes.
Thus the variable context API was designed as an abstract bridge to different scope based frameworks. However, Gracelets itself comes with a primitive default
variable context implementation that defines a view, request, conversation, session and application scopes. When another framework is being used, its variable
context implementation will take precedence over the default implementation, thus allowing it to have the first shot at resolving variables.
For example, the
JBoss Seam extension uses this api to allow gracelet scripts to have access to JBoss Seam components and scope
variables.
The package containing the classes for this api is in the
gracelets.api.context
package. And the main interfaces for creating
a variable context are the
gracelets.api.context.VariableContext
interface and the
gracelets.api.context.Scope
interface. These interfaces are defined as
follows:
VariableContext.javaToggle Line Numbers |
1
package gracelets.api.context; 2
3
import gracelets.api.context.factory.Factory; 4
import gracelets.api.context.factory.FactoryStore; 5
import groovy.lang.GroovyObject; 6
7
import java.io.Serializable; 8
import java.util.List; 9
import java.util.Map; 10
11
import javax.faces.event.PhaseEvent; 12
13
14
@link 15
16
17
@author 18
@author 19
@version 20
21
public interface VariableContext extends Serializable, GroovyObject, FactoryStore { 22
23
24
25
26
27
@param 28
@param 29
@return 30
31
Object get (Object caller, Object key); 32
33
34
35
36
@param 37
@param 38
@param 39
@return 40
41
@see 42
43
Object get (Object caller, Object key, Scope scope); 44
45
46
47
48
49
50
@link 51
52
@param 53
@param 54
@param 55
@return 56
57
VariableContext set (Object caller, Object key, Object value); 58
59
60
@param 61
@param 62
@param 63
@param 64
@return 65
66
VariableContext set (Object caller, Object key, Scope scope, Object value); 67
68
69
@param 70
@return 71
72
boolean handlesScope (Scope scope); 73
74
75
@param 76
@return 77
78
Scope getScopeByName (String name); 79
80
81
@return 82
83
List<Scope> getAvailableScopes (); 84
85
86
@return 87
88
Scope getDefaultScope (); 89
90
91
@param 92
@return@link 93
94
Scope getDefaultScope (Object name); 95
96
97
98
99
@param 100
101
void beforePhase (PhaseEvent evt); 102
103
104
105
106
@param 107
108
void afterPhase (PhaseEvent evt); 109
110
111
@param 112
@return 113
114
boolean isSetOrHasFactory (Object key); 115
116
117
118
119
@return 120
121
ConversationManager getConversationManager(); 122
123
124
125
126
void cleanup (); 127
128
}
|
Scope.javaToggle Line Numbers |
1
package gracelets.api.context; 2
3
import gracelets.api.Gracelets; 4
import gracelets.api.context.factory.Factory; 5
6
import java.io.Serializable; 7
8
9
@link 10
11
12
13
@author 14
@author 15
@version 16
17
@param 18
@param 19
20
public interface Scope<K,V> extends Serializable { 21
22
23
@return 24
25
String getName (); 26
27
28
@param 29
@return 30
31
boolean containsKey (K key); 32
33
34
35
36
@param 37
@param 38
@return 39
40
Scope set (K key, V value); 41
42
43
44
45
@param 46
@return 47
48
Scope remove (K key); 49
50
51
@param 52
@return 53
54
V get (K key); 55
56
57
58
59
void cleanup (); 60
61
62
@return 63
64
boolean isActive (); 65
66
67
@return@link 68
69
boolean isConversational (); 70
71
}
|
Above the variable context will define inside of itself various scopes. The scope interface was designed so that one can use different scope implementations
easily and rearragne their order in different variable contexts. For instance is you want to make your own variable context, but don't feel up to writing
a conversation level scope, you can reuse the one defined in the default implementation of Gracelets. The variable context and generally its scopes are instantiated
for every request. At the end of the request, the cleanup() method is called so that it can remove or close any resources it needs to.
One major feature that was added in Gracelets 2.0.0 was an independent factory solution. This solution is tightly connected to the Variable Contexts. In each
scope implementation, you can handle how factories are added/removed. Factories are implementations of the
gracelets.api.context.factory.Factory
interface which is defined
as follows:
Factory.javaToggle Line Numbers |
1
package gracelets.api.context.factory; 2
3
import gracelets.api.Gracelets; 4
import gracelets.api.context.Scope; 5
import gracelets.api.jsf.expression.GraceletExpressionSource; 6
import gracelets.api.resource.GraceletSource; 7
8
9
@link 10
11
@author 12
13
14
public interface Factory<T> { 15
16
17
@return 18
19
String getScope (); 20
21
22
@return 23
24
T generate (); 25
26
27
@return 28
29
GraceletExpressionSource getSource (); 30
31
}
|
Since Factories are application level definitions (independent of the scope they outject to), they need a place on the application level to hold their state.
Gracelets stores these in an implementation dependent Variable Context Manager to store and retreive factories.
There are a few basic implementations of the Factory interface, mainly to handle Closures as factories
and Java based classes to also be able to generate factory objects.
The basic idea of a factory is that when a context variable in a particular scope does not currently have a value, the factory is used to generate the
value automatically.
In conclusion, if you want to integrate a framework that has its own scopes for certain variables, you can use this extensible variable context api
and provide the instance via a
gracelet extension.