Package leodagdag.play2morphia

Source Code of leodagdag.play2morphia.MorphiaPlugin

package leodagdag.play2morphia;

import org.mongodb.morphia.AbstractEntityInterceptor;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.annotations.Embedded;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.logging.MorphiaLoggerFactory;
import org.mongodb.morphia.logging.slf4j.SLF4JLogrImplFactory;
import org.mongodb.morphia.mapping.Mapper;
import org.mongodb.morphia.ValidationExtension;
import com.mongodb.*;
import com.mongodb.gridfs.GridFS;
import leodagdag.play2morphia.utils.*;
import play.Application;
import play.Configuration;
import play.Plugin;
import play.libs.Classpath;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class MorphiaPlugin extends Plugin {

    private final Application application;

    private boolean isEnabled;

    private static Morphia morphia = null;

    private static Mongo mongo = null;
    private static Datastore ds = null;
    private static GridFS gridfs;


    public MorphiaPlugin(Application application) {
        this.application = application;
    }

    @Override
    public void onStart() {
        if (!isEnabled) {
            return;
        }
        // Register SLF4JLogrImplFactory as Logger
        // @see http://nesbot.com/2011/11/28/play-2-morphia-logging-error
        MorphiaLoggerFactory.reset();
        MorphiaLoggerFactory.registerLogger(SLF4JLogrImplFactory.class);

        try {
            Configuration morphiaConf = Configuration.root().getConfig(ConfigKey.PREFIX);
            if (morphiaConf == null) {
                throw Configuration.root().reportError(ConfigKey.PREFIX, "Missing Morphia configuration", null);
            }

            MorphiaLogger.debug(morphiaConf);

            String mongoURIstr = morphiaConf.getString(ConfigKey.DB_MONGOURI.getKey());
            String seeds = morphiaConf.getString(ConfigKey.DB_SEEDS.getKey());

            String dbName = null;
            String username = null;
            String password = null;
           
            if(StringUtils.isNotBlank(mongoURIstr)) {
                MongoURI mongoURI = new MongoURI(mongoURIstr);
                mongo = connect(mongoURI);
                dbName = mongoURI.getDatabase();
                username = mongoURI.getUsername();
                if(mongoURI.getPassword() != null) {
                    password = new String(mongoURI.getPassword());   
                }
            } else if (StringUtils.isNotBlank(seeds)) {
                mongo = connect(seeds);
            } else {
                mongo = connect(
                        morphiaConf.getString(ConfigKey.DB_HOST.getKey()),
                        morphiaConf.getString(ConfigKey.DB_PORT.getKey()));
            }

            if (StringUtils.isBlank(dbName)) {
                dbName = morphiaConf.getString(ConfigKey.DB_NAME.getKey());
                if (StringUtils.isBlank(dbName)) {
                    throw morphiaConf.reportError(ConfigKey.DB_NAME.getKey(), "Missing Morphia configuration", null);
                }
            }

            morphia = new Morphia();
            // To prevent problem during hot-reload
            if (application.isDev()) {
                morphia.getMapper().getOptions().objectFactory = new PlayCreator();
            }
            // Configure validator
            new ValidationExtension(morphia);

            //Check if credentials parameters are present
            if (StringUtils.isBlank(username)) {
                username = morphiaConf.getString(ConfigKey.DB_USERNAME.getKey());
            }
            if (StringUtils.isBlank(password)) {
                password = morphiaConf.getString(ConfigKey.DB_PASSWORD.getKey());
            }

            if (StringUtils.isNotBlank(username) ^ StringUtils.isNotBlank(password)) {
                throw morphiaConf.reportError(ConfigKey.DB_NAME.getKey(), "Missing username or password", null);
            }

            // Create datastore
            if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
                ds = morphia.createDatastore(mongo, dbName, username, password.toCharArray());
            } else {
                ds = morphia.createDatastore(mongo, dbName);
            }


            MorphiaLogger.debug("Datastore [%s] created", dbName);
            // Create GridFS
            String uploadCollection = morphiaConf.getString(ConfigKey.COLLECTION_UPLOADS.getKey());
            if (StringUtils.isBlank(dbName)) {
                uploadCollection = "uploads";
                MorphiaLogger.warn("Missing Morphia configuration key [%s]. Use default value instead [%s]", ConfigKey.COLLECTION_UPLOADS, "uploads");
            }
            gridfs = new GridFS(ds.getDB(), uploadCollection);
            MorphiaLogger.debug("GridFS created", "");
            MorphiaLogger.debug("Add Interceptor...", "");
            morphia.getMapper().addInterceptor(new AbstractEntityInterceptor() {

                @Override
                public void postLoad(final Object ent, final DBObject dbObj, final Mapper mapr) {
                    if (ent instanceof Model) {
                        Model m = (Model) ent;
                        m._post_Load();
                    }
                }
            });
            MorphiaLogger.debug("Classes mapping...", "");
            mapClasses();
            MorphiaLogger.debug("End of initializing Morphia", "");
        } catch (MongoException e) {
            MorphiaLogger.error(e, "Problem connecting MongoDB");
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            MorphiaLogger.error(e, "Problem mapping class");
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onStop() {
        if (isEnabled) {
            MorphiaLoggerFactory.reset();
            morphia = null;
            ds = null;
            gridfs = null;
            mongo.close();
        }
    }

    @Override
    public boolean enabled() {
        isEnabled = !"disabled".equals(application.configuration().getString(Constants.MORPHIA_PLUGIN_ENABLED));
        MorphiaLogger.warn(String.format("MorphiaPlugin is %s", isEnabled ? "enabled" : "disabled"));
        return isEnabled;
    }

    private void mapClasses() throws ClassNotFoundException {
        // Register all models.Class
        Set<String> classes = new HashSet<String>();
        classes.addAll(Classpath.getTypesAnnotatedWith(application, "models", Entity.class));
        classes.addAll(Classpath.getTypesAnnotatedWith(application, "models", Embedded.class));
        for (String clazz : classes) {
            MorphiaLogger.debug("mapping class: %1$s", clazz);
            morphia.map(Class.forName(clazz, true, application.classloader()));
        }
        // @see http://code.google.com/p/morphia/wiki/Datastore#Ensure_Indexes_and_Caps
        ds.ensureCaps(); //creates capped collections from @Entity
        ds.ensureIndexes(); //creates indexes from @Index annotations in your entities
    }

    private final static ConcurrentMap<String, Datastore> dataStores = new ConcurrentHashMap<String, Datastore>();

    public static Datastore ds(String dbName) {
        if (StringUtils.isBlank(dbName)) {
            return ds();
        }
        Datastore ds = dataStores.get(dbName);
        if (null == ds) {
            Datastore ds0 = morphia.createDatastore(mongo, dbName);
            ds = dataStores.putIfAbsent(dbName, ds0);
            if (null == ds) {
                ds = ds0;
            }
        }
        return ds;
    }

    public static Datastore ds() {
        return ds;
    }

    public static GridFS gridFs() {
        return gridfs;
    }

    public static DB db() {
        return ds().getDB();
    }

    private Mongo connect(MongoURI mongoURI) {
        try {
            return new Mongo(mongoURI);
        }
        catch(UnknownHostException e) {
            throw Configuration.root().reportError(ConfigKey.DB_MONGOURI.getKey(), "Cannot connect to mongodb: unknown host", e);
        }
    }

    private Mongo connect(String seeds) {
        String[] sa = seeds.split("[;,\\s]+");
        List<ServerAddress> addrs = new ArrayList<ServerAddress>(sa.length);
        for (String s : sa) {
            String[] hp = s.split(":");
            if (0 == hp.length) {
                continue;
            }
            String host = hp[0];
            int port = 27017;
            if (hp.length > 1) {
                port = Integer.parseInt(hp[1]);
            }
            try {
                addrs.add(new ServerAddress(host, port));
            } catch (UnknownHostException e) {
                MorphiaLogger.error(e, "Error creating mongo connection to %s:%s", host, port);
            }
        }
        if (addrs.isEmpty()) {
            throw Configuration.root().reportError(ConfigKey.DB_SEEDS.getKey(), "Cannot connect to mongodb: no replica can be connected", null);
        }
        return new Mongo(addrs);
    }

    private Mongo connect(String host, String port) {
        String[] ha = host.split("[,\\s;]+");
        String[] pa = port.split("[,\\s;]+");
        int len = ha.length;
        if (len != pa.length) {
            throw Configuration.root().reportError(ConfigKey.DB_HOST.getKey() + "-" + ConfigKey.DB_PORT.getKey(), "host and ports number does not match", null);
        }
        if (1 == len) {
            try {
                return new Mongo(ha[0], Integer.parseInt(pa[0]));
            } catch (Exception e) {
                throw Configuration.root().reportError(
                        ConfigKey.DB_HOST.getKey() + "-"
                                + ConfigKey.DB_PORT.getKey(),
                        String.format("Cannot connect to mongodb at %s:%s",
                                host, port), e);
            }
        }
        List<ServerAddress> addrs = new ArrayList<ServerAddress>(ha.length);
        for (int i = 0; i < len; ++i) {
            try {
                addrs.add(new ServerAddress(ha[i], Integer.parseInt(pa[i])));
            } catch (Exception e) {
                MorphiaLogger.error(e, "Error creating mongo connection to %s:%s", host, port);
            }
        }
        if (addrs.isEmpty()) {
            throw Configuration.root().reportError(
                    ConfigKey.DB_HOST.getKey() + "-" + ConfigKey.DB_PORT.getKey(), "Cannot connect to mongodb: no replica can be connected",
                    null);
        }
        return new Mongo(addrs);
    }

}
TOP

Related Classes of leodagdag.play2morphia.MorphiaPlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.