1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.dispatcher;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31
32 import javax.servlet.ServletContext;
33 import javax.servlet.ServletException;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
37 import org.apache.struts2.ServletActionContext;
38 import org.apache.struts2.StrutsConstants;
39 import org.apache.struts2.StrutsStatics;
40 import org.apache.struts2.config.BeanSelectionProvider;
41 import org.apache.struts2.config.DefaultPropertiesProvider;
42 import org.apache.struts2.config.LegacyPropertiesConfigurationProvider;
43 import org.apache.struts2.config.StrutsXmlConfigurationProvider;
44 import org.apache.struts2.dispatcher.mapper.ActionMapping;
45 import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
46 import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
47 import org.apache.struts2.util.AttributeMap;
48 import org.apache.struts2.util.ClassLoaderUtils;
49 import org.apache.struts2.util.ObjectFactoryDestroyable;
50 import org.apache.struts2.views.freemarker.FreemarkerManager;
51
52 import com.opensymphony.xwork2.ActionContext;
53 import com.opensymphony.xwork2.ActionProxy;
54 import com.opensymphony.xwork2.ActionProxyFactory;
55 import com.opensymphony.xwork2.ObjectFactory;
56 import com.opensymphony.xwork2.Result;
57 import com.opensymphony.xwork2.config.Configuration;
58 import com.opensymphony.xwork2.config.ConfigurationException;
59 import com.opensymphony.xwork2.config.ConfigurationManager;
60 import com.opensymphony.xwork2.config.ConfigurationProvider;
61 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
62 import com.opensymphony.xwork2.inject.Container;
63 import com.opensymphony.xwork2.inject.ContainerBuilder;
64 import com.opensymphony.xwork2.inject.Inject;
65 import com.opensymphony.xwork2.util.FileManager;
66 import com.opensymphony.xwork2.util.LocalizedTextUtil;
67 import com.opensymphony.xwork2.util.ValueStack;
68 import com.opensymphony.xwork2.util.ValueStackFactory;
69 import com.opensymphony.xwork2.util.location.LocatableProperties;
70 import com.opensymphony.xwork2.util.location.Location;
71 import com.opensymphony.xwork2.util.location.LocationUtils;
72 import com.opensymphony.xwork2.util.logging.Logger;
73 import com.opensymphony.xwork2.util.logging.LoggerFactory;
74 import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
75
76 import freemarker.template.Template;
77
78 /***
79 * A utility class the actual dispatcher delegates most of its tasks to. Each instance
80 * of the primary dispatcher holds an instance of this dispatcher to be shared for
81 * all requests.
82 *
83 * @see org.apache.struts2.dispatcher.FilterDispatcher
84 */
85 public class Dispatcher {
86
87 /***
88 * Provide a logging instance.
89 */
90 private static final Logger LOG = LoggerFactory.getLogger(Dispatcher.class);
91
92 /***
93 * Provide a thread local instance.
94 */
95 private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
96
97 /***
98 * Store list of DispatcherListeners.
99 */
100 private static List<DispatcherListener> dispatcherListeners =
101 new ArrayList<DispatcherListener>();
102
103 /***
104 * Store ConfigurationManager instance, set on init.
105 */
106 private ConfigurationManager configurationManager;
107
108 /***
109 * Store state of StrutsConstants.STRUTS_DEVMODE setting.
110 */
111 private boolean devMode;
112
113 /***
114 * Store state of StrutsConstants.STRUTS_I18N_ENCODING setting.
115 */
116 private String defaultEncoding;
117
118 /***
119 * Store state of StrutsConstants.STRUTS_LOCALE setting.
120 */
121 private String defaultLocale;
122
123 /***
124 * Store state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
125 */
126 private String multipartSaveDir;
127
128 /***
129 * Provide list of default configuration files.
130 */
131 private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
132
133 /***
134 * Store state of STRUTS_DISPATCHER_PARAMETERSWORKAROUND.
135 * <p/>
136 * The workaround is for WebLogic.
137 * We try to autodect WebLogic on Dispatcher init.
138 * The workaround can also be enabled manually.
139 */
140 private boolean paramsWorkaroundEnabled = false;
141
142 /***
143 * Provide the dispatcher instance for the current thread.
144 *
145 * @return The dispatcher instance
146 */
147 public static Dispatcher getInstance() {
148 return instance.get();
149 }
150
151 /***
152 * Store the dispatcher instance for this thread.
153 *
154 * @param instance The instance
155 */
156 public static void setInstance(Dispatcher instance) {
157 Dispatcher.instance.set(instance);
158 }
159
160 /***
161 * Add a dispatcher lifecycle listener.
162 *
163 * @param listener The listener to add
164 */
165 public static synchronized void addDispatcherListener(DispatcherListener listener) {
166 dispatcherListeners.add(listener);
167 }
168
169 /***
170 * Remove a specific dispatcher lifecycle listener.
171 *
172 * @param listener The listener
173 */
174 public static synchronized void removeDispatcherListener(DispatcherListener listener) {
175 dispatcherListeners.remove(listener);
176 }
177
178 private ServletContext servletContext;
179 private Map<String, String> initParams;
180
181 private ValueStackFactory valueStackFactory;
182
183
184 /***
185 * Create the Dispatcher instance for a given ServletContext and set of initialization parameters.
186 *
187 * @param servletContext Our servlet context
188 * @param initParams The set of initialization parameters
189 */
190 public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
191 this.servletContext = servletContext;
192 this.initParams = initParams;
193 }
194
195 /***
196 * Modify state of StrutsConstants.STRUTS_DEVMODE setting.
197 * @param mode New setting
198 */
199 @Inject(StrutsConstants.STRUTS_DEVMODE)
200 public void setDevMode(String mode) {
201 devMode = "true".equals(mode);
202 }
203
204 /***
205 * Modify state of StrutsConstants.STRUTS_LOCALE setting.
206 * @param val New setting
207 */
208 @Inject(value=StrutsConstants.STRUTS_LOCALE, required=false)
209 public void setDefaultLocale(String val) {
210 defaultLocale = val;
211 }
212
213 /***
214 * Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
215 * @param val New setting
216 */
217 @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
218 public void setDefaultEncoding(String val) {
219 defaultEncoding = val;
220 }
221
222 /***
223 * Modify state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
224 * @param val New setting
225 */
226 @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR)
227 public void setMultipartSaveDir(String val) {
228 multipartSaveDir = val;
229 }
230
231 @Inject
232 public void setValueStackFactory(ValueStackFactory valueStackFactory) {
233 this.valueStackFactory = valueStackFactory;
234 }
235
236 /***
237 * Releases all instances bound to this dispatcher instance.
238 */
239 public void cleanup() {
240
241
242 ObjectFactory objectFactory = getContainer().getInstance(ObjectFactory.class);
243 if (objectFactory == null) {
244 LOG.warn("Object Factory is null, something is seriously wrong, no clean up will be performed");
245 }
246 if (objectFactory instanceof ObjectFactoryDestroyable) {
247 try {
248 ((ObjectFactoryDestroyable)objectFactory).destroy();
249 }
250 catch(Exception e) {
251
252 LOG.error("exception occurred while destroying ObjectFactory ["+objectFactory+"]", e);
253 }
254 }
255
256
257 instance.set(null);
258
259
260 synchronized(Dispatcher.class) {
261 if (dispatcherListeners.size() > 0) {
262 for (DispatcherListener l : dispatcherListeners) {
263 l.dispatcherDestroyed(this);
264 }
265 }
266 }
267
268
269 configurationManager.destroyConfiguration();
270 configurationManager = null;
271 }
272
273 private void init_DefaultProperties() {
274 configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
275 }
276
277 private void init_LegacyStrutsProperties() {
278 configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider());
279 }
280
281 private void init_TraditionalXmlConfigurations() {
282 String configPaths = initParams.get("config");
283 if (configPaths == null) {
284 configPaths = DEFAULT_CONFIGURATION_PATHS;
285 }
286 String[] files = configPaths.split("//s*[,]//s*");
287 for (String file : files) {
288 if (file.endsWith(".xml")) {
289 if ("xwork.xml".equals(file)) {
290 configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
291 } else {
292 configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
293 }
294 } else {
295 throw new IllegalArgumentException("Invalid configuration file name");
296 }
297 }
298 }
299
300 private void init_CustomConfigurationProviders() {
301 String configProvs = initParams.get("configProviders");
302 if (configProvs != null) {
303 String[] classes = configProvs.split("//s*[,]//s*");
304 for (String cname : classes) {
305 try {
306 Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
307 ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance();
308 configurationManager.addConfigurationProvider(prov);
309 } catch (InstantiationException e) {
310 throw new ConfigurationException("Unable to instantiate provider: "+cname, e);
311 } catch (IllegalAccessException e) {
312 throw new ConfigurationException("Unable to access provider: "+cname, e);
313 } catch (ClassNotFoundException e) {
314 throw new ConfigurationException("Unable to locate provider class: "+cname, e);
315 }
316 }
317 }
318 }
319
320 private void init_MethodConfigurationProvider() {
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 }
352
353 private void init_FilterInitParameters() {
354 configurationManager.addConfigurationProvider(new ConfigurationProvider() {
355 public void destroy() {}
356 public void init(Configuration configuration) throws ConfigurationException {}
357 public void loadPackages() throws ConfigurationException {}
358 public boolean needsReload() { return false; }
359
360 public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
361 props.putAll(initParams);
362 }
363 });
364 }
365
366 private void init_AliasStandardObjects() {
367 configurationManager.addConfigurationProvider(new BeanSelectionProvider());
368 }
369
370 private Container init_PreloadConfiguration() {
371 Configuration config = configurationManager.getConfiguration();
372 Container container = config.getContainer();
373
374 boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));
375 LocalizedTextUtil.setReloadBundles(reloadi18n);
376
377 return container;
378 }
379
380 private void init_CheckConfigurationReloading(Container container) {
381 FileManager.setReloadingConfigs("true".equals(container.getInstance(String.class,
382 StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)));
383 }
384
385 private void init_CheckWebLogicWorkaround(Container container) {
386
387 if (servletContext != null && servletContext.getServerInfo() != null
388 && servletContext.getServerInfo().indexOf("WebLogic") >= 0) {
389 LOG.info("WebLogic server detected. Enabling Struts parameter access work-around.");
390 paramsWorkaroundEnabled = true;
391 } else {
392 paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class,
393 StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
394 }
395
396 synchronized(Dispatcher.class) {
397 if (dispatcherListeners.size() > 0) {
398 for (DispatcherListener l : dispatcherListeners) {
399 l.dispatcherInitialized(this);
400 }
401 }
402 }
403
404 }
405
406 /***
407 * Load configurations, including both XML and zero-configuration strategies,
408 * and update optional settings, including whether to reload configurations and resource files.
409 */
410 public void init() {
411
412 if (configurationManager == null) {
413 configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
414 }
415
416 init_DefaultProperties();
417 init_TraditionalXmlConfigurations();
418 init_LegacyStrutsProperties();
419 init_CustomConfigurationProviders();
420 init_MethodConfigurationProvider();
421 init_FilterInitParameters() ;
422 init_AliasStandardObjects() ;
423
424 Container container = init_PreloadConfiguration();
425 container.inject(this);
426 init_CheckConfigurationReloading(container);
427 init_CheckWebLogicWorkaround(container);
428
429 }
430
431 /***
432 * Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.
433 * <p/>
434 * This method first creates the action context from the given parameters,
435 * and then loads an <tt>ActionProxy</tt> from the given action name and namespace.
436 * After that, the Action method is executed and output channels through the response object.
437 * Actions not found are sent back to the user via the {@link Dispatcher#sendError} method,
438 * using the 404 return code.
439 * All other errors are reported by throwing a ServletException.
440 *
441 * @param request the HttpServletRequest object
442 * @param response the HttpServletResponse object
443 * @param mapping the action mapping object
444 * @throws ServletException when an unknown error occurs (not a 404, but typically something that
445 * would end up as a 5xx by the servlet container)
446 * @param context Our ServletContext object
447 */
448 public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
449 ActionMapping mapping) throws ServletException {
450
451 Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
452
453
454 ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
455 if (stack != null) {
456 extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
457 }
458
459 String timerKey = "Handling request from Dispatcher";
460 try {
461 UtilTimerStack.push(timerKey);
462 String namespace = mapping.getNamespace();
463 String name = mapping.getName();
464 String method = mapping.getMethod();
465
466 Configuration config = configurationManager.getConfiguration();
467 ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
468 namespace, name, method, extraContext, true, false);
469
470 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
471
472
473 if (mapping.getResult() != null) {
474 Result result = mapping.getResult();
475 result.execute(proxy.getInvocation());
476 } else {
477 proxy.execute();
478 }
479
480
481 if (stack != null) {
482 request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
483 }
484 } catch (ConfigurationException e) {
485 LOG.error("Could not find action or result", e);
486 sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
487 } catch (Exception e) {
488 sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
489 } finally {
490 UtilTimerStack.pop(timerKey);
491 }
492 }
493
494 /***
495 * Create a context map containing all the wrapped request objects
496 *
497 * @param request The servlet request
498 * @param response The servlet response
499 * @param mapping The action mapping
500 * @param context The servlet context
501 * @return A map of context objects
502 */
503 public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
504 ActionMapping mapping, ServletContext context) {
505
506
507 Map requestMap = new RequestMap(request);
508
509
510 Map params = new HashMap(request.getParameterMap());
511
512
513 Map session = new SessionMap(request);
514
515
516 Map application = new ApplicationMap(context);
517
518 Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);
519 extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
520 return extraContext;
521 }
522
523 /***
524 * Merge all application and servlet attributes into a single <tt>HashMap</tt> to represent the entire
525 * <tt>Action</tt> context.
526 *
527 * @param requestMap a Map of all request attributes.
528 * @param parameterMap a Map of all request parameters.
529 * @param sessionMap a Map of all session attributes.
530 * @param applicationMap a Map of all servlet context attributes.
531 * @param request the HttpServletRequest object.
532 * @param response the HttpServletResponse object.
533 * @param servletContext the ServletContextmapping object.
534 * @return a HashMap representing the <tt>Action</tt> context.
535 */
536 public HashMap<String,Object> createContextMap(Map requestMap,
537 Map parameterMap,
538 Map sessionMap,
539 Map applicationMap,
540 HttpServletRequest request,
541 HttpServletResponse response,
542 ServletContext servletContext) {
543 HashMap<String,Object> extraContext = new HashMap<String,Object>();
544 extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
545 extraContext.put(ActionContext.SESSION, sessionMap);
546 extraContext.put(ActionContext.APPLICATION, applicationMap);
547
548 Locale locale;
549 if (defaultLocale != null) {
550 locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
551 } else {
552 locale = request.getLocale();
553 }
554
555 extraContext.put(ActionContext.LOCALE, locale);
556
557
558 extraContext.put(StrutsStatics.HTTP_REQUEST, request);
559 extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
560 extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);
561
562
563 extraContext.put("request", requestMap);
564 extraContext.put("session", sessionMap);
565 extraContext.put("application", applicationMap);
566 extraContext.put("parameters", parameterMap);
567
568 AttributeMap attrMap = new AttributeMap(extraContext);
569 extraContext.put("attr", attrMap);
570
571 return extraContext;
572 }
573
574 /***
575 * Return the path to save uploaded files to (this is configurable).
576 *
577 * @return the path to save uploaded files to
578 * @param servletContext Our ServletContext
579 */
580 private String getSaveDir(ServletContext servletContext) {
581 String saveDir = multipartSaveDir.trim();
582
583 if (saveDir.equals("")) {
584 File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
585 LOG.info("Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
586
587 if (tempdir != null) {
588 saveDir = tempdir.toString();
589 setMultipartSaveDir(saveDir);
590 }
591 } else {
592 File multipartSaveDir = new File(saveDir);
593
594 if (!multipartSaveDir.exists()) {
595 multipartSaveDir.mkdir();
596 }
597 }
598
599 if (LOG.isDebugEnabled()) {
600 LOG.debug("saveDir=" + saveDir);
601 }
602
603 return saveDir;
604 }
605
606 /***
607 * Prepare a request, including setting the encoding and locale.
608 *
609 * @param request The request
610 * @param response The response
611 */
612 public void prepare(HttpServletRequest request, HttpServletResponse response) {
613 String encoding = null;
614 if (defaultEncoding != null) {
615 encoding = defaultEncoding;
616 }
617
618 Locale locale = null;
619 if (defaultLocale != null) {
620 locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
621 }
622
623 if (encoding != null) {
624 try {
625 request.setCharacterEncoding(encoding);
626 } catch (Exception e) {
627 LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
628 }
629 }
630
631 if (locale != null) {
632 response.setLocale(locale);
633 }
634
635 if (paramsWorkaroundEnabled) {
636 request.getParameter("foo");
637 }
638 }
639
640 /***
641 * Wrap and return the given request or return the original request object.
642 * </p>
643 * This method transparently handles multipart data as a wrapped class around the given request.
644 * Override this method to handle multipart requests in a special way or to handle other types of requests.
645 * Note, {@link org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper} is
646 * flexible - look first to that object before overriding this method to handle multipart data.
647 *
648 * @param request the HttpServletRequest object.
649 * @param servletContext Our ServletContext object
650 * @return a wrapped request or original request.
651 * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper
652 * @throws java.io.IOException on any error.
653 */
654 public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
655
656 if (request instanceof StrutsRequestWrapper) {
657 return request;
658 }
659
660 String content_type = request.getContentType();
661 if (content_type != null && content_type.indexOf("multipart/form-data") != -1) {
662 MultiPartRequest multi = getContainer().getInstance(MultiPartRequest.class);
663 request = new MultiPartRequestWrapper(multi, request, getSaveDir(servletContext));
664 } else {
665 request = new StrutsRequestWrapper(request);
666 }
667
668 return request;
669 }
670
671 /***
672 * Send an HTTP error response code.
673 *
674 * @param request the HttpServletRequest object.
675 * @param response the HttpServletResponse object.
676 * @param code the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible error codes).
677 * @param e the Exception that is reported.
678 * @param ctx the ServletContext object.
679 */
680 public void sendError(HttpServletRequest request, HttpServletResponse response,
681 ServletContext ctx, int code, Exception e) {
682 if (devMode) {
683 response.setContentType("text/html");
684
685 try {
686 FreemarkerManager mgr = getContainer().getInstance(FreemarkerManager.class);
687
688 freemarker.template.Configuration config = mgr.getConfiguration(ctx);
689 Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl");
690
691 List<Throwable> chain = new ArrayList<Throwable>();
692 Throwable cur = e;
693 chain.add(cur);
694 while ((cur = cur.getCause()) != null) {
695 chain.add(cur);
696 }
697
698 HashMap<String,Object> data = new HashMap<String,Object>();
699 data.put("exception", e);
700 data.put("unknown", Location.UNKNOWN);
701 data.put("chain", chain);
702 data.put("locator", new Locator());
703 template.process(data, response.getWriter());
704 response.getWriter().close();
705 } catch (Exception exp) {
706 try {
707 response.sendError(code, "Unable to show problem report: " + exp);
708 } catch (IOException ex) {
709
710 }
711 }
712 } else {
713 try {
714
715 if (code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
716
717
718 request.setAttribute("javax.servlet.error.exception", e);
719
720
721 request.setAttribute("javax.servlet.jsp.jspException", e);
722 }
723
724
725 response.sendError(code, e.getMessage());
726 } catch (IOException e1) {
727
728 }
729 }
730 }
731
732
733
734 /***
735 * Provide an accessor class for static XWork utility.
736 */
737 public static class Locator {
738 public Location getLocation(Object obj) {
739 Location loc = LocationUtils.getLocation(obj);
740 if (loc == null) {
741 return Location.UNKNOWN;
742 }
743 return loc;
744 }
745 }
746
747 /***
748 * Expose the ConfigurationManager instance.
749 *
750 * @return The instance
751 */
752 public ConfigurationManager getConfigurationManager() {
753 return configurationManager;
754 }
755
756 /***
757 * Modify the ConfigurationManager instance
758 *
759 * @param mgr The configuration manager
760 */
761 public void setConfigurationManager(ConfigurationManager mgr) {
762 this.configurationManager = mgr;
763 }
764
765 /***
766 * Expose the dependency injection container.
767 * @return Our dependency injection container
768 */
769 public Container getContainer() {
770 ConfigurationManager mgr = getConfigurationManager();
771 if (mgr == null) {
772 throw new IllegalStateException("The configuration manager shouldn't be null");
773 } else {
774 Configuration config = mgr.getConfiguration();
775 if (config == null) {
776 throw new IllegalStateException("Unable to load configuration");
777 } else {
778 return config.getContainer();
779 }
780 }
781 }
782 }