Last active
November 21, 2017 08:16
-
-
Save heruan/460792a6f701d992efbf3b475711adf6 to your computer and use it in GitHub Desktop.
Transactional DataCommunicator and Grid for Flow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.function.Predicate; | |
import java.util.function.Supplier; | |
import java.util.stream.Stream; | |
import com.vaadin.data.provider.AbstractBackEndDataProvider; | |
import com.vaadin.data.provider.Query; | |
public class StreamDataProvider<T> extends AbstractBackEndDataProvider<T, Predicate<T>> { | |
private final Supplier<Stream<T>> streamSupplier; | |
public StreamDataProvider(Supplier<Stream<T>> streamSupplier) { | |
this.streamSupplier = streamSupplier; | |
} | |
@Override | |
protected Stream<T> fetchFromBackEnd(Query<T, Predicate<T>> query) { | |
Stream<T> stream = this.streamSupplier.get(); | |
if (query.getFilter().isPresent()) { | |
stream = stream.filter(query.getFilter().get()); | |
} | |
return stream.skip(query.getOffset()).limit(query.getLimit()); | |
} | |
@Override | |
protected int sizeInBackEnd(Query<T, Predicate<T>> query) { | |
Stream<T> stream = this.streamSupplier.get(); | |
if (query.getFilter().isPresent()) { | |
stream = stream.filter(query.getFilter().get()); | |
} | |
long count = stream.skip(query.getOffset()).limit(query.getLimit()).count(); | |
return Math.toIntExact(count); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
import org.springframework.transaction.PlatformTransactionManager; | |
import org.springframework.transaction.support.TransactionTemplate; | |
import com.vaadin.data.provider.ArrayUpdater; | |
import com.vaadin.data.provider.DataCommunicator; | |
import com.vaadin.data.provider.DataGenerator; | |
import com.vaadin.flow.StateNode; | |
import com.vaadin.function.SerializableConsumer; | |
import elemental.json.JsonArray; | |
public class TransactionalDataCommunicator<T> extends DataCommunicator<T> { | |
private final TransactionTemplate transactionTemplate; | |
public TransactionalDataCommunicator(PlatformTransactionManager transactionManager, DataGenerator<T> dataGenerator, | |
ArrayUpdater arrayUpdater, SerializableConsumer<JsonArray> dataUpdater, StateNode stateNode) { | |
super(dataGenerator, arrayUpdater, dataUpdater, stateNode); | |
this.transactionTemplate = new TransactionTemplate(transactionManager); | |
this.transactionTemplate.setReadOnly(true); | |
} | |
@Override | |
protected Stream<T> fetchFromProvider(int offset, int limit) { | |
// Collecting the stream here since DataCommunicator::activate is | |
// private, therefore it cannot be made transacitonal | |
return this.transactionTemplate | |
.execute(status -> super.fetchFromProvider(offset, limit).collect(Collectors.toList()).stream()); | |
} | |
@Override | |
protected int getDataProviderSize() { | |
return this.transactionTemplate.execute(status -> super.getDataProviderSize()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import java.util.Optional; | |
import org.springframework.transaction.PlatformTransactionManager; | |
import com.vaadin.data.provider.ArrayUpdater; | |
import com.vaadin.data.provider.DataCommunicator; | |
import com.vaadin.data.provider.DataGenerator; | |
import com.vaadin.ui.grid.Grid; | |
public class TransactionalGrid<T> extends Grid<T> { | |
private final DataCommunicator<T> transactionalDataCommunicator; | |
public TransactionalGrid(PlatformTransactionManager transactionManager) { | |
this.transactionalDataCommunicator = this.createDataCommunicator(transactionManager); | |
this.transactionalDataCommunicator.setRequestedRange(0, this.getPageSize()); | |
} | |
@Override | |
public DataCommunicator<T> getDataCommunicator() { | |
// Needed because getDataCommunicator() is called by the super | |
// constructor, therefore at that moment the transactional one isn't | |
// built yet | |
return Optional.ofNullable(this.transactionalDataCommunicator).orElseGet(super::getDataCommunicator); | |
} | |
@SuppressWarnings("unchecked") | |
private DataCommunicator<T> createDataCommunicator(PlatformTransactionManager transactionManager) { | |
try { | |
Field dataGeneratorField = Grid.class.getDeclaredField("gridDataGenerator"); | |
Field arrayUpdaterfield = Grid.class.getDeclaredField("arrayUpdater"); | |
dataGeneratorField.setAccessible(true); | |
arrayUpdaterfield.setAccessible(true); | |
DataGenerator<T> dataGenerator = (DataGenerator<T>) dataGeneratorField.get(this); | |
ArrayUpdater arrayUpdater = (ArrayUpdater) arrayUpdaterfield.get(this); | |
return new TransactionalDataCommunicator<>(transactionManager, dataGenerator, arrayUpdater, | |
data -> this.getElement().callFunction("$connector.updateData", data), this.getElement().getNode()); | |
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment