    001    package org.apache.turbine.services.avaloncomponent;
    002
    003
    004    /*
    005     * Licensed to the Apache Software Foundation (ASF) under one
    006     * or more contributor license agreements.  See the NOTICE file
    007     * distributed with this work for additional information
    008     * regarding copyright ownership.  The ASF licenses this file
    009     * to you under the Apache License, Version 2.0 (the
    010     * "License"); you may not use this file except in compliance
    011     * with the License.  You may obtain a copy of the License at
    012     *
    013     *   http://www.apache.org/licenses/LICENSE-2.0
    014     *
    015     * Unless required by applicable law or agreed to in writing,
    016     * software distributed under the License is distributed on an
    017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018     * KIND, either express or implied.  See the License for the
    019     * specific language governing permissions and limitations
    020     * under the License.
    021     */
    022
    023
    024    import java.util.ArrayList;
    025    import java.util.Iterator;
    026    import java.util.List;
    027
    028    import org.apache.avalon.excalibur.component.DefaultRoleManager;
    029    import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
    030    import org.apache.avalon.excalibur.logger.Log4JLoggerManager;
    031    import org.apache.avalon.excalibur.logger.LoggerManager;
    032    import org.apache.avalon.framework.activity.Disposable;
    033    import org.apache.avalon.framework.activity.Initializable;
    034    import org.apache.avalon.framework.component.Component;
    035    import org.apache.avalon.framework.component.ComponentException;
    036    import org.apache.avalon.framework.configuration.Configuration;
    037    import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
    038    import org.apache.avalon.framework.context.DefaultContext;
    039    import org.apache.avalon.framework.logger.Logger;
    040    import org.apache.avalon.framework.service.ServiceException;
    041    import org.apache.commons.logging.Log;
    042    import org.apache.commons.logging.LogFactory;
    043    import org.apache.turbine.Turbine;
    044    import org.apache.turbine.services.InitializationException;
    045    import org.apache.turbine.services.InstantiationException;
    046    import org.apache.turbine.services.TurbineBaseService;
    047
    048    /**
    049     * An implementation of AvalonComponentService which loads all the
    050     * components given in the TurbineResources.properties File.
    051     * <p>
    052     * For component which require the location of the application or
    053     * context root, there are two ways to get it.
    054     * <ol>
    055     * <li>
    056     *   Implement the Contextualizable interface.  The full path to the
    057     *   correct OS directory can be found under the ComponentAppRoot key.
    058     * </li>
    059     * <li>
    060     *   The system property "applicationRoot" is also set to the full path
    061     *   of the correct OS directory.
    062     * </li>
    063     * </ol>
    064     * If you want to initialize Torque by using the AvalonComponentService, you
    065     * must activate Torque at initialization time by specifying
    066     *
    067     * services.AvalonComponentService.lookup = org.apache.torque.Torque
    068     *
    069     * in your TurbineResources.properties.
    070     *
    071     * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
    072     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    073     * @version $Id: TurbineAvalonComponentService.java 615328 2008-01-25 20:25:05Z tv $
    074     */
    075    public class TurbineAvalonComponentService
    076            extends TurbineBaseService
    077            implements AvalonComponentService, Initializable, Disposable
    078    {
    079        /** Logging */
    080        private static Log log = LogFactory.getLog(
    081                TurbineAvalonComponentService.class);
    082
    083        /** Component manager */
    084        private ExcaliburComponentManager manager = null;
    085
    086        // -------------------------------------------------------------
    087        // Service initialization
    088        // -------------------------------------------------------------
    089
    090        /**
    091         * Load all configured components and initialize them. This is
    092         * a zero parameter variant which queries the Turbine Servlet
    093         * for its config.
    094         *
    095         * @throws InitializationException Something went wrong in the init
    096         *         stage
    097         */
    098        public void init()
    099                throws InitializationException
    100        {
    101            try
    102            {
    103                initialize();
    104
    105                setInit(true);
    106            }
    107            catch (Exception e)
    108            {
    109                throw new InitializationException("init failed", e);
    110            }
    111        }
    112
    113        /**
    114         * Shuts the Component Service down, calls dispose on the components that
    115         * implement this interface
    116         *
    117         */
    118        public void shutdown()
    119        {
    120            dispose();
    121            setInit(false);
    122        }
    123
    124        // -------------------------------------------------------------
    125        // Avalon lifecycle interfaces
    126        // -------------------------------------------------------------
    127
    128        /**
    129         * Initializes the container
    130         *
    131         * @throws Exception generic exception
    132         */
    133        public void initialize() throws Exception
    134        {
    135            org.apache.commons.configuration.Configuration conf
    136                    = getConfiguration();
    137
    138            // get the filenames and expand them relative to webapp root
    139            String sysConfigFilename = Turbine.getRealPath(
    140                    conf.getString(COMPONENT_CONFIG_KEY, COMPONENT_CONFIG_VALUE));
    141            String roleConfigFilename = Turbine.getRealPath(
    142                    conf.getString(COMPONENT_ROLE_KEY, COMPONENT_ROLE_VALUE));
    143
    144            log.debug("Config File: " + sysConfigFilename);
    145            log.debug("Role File:   " + roleConfigFilename);
    146
    147            // process configuration files
    148
    149            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
    150            Configuration sysConfig  = builder.buildFromFile(sysConfigFilename);
    151            Configuration roleConfig = builder.buildFromFile(roleConfigFilename);
    152
    153            // Create the LoggerManager for Log4J
    154            LoggerManager lm = new Log4JLoggerManager();
    155
    156            // Setup the RoleManager
    157            DefaultRoleManager roles = new DefaultRoleManager();
    158
    159            Logger logger = lm.getLoggerForCategory(AVALON_LOG_CATEGORY);
    160
    161            roles.enableLogging(logger);
    162            roles.configure(roleConfig);
    163
    164            // Setup ECM
    165            manager = new ExcaliburComponentManager();
    166
    167            manager.setLoggerManager(lm);
    168            manager.enableLogging(logger);
    169
    170            DefaultContext context = new DefaultContext();
    171            String realPath = Turbine.getRealPath("/");
    172
    173            context.put(AvalonComponentService.COMPONENT_APP_ROOT, realPath);
    174            // urn:avalon:home is used by Merlinized components.  Makes things
    175            // a bit more backwards compatible.
    176            context.put("urn:avalon:home", realPath);
    177            System.setProperty("applicationRoot", realPath);
    178            System.setProperty("urn:avalon:home", realPath);
    179
    180            log.debug("Application Root is " + realPath);
    181
    182            manager.contextualize(context);
    183            manager.setRoleManager(roles);
    184            manager.configure(sysConfig);
    185
    186            // Init ECM!!!!
    187            manager.initialize();
    188
    189            List lookupComponents = conf.getList(COMPONENT_LOOKUP_KEY,
    190                    new ArrayList());
    191
    192            for (Iterator it = lookupComponents.iterator(); it.hasNext();)
    193            {
    194                String component = (String) it.next();
    195                try
    196                {
    197                    Component c = manager.lookup(component);
    198                    log.info("Lookup for Component " + component + " successful");
    199                    manager.release(c);
    200                }
    201                catch (Exception e)
    202                {
    203                    log.error("Lookup for Component " + component + " failed!");
    204                }
    205            }
    206        }
    207
    208        /**
    209         * Disposes of the container and releases resources
    210         */
    211        public void dispose()
    212        {
    213            manager.dispose();
    214        }
    215
    216        /**
    217         * Returns an instance of the named component
    218         *
    219         * @param roleName Name of the role the component fills.
    220         * @return an instance of the named component
    221         * @throws ComponentException generic exception
    222         */
    223        public Object lookup(String roleName)
    224                throws ServiceException
    225        {
    226            try
    227            {
    228                return manager.lookup(roleName);
    229            }
    230            catch (ComponentException e)
    231            {
    232                throw new ServiceException(name, e.getMessage());
    233            }
    234        }
    235
    236        /**
    237         * Releases the component
    238         *
    239         * @param component the component to release
    240         */
    241        public void release(Object component)
    242        {
    243            if( component instanceof Component )
    244            {
    245                manager.release((Component)component);
    246            }
    247        }
    248
    249        /**
    250         * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
    251         */
    252        public boolean hasService(String roleName)
    253        {
    254            return manager.hasComponent(roleName);
    255        }
    256
    257        // -------------------------------------------------------------
    258        // TurbineServiceProvider
    259        // -------------------------------------------------------------
    260
    261        /**
    262         * @see org.apache.turbine.services.TurbineServiceProvider#exists(java.lang.String)
    263         */
    264        public boolean exists(String roleName)
    265        {
    266            return this.hasService(roleName);
    267        }
    268
    269        /**
    270         * @see org.apache.turbine.services.TurbineServiceProvider#get(java.lang.String)
    271         */
    272        public Object get(String roleName) throws InstantiationException
    273        {
    274            try
    275            {
    276                return this.lookup(roleName);
    277            }
    278            catch (ServiceException e)
    279            {
    280                String msg = "Unable to get the following service : " + roleName;
    281                log.error(msg);
    282                throw new InstantiationException(msg);
    283            }
    284            catch (Throwable t)
    285            {
    286                String msg = "Unable to get the following service : " + roleName;
    287                log.error(msg,t);
    288                throw new InstantiationException(msg,t);
    289            }
    290        }
    291    }