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 }