View Javadoc

1   /*
2    * Copyright 2006-2016 The JGUIraffe Team.
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 net.sf.jguiraffe.di.impl.providers;
17  
18  import net.sf.jguiraffe.di.BeanProvider;
19  import net.sf.jguiraffe.di.BeanStore;
20  import net.sf.jguiraffe.di.Dependency;
21  import net.sf.jguiraffe.di.DependencyProvider;
22  
23  /**
24   * <p>
25   * A concrete implementation of the <code>BeanProvider</code> interface that
26   * will always return the same bean instance.
27   * </p>
28   * <p>
29   * When an instance of this class is created, the managed bean instance (and
30   * optionally the target class if a type conversion is required) is passed in.
31   * On its first call the {@link #getBean(DependencyProvider)} method checks
32   * whether a type conversion if required. If this is the case, the conversion is
33   * performed, and the resulting object is stored. Later invocations will then
34   * always return this bean instance. The other methods defined by the
35   * <code>BeanProvider</code> interface are implemented as dummies: There are no
36   * dependencies, and synchronization support is not needed.
37   * </p>
38   * <p>
39   * In addition to the <code>BeanProvider</code> interface, the
40   * <code>Dependency</code> interface is also implemented. This makes it possible
41   * to have static dependencies, which are always resolved to a
42   * <code>BeanProvider</code> returning a constant bean. Dependencies of this
43   * type may seem strange first, but they make sense in some cases. For instance
44   * when a method is to be invoked, its parameters need to be defined. The
45   * current parameter values may be dependencies to other beans in the current
46   * bean store; so they need to be defined using dependencies. In simple cases
47   * however constant values need to be passed (e.g. integers, flags, or string
48   * values). For this purpose such a constant dependency can be used.
49   * </p>
50   * <p>
51   * Instances of this class can be created using the static
52   * <code>getInstance()</code> factory methods. In any case the constant value of
53   * the dependency must be passed in. It is also possible to specify the class of
54   * this dependency. In this case the class will try a type conversion as
55   * described above.
56   * </p>
57   *
58   * @author Oliver Heger
59   * @version $Id: ConstantBeanProvider.java 205 2012-01-29 18:29:57Z oheger $
60   */
61  public final class ConstantBeanProvider extends SimpleBeanProvider implements
62          BeanProvider, Dependency
63  {
64      /** Constant for a dependency that will be resolved to <b>null</b>. */
65      public static final ConstantBeanProvider NULL = new ConstantBeanProvider(
66              null, null);
67  
68      /** Stores the managed bean. */
69      private final Object bean;
70  
71      /** Stores the class of the bean. */
72      private final Class<?> beanClass;
73  
74      /** The converted bean. */
75      private Object convertedBean;
76  
77      /**
78       * Creates a new instance of {@code ConstantBeanProvider} and initializes it
79       * with the bean to manage. The class of the bean can also be specified -
80       * this is required if type conversion is needed. Clients use the static
81       * factory method for creating new instances.
82       *
83       * @param conversionClass the class of the bean
84       * @param obj the bean to be managed
85       */
86      private ConstantBeanProvider(Class<?> conversionClass, Object obj)
87      {
88          bean = obj;
89  
90          if (conversionClass != null)
91          {
92              beanClass = conversionClass;
93          }
94          else
95          {
96              convertedBean = obj;
97              beanClass = (obj != null) ? obj.getClass() : Object.class;
98          }
99      }
100 
101     /**
102      * Returns the bean managed by this provider. This is the same bean as was
103      * passed to the constructor. No type conversion has been performed.
104      *
105      * @return the bean passed to the constructor
106      */
107     public Object getBean()
108     {
109         return bean;
110     }
111 
112     /**
113      * Returns the bean managed by this provider. This implementation operates
114      * on the bean that was passed when this object was created. If necessary,
115      * type conversion is performed (the result of this conversion is cached, so
116      * that the conversion is only done on first access).
117      *
118      * @param dependencyProvider the dependency provider
119      * @return the bean managed by this provider
120      */
121     public Object getBean(DependencyProvider dependencyProvider)
122     {
123         if (convertedBean == null && bean != null)
124         {
125             convertedBean =
126                     dependencyProvider.getInvocationHelper()
127                             .getConversionHelper().convert(beanClass, bean);
128         }
129 
130         return convertedBean;
131     }
132 
133     /**
134      * Returns the class of the managed bean. If a class was passed on creation
135      * time, it is directly returned. Otherwise, the class is obtained from the
136      * managed bean. If the bean is <b>null</b>, the type
137      * {@code java.lang.Object} is returned.
138      *
139      * @param dependencyProvider the dependency provider
140      * @return the class of the managed bean
141      */
142     public Class<?> getBeanClass(DependencyProvider dependencyProvider)
143     {
144         return beanClass;
145     }
146 
147     /**
148      * Returns the <code>BeanProvider</code> this <code>Dependency</code> refers
149      * to. This implementation simply returns the <b>this</b> pointer.
150      *
151      * @param store the bean store
152      * @param depProvider the dependency provider
153      * @return the {@code BeanProvider} this {@code Dependency} refers to
154      */
155     public BeanProvider resolve(BeanStore store, DependencyProvider depProvider)
156     {
157         return this;
158     }
159 
160     /**
161      * Returns a string representation of this object. This string will contain
162      * the value of this bean provider.
163      *
164      * @return a string for this object
165      */
166     @Override
167     public String toString()
168     {
169         StringBuilder buf = new StringBuilder(getClass().getName());
170         buf.append(" [ value = ").append(getBean()).append(" ]");
171         return buf.toString();
172     }
173 
174     /**
175      * Creates a new instance of this class and initializes it with the bean to
176      * be managed.
177      *
178      * @param bean the bean to be managed
179      * @return the new instance of this class
180      */
181     public static ConstantBeanProvider getInstance(Object bean)
182     {
183         return new ConstantBeanProvider(null, bean);
184     }
185 
186     /**
187      * Returns an instance of this class that refers to the specified value of
188      * the given class. If necessary, a conversion will be performed to convert
189      * the value to the given class.
190      *
191      * @param valueClass the class of this bean provider (can be <b>null</b>)
192      * @param value the value of the managed bean
193      * @return the instance representing this value
194      * @throws IllegalArgumentException if a conversion is necessary, but cannot
195      *         be performed
196      */
197     public static ConstantBeanProvider getInstance(Class<?> valueClass,
198             Object value)
199     {
200         return new ConstantBeanProvider(valueClass, value);
201     }
202 }