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