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    }