All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mastfrog.asyncpromises.mongo.FindBuilderImpl Maven / Gradle / Ivy

There is a newer version: 2.9.7
Show newest version
/*
 * 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