/**
* Global Sensor Networks (GSN) Source Code
* Copyright (c) 2006-2016, Ecole Polytechnique Federale de Lausanne (EPFL)
*
* This file is part of GSN.
*
* GSN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GSN 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GSN. If not, see <http://www.gnu.org/licenses/>.
*
* File: src/ch/epfl/gsn/vsensor/ModellingVirtualSensor.java
*
* @author Julien Eberle
*
*/
package ch.epfl.gsn.vsensor;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeMap;
import org.slf4j.LoggerFactory;
import ch.epfl.gsn.beans.StreamElement;
import ch.epfl.gsn.utils.models.AbstractModel;
import ch.epfl.gsn.vsensor.AbstractVirtualSensor;
import ch.epfl.gsn.vsensor.ModellingVirtualSensor;
import org.slf4j.Logger;
/**
* This class is linked to an array of AbstractModels and keep them updated by pushing every StreamElement to them.
* The model classes are defined by their class names separated by "," as a parameter of the VS.
* If a model need some parameters before initializing, they can be specified in the VS parameters as "model.i.param",
* where i is the index of the model and param the parameter name.
* @author jeberle
*
*/
public class ModellingVirtualSensor extends AbstractVirtualSensor {
private static final transient Logger logger = LoggerFactory.getLogger(ModellingVirtualSensor.class);
private static final String PARAM_MODEL_CLASS = "model";
private static final String PARAM_MODEL_PREFIX ="model";
private String[] model;
private AbstractModel[] am;
@Override
public boolean initialize() {
TreeMap<String, String> params = getVirtualSensorConfiguration().getMainClassInitialParams();
//get all the models
String model_str = params.get(PARAM_MODEL_CLASS);
if (model_str == null) {
logger.warn("Parameter \"" + PARAM_MODEL_CLASS + "\" not provided in Virtual Sensor file");
return false;
}
model = model_str.trim().split(",");
am = new AbstractModel[model.length];
for(int i=0;i<model.length;i++){
try {
//instantiate the models, ...
Class<?> fc = Class.forName(model[i]);
am[i] = (AbstractModel) fc.newInstance();
//output structure of the models is the same as the one of the VS
am[i].setOutputFields(getVirtualSensorConfiguration().getOutputStructure());
//...set their parameters...
for (String k: params.navigableKeySet())
{
String prefix = PARAM_MODEL_PREFIX+"."+i+".";
if (k.startsWith(prefix)){
am[i].setParam(k.substring(prefix.length()),params.get(k));
}
}
am[i].setVirtualSensor(this);
//... and initialize them.
if (! am[i].initialize()){
return false;
}
} catch (Exception e) {
logger.error( e.getMessage( ) , e );
return false;
}
}
return true;
}
@Override
public void dispose() {
}
@Override
public void dataAvailable(String inputStreamName, StreamElement streamElement) {
StreamElement[] out = new StreamElement[]{streamElement};
if (am.length > 0){
out = am[0].pushData(streamElement,inputStreamName); //by default returns the result from the first model
}
for(int i=1;i<am.length;i++){
if (am[i] != null){
am[i].pushData(streamElement,inputStreamName);//push the data to all other models too
}
}
if(out != null){
Arrays.sort(out,new Comparator<StreamElement>(){
@Override
public int compare(StreamElement o1, StreamElement o2) {
return Long.valueOf(o1.getTimeStamp()).compareTo(o2.getTimeStamp());
}});
for(int i=0;i<out.length;i++){
if(out[i] != null){
dataProduced(out[i]);
}
}
}
}
/**
* Return the model corresponding to the given index
* @param index of the model
* @return the model if it exists or null if the index is out of bound
*/
public AbstractModel getModel(int index){
if (index>=0 && index <am.length)
return am[index];
else
return null;
}
}