package org.jactr.tools.experiment.dc;
/*
* default logging
*/
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.model.IModel;
import org.jactr.tools.experiment.dc.data.ISubjectDataProvider;
import org.jactr.tools.experiment.dc.data.SubjectData;
/**
* static singleton entry point for getting {@link SubjectData}
*
* @author harrison
*/
public class DataCollector
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(DataCollector.class);
static private DataCollector _default;
static public void set(DataCollector collector)
{
_default = collector;
}
static public DataCollector get()
{
return _default;
}
/**
* create a timestamp subjectId
*
* @return
*/
static public String createSubjectId(long systemTime)
{
return String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS%1$tL", new Date(
systemTime));
}
final private Map<String, SubjectData<?>> _subjectData;
private ISubjectDataProvider<?> _dataProvider;
private File _dataPath;
public DataCollector(ISubjectDataProvider<?> provider)
{
_subjectData = new TreeMap<String, SubjectData<?>>();
setDataProvider(provider);
}
public void setDataProvider(ISubjectDataProvider<?> provider)
{
_dataProvider = provider;
}
public void setDataDirectory(File dir)
{
_dataPath = dir;
}
/**
* @param model
* @return
*/
static public String getSubjectId(IModel model)
{
synchronized (model)
{
String modelId = (String) model.getMetaData("dataCollector.subjectId");
if (modelId == null)
{
modelId = createSubjectId(model.hashCode() + System.currentTimeMillis());
model.setMetaData("dataCollector.subjectId", modelId);
}
return modelId;
}
}
/**
* Get or create the subject data for this model. If the model has
* {@link IModel#getMetaData(String)} "dataCollector.subjectId", it will use
* that string for the subject Id. Otherwise, one will be created (and the
* metadata set). Just call {@link SubjectData#getSubjectId()} to see what it
* is.
*
* @param model
* @param createIfMissing
* @return
*/
synchronized public SubjectData<?> getSubjectData(IModel model,
boolean createIfMissing)
{
String modelId = getSubjectId(model);
return getSubjectData(modelId, createIfMissing);
}
/**
* not thread safe.
*
* @param subjectId
* @param createIfMissing
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
synchronized public SubjectData<?> getSubjectData(String subjectId,
boolean createIfMissing)
{
SubjectData<?> data = _subjectData.get(subjectId);
if (data == null && createIfMissing)
{
data = new SubjectData(subjectId, new File(_dataPath, subjectId),
_dataProvider, _dataProvider.newData());
_dataProvider.newSubject(data);
_subjectData.put(subjectId, data);
}
return data;
}
synchronized public SubjectData<?> removeSubjectData(String subjectId)
{
return _subjectData.remove(subjectId);
}
synchronized public void clear()
{
_subjectData.clear();
}
}