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

com.github.aidensuen.mongo.session.impl.DefaultMongoSession Maven / Gradle / Ivy

There is a newer version: 1.1.2
Show newest version
package com.github.aidensuen.mongo.session.impl;

import com.github.aidensuen.mongo.core.MongoDaoStatement;
import com.github.aidensuen.mongo.exception.BindingException;
import com.github.aidensuen.mongo.executor.Executor;
import com.github.aidensuen.mongo.session.Configuration;
import com.github.aidensuen.mongo.session.ExecutorType;
import com.github.aidensuen.mongo.session.MongoSession;
import com.github.aidensuen.util.StringUtil;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;

public class DefaultMongoSession implements MongoSession {

    private static Logger LOGGER = LoggerFactory.getLogger(DefaultMongoSession.class);

    private final MongoOperations mongoOperations;

    private final Configuration configuration;

    private final Executor executor;

    public DefaultMongoSession(MongoOperations mongoOperations, Configuration configuration) {
        this.mongoOperations = mongoOperations;
        this.configuration = configuration;
        this.executor = this.configuration.newExecutor(mongoOperations, ExecutorType.SIMPLE);
    }

    public DefaultMongoSession(MongoOperations mongoOperations, Configuration configuration, Executor executor) {
        this.mongoOperations = mongoOperations;
        this.configuration = configuration;
        this.executor = executor;
    }

    @Override
    public MongoDatabase getDb() {
        if (this.mongoOperations instanceof MongoTemplate) {
            return ((MongoTemplate) this.mongoOperations).getDb();
        }
        return null;
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }

    @Override
    public  T save(String statement, T objectToSave) {
        return this.executor.save(getMongoDaoStatement(statement), objectToSave);
    }

    @Override
    public  T insert(String statement, T objectToSave) {
        return this.executor.insert(getMongoDaoStatement(statement), objectToSave);
    }

    @Override
    public  Collection insert(String statement, Collection batchToSave) {
        return this.executor.insert(getMongoDaoStatement(statement), batchToSave);
    }

    @Override
    public DeleteResult remove(String statement, Object parameter) {
        return this.executor.remove(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public  Map findMap(String statement, Object parameter, String mapKey) {
        return this.findMap(statement, parameter, mapKey, null);
    }

    @Override
    public  Map findMap(String statement, Object parameter, String mapKey, Pageable pageable) {
        final Map result = new HashMap();
        try {
            List list = this.find(statement, parameter, pageable);
            if (list.size() > 0) {
                final String separator;
                Set keys = new HashSet<>();
                keys.add("id");
                if (StringUtil.hasText(mapKey)) {
                    List newKeys = Arrays.asList(mapKey.split(","));
                    String[] separatorStr = newKeys.get(newKeys.size() - 1).split("@separator@");
                    separator = separatorStr.length > 0 ? separatorStr[1] : "";
                    keys.addAll(newKeys);
                    if (!newKeys.contains("id") || keys.contains(separator)) {
                        keys.remove("id");
                        keys.remove(StringUtil.appendStrs("@separator@", separator));
                    }
                } else {
                    separator = "";
                }
                if (list.size() == 1) {
                    Object o = list.get(0);
                    if (o != null) {
                        BeanUtils.populate(o, result);
                    }
                } else {
                    list.stream().forEach(o -> {
                        StringBuilder builder = new StringBuilder();
                        keys.stream().forEach(key -> {
                            Object propertyValue = null;
                            try {
                                propertyValue = BeanUtils.getProperty(o, key);
                            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                                LOGGER.warn("{} has not property of {} !", o, key);
                            }
                            if (propertyValue != null) {
                                builder.append(propertyValue.toString());
                            } else {
                                builder.append(String.valueOf(new Date().getTime()));
                            }
                            if (StringUtil.hasText(separator)) {
                                builder.append(separator);
                            }
                        });
                        result.put(builder.substring(0, builder.length() - separator.length()), o);
                    });
                }
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public  List find(String statement, Object parameter) {
        return find(statement, parameter, (Pageable) null);
    }

    @Override
    public  List find(String statement, Object parameter, Pageable pageable) {
        return this.find(statement, parameter, pageable, Executor.DEFAULT_CONVERTER);
    }

    @Override
    public  List find(String statement, Object parameter, Function converter) {
        return this.find(statement, parameter, null, converter);
    }

    @Override
    public  List find(String statement, Object parameter, Pageable pageable, Function converter) {
        return this.executor.find(getMongoDaoStatement(statement), wrapCollection(parameter), pageable, converter);
    }

    @Override
    public  T findOne(String statement, Object parameter) {
        List result = this.executor.find(getMongoDaoStatement(statement), wrapCollection(parameter), null, Executor.DEFAULT_CONVERTER);
        if (result != null && result.size() > 0) {
            return (T) result.get(0);
        }
        return null;
    }

    @Override
    public long count(String statement, Object parameter) {
        return this.executor.count(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public boolean exists(String statement, Object parameter) {
        return this.executor.exists(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public UpdateResult updateFirst(String statement, Object parameter) {
        return this.executor.update(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public UpdateResult updateMulti(String statement, Object parameter) {
        return this.executor.update(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public UpdateResult upsert(String statement, Object parameter) {
        return this.executor.update(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    @Override
    public  AggregationResults aggregate(String statement, Object parameter) {
        return this.executor.aggregate(getMongoDaoStatement(statement), wrapCollection(parameter));
    }

    private Object wrapCollection(final Object object) {
        if (object instanceof Collection) {
            StrictMap map = new StrictMap();
            map.put("collection", object);
            if (object instanceof List) {
                map.put("list", object);
            }
            return map;
        } else if (object != null && object.getClass().isArray()) {
            StrictMap map = new StrictMap();
            map.put("array", object);
            return map;
        }
        return object;
    }

    public static class StrictMap extends HashMap {

        private static final long serialVersionUID = 8543898850667756418L;

        @Override
        public V get(Object key) {
            if (!super.containsKey(key)) {
                throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
            }
            return super.get(key);
        }
    }

    protected MongoDaoStatement getMongoDaoStatement(String statement) {
        return this.configuration.getMongoDaoStatement(statement);
    }

    @Override
    public  T getMongoDao(Class type) {
        return configuration.getMongoDao(type, this);
    }
}