View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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 &lt;-&gt; 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 }