1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.betwixt.expression;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.apache.commons.betwixt.BindingConfiguration;
22 import org.apache.commons.betwixt.strategy.ObjectStringConverter;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 /*** <p><code>Context</code> describes the context used to evaluate
27 * bean expressions.
28 * This is mostly a bean together with a number of context variables.
29 * Context variables are named objects.
30 * In other words,
31 * a context variable associates an object with a string.</p>
32 *
33 * <p> Logging during expression evaluation is done through the logging
34 * instance held by this class.
35 * The object initiating the evaluation should control this logging
36 * and so passing a <code>Log</code> instance is enforced by the constructors.</p>
37 *
38 * <p><code>Context</code> is a natural place to include shared evaluation code.
39 * One of the problems that you get with object graphs is that they can be cyclic.
40 * Xml cannot (directly) include cycles.
41 * Therefore <code>betwixt</code> needs to find and deal properly with cycles.
42 * The algorithm used is to check the parentage of a new child.
43 * If the child is a parent then that operation fails. </p>
44 *
45 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
46 * @version $Revision: 1.10.2.1 $
47 */
48 public class Context {
49
50 /*** Evaluate this bean */
51 private Object bean;
52 /*** Variables map */
53 private Map variables;
54 /***
55 * Logging uses commons-logging <code>Log</code>
56 * named <code>org.apache.commons.betwixt</code>
57 */
58 private Log log;
59 /*** Configuration for dynamic binding properties */
60 private BindingConfiguration bindingConfiguration;
61
62 /***
63 * Construct context with default log
64 */
65 public Context() {
66 this( null, LogFactory.getLog( Context.class ) );
67 }
68
69 /*** Convenience constructor sets evaluted bean and log.
70 *
71 * @param bean evaluate expressions against this bean
72 * @param log log to this logger
73 * @deprecated 0.5 use constructor which takes a BindingConfiguration
74 */
75 public Context(Object bean, Log log) {
76 this( bean, log, new BindingConfiguration() );
77 }
78
79
80 /*** Convenience constructor sets evaluted bean and log.
81 *
82 * @param bean evaluate expressions against this bean
83 * @param log log to this logger
84 * @param bindingConfiguration not null
85 */
86 public Context(Object bean, Log log, BindingConfiguration bindingConfiguration) {
87 this( bean, new HashMap(), log, bindingConfiguration );
88 }
89
90 /***
91 * Construct a cloned context.
92 * The constructed context should share bean, variables, log and binding configuration.
93 * @param context duplicate the attributes of this bean
94 */
95 public Context( Context context ) {
96 this(context.bean, context.variables, context.log, context.bindingConfiguration);
97 }
98
99
100 /*** Convenience constructor sets evaluted bean, context variables and log.
101 *
102 * @param bean evaluate expressions against this bean
103 * @param variables context variables
104 * @param log log to this logger
105 * @deprecated 0.5 use constructor which takes a converter
106 */
107 public Context(Object bean, Map variables, Log log) {
108 this( bean, variables, log, new BindingConfiguration() );
109 }
110
111 /*** Convenience constructor sets evaluted bean, context variables and log.
112 *
113 * @param bean evaluate expressions against this bean
114 * @param variables context variables
115 * @param log log to this logger
116 * @param bindingConfiguration not null
117 */
118 public Context(Object bean, Map variables, Log log, BindingConfiguration bindingConfiguration) {
119 this.bean = bean;
120 this.variables = variables;
121 this.log = log;
122 this.bindingConfiguration = bindingConfiguration;
123 }
124
125 /*** Returns a new child context with the given bean but the same log and variables.
126 *
127 * @param newBean create a child context for this bean
128 * @return new Context with new bean but shared variables
129 */
130 public Context newContext(Object newBean) {
131 Context context = new Context(this);
132 context.setBean( newBean );
133 return context;
134 }
135
136 /***
137 * Gets the current bean.
138 * @return the bean against which expressions are evaluated
139 */
140 public Object getBean() {
141 return bean;
142 }
143
144 /***
145 * Set the current bean.
146 * @param bean the Object against which expressions will be evaluated
147 */
148 public void setBean(Object bean) {
149 this.bean = bean;
150 }
151
152 /***
153 * Gets context variables.
154 * @return map containing variable values keyed by variable name
155 */
156 public Map getVariables() {
157 return variables;
158 }
159
160 /***
161 * Sets context variables.
162 * @param variables map containing variable values indexed by varibable name Strings
163 */
164 public void setVariables(Map variables) {
165 this.variables = variables;
166 }
167
168 /***
169 * Gets the value of a particular context variable.
170 * @param name the name of the variable whose value is to be returned
171 * @return the variable value or null if the variable isn't set
172 */
173 public Object getVariable(String name) {
174 return variables.get( name );
175 }
176
177 /***
178 * Sets the value of a particular context variable.
179 * @param name the name of the variable
180 * @param value the value of the variable
181 */
182 public void setVariable(String name, Object value) {
183 variables.put( name, value );
184 }
185
186 /***
187 * Gets the current log.
188 *
189 * @return the implementation to which this class logs
190 */
191 public Log getLog() {
192 return log;
193 }
194
195 /***
196 * Set the log implementation to which this class logs
197 *
198 * @param log the implemetation that this class should log to
199 */
200 public void setLog(Log log) {
201 this.log = log;
202 }
203
204 /***
205 * Gets object <-> string converter.
206 * @return the Converter to be used for conversions, not null
207 * @since 0.5
208 */
209 public ObjectStringConverter getObjectStringConverter() {
210 return bindingConfiguration.getObjectStringConverter();
211 }
212
213 /***
214 * Should <code>ID</code>'s and <code>IDREF</code> attributes
215 * be used to cross-reference matching objects?
216 *
217 * @return true if <code>ID</code> and <code>IDREF</code>
218 * attributes should be used to cross-reference instances
219 * @since 0.5
220 */
221 public boolean getMapIDs() {
222 return bindingConfiguration.getMapIDs();
223 }
224
225 /***
226 * The name of the attribute which can be specified in the XML to override the
227 * type of a bean used at a certain point in the schema.
228 *
229 * <p>The default value is 'className'.</p>
230 *
231 * @return The name of the attribute used to overload the class name of a bean
232 * @since 0.5
233 */
234 public String getClassNameAttribute() {
235 return bindingConfiguration.getClassNameAttribute();
236 }
237
238 /***
239 * Sets the name of the attribute which can be specified in
240 * the XML to override the type of a bean used at a certain
241 * point in the schema.
242 *
243 * <p>The default value is 'className'.</p>
244 *
245 * @param classNameAttribute The name of the attribute used to overload the class name of a bean
246 * @since 0.5
247 */
248 public void setClassNameAttribute(String classNameAttribute) {
249 bindingConfiguration.setClassNameAttribute( classNameAttribute );
250 }
251 }