View Javadoc
1   package org.apache.fulcrum.yaafi.framework.container;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.InputStream;
24  import java.util.ArrayList;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Properties;
28  
29  import org.apache.avalon.framework.configuration.Configuration;
30  import org.apache.avalon.framework.configuration.ConfigurationException;
31  import org.apache.avalon.framework.configuration.DefaultConfiguration;
32  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
33  import org.apache.avalon.framework.container.ContainerUtil;
34  import org.apache.avalon.framework.context.Context;
35  import org.apache.avalon.framework.context.ContextException;
36  import org.apache.avalon.framework.context.DefaultContext;
37  import org.apache.avalon.framework.logger.Logger;
38  import org.apache.avalon.framework.parameters.ParameterException;
39  import org.apache.avalon.framework.parameters.Parameters;
40  import org.apache.avalon.framework.service.ServiceException;
41  import org.apache.avalon.framework.service.ServiceManager;
42  import org.apache.fulcrum.yaafi.framework.component.AvalonServiceComponentImpl;
43  import org.apache.fulcrum.yaafi.framework.component.ServiceComponent;
44  import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolver;
45  import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolverImpl;
46  import org.apache.fulcrum.yaafi.framework.constant.AvalonYaafiConstants;
47  import org.apache.fulcrum.yaafi.framework.context.AvalonToYaafiContextMapper;
48  import org.apache.fulcrum.yaafi.framework.context.YaafiToAvalonContextMapper;
49  import org.apache.fulcrum.yaafi.framework.crypto.CryptoStreamFactory;
50  import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParser;
51  import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParserImpl;
52  import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
53  import org.apache.fulcrum.yaafi.framework.util.ConfigurationUtil;
54  import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator;
55  import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
56  import org.apache.fulcrum.yaafi.framework.util.Validate;
57  
58  import org.apache.commons.lang3.StringUtils;
59  
60  /**
61   * Yet another avalon framework implementation (YAAFI).
62   *
63   * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
64   */
65  
66  public class ServiceContainerImpl implements ServiceContainer, ServiceConstants {
67  	/** Default timeout before disposing the container */
68  	private static final int DISPOSAL_DELAY_DEFAULT = 0;
69  
70  	/** Default timeout before reconfiguring the container or services */
71  	private static final int RECONFIGURATION_DELAY_DEFAULT = 2000;
72  
73  	/** The role configuration file to be used */
74  	private String componentRolesLocation;
75  
76  	/** is the component role file encrypted? */
77  	private String isComponentRolesEncrypted;
78  
79  	/** which flavour of component role file we have to parse? */
80  	private String componentRolesFlavour;
81  
82  	/** The service configuration file to be used */
83  	private String componentConfigurationLocation;
84  
85  	/** is the component configuration file encrypted? */
86  	private String isComponentConfigurationEncrypted;
87  
88  	/** The parameters file to be used */
89  	private String parametersLocation;
90  
91  	/** is the parameters file encrypted? */
92  	private String isParametersEncrypted;
93  
94  	/** The application directory aka the current working directory */
95  	private File applicationRootDir;
96  
97  	/** The directory for storing temporary files */
98  	private File tempRootDir;
99  
100 	/** The logger to be used passed by the caller */
101 	private Logger logger;
102 
103 	/** The service manager passed to the container */
104 	private ServiceManager parentServiceManager;
105 
106 	/** The list of services instantiated */
107 	private List<ServiceComponent> serviceList;
108 
109 	/** The map of services used for the lookup */
110 	private HashMap<String, ServiceComponent> serviceMap;
111 
112 	/** The Avalon role configuration loaded by this class */
113 	private Configuration roleConfiguration;
114 
115 	/** The Avalon service configuration loaded by this class */
116 	private Configuration serviceConfiguration;
117 
118 	/** The temporary Avalon context passed to the implementation */
119 	private Context callerContext;
120 
121 	/** The default Avalon context passed to the services */
122 	private Context context;
123 
124 	/** The default Avalon parameters */
125 	private Parameters parameters;
126 
127 	/** Is this instance already disposed? */
128 	private volatile boolean isAlreadyDisposed;
129 
130 	/** Is this instance currently disposed? */
131 	private volatile boolean isCurrentlyDisposing;
132 
133 	/** The type of container where YAAFI is embedded */
134 	private String containerFlavour;
135 
136 	/**
137 	 * The ms to wait before triggering a reconfiguration of the container or
138 	 * service
139 	 */
140 	private int reconfigurationDelay;
141 
142 	/** The ms to wait before triggering a disposal of the container */
143 	private int disposalDelay;
144 
145 	/** global flag for enabling/disabling dynamic proxies */
146 	private boolean hasDynamicProxies;
147 
148 	/** The list of interceptor services applied to all services */
149 	private ArrayList<String> defaultInterceptorServiceList;
150 
151 	/** The list of ServiceManagers as fallback service lookup */
152 	private ArrayList<String> fallbackServiceManagerList;
153 
154 	/**
155 	 * the configuration for running the ComponentConfigurationPropertiesResolver
156 	 */
157 	private Configuration componentConfigurationPropertiesResolverConfig;
158 
159 	/////////////////////////////////////////////////////////////////////////
160 	// Avalon Service Lifecycle
161 	/////////////////////////////////////////////////////////////////////////
162 
163 	/**
164 	 * Constructor using sensible defaults.
165 	 */
166 	public ServiceContainerImpl() {
167 		super();
168 
169 		this.containerFlavour = COMPONENT_CONTAINERFLAVOUR_VALUE;
170 		this.componentRolesFlavour = COMPONENT_ROLECONFIGFLAVOUR_VALUE;
171 
172 		this.componentRolesLocation = COMPONENT_ROLE_VALUE;
173 		this.componentConfigurationLocation = COMPONENT_CONFIG_VALUE;
174 		this.parametersLocation = COMPONENT_PARAMETERS_VALUE;
175 
176 		this.isComponentConfigurationEncrypted = "false";
177 		this.isComponentRolesEncrypted = "false";
178 		this.isParametersEncrypted = "false";
179 
180 		this.isAlreadyDisposed = false;
181 		this.isCurrentlyDisposing = false;
182 
183 		this.serviceList = new ArrayList<ServiceComponent>();
184 		this.serviceMap = new HashMap<String, ServiceComponent>();
185 
186 		this.applicationRootDir = new File(new File("").getAbsolutePath());
187 		this.tempRootDir = new File(System.getProperty("java.io.tmpdir", "."));
188 
189 		this.fallbackServiceManagerList = new ArrayList<String>();
190 		this.defaultInterceptorServiceList = new ArrayList<String>();
191 
192 		this.disposalDelay = DISPOSAL_DELAY_DEFAULT;
193 		this.reconfigurationDelay = RECONFIGURATION_DELAY_DEFAULT;
194 	}
195 
196 	/**
197 	 * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
198 	 */
199 	public void enableLogging(Logger logger) {
200 		Validate.notNull(logger, "logger");
201 		this.logger = logger;
202 	}
203 
204 	/**
205 	 * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
206 	 */
207 	public void contextualize(Context context) throws ContextException {
208 		Validate.notNull(context, "context");
209 		// Argghhh - I need to to parse the Configuration before I can map the Context
210 		this.callerContext = context;
211 	}
212 
213 	/**
214 	 * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
215 	 */
216 	public void service(ServiceManager serviceManager) throws ServiceException {
217 		this.parentServiceManager = serviceManager;
218 	}
219 
220 	/**
221 	 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
222 	 */
223 	public void configure(Configuration configuration) throws ConfigurationException {
224 		Validate.notNull(configuration, "configuration");
225 
226 		// retrieve the reconfigurationDelay
227 
228 		this.reconfigurationDelay = configuration.getChild(RECONFIGURATION_DELAY_KEY)
229 				.getValueAsInteger(RECONFIGURATION_DELAY_DEFAULT);
230 
231 		// retrieve the disposal delay
232 
233 		this.disposalDelay = configuration.getChild(DISPOSAL_DELAY_KEY).getValueAsInteger(DISPOSAL_DELAY_DEFAULT);
234 
235 		// evaluate if we are using dynamic proxies
236 
237 		this.hasDynamicProxies = configuration.getChild(DYNAMICPROXY_ENABLED_KEY).getValueAsBoolean(false);
238 
239 		// retrieve the container flavour
240 
241 		this.setContainerFlavour(
242 				configuration.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue(COMPONENT_CONTAINERFLAVOUR_VALUE));
243 
244 		this.getLogger().debug("Using the following container type : " + this.getContainerFlavour());
245 
246 		// process the caller-supplied context here
247 
248 		try {
249 			// instantiate a mapper using the existing context - it might
250 			// contain application specific entries we are not aware of
251 
252 			AvalonToYaafiContextMapper mapper = new AvalonToYaafiContextMapper(this.getTempRootDir(),
253 					this.callerContext, this.getClassLoader());
254 
255 			// do the magic mapping
256 
257 			this.context = mapper.mapFrom(this.callerContext, this.getContainerFlavour());
258 
259 			// don't keep a reference of the caller-supplied context
260 
261 			this.callerContext = null;
262 		} catch (ContextException e) {
263 			String msg = "Failed to parse the caller-supplied context";
264 			this.getLogger().error(msg, e);
265 			throw new ConfigurationException(msg);
266 		}
267 
268 		// evaluate componentRoles
269 
270 		Configuration currComponentRoles = configuration.getChild(COMPONENT_ROLE_KEYS);
271 
272 		this.setComponentRolesLocation(
273 				currComponentRoles.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_ROLE_VALUE));
274 
275 		this.setComponentRolesFlavour(
276 				currComponentRoles.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue(COMPONENT_ROLECONFIGFLAVOUR_VALUE));
277 
278 		this.setComponentRolesEncrypted(currComponentRoles.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
279 
280 		// evaluate componentConfiguraion
281 
282 		Configuration currComponentConfiguration = configuration.getChild(COMPONENT_CONFIG_KEY);
283 
284 		this.setComponentConfigurationLocation(
285 				currComponentConfiguration.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_CONFIG_VALUE));
286 
287 		this.setComponentConfigurationEncrypted(
288 				currComponentConfiguration.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
289 
290 		// get the configuration for componentConfigurationPropertiesResolver
291 
292 		this.componentConfigurationPropertiesResolverConfig = configuration.getChild(COMPONENT_CONFIG_PROPERTIES_KEY);
293 
294 		// evaluate parameters
295 
296 		Configuration currParameters = configuration.getChild(COMPONENT_PARAMETERS_KEY);
297 
298 		this.setParametersLocation(
299 				currParameters.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_PARAMETERS_VALUE));
300 
301 		this.setParametersEncrypted(currParameters.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
302 
303 		// evaluate the default interceptors
304 
305 		Configuration currInterceptorList = configuration.getChild(INTERCEPTOR_LIST_KEY);
306 
307 		Configuration[] interceptorConfigList = currInterceptorList.getChildren(INTERCEPTOR_KEY);
308 
309 		for (int i = 0; i < interceptorConfigList.length; i++) {
310 			String interceptorServiceName = interceptorConfigList[i].getValue(null);
311 
312 			if (!StringUtils.isEmpty(interceptorServiceName) && this.hasDynamicProxies()) {
313 				this.defaultInterceptorServiceList.add(interceptorServiceName);
314 
315 				this.getLogger().debug("Using the following default interceptor service : " + interceptorServiceName);
316 			}
317 		}
318 
319 		// evaluate a list of service managers managing their own set of services
320 		// independent from the Avalon container. This service managers are used
321 		// to find services implemented as Spring bean or remote web services.
322 
323 		Configuration currServiceManagerList = configuration.getChild(SERVICEMANAGER_LIST_KEY);
324 
325 		Configuration[] serviceManagerConfigList = currServiceManagerList.getChildren(SERVICEMANAGER_KEY);
326 
327 		for (int i = 0; i < serviceManagerConfigList.length; i++) {
328 			String serviceManagerName = serviceManagerConfigList[i].getValue(null);
329 
330 			if (!StringUtils.isEmpty(serviceManagerName)) {
331 				this.fallbackServiceManagerList.add(serviceManagerName);
332 
333 				this.getLogger().debug("Using the following fallback service manager : " + serviceManagerName);
334 			}
335 		}
336 	}
337 
338 	/**
339 	 * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
340 	 */
341 	public void parameterize(Parameters parameters) throws ParameterException {
342 		this.parameters = parameters;
343 	}
344 
345 	/**
346 	 * @see org.apache.avalon.framework.activity.Initializable#initialize()
347 	 */
348 	public void initialize() throws Exception {
349 		this.getLogger().debug("YAAFI Service Framework is starting up");
350 
351 		// set the directories being used
352 
353 		this.setApplicationRootDir((File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_HOME));
354 
355 		this.setTempRootDir((File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_TEMP));
356 
357 		// get the configuration files
358 
359 		this.roleConfiguration = loadConfiguration(this.componentRolesLocation, this.isComponentRolesEncrypted());
360 
361 		if (this.roleConfiguration == null) {
362 			String msg = "Unable to locate the role configuration : " + this.componentRolesLocation;
363 			this.getLogger().error(msg);
364 			throw new ConfigurationException(msg);
365 		}
366 
367 		this.serviceConfiguration = loadConfiguration(this.componentConfigurationLocation,
368 				this.isComponentConfigurationEncrypted());
369 
370 		// create the configuration properties
371 
372 		Properties componentConfigurationProperties = this.loadComponentConfigurationProperties();
373 
374 		// expand the componentConfiguration using the componentConfigurationProperties
375 
376 		ConfigurationUtil.expand(this.getLogger(), (DefaultConfiguration) this.serviceConfiguration,
377 				componentConfigurationProperties);
378 
379 		// create the default parameters
380 
381 		if (this.getParameters() == null) {
382 			this.parameters = this.loadParameters(this.parametersLocation, this.isParametersEncrypted());
383 		}
384 
385 		// create the service implementation instances
386 
387 		List<ServiceComponent> currServiceList = this.createServiceComponents(this.roleConfiguration, this.getLogger());
388 
389 		this.setServiceList(currServiceList);
390 
391 		// fill the service map mapping from a service name to an instance
392 
393 		for (int i = 0; i < this.getServiceList().size(); i++) {
394 			ServiceComponent serviceComponent = (ServiceComponent) this.getServiceList().get(i);
395 			this.getServiceMap().put(serviceComponent.getName(), serviceComponent);
396 		}
397 
398 		// ensure that fallback service managers are available
399 
400 		for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
401 			String currServiceManagerName = (String) this.fallbackServiceManagerList.get(i);
402 			if (this.getServiceMap().get(currServiceManagerName) == null) {
403 				String msg = "The following fallback service manager was not found : " + currServiceManagerName;
404 				throw new IllegalArgumentException(msg);
405 			}
406 		}
407 
408 		// run the various lifecycle stages
409 
410 		this.incarnateAll(this.getServiceList());
411 
412 		// we are up and running
413 
414 		this.isCurrentlyDisposing = false;
415 		this.isAlreadyDisposed = false;
416 		this.getLogger().debug("YAAFI Avalon Service Container is up and running");
417 	}
418 
419 	/**
420 	 * Disposes the service container implementation.
421 	 *
422 	 * @see org.apache.avalon.framework.activity.Disposable#dispose()
423 	 */
424 	public void dispose() {
425 		if (this.isCurrentlyDisposing() || this.isAlreadyDisposed()) {
426 			return;
427 		}
428 
429 		this.isCurrentlyDisposing = true;
430 
431 		if (this.getLogger() != null) {
432 			this.getLogger().debug("Disposing all services");
433 		}
434 
435 		// wait some time before disposing all services
436 
437 		waitForDisposal();
438 
439 		synchronized (this) {
440 			// de-commission all services
441 
442 			this.decommissionAll(this.getServiceList());
443 
444 			// dispose all services
445 
446 			this.disposeAll(this.getServiceList());
447 
448 			// clean up
449 
450 			this.getServiceList().clear();
451 			this.getServiceMap().clear();
452 
453 			this.componentRolesLocation = null;
454 			this.componentConfigurationLocation = null;
455 			this.context = null;
456 			this.parametersLocation = null;
457 			this.roleConfiguration = null;
458 			this.serviceConfiguration = null;
459 			this.parameters = null;
460 			this.fallbackServiceManagerList = null;
461 			this.defaultInterceptorServiceList = null;
462 			this.isCurrentlyDisposing = false;
463 			this.isAlreadyDisposed = true;
464 
465 			if (this.getLogger() != null) {
466 				this.getLogger().debug("All services are disposed");
467 			}
468 		}
469 	}
470 
471 	/**
472 	 * Reconfiguring the services. I'm not sure how to implement this properly since
473 	 * the Avalon docs is vague on this subject. For now we suspend, reconfigure and
474 	 * resume the services in the correct order.
475 	 *
476 	 * @see org.apache.avalon.framework.configuration.Reconfigurable#reconfigure(org.apache.avalon.framework.configuration.Configuration)
477 	 */
478 	public synchronized void reconfigure(Configuration configuration) throws ConfigurationException {
479 		Validate.notNull(configuration, "configuration");
480 
481 		int exceptionCounter = 0;
482 		ServiceComponent serviceComponent;
483 
484 		this.getLogger().warn("Reconfiguring all services ...");
485 
486 		// 1) wait for some time
487 
488 		this.waitForReconfiguration();
489 
490 		// 2) store the new configuration
491 
492 		this.serviceConfiguration = configuration;
493 
494 		Properties componentConfigurationProperties = this.loadComponentConfigurationProperties();
495 
496 		ConfigurationUtil.expand(this.getLogger(), (DefaultConfiguration) this.serviceConfiguration,
497 				componentConfigurationProperties);
498 
499 		// 3) reconfigure the services
500 
501 		for (int i = 0; i < this.getServiceList().size(); i++) {
502 			serviceComponent = (ServiceComponent) this.getServiceList().get(i);
503 
504 			Configuration serviceComponentConfiguration = this.serviceConfiguration
505 					.getChild(serviceComponent.getShorthand());
506 
507 			try {
508 				serviceComponent.setConfiguration(serviceComponentConfiguration);
509 				serviceComponent.reconfigure();
510 			} catch (Throwable t) {
511 				String msg = "Reconfiguring of " + serviceComponent.getShorthand() + " failed";
512 				this.getLogger().error(msg);
513 				exceptionCounter++;
514 			}
515 		}
516 
517 		// 4) check the result
518 
519 		if (exceptionCounter > 0) {
520 			String msg = "The reconfiguration failed with " + exceptionCounter + " exception(s)";
521 			this.getLogger().error(msg);
522 			throw new ConfigurationException(msg);
523 		}
524 	}
525 
526 	/////////////////////////////////////////////////////////////////////////
527 	// Server Interface Implementation
528 	/////////////////////////////////////////////////////////////////////////
529 
530 	/**
531 	 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntry(java.lang.String)
532 	 */
533 	public synchronized RoleEntry getRoleEntry(String name) throws ServiceException {
534 		return this.getServiceComponentEx(name).getRoleEntry();
535 	}
536 
537 	/**
538 	 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#getRoleEntries()
539 	 */
540 	public synchronized RoleEntry[] getRoleEntries() {
541 		ServiceComponent serviceComponent;
542 		List<ServiceComponent> serviceList = this.getServiceList();
543 		RoleEntry[] result = new RoleEntry[serviceList.size()];
544 
545 		for (int i = 0; i < result.length; i++) {
546 			serviceComponent = (ServiceComponent) serviceList.get(i);
547 			result[i] = serviceComponent.getRoleEntry();
548 		}
549 
550 		return result;
551 	}
552 
553 	/**
554 	 * @see org.apache.fulcrum.yaafi.framework.container.ServiceLifecycleManager#reconfigure(java.lang.String[])
555 	 */
556 	public synchronized void reconfigure(String[] names) throws ServiceException, ConfigurationException {
557 		Validate.notNull(names, "names");
558 		Validate.noNullElements(names, "names");
559 
560 		this.waitForReconfiguration();
561 
562 		for (int i = 0; i < names.length; i++) {
563 			// ensure that the service exists since during our reconfiguration
564 			// we might use a stale reconfiguration entry
565 
566 			if (this.getServiceMap().get(names[i]) != null) {
567 				this.reconfigure(names[i]);
568 			}
569 		}
570 	}
571 
572 	/**
573 	 * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
574 	 */
575 	public boolean hasService(String name) {
576 		Validate.notEmpty(name, "name");
577 
578 		boolean result;
579 
580 		if (this.isCurrentlyDisposing() || this.isAlreadyDisposed()) {
581 			return false;
582 		}
583 
584 		synchronized (this) {
585 			// look at our available service
586 			result = this.getLocalServiceComponent(name) != null;
587 
588 			// look at fallback service managers
589 			if (!result)
590 				result = this.hasFallbackService(name);
591 		}
592 
593 		// if we haven't found anything ask the parent ServiceManager
594 		if (!result && this.hasParentServiceManager())
595 			result = this.getParentServiceManager().hasService(name);
596 
597 		return result;
598 	}
599 
600 	/**
601 	 * Lookup a service instance. The implementation uses the following mechanism
602 	 * <ul>
603 	 * <li>look for a matching local service
604 	 * <li>use the fallback service manager as they might know the service
605 	 * <li>ask the parent service manager
606 	 * </ul>
607 	 *
608 	 * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
609 	 */
610 	public Object lookup(String name) throws ServiceException {
611 		Validate.notEmpty(name, "name");
612 
613 		Object result = null;
614 		ServiceComponent serviceManagerComponent;
615 
616 		if (this.isAlreadyDisposed()) {
617 			String msg = "The container is disposed an no services are available";
618 			this.getLogger().error(msg);
619 			throw new ServiceException(name, msg);
620 		}
621 
622 		try {
623 			synchronized (this) {
624 				// 1) check our local services
625 				serviceManagerComponent = this.getLocalServiceComponent(name);
626 
627 				if (serviceManagerComponent != null) {
628 					result = serviceManagerComponent.getInstance();
629 
630 					if (result != null && this.getLogger().isDebugEnabled()) {
631 						String msg = "Located the service '" + name + "' in the local container";
632 						this.getLogger().debug(msg);
633 					}
634 				}
635 
636 				// 2) look at fallback service managers
637 				if (result == null) {
638 					result = this.getFallbackService(name);
639 				}
640 			}
641 		} catch (ServiceException e) {
642 			String msg = "Failed to lookup a service " + name;
643 			this.getLogger().error(msg, e);
644 			throw e;
645 		} catch (Throwable t) {
646 			String msg = "Failed to lookup a service " + name;
647 			this.getLogger().error(msg, t);
648 			throw new ServiceException(name, msg, t);
649 		}
650 
651 		// 3) if we haven't found anything ask the parent ServiceManager
652 		if (result == null && this.hasParentServiceManager()) {
653 			result = this.getParentServiceManager().lookup(name);
654 
655 			if (result != null && this.getLogger().isDebugEnabled()) {
656 				String msg = "Located the service '" + name + "' using the parent service manager";
657 				this.getLogger().debug(msg);
658 			}
659 		}
660 
661 		// if we still haven't found anything then complain
662 
663 		if (result == null) {
664 			String msg = "The following component does not exist : " + name;
665 			this.getLogger().error(msg);
666 			throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name);
667 		}
668 
669 		return result;
670 	}
671 
672 	/* (non-Javadoc)
673 	 * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
674 	 */
675 	public void release(Object object) {
676 		// AFAIK this is only useful for lifecycle management regarding
677 		// lifestyle other than singleton.
678 	}
679 
680 	/**
681 	 * @see org.apache.fulcrum.yaafi.framework.container.ServiceContainer#decommission(java.lang.String)
682 	 */
683 	public synchronized void decommission(String name) throws ServiceException {
684 		this.waitForReconfiguration();
685 		ServiceComponent serviceComponent = this.getServiceComponentEx(name);
686 		this.decommission(serviceComponent);
687 	}
688 
689 	/**
690 	 * @see org.apache.fulcrum.yaafi.framework.container.ServiceContainer#getParameters()
691 	 */
692 	public Parameters getParameters() {
693 		return this.parameters;
694 	}
695 
696 	/////////////////////////////////////////////////////////////////////////
697 	// Service Implementation
698 	/////////////////////////////////////////////////////////////////////////
699 
700 	/**
701 	 * @see java.lang.Object#toString()
702 	 */
703 	public String toString() {
704 		ToStringBuilder toStringBuilder = new ToStringBuilder(this);
705 		toStringBuilder.append("applicationRootDir", this.getApplicationRootDir());
706 		toStringBuilder.append("tempRootDir", this.getTempRootDir());
707 		toStringBuilder.append("componentRolesLocation", this.componentRolesLocation);
708 		toStringBuilder.append("componentConfigurationLocation", this.componentConfigurationLocation);
709 		toStringBuilder.append("parametersLocation", parametersLocation);
710 		toStringBuilder.append("logger", this.getLogger().getClass().getName());
711 		toStringBuilder.append("hasDynamicProxies", this.hasDynamicProxies);
712 		toStringBuilder.append("containerFlavour", this.containerFlavour);
713 		toStringBuilder.append("componentRolesFlavour", this.componentRolesFlavour);
714 		toStringBuilder.append("isComponentRolesEncrypted", this.isComponentRolesEncrypted);
715 		toStringBuilder.append("isComponentConfigurationEncrypted", this.isComponentConfigurationEncrypted);
716 		toStringBuilder.append("isParametersEncrypted", this.isParametersEncrypted);
717 
718 		return toStringBuilder.toString();
719 	}
720 
721 	/**
722 	 * Create a role configuration parser based on the container flavour.
723 	 * 
724 	 * @return the role configuration parser
725 	 */
726 	private RoleConfigurationParser createRoleConfigurationParser() {
727 		return new RoleConfigurationParserImpl(this.getComponentRolesFlavour());
728 	}
729 
730 	/**
731 	 * Reconfigure a single service
732 	 *
733 	 * @param name the name of the service to be reconfigured
734 	 * @throws ServiceException       the service was not found
735 	 * @throws ConfigurationException the reconfiguration failed
736 	 */
737 	private void reconfigure(String name) throws ServiceException, ConfigurationException {
738 		Validate.notEmpty(name, "name");
739 		ServiceComponent serviceComponent = this.getServiceComponentEx(name);
740 
741 		// reconfigure the component
742 
743 		try {
744 			serviceComponent.reconfigure();
745 		} catch (ConfigurationException e) {
746 			String msg = "Reconfiguring failed : " + serviceComponent.getShorthand();
747 			this.getLogger().error(msg, e);
748 			throw new ConfigurationException(msg, e);
749 		} catch (Throwable t) {
750 			String msg = "Reconfiguring failed : " + serviceComponent.getShorthand();
751 			this.getLogger().error(msg, t);
752 			throw new ConfigurationException(msg, t);
753 		}
754 	}
755 
756 	/**
757 	 * Enforce that a service is known to simplify error handling.
758 	 *
759 	 * @param name the name of the service component
760 	 * @return the service component
761 	 * @throws ServiceException the service was not found
762 	 */
763 	private ServiceComponent getServiceComponentEx(String name) throws ServiceException {
764 		Validate.notEmpty(name, "name");
765 		ServiceComponent result = (ServiceComponent) this.getServiceMap().get(name);
766 
767 		if (result == null) {
768 			String msg = "The following component does not exist : " + name;
769 			this.getLogger().error(msg);
770 			throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name);
771 		}
772 
773 		return result;
774 	}
775 
776 	/**
777 	 * Try to get a local service component.
778 	 *
779 	 * @param name the name of the service component
780 	 * @return the service component if any
781 	 */
782 	private ServiceComponent getLocalServiceComponent(String name) {
783 		Validate.notEmpty(name, "name");
784 		ServiceComponent result = (ServiceComponent) this.getServiceMap().get(name);
785 		return result;
786 	}
787 
788 	/**
789 	 * Try to get a service component provided by a fallback service manager.
790 	 *
791 	 * @param name the name of the service component
792 	 * @return the service component if any
793 	 * @throws Exception getting the service failed
794 	 */
795 	private Object getFallbackService(String name) throws Exception {
796 
797 		Validate.notEmpty(name, "name");
798 
799 		Object result = null;
800 		ServiceComponent serviceManagerComponent;
801 
802 		for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
803 			String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i);
804 			serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName);
805 
806 			if (serviceManagerComponent != null) {
807 				ServiceManager currServiceManager = (ServiceManager) serviceManagerComponent.getInstance();
808 
809 				if (currServiceManager.hasService(name)) {
810 					result = currServiceManager.lookup(name);
811 
812 					if (result != null && this.getLogger().isDebugEnabled()) {
813 						String msg = "Located the service '" + name + "' using the fallback service manager '"
814 								+ serviceManagerComponentName + "'";
815 						this.getLogger().debug(msg);
816 					}
817 				}
818 			}
819 		}
820 
821 		return result;
822 	}
823 
824 	/**
825 	 * Try to get a service provided by a fallback service manager.
826 	 *
827 	 * @param name the name of the service component
828 	 * @return the service component if any
829 	 */
830 	private boolean hasFallbackService(String name) {
831 		Validate.notEmpty(name, "name");
832 
833 		ServiceComponent serviceManagerComponent;
834 
835 		for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
836 			String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i);
837 			serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName);
838 
839 			if (serviceManagerComponent != null) {
840 				ServiceManager currServiceManager;
841 
842 				try {
843 					currServiceManager = (ServiceManager) serviceManagerComponent.getInstance();
844 					if (currServiceManager.hasService(name)) {
845 						return true;
846 					}
847 				} catch (Exception e) {
848 					String msg = "Unable to invoke fallback service manager '" + serviceManagerComponentName + "'";
849 					this.getLogger().error(msg, e);
850 					throw new RuntimeException(msg);
851 				}
852 			}
853 		}
854 
855 		return false;
856 	}
857 
858 	/**
859 	 * @param string The location of the component configuration file
860 	 */
861 	private void setComponentConfigurationLocation(String string) {
862 		this.componentConfigurationLocation = string;
863 	}
864 
865 	/**
866 	 * @param string The location of the component role file
867 	 */
868 	private void setComponentRolesLocation(String string) {
869 		this.componentRolesLocation = string;
870 	}
871 
872 	/**
873 	 * @param string The location of the parameters file
874 	 */
875 	private void setParametersLocation(String string) {
876 		this.parametersLocation = string;
877 	}
878 
879 	/**
880 	 * @return The logger of the service container
881 	 */
882 	private Logger getLogger() {
883 		return this.logger;
884 	}
885 
886 	/**
887 	 * @return Returns the serviceMap.
888 	 */
889 	private HashMap<String, ServiceComponent> getServiceMap() {
890 		return this.serviceMap;
891 	}
892 
893 	/**
894 	 * Incarnation of a list of services.
895 	 *
896 	 * @param serviceList the list of available services
897 	 * @throws Exception the incarnation of a service failed
898 	 */
899 	private void incarnateAll(List<ServiceComponent> serviceList) throws Exception {
900 		ServiceComponent serviceComponent;
901 
902 		// configure all services
903 
904 		for (int i = 0; i < serviceList.size(); i++) {
905 			serviceComponent = (ServiceComponent) this.getServiceList().get(i);
906 			this.configure(serviceComponent);
907 		}
908 
909 		// incarnate all services
910 
911 		for (int i = 0; i < serviceList.size(); i++) {
912 			serviceComponent = (ServiceComponent) this.getServiceList().get(i);
913 			this.incarnate(serviceComponent);
914 		}
915 
916 	}
917 
918 	/**
919 	 * Configure a single service component. After the invocation the service
920 	 * component is ready to be incarnated.
921 	 *
922 	 * @param serviceComponent The service component to be configured
923 	 * @throws Exception the configuration failed
924 	 */
925 	private void configure(ServiceComponent serviceComponent) throws Exception {
926 		this.getLogger().debug("Configuring the service component " + serviceComponent.getShorthand());
927 
928 		// map the context according to the Avalon component type
929 
930 		YaafiToAvalonContextMapper mapper = new YaafiToAvalonContextMapper(serviceComponent.getName(),
931 				this.getClassLoader());
932 
933 		RoleEntry roleEntry = serviceComponent.getRoleEntry();
934 		String componentFlavour = roleEntry.getComponentFlavour();
935 
936 		DefaultContext serviceComponentContext = mapper.mapTo(this.getContext(), componentFlavour);
937 
938 		// create the remaining Avalon artifacts for the service component
939 
940 		Logger serviceComponentLogger = this.getLogger().getChildLogger(roleEntry.getLogCategory());
941 
942 		Configuration serviceComponentConfiguration = this.serviceConfiguration.getChild(roleEntry.getShorthand());
943 
944 		Parameters serviceComponentParameters = this.getParameters();
945 
946 		// configure the service component with all the artifacts
947 
948 		serviceComponent.setLogger(serviceComponentLogger);
949 		serviceComponent.setServiceManager(this);
950 		serviceComponent.setContext(serviceComponentContext);
951 		serviceComponent.setConfiguration(serviceComponentConfiguration);
952 		serviceComponent.setParameters(serviceComponentParameters);
953 
954 		// load the implementation class of the service
955 
956 		serviceComponent.loadImplemtationClass(this.getClassLoader());
957 	}
958 
959 	/**
960 	 * Incarnation of a configured service component. After the incarnation the
961 	 * service component is operational.
962 	 *
963 	 * @param serviceComponent The service component to incarnate
964 	 * @exception Exception incarnating the service component failed
965 	 */
966 	private void incarnate(ServiceComponent serviceComponent) throws Exception {
967 		this.getLogger().debug("Incarnating the service " + serviceComponent.getShorthand());
968 
969 		serviceComponent.incarnate();
970 	}
971 
972 	/**
973 	 * De-commission a ist of services.
974 	 *
975 	 * @param serviceList the list of services to decommission
976 	 */
977 	private void decommissionAll(List<ServiceComponent> serviceList) {
978 		for (int i = serviceList.size() - 1; i >= 0; i--) {
979 			ServiceComponent serviceComponent = (ServiceComponent) serviceList.get(i);
980 			this.decommission(serviceComponent);
981 		}
982 	}
983 
984 	/**
985 	 * Decommission of a single service component. Decommission consists of running
986 	 * the whole Avalon decommission lifecycle process for a service component.
987 	 * After decommission the service is not operational any longer. During
988 	 * decommissioning we ignore any exceptions since it is quite common that
989 	 * something goes wrong.
990 	 *
991 	 * @param serviceComponent The service component to decommission
992 	 */
993 	private void decommission(ServiceComponent serviceComponent) {
994 		this.getLogger().debug("Decommission the service " + serviceComponent.getShorthand());
995 
996 		try {
997 			serviceComponent.decommision();
998 		} catch (Throwable e) {
999 			String msg = "Decommissioning the following service failed : " + serviceComponent.getName();
1000 			this.getLogger().error(msg, e);
1001 		}
1002 	}
1003 
1004 	/**
1005 	 * Disposing a ist of services
1006 	 *
1007 	 * @param serviceList the list of services to dispose
1008 	 */
1009 	private void disposeAll(List<ServiceComponent> serviceList) {
1010 		for (int i = serviceList.size() - 1; i >= 0; i--) {
1011 			ServiceComponent serviceComponent = (ServiceComponent) serviceList.get(i);
1012 			this.dispose(serviceComponent);
1013 		}
1014 	}
1015 
1016 	/**
1017 	 * Disposing of a single service component.
1018 	 * 
1019 	 * @param serviceComponent The service component to decommission
1020 	 */
1021 	private void dispose(ServiceComponent serviceComponent) {
1022 		this.getLogger().debug("Disposing the service " + serviceComponent.getShorthand());
1023 
1024 		try {
1025 			serviceComponent.dispose();
1026 		} catch (Throwable e) {
1027 			String msg = "Disposing the following service failed : " + serviceComponent.getName();
1028 			this.getLogger().error(msg, e);
1029 		}
1030 	}
1031 
1032 	private boolean isCurrentlyDisposing() {
1033 		return isCurrentlyDisposing;
1034 	}
1035 
1036 	private boolean isAlreadyDisposed() {
1037 		return isAlreadyDisposed;
1038 	}
1039 
1040 	/**
1041 	 * @return The list of currently know services
1042 	 */
1043 	private List<ServiceComponent> getServiceList() {
1044 		return this.serviceList;
1045 	}
1046 
1047 	/**
1048 	 * @param list The list of known services
1049 	 */
1050 	private void setServiceList(List<ServiceComponent> list) {
1051 		this.serviceList = list;
1052 	}
1053 
1054 	/**
1055 	 * Factory method for creating services. The service instances are not
1056 	 * initialized at this point.
1057 	 *
1058 	 * @param roleConfiguration the role configuration file
1059 	 * @param logger            the logger
1060 	 * @return the list of service components
1061 	 * @throws ConfigurationException creating the service instance failed
1062 	 */
1063 	private List<ServiceComponent> createServiceComponents(Configuration roleConfiguration, Logger logger)
1064 			throws ConfigurationException {
1065 		Validate.notNull(roleConfiguration, "roleConfiguration");
1066 		Validate.notNull(logger, "logger");
1067 
1068 		ArrayList<ServiceComponent> result = new ArrayList<ServiceComponent>();
1069 		ServiceComponent serviceComponent = null;
1070 
1071 		// create an appropriate instance of role configuration parser
1072 
1073 		RoleConfigurationParser roleConfigurationParser = this.createRoleConfigurationParser();
1074 
1075 		// extract the role entries
1076 
1077 		RoleEntry[] roleEntryList = roleConfigurationParser.parse(roleConfiguration);
1078 
1079 		// get the default interceptors defined for the container
1080 
1081 		ArrayList<String> defaultInterceptorList = this.getDefaultInterceptorServiceList();
1082 
1083 		// create the service components based on the role entries
1084 
1085 		for (int i = 0; i < roleEntryList.length; i++) {
1086 			try {
1087 				// add the default interceptors to all role entries
1088 
1089 				RoleEntry roleEntry = roleEntryList[i];
1090 
1091 				if (this.hasDynamicProxies()) {
1092 					roleEntry.addInterceptors(defaultInterceptorList);
1093 				} else {
1094 					roleEntry.setHasDynamicProxy(false);
1095 				}
1096 
1097 				serviceComponent = new AvalonServiceComponentImpl(roleEntry, this.getLogger(), logger);
1098 
1099 				result.add(serviceComponent);
1100 			} catch (Throwable t) {
1101 				String serviceComponentName = (serviceComponent != null ? serviceComponent.getName() : "unknown");
1102 				String msg = "Failed to load the service " + serviceComponentName;
1103 				this.getLogger().error(msg, t);
1104 				throw new ConfigurationException(msg, t);
1105 			}
1106 		}
1107 
1108 		return result;
1109 	}
1110 
1111 	/**
1112 	 * Load a configuration file either from a file or using the class loader.
1113 	 * 
1114 	 * @param location    the location of the file
1115 	 * @param isEncrypted is the configuration encrypted
1116 	 * @return The loaded configuration
1117 	 * @throws Exception Something went wrong
1118 	 */
1119 	private Configuration loadConfiguration(String location, String isEncrypted) throws Exception {
1120 		Configuration result = null;
1121 		InputStreamLocator locator = this.createInputStreamLocator();
1122 		InputStream is = locator.locate(location);
1123 		DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
1124 
1125 		if (is != null) {
1126 			try {
1127 				is = this.getDecryptingInputStream(is, isEncrypted);
1128 				result = builder.build(is);
1129 			} catch (Exception e) {
1130 				String msg = "Unable to parse the following file : " + location;
1131 				this.getLogger().error(msg, e);
1132 				throw e;
1133 			} finally {
1134 				safeClose(is);
1135 			}
1136 		}
1137 
1138 		return result;
1139 	}
1140 
1141 	/**
1142 	 * Load a configuration property file either from a file or using the class
1143 	 * loader.
1144 	 * 
1145 	 * @return The loaded property file
1146 	 * @throws ConfigurationException Something went wrong
1147 	 */
1148 	private Properties loadComponentConfigurationProperties() throws ConfigurationException {
1149 		Properties result;
1150 		ComponentConfigurationPropertiesResolver resolver;
1151 
1152 		String className = this.componentConfigurationPropertiesResolverConfig.getChild("resolver")
1153 				.getValue(ComponentConfigurationPropertiesResolverImpl.class.getName());
1154 
1155 		try {
1156 			Class<?> resolverClass = this.getClassLoader().loadClass(className);
1157 			resolver = (ComponentConfigurationPropertiesResolver) resolverClass.newInstance();
1158 			ContainerUtil.enableLogging(resolver, this.getLogger());
1159 			ContainerUtil.contextualize(resolver, this.getContext());
1160 			ContainerUtil.configure(resolver, this.componentConfigurationPropertiesResolverConfig);
1161 
1162 			result = resolver.resolve(null);
1163 
1164 			this.getLogger().debug("Using the following componentConfigurationProperties: " + result);
1165 		} catch (Exception e) {
1166 			String msg = "Resolving componentConfigurationProperties failed using the following class : " + className;
1167 			this.getLogger().error(msg, e);
1168 			throw new ConfigurationException(msg, e);
1169 		}
1170 
1171 		return result;
1172 	}
1173 
1174 	/**
1175 	 * Load the parameters
1176 	 * 
1177 	 * @param location    The location as a file
1178 	 * @param isEncrypted is the file encrypted
1179 	 * @return The loaded configuration
1180 	 * @throws Exception Something went wrong
1181 	 */
1182 	private Parameters loadParameters(String location, String isEncrypted) throws Exception {
1183 		InputStreamLocator locator = this.createInputStreamLocator();
1184 		InputStream is = locator.locate(location);
1185 		Parameters result = new Parameters();
1186 
1187 		if (is != null) {
1188 			try {
1189 				is = this.getDecryptingInputStream(is, isEncrypted);
1190 				Properties props = new Properties();
1191 				props.load(is);
1192 				result = Parameters.fromProperties(props);
1193 			} finally {
1194 				safeClose(is);
1195 			}
1196 		}
1197 
1198 		return result;
1199 	}
1200 
1201 	/**
1202 	 * Creates a locator to find a resource either in the file system or in the
1203 	 * classpath.
1204 	 *
1205 	 * @return the locator
1206 	 */
1207 	private InputStreamLocator createInputStreamLocator() {
1208 		return new InputStreamLocator(this.getApplicationRootDir(), this.getLogger());
1209 	}
1210 
1211 	/**
1212 	 * Set the application directory of the container.
1213 	 *
1214 	 * @param dir The applicationRootDir to set.
1215 	 */
1216 	private void setApplicationRootDir(File dir) {
1217 		this.getLogger().debug("Setting applicationRootDir to " + dir.getAbsolutePath());
1218 
1219 		Validate.notNull(dir, "applicationRootDir is <null>");
1220 		Validate.isTrue(dir.exists(), "applicationRootDir does not exist");
1221 
1222 		this.applicationRootDir = dir;
1223 	}
1224 
1225 	/**
1226 	 * @return Returns the applicationRootDir.
1227 	 */
1228 	private File getApplicationRootDir() {
1229 		return this.applicationRootDir;
1230 	}
1231 
1232 	/**
1233 	 * @return Returns the serviceManager of the parent container
1234 	 */
1235 	private ServiceManager getParentServiceManager() {
1236 		return this.parentServiceManager;
1237 	}
1238 
1239 	/**
1240 	 * @return is a parent ServiceManager available
1241 	 */
1242 	private boolean hasParentServiceManager() {
1243 		return this.getParentServiceManager() != null;
1244 	}
1245 
1246 	/**
1247 	 * Set the temporary directory of the container.
1248 	 *
1249 	 * @param dir The tempRootDir to set.
1250 	 */
1251 	private void setTempRootDir(File dir) {
1252 		this.getLogger().debug("Setting tempRootDir to " + dir.getAbsolutePath());
1253 
1254 		Validate.notNull(dir, "tempRootDir is <null>");
1255 		Validate.isTrue(dir.exists(), "tempRootDir does not exist");
1256 		Validate.isTrue(dir.canWrite(), "tempRootDir is not writeable");
1257 
1258 		this.tempRootDir = dir;
1259 	}
1260 
1261 	/**
1262 	 * @return Returns the tempRootDir.
1263 	 */
1264 	private File getTempRootDir() {
1265 		return tempRootDir;
1266 	}
1267 
1268 	/**
1269 	 * @return Returns the isComponentConfigurationEncrypted.
1270 	 */
1271 	private String isComponentConfigurationEncrypted() {
1272 		return isComponentConfigurationEncrypted;
1273 	}
1274 
1275 	/**
1276 	 * @param isComponentConfigurationEncrypted The
1277 	 *                                          isComponentConfigurationEncrypted to
1278 	 *                                          set.
1279 	 */
1280 	private void setComponentConfigurationEncrypted(String isComponentConfigurationEncrypted) {
1281 		this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted;
1282 	}
1283 
1284 	/**
1285 	 * @return Returns the isComponentRolesEncrypted.
1286 	 */
1287 	private String isComponentRolesEncrypted() {
1288 		return isComponentRolesEncrypted;
1289 	}
1290 
1291 	/**
1292 	 * @param isComponentRolesEncrypted The isComponentRolesEncrypted to set.
1293 	 */
1294 	private void setComponentRolesEncrypted(String isComponentRolesEncrypted) {
1295 		this.isComponentRolesEncrypted = isComponentRolesEncrypted;
1296 	}
1297 
1298 	/**
1299 	 * @return Returns the isParametersEncrypted.
1300 	 */
1301 	private String isParametersEncrypted() {
1302 		return isParametersEncrypted;
1303 	}
1304 
1305 	/**
1306 	 * @param isParametersEncrypted The isParametersEncrypted to set.
1307 	 */
1308 	private void setParametersEncrypted(String isParametersEncrypted) {
1309 		this.isParametersEncrypted = isParametersEncrypted;
1310 	}
1311 
1312 	/**
1313 	 * Create a decrypting input stream using the default password.
1314 	 *
1315 	 * @param is          the input stream to be decrypted
1316 	 * @param isEncrypted the encryption mode (true|false|auto)
1317 	 * @return an decrypting input stream
1318 	 * @throws Exception reading the input stream failed
1319 	 */
1320 	private InputStream getDecryptingInputStream(InputStream is, String isEncrypted) throws Exception {
1321 		return CryptoStreamFactory.getDecryptingInputStream(is, isEncrypted);
1322 	}
1323 
1324 	/**
1325 	 * @return Returns the containerFlavour.
1326 	 */
1327 	private String getContainerFlavour() {
1328 		return containerFlavour;
1329 	}
1330 
1331 	/**
1332 	 * @param containerFlavour The containerFlavour to set.
1333 	 */
1334 	private void setContainerFlavour(String containerFlavour) {
1335 		this.containerFlavour = containerFlavour;
1336 	}
1337 
1338 	/**
1339 	 * @return Returns the componentRolesFlavour.
1340 	 */
1341 	private String getComponentRolesFlavour() {
1342 		return componentRolesFlavour;
1343 	}
1344 
1345 	/**
1346 	 * @param componentRolesFlavour The componentRolesFlavour to set.
1347 	 */
1348 	private void setComponentRolesFlavour(String componentRolesFlavour) {
1349 		this.componentRolesFlavour = componentRolesFlavour;
1350 	}
1351 
1352 	/**
1353 	 * @return Returns the context.
1354 	 */
1355 	private Context getContext() {
1356 		return context;
1357 	}
1358 
1359 	/**
1360 	 * @return Returns the hasDynamicProxies.
1361 	 */
1362 	private boolean hasDynamicProxies() {
1363 		return this.hasDynamicProxies;
1364 	}
1365 
1366 	/**
1367 	 * @return Returns the defaultInterceptorServiceList.
1368 	 */
1369 	private ArrayList<String> getDefaultInterceptorServiceList() {
1370 		return defaultInterceptorServiceList;
1371 	}
1372 
1373 	/**
1374 	 * @return the containers class loader
1375 	 */
1376 	private ClassLoader getClassLoader() {
1377 		return this.getClass().getClassLoader();
1378 	}
1379 
1380 	/**
1381 	 * Wait for the time configured as 'reconfigurationDelay' before reconfiguring
1382 	 * the container or services.
1383 	 */
1384 	private void waitForReconfiguration() {
1385 		try {
1386 			Thread.sleep(this.reconfigurationDelay);
1387 		} catch (InterruptedException e) {
1388 			// nothing to do
1389 		}
1390 	}
1391 
1392 	/**
1393 	 * Wait for the time configured as 'disposalDelay' before disposing the
1394 	 * container.
1395 	 */
1396 	private void waitForDisposal() {
1397 		try {
1398 			Thread.sleep(this.disposalDelay);
1399 		} catch (InterruptedException e) {
1400 			// nothing to do
1401 		}
1402 	}
1403 
1404 	private void safeClose(InputStream is) {
1405 		if (is != null) {
1406 			try {
1407 				is.close();
1408 			} catch (Exception e) {
1409 				getLogger().error("Failed to close an input stream", e);
1410 			}
1411 		}
1412 	}
1413 }