001    package org.apache.fulcrum.yaafi.framework.factory;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.avalon.framework.configuration.Configuration;
023    import org.apache.avalon.framework.configuration.ConfigurationUtil;
024    import org.apache.avalon.framework.container.ContainerUtil;
025    import org.apache.avalon.framework.context.Context;
026    import org.apache.avalon.framework.logger.Logger;
027    import org.apache.fulcrum.yaafi.framework.container.ServiceConstants;
028    import org.apache.fulcrum.yaafi.framework.container.ServiceContainer;
029    import org.apache.fulcrum.yaafi.framework.util.Validate;
030    
031    /**
032     * A factory to hide how to initialize YAFFI since this might change over the time
033     *
034     * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
035     */
036    
037    public class ServiceContainerFactory
038    {
039        /** The logger to be used */
040        private static Logger logger;
041    
042        /**
043         * Create a fully initialized YAFFI service container.
044         *
045         * @param serviceManagerConfig the configuration to use
046         * @return the service container
047         * @throws Exception the creation failed
048         */
049        public static ServiceContainer create(
050            ServiceContainerConfiguration serviceManagerConfig)
051            throws Exception
052        {
053            Validate.notNull(serviceManagerConfig,"serviceManagerConfig");
054            Context context = serviceManagerConfig.createFinalContext();
055            return ServiceContainerFactory.create( serviceManagerConfig, context );
056        }
057    
058        /**
059         * Create a fully initialized YAFFI service container
060         *
061         * @param serviceManagerConfig the configuration to use
062         * @param context the context to use
063         * @return the service container
064         * @throws Exception the creation failed
065         */
066        public static ServiceContainer create(
067            ServiceContainerConfiguration serviceManagerConfig, Context context )
068            throws Exception
069        {
070            Validate.notNull(serviceManagerConfig,"serviceManagerConfig");
071            Validate.notNull(context,"context");
072    
073            String clazzName;
074            Class clazz = null;
075            Configuration configuration = null;
076            ServiceContainer result = null;
077    
078            // Enforce a logger from the caller
079    
080            try
081            {
082                // bootstrap the logging
083    
084                ServiceContainerFactory.logger = serviceManagerConfig.getLogger();
085    
086                // bootstrap the configuration settings
087    
088                configuration = serviceManagerConfig.createFinalConfiguration();
089    
090                // bootstrap the service container
091    
092                clazzName = getServiceContainerClazzName(configuration);
093    
094                ServiceContainerFactory.logger.debug(
095                    "Loading the service container class " + clazzName
096                    );
097    
098                clazz = ServiceContainerFactory.class.getClassLoader().loadClass(
099                    clazzName
100                    );
101    
102                ServiceContainerFactory.logger.debug(
103                    "Instantiating the service container class " + clazzName
104                    );
105    
106                result = (ServiceContainer) clazz.newInstance();
107            }
108            catch (Exception e)
109            {
110                String msg = "Creating the ServiceContainer failed";
111                ServiceContainerFactory.logger.error( msg, e );
112                throw e;
113            }
114    
115            Logger serviceContainerLogger = serviceManagerConfig.getLogger();
116    
117            serviceContainerLogger.debug(
118                "Using the following configuration : "
119                + ConfigurationUtil.toString( configuration )
120                );
121    
122            ContainerUtil.enableLogging( result, serviceManagerConfig.getLogger() );
123            ContainerUtil.contextualize( result, context );
124    
125            if(serviceManagerConfig.getParentServiceManager() != null)
126            {
127                ContainerUtil.service(result, serviceManagerConfig.getParentServiceManager());
128            }
129            
130            ContainerUtil.configure( result, configuration );
131            ContainerUtil.initialize( result );
132    
133            return result;
134        }
135    
136        /**
137         * Disposes the container.
138         *
139         * @param container the container to be disposed
140         * @return true if the disposal was successful or false otherwise
141         */
142        public static boolean dispose( ServiceContainer container )
143        {
144            try
145            {
146                if( container != null )
147                {
148                    container.dispose();
149                }
150    
151                return true;
152            }
153            catch( Throwable t )
154            {
155                String msg = "Disposing the container failed : " + t.getMessage();
156                System.err.println(msg);
157                t.printStackTrace();
158                return false;
159            }
160        }
161    
162        /**
163         * Reads the implementation class of the YAAFI container.
164         *
165         * @param configuration the Avalon configuration
166         * @return the implementation class name of the container
167         */
168        private static String getServiceContainerClazzName( Configuration configuration )
169        {
170            Configuration containerClazzNameConfig = configuration.getChild(
171                ServiceConstants.CONTAINERCLAZZNAME_CONFIG_KEY
172                );
173    
174            if( containerClazzNameConfig != null )
175            {
176                return containerClazzNameConfig.getValue(ServiceConstants.CLAZZ_NAME);
177            }
178            else
179            {
180                return ServiceConstants.CLAZZ_NAME;
181            }
182        }
183    
184    }