com.mastfrog.asyncpromises.mongo.FindBuilderImpl Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright 2015 Tim Boudreau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.mastfrog.asyncpromises.mongo;
import com.mastfrog.asyncpromises.AsyncPromise;
import com.mastfrog.asyncpromises.Logic;
import com.mastfrog.asyncpromises.PromiseContext;
import com.mastfrog.asyncpromises.PromiseContext.Key;
import com.mastfrog.asyncpromises.Trigger;
import com.mongodb.CursorType;
import com.mongodb.async.client.FindIterable;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
import org.bson.conversions.Bson;
/**
*
* @author Tim Boudreau
*/
final class FindBuilderImpl implements FindBuilder {
private int batchSize;
private Bson projection;
private CursorType cursorType;
private int limit = 0;
private Bson filter;
private Bson modifiers;
private Bson sort;
private long maxTime = 0;
private TimeUnit unit;
private final Factory factory;
public static final Key QUERY_KEY = PromiseContext.newKey(Bson.class);
FindBuilderImpl(Factory promises) {
this.factory = promises;
}
static FindBuilderImpl create(CollectionPromises promises) {
checkNull("promises", promises);
return new FindBuilderImpl<>(new StandardFactory<>(promises));
}
static FindBuilderImpl create(CollectionPromises promises, Bson query) {
checkNull("promises", promises);
checkNull("query", query);
return new FindBuilderImpl<>(new VoidFactory(promises, query));
}
@Override
public ProjectionBuilder> projection() {
return new ProjectionBuilderImpl<>(new ProjectionBuilderImpl.Factory>(){
@Override
public FindBuilder build(Document projection) {
FindBuilderImpl.this.projection = projection;
return FindBuilderImpl.this;
}
});
}
static class VoidFactory implements Factory {
private final Factory standard;
private final Bson query;
public VoidFactory(CollectionPromises promises, Bson query) {
this(new StandardFactory<>(promises), query);
}
public VoidFactory(Factory standard, Bson query) {
this.standard = standard;
this.query = query;
}
@Override
public AsyncPromise findOne(FindBuilderImpl builder) {
return AsyncPromise.create(new Logic() {
@Override
public void run(Void data, Trigger next, PromiseContext context) throws Exception {
context.put(QUERY_KEY, query);
next.trigger(query, null);
}
}).then(standard.findOne(builder));
}
@Override
public Factory withType(Class type) {
return new VoidFactory(standard.withType(type), query);
}
@Override
public AsyncPromise find(FindBuilderImpl builder, FindReceiver> logic) {
return AsyncPromise.create(new Logic() {
@Override
public void run(Void data, Trigger next, PromiseContext context) throws Exception {
context.put(QUERY_KEY, query);
next.trigger(query, null);
}
}).then(standard.find(builder, logic));
}
}
static class StandardFactory implements Factory {
private final CollectionPromises promises;
public StandardFactory(CollectionPromises promises) {
checkNull("promises", promises);
this.promises = promises;
}
@Override
public AsyncPromise find(FindBuilderImpl builder, FindReceiver> logic) {
checkNull("logic", logic);
AsyncPromise> result = promises.find(builder, logic);
return result.then(new Logic, Void>() {
@Override
public void run(List data, Trigger next, PromiseContext context) throws Exception {
next.trigger(null, null);
}
});
}
@Override
public AsyncPromise findOne(FindBuilderImpl builder) {
return promises.findOne(builder);
}
@Override
public Factory withType(Class type) {
return new StandardFactory<>(promises.withType(type));
}
}
interface Factory {
AsyncPromise find(FindBuilderImpl builder, FindReceiver> logic);
AsyncPromise findOne(FindBuilderImpl builder);
Factory withType(Class type);
}
@Override
public FindBuilder withResultType(Class type) {
FindBuilderImpl result = new FindBuilderImpl<>(factory.withType(type));
result.batchSize = batchSize;
result.projection = projection;
result.cursorType = cursorType;
result.limit = limit;
result.filter = filter;
result.modifiers = modifiers;
result.sort = sort;
result.maxTime = maxTime;
result.unit = unit;
return result;
}
FindIterable apply(FindIterable iter) {
if (batchSize > 0) {
iter = iter.batchSize(batchSize);
}
if (limit > 0) {
iter = iter.limit(limit);
}
if (projection != null) {
iter = iter.projection(projection);
}
if (cursorType != null) {
iter = iter.cursorType(cursorType);
}
if (filter != null) {
iter = iter.filter(filter);
}
if (modifiers != null) {
iter = iter.modifiers(modifiers);
}
if (unit != null) {
iter = iter.maxTime(maxTime, unit);
}
if (sort != null) {
iter = iter.sort(sort);
}
return iter;
}
@Override
public FindBuilder withBatchSize(int size) {
if (size <= 0) {
throw new IllegalArgumentException("Batch size must be at least one: " + size);
}
batchSize = size;
return this;
}
@Override
public FindBuilder withProjection(Bson projection) {
this.projection = projection;
return this;
}
@Override
public FindBuilder withCursorType(CursorType cursorType) {
this.cursorType = cursorType;
return this;
}
@Override
public FindBuilder limit(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Limit must be at least one: " + amount);
}
this.limit = amount;
return this;
}
static void checkNull(String name, Object o) {
if (o == null) {
throw new IllegalArgumentException(name + " is null");
}
}
@Override
public FindBuilder filter(Bson bson) {
checkNull("filter", bson);
this.filter = bson;
return this;
}
@Override
public FindBuilder modifiers(Bson bson) {
checkNull("modifiers", bson);
this.modifiers = bson;
return this;
}
@Override
public FindBuilder sort(Bson bson) {
checkNull("sort", bson);
this.sort = bson;
return this;
}
@Override
public FindBuilder ascendingSortBy(String name) {
checkNull("name", name);
return sort(new Document(name, 1));
}
@Override
public FindBuilder descendingSortBy(String name) {
checkNull("name", name);
return sort(new Document(name, -1));
}
@Override
public FindBuilder maxTime(long amount, TimeUnit units) {
if (amount < 0) {
throw new IllegalArgumentException("Amount must be > 0");
}
checkNull("units", units);
this.maxTime = amount;
this.unit = units;
return this;
}
@Override
public AsyncPromise find(FindReceiver> logic) {
checkNull("logic", logic);
return factory.find(this, logic);
}
@Override
public AsyncPromise findOne() {
return factory.findOne(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy