/*
* Created on Aug 14, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version. This library is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jactr.core.module;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.buffer.IActivationBuffer;
import org.jactr.core.concurrent.ExecutorServices;
import org.jactr.core.model.IModel;
public abstract class AbstractModule implements IModule
{
/**
* logger definition
*/
static public final Log LOGGER = LogFactory.getLog(AbstractModule.class);
private IModel _model;
private String _name;
private Executor _executor = ExecutorServices.INLINE_EXECUTOR;
public AbstractModule(String name)
{
_name = name;
}
/**
* @param executor
*/
protected void setExecutor(Executor executor)
{
_executor = executor;
}
/**
* default executor INLINE_EXECUTOR is used
*
* @return
*/
public Executor getExecutor()
{
return _executor;
}
public void dispose()
{
_model = null;
}
public IModel getModel()
{
return _model;
}
public String getName()
{
return _name;
}
public void install(IModel model)
{
_model = model;
for (IActivationBuffer buffer : createBuffers())
_model.addActivationBuffer(buffer);
}
/**
* called to create any buffers used by this buffer. They will be installed
* into the model by the install(IModel) call
*
* @return
*/
protected Collection<IActivationBuffer> createBuffers()
{
return Collections.EMPTY_LIST;
}
public void uninstall(IModel model)
{
_model = null;
}
abstract public void initialize();
/**
* return a safe, noncolliding name - calls to this should make sure that the
* map is readlocked
*
* @param name
* @param mapping
* @return
*/
protected String getSafeName(String name, Map<String, ?> mapping)
{
if (!mapping.containsKey(name.toLowerCase())) return name;
// does the oldName match the name-# pattern
int lastIndex = -1;
if ((lastIndex = name.lastIndexOf("-")) != -1)
{
String snippet = name.substring(lastIndex + 1, name.length());
try
{
/*
* if snippet is a number, we cut it off
*/
Integer.parseInt(snippet);
name = name.substring(0, lastIndex);
}
catch (NumberFormatException nfe)
{
}
}
StringBuilder sb = new StringBuilder(name);
if (sb.charAt(sb.length() - 1) != '-') sb.append("-");
sb.append(mapping.size());
String rtn = sb.toString();
return rtn;
}
static public <T> Future<T> immediateReturn(T value)
{
FutureTask<T> ft = new FutureTask<T>(new Runnable() {
public void run()
{
// noop
}
}, value);
ft.run();
return ft;
}
/**
* create a future task and execute it immediately using the INLINE_EXECUTOR
*
* @param <T>
* @param caller
* @return
*/
static public <T> Future<T> immediateFuture(Callable<T> caller)
{
return delayedFuture(caller, ExecutorServices.INLINE_EXECUTOR);
}
/**
* create a future task and execute it on the exector
*
* @param <T>
* @param caller
* @param executor
* @return
*/
static public <T> Future<T> delayedFuture(Callable<T> caller,
Executor executor)
{
FutureTask<T> future = new FutureTask<T>(caller);
if (executor != null) executor.execute(future);
else
future.run();
return future;
}
}