package info.limpet.ui.stacked; import info.limpet.IBaseQuantityCollection; import info.limpet.IChangeListener; import info.limpet.ICollection; import info.limpet.IStoreGroup; import info.limpet.IStoreItem; import info.limpet.ITemporalQuantityCollection; import info.limpet.data.impl.QuantityCollection; import info.limpet.data.impl.TemporalQuantityCollection; import info.limpet.stackedcharts.model.DataItem; import info.limpet.stackedcharts.model.Dataset; import info.limpet.stackedcharts.model.Datum; import info.limpet.stackedcharts.model.ScatterSet; import info.limpet.stackedcharts.model.impl.StackedchartsFactoryImpl; import info.limpet.stackedcharts.ui.view.adapter.IStackedDatasetAdapter; import info.limpet.stackedcharts.ui.view.adapter.IStackedScatterSetAdapter; import info.limpet.ui.data_provider.data.CollectionWrapper; import info.limpet.ui.data_provider.data.GroupWrapper; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.measure.Measurable; import javax.measure.quantity.Duration; import javax.measure.quantity.Quantity; import javax.measure.unit.Unit; public class LimpetStackedChartsAdapter implements IStackedDatasetAdapter, IStackedScatterSetAdapter { protected static class CollectionChangeListener implements IChangeListener { private final TemporalQuantityCollection<Quantity> _collection; private final Dataset _dataset; public CollectionChangeListener( TemporalQuantityCollection<Quantity> collection, Dataset subject) { _dataset = subject; _collection = collection; _collection.addChangeListener(this); } @Override public void dataChanged(IStoreItem subject) { StackedchartsFactoryImpl factory = new StackedchartsFactoryImpl(); // ok, repopulate the dataset populateDataset(factory, _collection, _dataset); } @Override public void metadataChanged(IStoreItem subject) { // ignore metadata change } @Override public void collectionDeleted(IStoreItem subject) { _collection.removeChangeListener(this); } } protected static void populateDataset( final StackedchartsFactoryImpl factory, final TemporalQuantityCollection<Quantity> tqc, final Dataset dataset) { // get ready to store the data dataset.setName(tqc.getName() + "(" + tqc.getUnits() + ")"); // and the units dataset.setUnits(tqc.getUnits().toString()); // clear the dataset dataset.getMeasurements().clear(); final Unit<Quantity> hisUnits = tqc.getUnits(); Iterator<Long> times = tqc.getTimes().iterator(); Iterator<?> values = tqc.getValues().iterator(); while (times.hasNext()) { long thisTime = times.next(); @SuppressWarnings("unchecked") final Measurable<Quantity> meas = (Measurable<Quantity>) values .next(); final DataItem item = factory.createDataItem(); item.setIndependentVal(thisTime); final Double value = meas.doubleValue(hisUnits); item.setDependentVal(value); // and store it dataset.getMeasurements().add(item); } } @SuppressWarnings({ "unchecked" }) @Override public List<Dataset> convertToDataset(Object data) { List<Dataset> res = null; // we should have already checked, but just // double-check we can handle it if (canConvertToDataset(data)) { final StackedchartsFactoryImpl factory = new StackedchartsFactoryImpl(); // have a look at the type if (data instanceof CollectionWrapper) { CollectionWrapper cw = (CollectionWrapper) data; ICollection collection = cw.getCollection(); if (collection.isQuantity() && collection.isTemporal()) { TemporalQuantityCollection<Quantity> qq = (TemporalQuantityCollection<Quantity>) collection; final Dataset dataset = factory.createDataset(); populateDataset(factory, qq, dataset); // ok, register a listener for collection changes @SuppressWarnings("unused") CollectionChangeListener newListener = new CollectionChangeListener( qq, dataset); // have we got a results object yet? if (res == null) { res = new ArrayList<Dataset>(); } // give it some style dataset.setStyling(factory.createPlainStyling()); res.add(dataset); } } else if (data instanceof GroupWrapper) { GroupWrapper groupW = (GroupWrapper) data; IStoreGroup group = groupW.getGroup(); Iterator<IStoreItem> cIter = group.iterator(); while (cIter.hasNext()) { IStoreItem thisI = (IStoreItem) cIter.next(); if (thisI instanceof ICollection) { ICollection thisC = (ICollection) thisI; if (thisC.isQuantity() && thisC.isTemporal()) { List<Dataset> newItems = convertToDataset(thisC); if (newItems != null && newItems.size() > 0) { if (res == null) { res = new ArrayList<Dataset>(); } res.addAll(newItems); } } } } } else if (data instanceof ICollection) { ICollection coll = (ICollection) data; if (coll.isQuantity() && coll.isTemporal()) { Dataset dataset = factory.createDataset(); populateDataset(factory, (TemporalQuantityCollection<Quantity>) coll, dataset); // setup the listener TemporalQuantityCollection<Quantity> tempColl = (TemporalQuantityCollection<Quantity>) coll; @SuppressWarnings("unused") CollectionChangeListener listener = new CollectionChangeListener( tempColl, dataset); // give it some style dataset.setStyling(factory.createPlainStyling()); // collate the results if (res == null) { res = new ArrayList<Dataset>(); } res.add(dataset); } } else if (data instanceof List) { List<?> list = (List<?>) data; for (Object item : list) { List<Dataset> items = convertToDataset(item); if (items != null) { if (res == null) { res = new ArrayList<Dataset>(); } res.addAll(items); } } } } return res; } @Override public boolean canConvertToDataset(Object data) { boolean res = false; // have a look at the type if (data instanceof CollectionWrapper) { CollectionWrapper cw = (CollectionWrapper) data; ICollection collection = cw.getCollection(); if (collection.isQuantity() && collection.isTemporal()) { res = true; } else if (collection.isQuantity() && !collection.isTemporal()) { // check if its' a series of timestampes IBaseQuantityCollection<?> qc = (IBaseQuantityCollection<?>) collection; Unit<?> units = qc.getUnits(); if (units.equals(Duration.UNIT)) { res = true; } } } else if (data instanceof GroupWrapper) { res = true; } else if (data instanceof ITemporalQuantityCollection<?>) { res = true; } else if (data instanceof List) { List<?> list = (List<?>) data; for (Object item : list) { boolean thisRes = canConvertToDataset(item); if (!thisRes) { break; } } res = true; } return res; } @SuppressWarnings({ "unchecked" }) @Override public List<ScatterSet> convertToScatterSet(Object data) { List<ScatterSet> res = null; // we should have already checked, but just // double-check we can handle it if (canConvertToScatterSet(data)) { final StackedchartsFactoryImpl factory = new StackedchartsFactoryImpl(); // have a look at the type if (data instanceof CollectionWrapper) { CollectionWrapper cw = (CollectionWrapper) data; ICollection collection = cw.getCollection(); if (collection.isQuantity() && !collection.isTemporal()) { // check if its' a series of timestampes QuantityCollection<?> qc = (QuantityCollection<?>) collection; Unit<?> units = qc.getUnits(); if (units.equals(Duration.UNIT)) { // ok, create scatter set if (qc.getValuesCount() > 0) { ScatterSet scatter = factory.createScatterSet(); scatter.setName(qc.getName()); final List<?> values = qc.getValues(); for (Object value : values) { Measurable<Duration> val = (Measurable<Duration>) value; double time = val .doubleValue((Unit<Duration>) qc .getUnits()); Datum datum = factory.createDatum(); datum.setVal(time); scatter.getDatums().add(datum); } // do we have a results store? if (res == null) { res = new ArrayList<ScatterSet>(); } // ok, store it res.add(scatter); } } } // now store the data // hook up listener } else if (data instanceof List) { List<?> list = (List<?>) data; for (Object item : list) { List<ScatterSet> items = convertToScatterSet(item); if (items != null) { if (res == null) { res = new ArrayList<ScatterSet>(); } res.addAll(items); } } } } return res; } @Override public boolean canConvertToScatterSet(Object data) { boolean res = false; // have a look at the type if (data instanceof CollectionWrapper) { CollectionWrapper cw = (CollectionWrapper) data; ICollection collection = cw.getCollection(); if (collection.isQuantity() && !collection.isTemporal()) { // check if its' a series of timestampes IBaseQuantityCollection<?> qc = (IBaseQuantityCollection<?>) collection; Unit<?> units = qc.getUnits(); if (units.equals(Duration.UNIT)) { res = true; } } } else if (data instanceof List) { List<?> list = (List<?>) data; for (Object item : list) { boolean thisRes = canConvertToScatterSet(item); if (!thisRes) { break; } } res = true; } return res; } }