/** * 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; } }