/***************************************************************************** | |
* Copyright (c) 2016 CEA LIST. | |
* | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* David LOPEZ BETANCUR (CEA LIST) | |
* Sebastien REVOL (CEA LIST) | |
* | |
*****************************************************************************/ | |
package org.eclipse.papyrus.moka.datavisualization.service; | |
import java.util.ArrayList; | |
import java.util.List; | |
import org.eclipse.papyrus.infra.core.services.IService; | |
import org.eclipse.papyrus.infra.core.services.ServiceException; | |
import org.eclipse.papyrus.infra.core.services.ServicesRegistry; | |
import org.eclipse.papyrus.moka.datavisualization.profile.BooleanSeries; | |
import org.eclipse.papyrus.moka.datavisualization.profile.DataSource; | |
import org.eclipse.papyrus.moka.datavisualization.profile.DoubleSeries; | |
import org.eclipse.papyrus.moka.datavisualization.profile.IntegerSeries; | |
import org.eclipse.papyrus.moka.datavisualization.profile.ValueSeries; | |
import org.eclipse.papyrus.moka.datavisualization.profile.VisualizationPackage; | |
import org.eclipse.papyrus.moka.datavisualization.ui.GraphBuilderHelper; | |
import org.eclipse.papyrus.moka.xygraph.mapping.common.Variable; | |
import org.eclipse.papyrus.moka.xygraph.mapping.common.Variable.VariableID; | |
import org.eclipse.papyrus.moka.xygraph.mapping.util.DataBatch; | |
public class DataVisualizationService implements IService{ | |
private List<DataPort> dataPorts; | |
private VariableEntryTable<VariableEntry> varTable; | |
private DataVisualizationService(){ | |
dataPorts = new ArrayList<>(); | |
varTable = new VariableEntryTable<>(); | |
} | |
private static DataVisualizationService instance = new DataVisualizationService(); | |
public static DataVisualizationService getInstance(){ | |
return instance; | |
} | |
public void registerUnlinkedVariable(Variable v){ | |
if( hasVariable(v) ) | |
return; | |
varTable.addEntryFor(v.getID(), new VariableDataEntry(v)); | |
} | |
public boolean hasVariable(Variable var){ | |
return hasVariable(var.getID()); | |
} | |
private boolean hasVariable(VariableID id){ | |
return varTable.hasVariable(id); | |
} | |
public void addDataPort(DataPort port){ | |
if( dataPorts.contains(port) ) | |
return; | |
dataPorts.add(port); | |
} | |
private VariableDataEntry getEntry(VariableID vID){ | |
return (VariableDataEntry) varTable.getEntry(vID); | |
} | |
public Variable makeIndependentVariable(ValueSeries independentSeries){ | |
return new VariableImpl(independentSeries.getBase_Property().getLabel(), new DataSourceVariableID(independentSeries)); | |
} | |
public Variable makeDependentVariable(ValueSeries depSeries, Variable independent){ | |
return new VariableImpl(depSeries.getBase_Property().getLabel(), new DataSourceVariableID(depSeries), independent); | |
} | |
public void setVariableBatch( Variable var, DataBatch batch){ | |
getEntry(var.getID()).setData(batch); | |
} | |
public List<Variable> importNewDataValueSet(DataSource set){ | |
ArrayList<Variable> contained = new ArrayList<>(); | |
ArrayList<ValueSeries> independent = new ArrayList<>(); | |
ArrayList<ValueSeries> dependent = new ArrayList<>(); | |
GraphBuilderHelper.separateValueSeries( set.getSeries(), independent, dependent ); | |
if( independent.size() == 0 ) | |
return contained; | |
ValueSeries independentSeries = independent.get(0); | |
//1. Check the independent variables. | |
//For the moment we are adding a new series only if it wasn't previously. | |
if( getVariable(independentSeries) == null ){ | |
//For the moment only 1 is supported. | |
Variable iVar = makeIndependentVariable(independentSeries); | |
//1.1. Add the independent variables. | |
registerUnlinkedVariable(iVar); | |
setVariableBatch(iVar, getDataFromValueSeries(independentSeries) ); | |
} | |
//2. Add the dependent variables. | |
for( ValueSeries dep : dependent ){ | |
//if it's already a contained variable, ignore it. | |
if( getEntryFromSerie(dep) != null ) | |
continue; | |
Variable in = getEntryFromSerie(dep.getDependent()).getVariable(); | |
//TODO Formally validate this before this method | |
//Assert.isNotNull(in, "The independent series for " + dep.getBase_Property().getLabel() + " is not in the dataset"); | |
//Assert.isTrue( !in.isIndependent(), "The independent series for " + dep.getBase_Property() + " is not independent"); | |
Variable dVar = makeDependentVariable( dep, in ); | |
registerUnlinkedVariable(dVar); | |
setVariableBatch(dVar, getDataFromValueSeries(dep) ); | |
} | |
return contained; | |
} | |
private VariableEntry getEntryFromSerie(ValueSeries dependent) { | |
DataSourceVariableID dsID = new DataSourceVariableID(dependent); | |
return getEntry(dsID); | |
} | |
public void updateVariableData(Variable v, DataBatch values) { | |
VariableDataEntry entry = getEntry(v.getID()); | |
entry.setData(values); | |
} | |
public void flushData(){ | |
for( DataPort port : dataPorts ) | |
pullAllData( port ); | |
} | |
public void flushVariable(Variable v){ | |
for( DataPort port : dataPorts ) | |
if( !v.isIndependent() && port.getSupportedVariableIDs().contains(v.getID()) ) | |
flushVariableToPort(getEntry(v.getID()), port); | |
} | |
private void flushVariableToPort(VariableDataEntry entry, DataPort port) { | |
if( entry.getVariable().isIndependent() ) | |
return; | |
Variable v = entry.getVariable(); | |
VariableDataEntry indepEntry = getEntry(v.getDependsOn().getID()); | |
long portLastUpdate = port.getLastUpdate(v.getID()); | |
if( portLastUpdate < indepEntry.getLastUpdate() ){ | |
port.resetValues(v.getID(), indepEntry.getValuesBatch(), entry.getValuesBatch()); | |
} | |
} | |
public void pullAllData(DataPort port){ | |
for( VariableID vId : port.getSupportedVariableIDs() ){ | |
VariableDataEntry entry = getEntry(vId); | |
flushVariableToPort(entry, port); | |
} | |
} | |
public static DataBatch getDataFromValueSeries(ValueSeries serie){ | |
switch (serie.eClass().getClassifierID()){ | |
case VisualizationPackage.BOOLEAN_SERIES : | |
return DataBatch.fromBoolean( ((BooleanSeries) serie).getValues() ); | |
case VisualizationPackage.INTEGER_SERIES : | |
return DataBatch.fromInteger( ((IntegerSeries) serie).getValues() ); | |
case VisualizationPackage.DOUBLE_SERIES : | |
return DataBatch.fromDouble( ((DoubleSeries) serie).getValues() ); | |
default : | |
//TODO This case is not implemented | |
return DataBatch.dummy(); | |
} | |
} | |
@Override | |
public void init(ServicesRegistry servicesRegistry) throws ServiceException { | |
} | |
@Override | |
public void startService() throws ServiceException { | |
} | |
@Override | |
public void disposeService() throws ServiceException { | |
//TODO Dispose all dataPorts ? | |
} | |
//TODO This should be done automatically at the DataSource instantiation. | |
public void fixDependencies(DataSource dataSource) { | |
ValueSeries dep = null; | |
for(ValueSeries serie : dataSource.getSeries()) | |
if( "time".equalsIgnoreCase(serie.getBase_Property().getLabel()) ){ | |
dep = serie; | |
break; | |
} | |
for(ValueSeries serie : dataSource.getSeries()){ | |
if( "time".equalsIgnoreCase(serie.getBase_Property().getLabel()) ){ | |
continue; | |
} | |
serie.setDependent(dep); | |
} | |
} | |
public Variable getVariable(ValueSeries series){ | |
VariableEntry entry = varTable.getEntry(new DataSourceVariableID(series)); | |
if( entry == null ) | |
return null; | |
return entry.getVariable(); | |
} | |
public void removeDataPort(DataPort port) { | |
dataPorts.remove(port); | |
} | |
} |