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