blob: e936f7be4215353b809c012179a7fd5408dfa5e3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.components.language.generator;
import org.apache.avalon.excalibur.component.ComponentHandler;
import org.apache.avalon.excalibur.component.ExcaliburComponentSelector;
import org.apache.avalon.excalibur.component.LogkitLoggerManager;
import org.apache.avalon.excalibur.component.RoleManager;
import org.apache.avalon.excalibur.logger.LogKitManager;
import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.context.Context;
import org.apache.cocoon.Constants;
import org.apache.cocoon.components.classloader.ClassLoaderManager;
import org.apache.cocoon.components.language.programming.Program;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* This interface is the common base of all Compiled Components. This
* includes Sitemaps and XSP Pages
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
* @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
* @version $Id$
*/
public class GeneratorSelector extends ExcaliburComponentSelector {
public final static String ROLE = "org.apache.cocoon.components.language.generator.ServerPages";
private ClassLoaderManager classManager;
/** The component manager */
protected ComponentManager manager;
private LogkitLoggerManager logKitManager;
protected Context context;
protected RoleManager roles;
protected Map componentHandlers = new HashMap();
/** Dynamic component handlers mapping. */
private Map componentMapping = new ConcurrentHashMap();
public void contextualize(Context context) {
super.contextualize(context);
this.context = context;
}
public void setRoleManager(RoleManager roleMgr) {
super.setRoleManager(roleMgr);
this.roles = roleMgr;
}
/**
* Configure the LogKitManager
*/
public void setLogKitManager( final LogKitManager logkit ) {
super.setLogKitManager(logkit);
if( null == this.logKitManager ) {
this.logKitManager = new LogkitLoggerManager( null, logkit );
}
}
/**
* Configure the LoggerManager.
*/
public void setLoggerManager( final LoggerManager logkit ) {
super.setLoggerManager(logkit);
if( null == this.logKitManager ) {
this.logKitManager = new LogkitLoggerManager( logkit, null );
}
}
public void compose(ComponentManager manager) throws ComponentException {
super.compose(manager);
this.manager = manager;
try {
this.classManager = (ClassLoaderManager) manager.lookup(ClassLoaderManager.ROLE);
} catch (ComponentException cme) {
throw new ComponentException(ClassLoaderManager.ROLE, "GeneratorSelector", cme);
}
try {
this.classManager.addDirectory((File) this.m_context.get(Constants.CONTEXT_WORK_DIR));
} catch (Exception e) {
throw new ComponentException(ROLE, "Could not add repository to ClassLoaderManager", e);
}
}
public Component select(Object hint) throws ComponentException {
ComponentHandler handler = (ComponentHandler) this.componentHandlers.get(hint);
if (handler == null) {
throw new ComponentException(ROLE, "Could not find component for hint: " + hint);
}
try {
Component component = handler.get();
componentMapping.put(component, handler);
return component;
} catch (Exception ce) {
if (getLogger().isDebugEnabled())
getLogger().debug("Could not access component for hint: " + hint, ce);
throw new ComponentException(ROLE, "Could not access component for hint: " + hint, ce);
}
}
public void release(Component component) {
ComponentHandler handler = (ComponentHandler)componentMapping.remove(component);
if (handler != null) {
try {
handler.put(component);
} catch (Exception e) {
getLogger().error("Error trying to release component", e);
}
}
}
public void addGenerator(ComponentManager newManager,
Object hint, Program generator)
throws Exception {
try {
final ComponentHandler handler =
generator.getHandler(newManager, this.context, this.roles, this.logKitManager);
handler.enableLogging(getLogger());
handler.initialize();
this.componentHandlers.put(hint, handler);
if (getLogger().isDebugEnabled()) {
getLogger().debug("Adding " + generator.getName() + " for " + hint);
}
} catch(final Exception e) {
// Error will be logged by caller. This is for debug only
if (getLogger().isDebugEnabled()) {
getLogger().debug("Could not set up Component for hint: " + hint, e);
}
throw e;
}
}
public void removeGenerator(Object hint) {
ComponentHandler handler = (ComponentHandler) this.componentHandlers.remove(hint);
if (handler != null) {
handler.dispose();
this.classManager.reinstantiate();
if (getLogger().isDebugEnabled()) {
getLogger().debug("Removing " + handler.getClass().getName() + " for " + hint.toString());
}
}
}
public void dispose() {
this.manager.release(this.classManager);
synchronized(this) {
Iterator keys = this.componentHandlers.keySet().iterator();
List keyList = new ArrayList();
while(keys.hasNext()) {
Object key = keys.next();
ComponentHandler handler =
(ComponentHandler)this.componentHandlers.get(key);
handler.dispose();
keyList.add(key);
}
keys = keyList.iterator();
while(keys.hasNext()) {
this.componentHandlers.remove(keys.next());
}
keyList.clear();
}
super.dispose();
}
}