br.com.anteros.nosql.persistence.mongodb.mapping.DefaultMongoCreator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Anteros-NoSql-Persistence-MongoDB Show documentation
Show all versions of Anteros-NoSql-Persistence-MongoDB Show documentation
Anteros NoSQL Persistence MongoDB.
package br.com.anteros.nosql.persistence.mongodb.mapping;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bson.Document;
import br.com.anteros.core.log.LogLevel;
import br.com.anteros.core.log.Logger;
import br.com.anteros.core.log.LoggerProvider;
import br.com.anteros.nosql.persistence.converters.NoSQLMappingException;
import br.com.anteros.nosql.persistence.metadata.NoSQLDescriptionField;
import br.com.anteros.nosql.persistence.session.mapping.AbstractNoSQLObjectMapper;
import br.com.anteros.nosql.persistence.session.mapping.NoSQLMapperOptions;
import br.com.anteros.nosql.persistence.session.mapping.NoSQLObjectFactory;
public class DefaultMongoCreator implements NoSQLObjectFactory {
private static Logger LOG = LoggerProvider.getInstance().getLogger(NoSQLObjectFactory.class);
private Map> classNameCache = new ConcurrentHashMap<>();
private NoSQLMapperOptions options = null;
public DefaultMongoCreator() {
}
public DefaultMongoCreator(final NoSQLMapperOptions options) {
this.options = options;
}
private static Constructor getNoArgsConstructor(final Class type) {
try {
final Constructor constructor = type.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor;
} catch (NoSuchMethodException e) {
throw new NoSQLMappingException("No usable constructor for " + type.getName(), e);
}
}
@Override
@SuppressWarnings("unchecked")
public T createInstance(final Class clazz) {
try {
return getNoArgsConstructor(clazz).newInstance();
} catch (Exception e) {
if (Collection.class.isAssignableFrom(clazz)) {
return (T) createList(null);
} else if (Map.class.isAssignableFrom(clazz)) {
return (T) createMap(null);
} else if (Set.class.isAssignableFrom(clazz)) {
return (T) createSet(null);
}
throw new NoSQLMappingException("No usable constructor for " + clazz.getName(), e);
}
}
@Override
public T createInstance(final Class clazz, final Object dbObj) {
Class c = getClass((Document)dbObj);
if (c == null) {
c = clazz;
}
return createInstance(c);
}
@Override
@SuppressWarnings("unchecked")
public Object createInstance(final AbstractNoSQLObjectMapper mapper, final NoSQLDescriptionField descriptionField, final Object dbObj) {
Class> c = getClass((Document)dbObj);
if (c == null) {
c = descriptionField.isSimple() ? descriptionField.getConcreteType() : descriptionField.getSubClass();
if (c.equals(Object.class)) {
c = descriptionField.getConcreteType();
}
}
try {
return createInstance(c, dbObj);
} catch (RuntimeException e) {
if (!descriptionField.hasConstructorArgs()) {
throw e;
}
final Object[] args = new Object[descriptionField.getConstructorArgs().length];
final Class>[] argTypes = new Class[descriptionField.getConstructorArgs().length];
for (int i = 0; i < descriptionField.getConstructorArgs().length; i++) {
final Object val = ((Document)dbObj).get(descriptionField.getConstructorArgs()[i]);
args[i] = val;
argTypes[i] = val.getClass();
}
try {
final Constructor> constructor = c.getDeclaredConstructor(argTypes);
constructor.setAccessible(true);
return constructor.newInstance(args);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
@Override
@SuppressWarnings("unchecked")
public List> createList(final NoSQLDescriptionField descriptionField) {
return newInstance(descriptionField != null ? descriptionField.getConstructor() : null, ArrayList.class);
}
@Override
@SuppressWarnings("unchecked")
public Map,?> createMap(final NoSQLDescriptionField descriptionField) {
return newInstance(descriptionField != null ? descriptionField.getConstructor() : null, HashMap.class);
}
@Override
@SuppressWarnings("unchecked")
public Set> createSet(final NoSQLDescriptionField descriptionField) {
return newInstance(descriptionField != null ? descriptionField.getConstructor() : null, HashSet.class);
}
public Map> getClassNameCache() {
HashMap> copy = new HashMap>();
copy.putAll(classNameCache);
return copy;
}
protected ClassLoader getClassLoaderForClass() {
return Thread.currentThread().getContextClassLoader();
}
private Class getClass(final Document dbObj) {
Class c = null;
if (dbObj.containsKey(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME)) {
final String className = (String) dbObj.get(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME);
try {
if (options != null && options.isCacheClassLookups()) {
c = classNameCache.get(className);
if (c == null) {
c = Class.forName(className, true, getClassLoaderForClass());
classNameCache.put(className, c);
}
} else {
c = Class.forName(className, true, getClassLoaderForClass());
}
} catch (ClassNotFoundException e) {
if (LOG.isWarnEnabled()) {
LOG.log(LogLevel.WARN,"Class not found defined in dbObj: ", e);
}
}
}
return c;
}
private T newInstance(final Constructor tryMe, final Class fallbackType) {
if (tryMe != null) {
tryMe.setAccessible(true);
try {
return tryMe.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return createInstance(fallbackType);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy