<commit_before>package act.db.morphia;

import act.Act;
import act.app.App;
import act.app.DbServiceManager;
import act.db.DB;
import act.db.Dao;
import act.db.DbService;
import act.db.morphia.util.FastJsonObjectIdCodec;
import act.util.FastJsonIterableSerializer;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoInterruptedException;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.mapping.DefaultCreator;
import org.mongodb.morphia.mapping.Mapper;
import org.mongodb.morphia.mapping.MapperOptions;
import org.mongodb.morphia.query.MorphiaIterator;
import org.osgl.$;
import org.osgl.util.E;
import org.osgl.util.S;
import org.osgl.util.StringValueResolver;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import static act.app.App.logger;

public class MorphiaService extends DbService {

    public static final String QUERY_SEP = "[,;:]+";
    public static final String GROUP_SEP = S.COMMON_SEP;

    // the morphia instance - keep track of class mapping
    private static Morphia morphia;

    private Datastore ds;

    /**
     * Map from Java object field name to mongodb property name
     */
    private Map<Class, Map<String, String>> fieldNameLookup;

    public MorphiaService(String id, final App app, Map<String, Object> conf) {
        super(id, app);
        if (null == morphia) {
            morphia = new Morphia();
            MapperOptions options = morphia.getMapper().getOptions();
            options.setObjectFactory(new DefaultCreator(){
                @Override
                protected ClassLoader getClassLoaderForClass() {
                    return app.classLoader();
                }
            });
            // the TypeConverterFinder will register it
            // morphia.getMapper().getConverters().addConverter(new DateTimeConverter());
        }
        fieldNameLookup = new HashMap<Class, Map<String, String>>();
        $.T2<MongoClientURI, MongoClient> t2 = ClientManager.register(this, conf);
        initDataStore(t2, conf);
        delayedEnsureIndexesAndCaps(app);
        registerFastJsonConfig();
        app.registerSingleton(MorphiaService.class, this);
        app.resolverManager().register(ObjectId.class, new StringValueResolver<ObjectId>() {
            @Override
            public ObjectId resolve(String s) {
                return new ObjectId(s);
            }
        });
    }

    @Override
    protected void releaseResources() {
        ClientManager.release(this);
        fieldNameLookup.clear();
        morphia = null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <DAO extends Dao> DAO defaultDao(Class<?> modelType) {
        if (MorphiaModel.class.isAssignableFrom(modelType)) {
            return $.cast(new MorphiaDao(modelType, ds));
        }
        if (MorphiaModelWithLongId.class.isAssignableFrom(modelType)) {
            return $.cast(new MorphiaDaoWithLongId(modelType, ds()));
        }
        if (MorphiaModelBase.class.isAssignableFrom(modelType)) {
            Type type = modelType.getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                return $.cast(new MorphiaDaoBase((Class)((ParameterizedType) type).getActualTypeArguments()[0], modelType, ds));
            }
        }
        Class idType = findModelIdTypeByAnnotation(modelType, Id.class);
        E.illegalArgumentIf(null == idType, "Cannot find out Dao for model type[%s]: unable to identify the ID type", modelType);
        return $.cast(new MorphiaDaoBase(idType, modelType, ds));
    }
<commit_msg>ObjectId StringValueResolver: return null if string is blank<commit_after>package act.db.morphia;

import act.Act;
import act.app.App;
import act.app.DbServiceManager;
import act.db.DB;
import act.db.Dao;
import act.db.DbService;
import act.db.morphia.util.FastJsonObjectIdCodec;
import act.util.FastJsonIterableSerializer;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoInterruptedException;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.mapping.DefaultCreator;
import org.mongodb.morphia.mapping.Mapper;
import org.mongodb.morphia.mapping.MapperOptions;
import org.mongodb.morphia.query.MorphiaIterator;
import org.osgl.$;
import org.osgl.util.E;
import org.osgl.util.S;
import org.osgl.util.StringValueResolver;

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import static act.app.App.logger;

public class MorphiaService extends DbService {

    public static final String QUERY_SEP = "[,;:]+";
    public static final String GROUP_SEP = S.COMMON_SEP;

    // the morphia instance - keep track of class mapping
    private static Morphia morphia;

    private Datastore ds;

    /**
     * Map from Java object field name to mongodb property name
     */
    private Map<Class, Map<String, String>> fieldNameLookup;

    public MorphiaService(String id, final App app, Map<String, Object> conf) {
        super(id, app);
        if (null == morphia) {
            morphia = new Morphia();
            MapperOptions options = morphia.getMapper().getOptions();
            options.setObjectFactory(new DefaultCreator(){
                @Override
                protected ClassLoader getClassLoaderForClass() {
                    return app.classLoader();
                }
            });
            // the TypeConverterFinder will register it
            // morphia.getMapper().getConverters().addConverter(new DateTimeConverter());
        }
        fieldNameLookup = new HashMap<Class, Map<String, String>>();
        $.T2<MongoClientURI, MongoClient> t2 = ClientManager.register(this, conf);
        initDataStore(t2, conf);
        delayedEnsureIndexesAndCaps(app);
        registerFastJsonConfig();
        app.registerSingleton(MorphiaService.class, this);
        app.resolverManager().register(ObjectId.class, new StringValueResolver<ObjectId>() {
            @Override
            public ObjectId resolve(String s) {
                return S.blank(s) ? null : new ObjectId(s);
            }
        });
    }

    @Override
    protected void releaseResources() {
        ClientManager.release(this);
        fieldNameLookup.clear();
        morphia = null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <DAO extends Dao> DAO defaultDao(Class<?> modelType) {
        if (MorphiaModel.class.isAssignableFrom(modelType)) {
            return $.cast(new MorphiaDao(modelType, ds));
        }
        if (MorphiaModelWithLongId.class.isAssignableFrom(modelType)) {
            return $.cast(new MorphiaDaoWithLongId(modelType, ds()));
        }
        if (MorphiaModelBase.class.isAssignableFrom(modelType)) {
            Type type = modelType.getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                return $.cast(new MorphiaDaoBase((Class)((ParameterizedType) type).getActualTypeArguments()[0], modelType, ds));
            }
        }
        Class idType = findModelIdTypeByAnnotation(modelType, Id.class);
        E.illegalArgumentIf(null == idType, "Cannot find out Dao for model type[%s]: unable to identify the ID type", modelType);
        return $.cast(new MorphiaDaoBase(idType, modelType, ds));
    }

{'fraction_non_alphanumeric': 0.10494677520350658, 'fraction_numerical': 0.0010018785222291797, 'mean_word_length': 3.1442656979761288, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1078685', 'n_tokens_mistral': 2371, 'n_tokens_neox': 2326, 'n_words': 499}