de.flapdoodle.mongoom.datastore.query.QueryResult.java Source code

Java tutorial

Introduction

Here is the source code for de.flapdoodle.mongoom.datastore.query.QueryResult.java

Source

/**
 * Copyright (C) 2010 Michael Mosmann <michael@mosmann.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.flapdoodle.mongoom.datastore.query;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

import de.flapdoodle.mongoom.IQueryResult;
import de.flapdoodle.mongoom.datastore.factories.DBObjectFactory;
import de.flapdoodle.mongoom.datastore.iterator.TypedIterator;
import de.flapdoodle.mongoom.exceptions.MappingException;
import de.flapdoodle.mongoom.logging.LogConfig;
import de.flapdoodle.mongoom.mapping.IEntityTransformation;
import de.flapdoodle.mongoom.mapping.ITransformation;
import de.flapdoodle.mongoom.mapping.naming.PropertyName;

public class QueryResult<T> implements IQueryResult<T> {

    private static final Logger _logger = LogConfig.getLogger(QueryResult.class);

    private int _limit = -1;
    private int _skip = -1;

    private final DBCollection _dbCollection;

    private final ITransformation<T, DBObject> _converter;

    private final DBObject _query;

    private final DBObject _view;

    private final IEntityTransformation<?> _entityConverter;

    private final Map<String, Integer> _sort = Maps.newLinkedHashMap();

    public QueryResult(IEntityTransformation<?> entityConverter, ITransformation<T, DBObject> converter,
            DBCollection dbCollection, DBObject query, DBObject view) {
        _entityConverter = entityConverter;
        _converter = converter != null ? converter : (ITransformation<T, DBObject>) entityConverter;

        _dbCollection = dbCollection;
        _query = query;
        _view = view;
    }

    @Override
    public List<T> asList() {
        DBCursor find = getCursor();

        if (_limit > 0)
            find.limit(_limit);
        if (_skip > 0)
            find.skip(_skip);

        return asList(find);
    }

    @Override
    public T get() {
        //      List<T> list = asList(_dbCollection.find(query).limit(1));
        //      return list.isEmpty() ? null : list.get(0);
        DBObject one = _view != null ? _dbCollection.findOne(_query, _view) : _dbCollection.findOne(_query);
        return one != null ? _converter.asEntity(one) : null;
    }

    @Override
    public IQueryResult<T> limit(int limit) {
        _limit = limit;
        return this;
    }

    @Override
    public IQueryResult<T> skip(int skip) {
        _skip = skip;
        return this;
    }

    @Override
    public long countAll() {
        return getCursor().count();
    }

    private DBCursor getCursor() {
        _logger.severe("Query: " + _query + ", View: " + _view);
        DBCursor ret = _view != null ? _dbCollection.find(_query, _view) : _dbCollection.find(_query);
        if (!_sort.isEmpty()) {
            DBObjectFactory sort = DBObjectFactory.start();
            for (String name : _sort.keySet()) {
                sort.set(name, _sort.get(name));
            }
            DBObject sortBy = sort.get();
            _logger.severe("Sort: " + sortBy);
            ret.sort(sortBy);
        }
        return ret;
    }

    @Override
    public Iterator<T> iterator() {
        DBCursor find = getCursor();
        if (_limit > 0)
            find.limit(_limit);
        if (_skip > 0)
            find.skip(_skip);
        return new TypedIterator<T>(this, _converter, find);
    }

    @Override
    public IQueryResult<T> order(String field, boolean asc) {
        PropertyName propertyName = _entityConverter.propertyName(field);
        if (propertyName == null)
            throw new MappingException("Field " + field + " not mapped");
        _sort.put(propertyName.getMapped(), asc ? 1 : -1);
        return this;
    }

    private List<T> asList(DBCursor cursor) {
        return Lists.transform(Lists.newArrayList(cursor.iterator()), new DBObjectToEntityTransformator());
    }

    private final class DBObjectToEntityTransformator implements Function<DBObject, T> {

        @Override
        public T apply(DBObject dbobject) {
            return _converter.asEntity(dbobject);
        }
    }
}