import com.mongodb.MongoInterruptedException;import com.mongodb.MongoTimeoutException;import org.bson.Document;import org.reactivestreams.Subscriber;import org.reactivestreams.Subscription;import java.util.ArrayList;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;import java.util.function.Consumer;importstatic java.lang.String.format;/**
* Subscriber helper implementations for the Quick Tour.
*/publicfinalclassSubscriberHelpers{/**
* A Subscriber that stores the publishers results and provides a latch so can block on completion.
*
* @param <T> The publishers result type
*/publicabstractstaticclassObservableSubscriber<T>implementsSubscriber<T>{privatefinal List<T> received;privatefinal List<RuntimeException> errors;privatefinal CountDownLatch latch;privatevolatile Subscription subscription;privatevolatileboolean completed;/**
* Construct an instance
*/publicObservableSubscriber(){this.received =newArrayList<>();this.errors =newArrayList<>();this.latch =newCountDownLatch(1);}@OverridepublicvoidonSubscribe(final Subscription s){
subscription = s;}@OverridepublicvoidonNext(final T t){
received.add(t);}@OverridepublicvoidonError(final Throwable t){if(t instanceofRuntimeException){
errors.add((RuntimeException) t);}else{
errors.add(newRuntimeException("Unexpected exception", t));}onComplete();}@OverridepublicvoidonComplete(){
completed =true;
latch.countDown();}/**
* Gets the subscription
*
* @return the subscription
*/public Subscription getSubscription(){return subscription;}/**
* Get received elements
*
* @return the list of received elements
*/public List<T>getReceived(){return received;}/**
* Get error from subscription
*
* @return the error, which may be null
*/public RuntimeException getError(){if(errors.size()>0){return errors.get(0);}return null;}/**
* Get received elements.
*
* @return the list of receive elements
*/public List<T>get(){returnawait().getReceived();}/**
* Get received elements.
*
* @param timeout how long to wait
* @param unit the time unit
* @return the list of receive elements
*/public List<T>get(finallong timeout,final TimeUnit unit){returnawait(timeout, unit).getReceived();}/**
* Await completion or error
*
* @return this
*/public ObservableSubscriber<T>await(){returnawait(60, TimeUnit.SECONDS);}/**
* Await completion or error
*
* @param timeout how long to wait
* @param unit the time unit
* @return this
*/public ObservableSubscriber<T>await(finallong timeout,final TimeUnit unit){
subscription.request(Integer.MAX_VALUE);try{if(!latch.await(timeout, unit)){thrownewMongoTimeoutException("Publisher onComplete timed out");}}catch(InterruptedException e){thrownewMongoInterruptedException("Interrupted waiting for observeration", e);}if(!errors.isEmpty()){throw errors.get(0);}returnthis;}}/**
* A Subscriber that immediately requests Integer.MAX_VALUE onSubscribe
* 添加,更新,删除订阅
* @param <T> The publishers result type
*/publicstaticclassOperationSubscriber<T>extendsObservableSubscriber<T>{@OverridepublicvoidonSubscribe(final Subscription s){super.onSubscribe(s);
s.request(Integer.MAX_VALUE);}}/**
* A Subscriber that prints a message including the received items on completion
* 打印总记录数
* @param <T> The publishers result type
*/publicstaticclassPrintSubscriber<T>extendsOperationSubscriber<T>{privatefinal String message;/**
* A Subscriber that outputs a message onComplete.
*
* @param message the message to output onComplete
*/publicPrintSubscriber(final String message){this.message = message;}@OverridepublicvoidonComplete(){
System.out.println(format(message,getReceived()));super.onComplete();}}/**
* A Subscriber that prints the json version of each document
* 查询集合订阅
*/publicstaticclassPrintDocumentSubscriberextendsConsumerSubscriber<Document>{/**
* Construct a new instance
*/publicPrintDocumentSubscriber(){super(t -> System.out.println(t.toJson()));}}/**
* A Subscriber that prints the toString version of each element
* @param <T> the type of the element
*/publicstaticclassPrintToStringSubscriber<T>extendsConsumerSubscriber<T>{/**
* Construct a new instance
*/publicPrintToStringSubscriber(){super(System.out::println);}}/**
* A Subscriber that processes a consumer for each element
* @param <T> the type of the element
*/publicstaticclassConsumerSubscriber<T>extendsOperationSubscriber<T>{privatefinal Consumer<T> consumer;/**
* Construct a new instance
* @param consumer the consumer
*/publicConsumerSubscriber(final Consumer<T> consumer){this.consumer = consumer;}@OverridepublicvoidonNext(final T document){super.onNext(document);
consumer.accept(document);}}privateSubscriberHelpers(){}}