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;
17
18 import java.util.Set;
19
20 import net.sf.jguiraffe.di.BeanContext;
21 import net.sf.jguiraffe.di.BeanInitializer;
22 import net.sf.jguiraffe.di.BeanProvider;
23 import net.sf.jguiraffe.di.ClassLoaderProvider;
24 import net.sf.jguiraffe.di.Dependency;
25 import net.sf.jguiraffe.di.DependencyProvider;
26 import net.sf.jguiraffe.di.InjectionException;
27 import net.sf.jguiraffe.di.InvocationHelper;
28
29 /**
30 * <p>
31 * An implementation of the {@code DependencyProvider} interface, which does not
32 * support external dependencies.
33 * </p>
34 * <p>
35 * This class allows the execution of simple {@link Invokable} objects, which do
36 * not require access to other beans stored in a {@code BeanContext}. The
37 * methods defined by the {@link ClassLoaderProvider} interface are fully
38 * implemented (by delegating to a wrapped {@link ClassLoaderProvider}). But
39 * other methods for dealing with dependencies throw an exception. This makes it
40 * possible to execute simple invocation scripts (e.g. defined by a
41 * {@link ChainedInvocation}), including access to local variables. However,
42 * other bean providers cannot be accessed.
43 * </p>
44 * <p>
45 * A use case for this class is the execution of a shutdown script by a bean
46 * provider that is no longer needed. At the time the shutdown script is invoked
47 * the corresponding {@code BeanContext} (or {@code BeanStore}) may already be
48 * partly destroyed, so access to other beans is not safe. Nevertheless
49 * arbitrary methods on the affected bean can be invoked.
50 * </p>
51 * <p>
52 * When creating an instance of this class a {@link ClassLoaderProvider} object
53 * must be provided. All methods dealing with classes and class loaders are
54 * passed to this object. The other methods are implemented by simply throwing
55 * an exception.
56 * </p>
57 *
58 * @author Oliver Heger
59 * @version $Id: RestrictedDependencyProvider.java 205 2012-01-29 18:29:57Z oheger $
60 */
61 public class RestrictedDependencyProvider implements DependencyProvider
62 {
63 /** Stores the wrapped {@code ClassLoaderProvider}. */
64 private final ClassLoaderProvider classLoaderProvider;
65
66 /** Stores the invocation helper. */
67 private final InvocationHelper invocationHelper;
68
69 /**
70 * Creates a new instance of {@code RestrictedDependencyProvider} and
71 * initializes it with the specified {@code ClassLoaderProvider} and the
72 * {@code InvocationHelper}.
73 *
74 * @param clp the {@code ClassLoaderProvider} (must not be <b>null</b>)
75 * @param invHlp the {@code InvocationHelper} (must not be <b>null</b>)
76 * @throws IllegalArgumentException if a required parameter is <b>null</b>
77 */
78 public RestrictedDependencyProvider(ClassLoaderProvider clp,
79 InvocationHelper invHlp)
80 {
81 if (clp == null)
82 {
83 throw new IllegalArgumentException(
84 "ClassLoaderProvider must not be null!");
85 }
86 if (invHlp == null)
87 {
88 throw new IllegalArgumentException(
89 "InvocationHelper must not be null!");
90 }
91
92 classLoaderProvider = clp;
93 invocationHelper = invHlp;
94 }
95
96 /**
97 * Returns the wrapped {@code ClassLoaderProvider}.
98 *
99 * @return the {@code ClassLoaderProvider}
100 */
101 public ClassLoaderProvider getClassLoaderProvider()
102 {
103 return classLoaderProvider;
104 }
105
106 /**
107 * Adds a {@code BeanInitializer}. This implementation just throws an
108 * exception.
109 *
110 * @param initializer the initializer
111 */
112 public void addInitializer(BeanInitializer initializer)
113 {
114 throw new UnsupportedOperationException(
115 "BeanInitializers are not supported by this dependency provider!");
116 }
117
118 /**
119 * Notifies this dependency provider about a newly created bean. This
120 * implementation just throws an exception.
121 *
122 * @param bean the new bean
123 * @param provider the responsible bean provider
124 */
125 public void beanCreated(Object bean, BeanProvider provider)
126 {
127 throw new UnsupportedOperationException(
128 "This method is not supported by this dependency provider!");
129 }
130
131 /**
132 * Returns a dependent bean. This implementation invokes the passed in
133 * {@code Dependency} with a <b>null</b> bean store. If a bean provider is
134 * returned, this provider's bean is queried. This way certain {@code
135 * Dependency} implementations can be served, while others cause an
136 * exception.
137 *
138 * @param dependency the dependency to resolve
139 * @return the corresponding bean
140 * @throws InjectionException if the {@code Dependency} cannot be resolved
141 */
142 public Object getDependentBean(Dependency dependency)
143 {
144 try
145 {
146 BeanProvider bp = dependency.resolve(null, this);
147 return bp.getBean(this);
148 }
149 catch (NullPointerException npex)
150 {
151 throw new InjectionException(
152 "This dependency provider does not allow access to "
153 + dependency, npex);
154 }
155 }
156
157 /**
158 * Checks whether a bean is available. This implementation just throws an
159 * exception.
160 *
161 * @param dependency the dependency to the bean
162 * @return a flag whether this bean is available
163 */
164 public boolean isBeanAvailable(Dependency dependency)
165 {
166 throw new UnsupportedOperationException(
167 "This method is not supported by this dependency provider!");
168 }
169
170 /**
171 * Sets the context that is responsible for a bean creation event. This
172 * implementation just throws an exception.
173 *
174 * @param context the context
175 */
176 public void setCreationBeanContext(BeanContext context)
177 {
178 throw new UnsupportedOperationException(
179 "This method is not supported by this dependency provider!");
180 }
181
182 /**
183 * Returns a set with the names of all class loaders registered at this
184 * object. This implementation delegates to the wrapped {@code
185 * ClassLoaderProvider}.
186 *
187 * @return a set with the names of the known class loaders
188 */
189 public Set<String> classLoaderNames()
190 {
191 return getClassLoaderProvider().classLoaderNames();
192 }
193
194 /**
195 * Returns the class loader that was registered under the given name. This
196 * implementation delegates to the wrapped {@code ClassLoaderProvider}.
197 *
198 * @param name the name of the class loader
199 * @return the corresponding class loader
200 * @throws InjectionException if the name is unknown
201 */
202 public ClassLoader getClassLoader(String name)
203 {
204 return getClassLoaderProvider().getClassLoader(name);
205 }
206
207 /**
208 * Returns the name of the default class loader. This implementation
209 * delegates to the wrapped {@code ClassLoaderProvider}.
210 *
211 * @return the default class loader
212 */
213 public String getDefaultClassLoaderName()
214 {
215 return getClassLoaderProvider().getDefaultClassLoaderName();
216 }
217
218 /**
219 * Loads a class using the specified class loader. This implementation
220 * delegates to the wrapped {@code ClassLoaderProvider}.
221 *
222 * @param name the name of the class to load
223 * @param loaderRef the name of the class loader
224 * @return the corresponding class
225 * @throws InjectionException if an error occurs
226 */
227 public Class<?> loadClass(String name, String loaderRef)
228 {
229 return getClassLoaderProvider().loadClass(name, loaderRef);
230 }
231
232 /**
233 * Registers a class loader under a name. This implementation delegates to
234 * the wrapped {@code ClassLoaderProvider}.
235 *
236 * @param name the name
237 * @param loader the class loader
238 */
239 public void registerClassLoader(String name, ClassLoader loader)
240 {
241 getClassLoaderProvider().registerClassLoader(name, loader);
242 }
243
244 /**
245 * Sets the name of the default class loader. This implementation delegates
246 * to the wrapped {@code ClassLoaderProvider}.
247 *
248 * @param loaderName the new default class loader name
249 */
250 public void setDefaultClassLoaderName(String loaderName)
251 {
252 getClassLoaderProvider().setDefaultClassLoaderName(loaderName);
253 }
254
255 /**
256 * Returns the {@code InvocationHelper} object. This implementation returns
257 * the object that was passed to the constructor.
258 *
259 * @return the {@code InvocationHelper} object
260 */
261 public InvocationHelper getInvocationHelper()
262 {
263 return invocationHelper;
264 }
265 }