001    package org.apache.turbine.services.avaloncomponent;
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 java.io.IOException;
023    
024    import org.apache.avalon.framework.activity.Disposable;
025    import org.apache.avalon.framework.activity.Initializable;
026    import org.apache.avalon.framework.logger.CommonsLogger;
027    import org.apache.avalon.framework.logger.Logger;
028    import org.apache.avalon.framework.service.ServiceException;
029    import org.apache.commons.configuration.Configuration;
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.fulcrum.yaafi.framework.container.ServiceContainer;
033    import org.apache.fulcrum.yaafi.framework.factory.ServiceContainerConfiguration;
034    import org.apache.fulcrum.yaafi.framework.factory.ServiceContainerFactory;
035    import org.apache.turbine.Turbine;
036    import org.apache.turbine.services.InitializationException;
037    import org.apache.turbine.services.InstantiationException;
038    import org.apache.turbine.services.TurbineBaseService;
039    
040    /**
041     * An implementation of Turbine service initializing the YAAFI container
042     *
043     * @author <a href="mailto:siegfried.goescfl@it20one.at">Siegfried Goeschl</a>
044     */
045    public class TurbineYaafiComponentService
046            extends TurbineBaseService
047            implements AvalonComponentService, Initializable, Disposable
048    {
049        /** the logger to be used */
050        private static Log log = LogFactory.getLog(AVALON_LOG_CATEGORY);
051    
052        /** property to lookup the container configuration file */
053        public static final String CONTAINER_CONFIGURATION_KEY = "containerConfiguration";
054    
055        /** the default value for the container configuration file */
056        public static final String CONTAINER_CONFIGURATION_VALUE = "/WEB-INF/conf/containerConfiguration.xml";
057    
058        /** property to lookup the properties file */
059        public static final String COMPONENT_PARAMETERS_KEY = "parameters";
060    
061        /** the default value for the parameter file */
062        public static final String COMPONENT_PARAMETERS_VALUE = "/WEB-INF/conf/parameters.properties";
063    
064        /** YAFFI container */
065        private ServiceContainer container;
066    
067        // -------------------------------------------------------------
068        // Service initialization
069        // -------------------------------------------------------------
070    
071        public TurbineYaafiComponentService()
072        {
073            // nothing to do
074        }
075    
076        /**
077         * Load all configured components and initialize them. This is a zero parameter variant which
078         * queries the Turbine Servlet for its config.
079         *
080         * @throws InitializationException Something went wrong in the init stage
081         */
082        public void init() throws InitializationException
083        {
084            try
085            {
086                log.info( "Initializing TurbineYaafiComponentService ..." );
087                initialize();
088                setInit(true);
089            }
090            catch (Exception e)
091            {
092                log.error("Exception caught initialising service: ", e);
093                throw new InitializationException("Initializing TurbineYaafiComponentService failed", e);
094            }
095        }
096    
097        /**
098         * Shuts the Component Service down, calls dispose on the components that implement this
099         * interface
100         *
101         */
102        public void shutdown()
103        {
104            log.info( "Disposing TurbineYaafiComponentService ..." );
105            dispose();
106            setInit(false);
107        }
108    
109        // -------------------------------------------------------------
110        // Avalon lifecycle interfaces
111        // -------------------------------------------------------------
112    
113        /**
114         * Initializes the container
115         *
116         * @throws Exception generic exception
117         */
118        public void initialize() throws Exception
119        {
120            // get the configuration from the baseclass
121    
122            Configuration conf = this.getConfiguration();
123    
124            // determine the home directory
125    
126            String homePath = Turbine.getRealPath("/");
127            log.info( "Using the following home : " + homePath );
128    
129            // create the configuration for YAAFI
130    
131            ServiceContainerConfiguration config =
132                this.createServiceContainerConfiguration(conf);
133    
134            config.setLogger( this.createAvalonLogger() );
135            config.setApplicationRootDir( homePath );
136    
137            // initialize the container
138    
139            try
140            {
141                this.container = ServiceContainerFactory.create(
142                    config
143                    );
144            }
145            catch (Exception e)
146            {
147                String msg = "Initializing YAAFI failed";
148                log.error(msg,e);
149                throw e;
150            }
151        }
152    
153        /**
154         * Disposes of the container and releases resources
155         */
156        public void dispose()
157        {
158            if (this.container != null)
159            {
160                this.container.dispose();
161                this.container = null;
162            }
163        }
164    
165        /**
166         * Returns an instance of the named component
167         *
168         * @param roleName Name of the role the component fills.
169         * @return an instance of the named component
170         * @throws Exception generic exception
171         */
172        public Object lookup(String roleName) throws ServiceException
173        {
174            return this.container.lookup(roleName);
175        }
176    
177        /**
178         * Releases the component.
179         *
180         * @param component the component to release
181         */
182        public void release(Object component)
183        {
184            this.container.release( component );
185        }
186    
187        /**
188         * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
189         */
190        public boolean hasService(String roleName)
191        {
192            return this.container.hasService(roleName);
193        }
194    
195        /**
196         * Create a ServiceContainerConfiguration based on the Turbine configuration
197         *
198         * @param conf the Turbine configuration
199         * @return the YAAFI configuration
200         * @throws IOException creating the YAAFI configuration failed
201         */
202        protected ServiceContainerConfiguration createServiceContainerConfiguration( Configuration conf )
203            throws IOException
204        {
205            ServiceContainerConfiguration result = new ServiceContainerConfiguration();
206    
207            // are we using a "containerConfiguration.xml" ?!
208    
209            if( conf.containsKey(CONTAINER_CONFIGURATION_KEY) )
210            {
211                // determine the container configuration file
212    
213                String containerConfiguration = conf.getString(
214                    CONTAINER_CONFIGURATION_KEY
215                    );
216    
217                result.loadContainerConfiguration(containerConfiguration);
218            }
219            else if( conf.containsKey(COMPONENT_ROLE_KEY) )
220            {
221                // determine the location of the role configuraton file
222    
223                String roleConfigurationFileName = conf.getString(
224                    COMPONENT_ROLE_KEY,
225                    COMPONENT_ROLE_VALUE
226                    );
227    
228                // determine the location of component configuration file
229    
230                String componentConfigurationFileName = conf.getString(
231                    COMPONENT_CONFIG_KEY,
232                    COMPONENT_CONFIG_VALUE
233                    );
234    
235                // determine the location of parameters file
236    
237                String parametersFileName = conf.getString(
238                    COMPONENT_PARAMETERS_KEY,
239                    COMPONENT_PARAMETERS_VALUE
240                    );
241    
242                result.setComponentRolesLocation( roleConfigurationFileName );
243                result.setComponentConfigurationLocation( componentConfigurationFileName );
244                result.setParametersLocation( parametersFileName );
245            }
246            else
247            {
248                // determine the container configuration file
249    
250                String containerConfiguration = conf.getString(
251                    CONTAINER_CONFIGURATION_KEY,
252                    CONTAINER_CONFIGURATION_VALUE
253                    );
254    
255                result.loadContainerConfiguration(containerConfiguration);
256            }
257    
258            return result;
259        }
260    
261        /**
262         * Create the Avalon logger to be passed to YAAFI
263         * @return an Avalon Logger
264         */
265        protected Logger createAvalonLogger()
266        {
267            Logger result = new CommonsLogger(log, AVALON_LOG_CATEGORY);
268            return result;
269        }
270    
271        // -------------------------------------------------------------
272        // TurbineServiceProvider
273        // -------------------------------------------------------------
274    
275        /**
276         * @see org.apache.turbine.services.TurbineServiceProvider#exists(java.lang.String)
277         */
278        public boolean exists(String roleName)
279        {
280            return this.hasService(roleName);
281        }
282    
283        /**
284         * @see org.apache.turbine.services.TurbineServiceProvider#get(java.lang.String)
285         */
286        public Object get(String roleName) throws InstantiationException
287        {
288            try
289            {
290                return this.lookup(roleName);
291            }
292            catch (ServiceException e)
293            {
294                String msg = "Unable to get the following service : " + roleName;
295                log.error(msg);
296                throw new InstantiationException(msg);
297            }
298            catch (Throwable t)
299            {
300                String msg = "Unable to get the following service : " + roleName;
301                log.error(msg,t);
302                throw new InstantiationException(msg,t);
303            }
304        }
305    }