ServiceContainerConfiguration.java
package org.apache.fulcrum.yaafi.framework.factory;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.fulcrum.yaafi.framework.constant.AvalonMerlinConstants;
import org.apache.fulcrum.yaafi.framework.container.ServiceConstants;
import org.apache.fulcrum.yaafi.framework.crypto.CryptoStreamFactory;
import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator;
import org.apache.fulcrum.yaafi.framework.util.Validate;
/**
* Helper class to capture configuration related stuff. The are two ways for
* setting up the configuration:
* <ul>
* <li>set all parameters manually</li>
* <li>use a containerConfiguration file and provide the remaining settings</li>
* </ul>
*
* The Avalon context and configuration are created by
* <ul>
* <li>createFinalContext()</li>
* <li>createFinalConfiguration()</li>
* </ul>
*
* @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
*/
public class ServiceContainerConfiguration {
/** our default implementation class of the service container */
private String serviceContainerClazzName;
/** the location of the component role file */
private String componentRolesLocation;
/** is the component role file encrypted? */
private String isComponentRolesEncrypted;
/** the location of the component configuration file */
private String componentConfigurationLocation;
/** is the component configuration file encrypted? */
private String isComponentConfigurationEncrypted;
/** the location of the paramaters file */
private String parametersLocation;
/** is the parameters file encrypted? */
private String isParametersEncrypted;
/** the user-supplied Avalon context */
private DefaultContext context;
/** the Avalon logger */
private Logger logger;
/** the application directory */
private String applicationRootDir;
/** the temporary directory */
private String tempRootDir;
/** the class loader passed in the Avalon Context */
private ClassLoader componentClassLoader;
/** the type of container where YAAFI is embedded */
private String containerFlavour;
/** the caller-supplied container configuration */
private Configuration containerConfiguration;
/** to lookup service in the parent container */
private ServiceManager parentServiceManager;
/** a list of ServiceManager maintaining their own services */
private String[] serviceManagerList;
/** Constructor */
public ServiceContainerConfiguration() {
this(ConsoleLogger.LEVEL_DEBUG);
}
/**
* Constructor.
*
* @param logLevel the log level for the console logger.
*/
public ServiceContainerConfiguration(int logLevel) {
this.logger = new ConsoleLogger(logLevel);
this.containerFlavour = ServiceConstants.AVALON_CONTAINER_YAAFI;
this.serviceContainerClazzName = ServiceConstants.CLAZZ_NAME;
this.componentRolesLocation = ServiceConstants.COMPONENT_ROLE_VALUE;
this.isComponentRolesEncrypted = "false";
this.componentConfigurationLocation = ServiceConstants.COMPONENT_CONFIG_VALUE;
this.isComponentConfigurationEncrypted = "false";
this.parametersLocation = ServiceConstants.COMPONENT_PARAMETERS_VALUE;
this.isParametersEncrypted = "false";
this.context = new DefaultContext();
this.applicationRootDir = new File("").getAbsolutePath();
this.tempRootDir = System.getProperty("java.io.tmpdir", ".");
this.componentClassLoader = this.getClass().getClassLoader();
}
/**
* Add a new entry to the context by creating a new one.
*
* @param name the name of the new entry
* @param value the value of the new entry
*/
public void addToContext(String name, Object value) {
Validate.notEmpty(name, "name");
Validate.notNull(value, "value");
this.getContext().put(name, value);
}
/**
* Add a hashtable to the context
*
* @param hashtable the Hashtable to be added
*/
public void addToContext(Hashtable<?, ?> hashtable) {
Validate.notNull(hashtable, "hashtable");
String name = null;
Object value = null;
Enumeration<?> keys = hashtable.keys();
while (keys.hasMoreElements()) {
name = (String) keys.nextElement();
value = hashtable.get(name);
this.addToContext(name, value);
}
}
/**
* Create the final Avalon context passed to YAAFI containing
* <ul>
* <li>user-supplied context</li>
* <li>urn:avalon:home</li>
* <li>urn:avalon:temp</li>
* <li>urn:avalon:name</li>
* <li>urn:avalon:partition</li>
* <li>urn:avalon:classloader</li>
* </ul>
*
* @return the final Context
* @throws Exception if filename not defined
* @throws IOException if file not found
*/
public Context createFinalContext() throws IOException, Exception {
// 1) add the application root dir
this.addToContext(AvalonMerlinConstants.URN_AVALON_HOME, this.getApplicationRootDir());
// 2) add the temp root dir
this.addToContext(AvalonMerlinConstants.URN_AVALON_TEMP, this.getTempRootDir());
// 3) add the Avalon name
this.addToContext(AvalonMerlinConstants.URN_AVALON_NAME, ServiceConstants.ROLE_NAME);
// 4) add the Avalon partition name
this.addToContext(AvalonMerlinConstants.URN_AVALON_PARTITION, "root");
// 5) add the class loader
this.addToContext(AvalonMerlinConstants.URN_AVALON_CLASSLOADER, this.getComponentClassLoader());
return this.getContext();
}
/**
* Create a final configuration.
*
* @return the configuration
*/
public Configuration createFinalConfiguration() {
DefaultConfiguration result = null;
if (this.getContainerConfiguration() != null) {
return this.getContainerConfiguration();
} else {
// the root element is "fulcrum-yaafi"
result = new DefaultConfiguration(ServiceConstants.ROLE_NAME);
// add the following fragement
//
// <containerFlavour>merlin</containerFlavour>
DefaultConfiguration containerFlavourConfig = new DefaultConfiguration(
ServiceConstants.CONTAINERFLAVOUR_CONFIG_KEY);
containerFlavourConfig.setValue(this.getContainerFlavour());
result.addChild(containerFlavourConfig);
// add the following fragement
//
// <containerClazzName>...</containerClazzName>
DefaultConfiguration containerClazzNameConfig = new DefaultConfiguration(
ServiceConstants.CONTAINERCLAZZNAME_CONFIG_KEY);
containerClazzNameConfig.setValue(this.getServiceContainerClazzName());
result.addChild(containerClazzNameConfig);
// add the following fragement
//
// <componentRoles>
// <location>../conf/componentRoles.xml</location>
// <isEncrypted>true</isEncrypted>
// </componentRoles>
DefaultConfiguration componentRolesConfig = new DefaultConfiguration(ServiceConstants.COMPONENT_ROLE_KEYS);
DefaultConfiguration componentRolesLocation = new DefaultConfiguration(
ServiceConstants.COMPONENT_LOCATION_KEY);
componentRolesLocation.setValue(this.getComponentRolesLocation());
DefaultConfiguration componentRolesIsEncrypted = new DefaultConfiguration(
ServiceConstants.COMPONENT_ISENCRYPTED_KEY);
componentRolesIsEncrypted.setValue(this.isComponentRolesEncrypted());
componentRolesConfig.addChild(componentRolesLocation);
componentRolesConfig.addChild(componentRolesIsEncrypted);
result.addChild(componentRolesConfig);
// add the following fragement
//
// <componentConfiguration>
// <location>../conf/componentRoles.xml</location>
// <isEncrypted>true</isEncrypted>
// </componentConfiguration>
DefaultConfiguration componentConfigurationConfig = new DefaultConfiguration(
ServiceConstants.COMPONENT_CONFIG_KEY);
DefaultConfiguration componentConfigurationLocation = new DefaultConfiguration(
ServiceConstants.COMPONENT_LOCATION_KEY);
componentConfigurationLocation.setValue(this.getComponentConfigurationLocation());
DefaultConfiguration componentConfigurationIsEncrypted = new DefaultConfiguration(
ServiceConstants.COMPONENT_ISENCRYPTED_KEY);
componentConfigurationIsEncrypted.setValue(this.isComponentConfigurationEncrypted());
componentConfigurationConfig.addChild(componentConfigurationLocation);
componentConfigurationConfig.addChild(componentConfigurationIsEncrypted);
result.addChild(componentConfigurationConfig);
// Add the following fragement
//
// <parameters>
// <location>../conf/parameters.properties</location>
// <isEncrypted>true</isEncrypted>
// </parameters>
DefaultConfiguration parameterConfigurationConfig = new DefaultConfiguration(
ServiceConstants.COMPONENT_PARAMETERS_KEY);
DefaultConfiguration parameterConfigurationLocation = new DefaultConfiguration(
ServiceConstants.COMPONENT_LOCATION_KEY);
parameterConfigurationLocation.setValue(this.getParametersLocation());
DefaultConfiguration parameterConfigurationIsEncrypted = new DefaultConfiguration(
ServiceConstants.COMPONENT_ISENCRYPTED_KEY);
parameterConfigurationIsEncrypted.setValue(this.isParametersEncrypted());
parameterConfigurationConfig.addChild(parameterConfigurationLocation);
parameterConfigurationConfig.addChild(parameterConfigurationIsEncrypted);
result.addChild(parameterConfigurationConfig);
// Add the following fragement
//
// <serviceManagers>
// <serviceManagers>springFrameworkService</serviceManager>
// </serviceManagers>
if (this.hasServiceManagerList()) {
DefaultConfiguration serviceManagerListConfig = new DefaultConfiguration(
ServiceConstants.SERVICEMANAGER_LIST_KEY);
for (int i = 0; i < this.serviceManagerList.length; i++) {
DefaultConfiguration serviceManagerConfig = new DefaultConfiguration(
ServiceConstants.SERVICEMANAGER_KEY);
serviceManagerConfig.setValue(this.serviceManagerList[i]);
serviceManagerListConfig.addChild(serviceManagerConfig);
}
result.addChild(serviceManagerListConfig);
}
return result;
}
}
/////////////////////////////////////////////////////////////////////////
// Generated Getters/Setters
/////////////////////////////////////////////////////////////////////////
/**
* @return Returns the serviceContainerClazzName.
*/
private String getServiceContainerClazzName() {
return this.serviceContainerClazzName;
}
/**
* @return Returns the componentConfigurationLocation.
*/
private String getComponentConfigurationLocation() {
return componentConfigurationLocation;
}
/**
* @param componentConfigurationLocation The componentConfigurationLocation to
* set.
*/
public void setComponentConfigurationLocation(String componentConfigurationLocation) {
Validate.notNull(componentConfigurationLocation, "componentConfigurationLocation");
this.componentConfigurationLocation = componentConfigurationLocation;
}
/**
* @return Returns the componentRolesLocation.
*/
private String getComponentRolesLocation() {
return componentRolesLocation;
}
/**
* @param componentRolesLocation The componentRolesLocation to set.
*/
public void setComponentRolesLocation(String componentRolesLocation) {
this.componentRolesLocation = componentRolesLocation;
}
/**
* @return Returns the context.
*/
private DefaultContext getContext() {
return context;
}
/**
* @param context The context to set.
*/
public void setContext(Context context) {
if (context instanceof DefaultContext) {
this.context = (DefaultContext) context;
} else {
this.context = new DefaultContext(context);
}
}
/**
* @return Returns the isComponentConfigurationEncrypted.
*/
private String isComponentConfigurationEncrypted() {
return isComponentConfigurationEncrypted;
}
/**
* @param isComponentConfigurationEncrypted The
* isComponentConfigurationEncrypted to
* set.
*/
public void setComponentConfigurationEncrypted(String isComponentConfigurationEncrypted) {
this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted;
}
/**
* @return Returns the isComponentRolesEncrypted.
*/
private String isComponentRolesEncrypted() {
return isComponentRolesEncrypted;
}
/**
* @param isComponentRolesEncrypted The isComponentRolesEncrypted to set.
*/
public void setComponentRolesEncrypted(String isComponentRolesEncrypted) {
this.isComponentRolesEncrypted = isComponentRolesEncrypted;
}
/**
* @return Returns the isParametersEncrypted.
*/
private String isParametersEncrypted() {
return isParametersEncrypted;
}
/**
* @param isParametersEncrypted The isParametersEncrypted to set.
*/
public void setParametersEncrypted(String isParametersEncrypted) {
Validate.notEmpty(isParametersEncrypted, "isParametersEncrypted");
this.isParametersEncrypted = isParametersEncrypted;
}
/**
* @return Returns the logger.
*/
public Logger getLogger() {
return logger;
}
/**
* @param logger The logger to set.
*/
public void setLogger(Logger logger) {
this.logger = logger;
}
/**
* @return Returns the parametersLocation.
*/
private String getParametersLocation() {
return parametersLocation;
}
/**
* @param parametersLocation The parametersLocation to set.
*/
public void setParametersLocation(String parametersLocation) {
this.parametersLocation = parametersLocation;
}
/**
* @return Returns the applicationRootDir.
*/
private File getApplicationRootDir() {
return new File(applicationRootDir);
}
/**
* @param applicationRootDir The applicationRootDir to set.
*/
public void setApplicationRootDir(String applicationRootDir) {
Validate.notNull(applicationRootDir, "applicationRootDir");
if (applicationRootDir.equals(".")) {
this.applicationRootDir = new File("").getAbsolutePath();
} else {
this.applicationRootDir = new File(applicationRootDir).getAbsolutePath();
}
}
/**
* @return Returns the tempRootDir.
* @throws Exception
* @throws IOException
*/
private File getTempRootDir() throws IOException, Exception {
return makeAbsoluteFile(this.getApplicationRootDir(), this.tempRootDir);
}
/**
* @param tempRootDir The tempRootDir to set.
*/
public void setTempRootDir(String tempRootDir) {
Validate.notNull(tempRootDir, "tempRootDir");
this.tempRootDir = tempRootDir;
}
/**
* @return Returns the classLoader.
*/
private ClassLoader getComponentClassLoader() {
return componentClassLoader;
}
/**
* @param componentClassLoader The classLoader to set.
*/
public void setComponentClassLoader(ClassLoader componentClassLoader) {
Validate.notNull(componentClassLoader, "componentClassLoader");
this.componentClassLoader = componentClassLoader;
}
/**
* @return Returns the containerFlavour.
*/
private String getContainerFlavour() {
return containerFlavour;
}
/**
* @param containerFlavour The containerFlavour to set.
*/
public void setContainerFlavour(String containerFlavour) {
this.containerFlavour = containerFlavour;
}
/**
* @return Returns the containerConfiguration.
*/
private Configuration getContainerConfiguration() {
return containerConfiguration;
}
/**
* @param containerConfiguration The containerConfiguration to set.
*/
public void setContainerConfiguration(Configuration containerConfiguration) {
this.containerConfiguration = containerConfiguration;
}
/**
* Get the parent service manager to find service managed by the parent
* container.
*
* @return the parent container
*/
public ServiceManager getParentServiceManager() {
return parentServiceManager;
}
/**
* Set the parent service manager to find service managed by the parent
* container.
*
* @param parentServiceManager the parent container
*/
public void setParentServiceManager(ServiceManager parentServiceManager) {
this.parentServiceManager = parentServiceManager;
}
/**
* Get a list of service manager managing their own set of services.
*
* @return a list of service implementing the ServiceManager interface
*/
public String[] getServiceManagerList() {
return serviceManagerList;
}
/**
* Set a list of service manager managing their own set of services.
*
* @param serviceManagerList a list of service implementing the ServiceManager
* interface
*/
public void setServiceManagerList(String[] serviceManagerList) {
this.serviceManagerList = serviceManagerList;
}
/**
* @return true if there is a service manager defined
*/
public boolean hasServiceManagerList() {
if (this.serviceManagerList != null && this.serviceManagerList.length > 0)
return true;
return false;
}
/**
* Loads a containerConfiguration file and set is as the Avalon configuration to
* be used for Configurable.configure(). Take care that the implementation uses
* an InputStreamLocator to find the containerConfiguration which uses the
* previously set application root directory.
*
* @param location the location of the containerConfiguration
* @throws IOException loading the configuration failed
*/
public void loadContainerConfiguration(String location) throws IOException {
this.loadContainerConfiguration(location, "false");
}
/**
* Loads a containerConfiguration file and set is as the Avalon configuration to
* be used for Configurable.configure(). Take care that the implementation uses
* an InputStreamLocator to find the containerConfiguration which uses the
* previously set application root directory.
*
* @param location the location of the containerConfiguration
* @param isEncrypted is the file encrypted
* @throws IOException loading the configuration failed
*/
public void loadContainerConfiguration(String location, String isEncrypted) throws IOException {
Configuration result = null;
InputStreamLocator locator = new InputStreamLocator(this.getApplicationRootDir(), this.getLogger());
DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
InputStream is = locator.locate(location);
if (is != null) {
try {
is = CryptoStreamFactory.getDecryptingInputStream(is, isEncrypted);
result = builder.build(is);
this.setContainerConfiguration(result);
} catch (Exception e) {
String msg = "Unable to parse the following file : " + location;
this.getLogger().error(msg, e);
throw new IOException(msg);
}
} else {
String msg = "Unable to locate the containerConfiguration file : " + location;
this.getLogger().error(msg);
throw new IOException(msg);
}
}
/**
* Determines the absolute file.
*
* @param baseDir the base directory
* @param fileName the filename
* @return the absolute path
*/
private static File makeAbsoluteFile(File baseDir, String fileName) throws IOException, Exception {
if (baseDir.exists()) {
if (!StringUtils.isEmpty(fileName)) {
File result = new File(fileName);
if (!result.isAbsolute()) {
result = new File(baseDir, fileName);
}
return result;
} else {
throw new Exception("No filename specified");
}
} else {
throw new IOException("The directory does not exist");
}
}
}