Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
br.com.anteros.nosql.persistence.mongodb.mapping.MongoEmbeddedMapper Maven / Gradle / Ivy
package br.com.anteros.nosql.persistence.mongodb.mapping;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.bson.Document;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import br.com.anteros.core.utils.ListUtils;
import br.com.anteros.core.utils.ObjectUtils;
import br.com.anteros.nosql.persistence.converters.IterHelper;
import br.com.anteros.nosql.persistence.converters.IterHelper.MapIterCallback;
import br.com.anteros.nosql.persistence.metadata.NoSQLDescriptionField;
import br.com.anteros.nosql.persistence.metadata.NoSQLTypedDescriptionField;
import br.com.anteros.nosql.persistence.session.NoSQLSession;
import br.com.anteros.nosql.persistence.session.cache.NoSQLEntityCache;
import br.com.anteros.nosql.persistence.session.mapping.AbstractNoSQLObjectMapper;
import br.com.anteros.nosql.persistence.session.mapping.NoSQLCustomMapper;
class MongoEmbeddedMapper implements NoSQLCustomMapper {
static boolean shouldSaveClassName(final Object rawVal, final Object convertedVal,
final NoSQLDescriptionField descriptionField) {
if (rawVal == null || descriptionField == null) {
return true;
}
if (descriptionField.isSimple()) {
return !(descriptionField.getField().getType().equals(rawVal.getClass())
&& !(convertedVal instanceof BasicDBList));
}
boolean isDocument = convertedVal instanceof Document;
boolean anInterface = descriptionField.getSubClass().isInterface();
boolean anAbstract = Modifier.isAbstract(descriptionField.getSubClass().getModifiers());
boolean equals = descriptionField.getSubClass().equals(rawVal.getClass());
return convertedVal == null || !isDocument || anInterface || anAbstract || !equals;
}
private static boolean isMapOrCollection(final NoSQLDescriptionField descriptionField) {
return Map.class.isAssignableFrom(descriptionField.getSubClass())
|| Iterable.class.isAssignableFrom(descriptionField.getSubClass());
}
@Override
public void fromDocument(final NoSQLSession> session, final Object dbObject,
final NoSQLDescriptionField descriptionField, final Object entity, final NoSQLEntityCache cache,
final AbstractNoSQLObjectMapper mapper) throws Exception {
try {
if (descriptionField.isAnyMap()) {
readMap(session, mapper, entity, cache, descriptionField, (Document) dbObject);
} else if (descriptionField.isAnyArrayOrCollection()) {
readCollection(session, mapper, entity, cache, descriptionField, (Document) dbObject);
} else {
// single element
final Object dbVal = descriptionField.getDbObjectValue(session.getDialect(), dbObject);
if (dbVal != null) {
final boolean isDocument = dbVal instanceof Document;
// run converters
if (isDocument && !mapper.isMapped(descriptionField.getConcreteType())
&& (mapper.getConverters().hasDocumentConverter(descriptionField) || mapper.getConverters()
.hasDocumentConverter(descriptionField.getField().getType()))) {
mapper.getConverters().fromDocument(dbObject, descriptionField, entity);
} else {
Object refObj;
if (mapper.getConverters().hasSimpleValueConverter(descriptionField) || mapper.getConverters()
.hasSimpleValueConverter(descriptionField.getField().getType())) {
refObj = mapper.getConverters().decode(descriptionField.getField().getType(), dbVal,
descriptionField);
} else {
Document value = (dbVal instanceof DBObject?new Document(((DBObject)dbVal).toMap()):(Document) dbVal);
refObj = mapper.getOptions().getObjectFactory().createInstance(mapper, descriptionField,
value);
refObj = mapper.fromDocument(session, value, refObj, cache);
}
if (refObj != null) {
descriptionField.setObjectValue(entity, refObj);
}
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void toDocument(final Object entity, final NoSQLDescriptionField descriptionField, final Object dbObject,
final Map involvedObjects, final AbstractNoSQLObjectMapper mapper) throws Exception {
final String name = descriptionField.getName();
final Object fieldValue = descriptionField.getObjectValue(entity);
if (descriptionField.isAnyMap()) {
writeMap(descriptionField, (Document) dbObject, involvedObjects, name, fieldValue, mapper);
} else if (descriptionField.isAnyArrayOrCollection()) {
writeCollection(descriptionField, (Document) dbObject, involvedObjects, name, fieldValue, mapper);
} else {
// run converters
if (mapper.getConverters().hasDocumentConverter(descriptionField)
|| mapper.getConverters().hasDocumentConverter(entity.getClass())) {
mapper.getConverters().toDocument(entity, descriptionField, dbObject, mapper.getOptions());
return;
}
final Document dbObj = fieldValue == null ? null
: (Document) mapper.toDocument(fieldValue, involvedObjects);
if (dbObj != null) {
if (!shouldSaveClassName(fieldValue, dbObj, descriptionField)) {
dbObj.remove(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME);
}
if (!dbObj.keySet().isEmpty() || mapper.getOptions().isStoreEmpties()) {
((Document) dbObject).put(name, dbObj);
}
}
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void readCollection(final NoSQLSession session, final AbstractNoSQLObjectMapper mapper, final Object entity,
final NoSQLEntityCache cache, final NoSQLDescriptionField descriptionField, final Document dbObject)
throws Exception {
Collection values;
final Object dbVal = descriptionField.getDbObjectValue(session.getDialect(), dbObject);
if (dbVal != null) {
// multiple documents in a List
values = descriptionField.isAnyArrayOrCollection()
? mapper.getOptions().getObjectFactory().createSet(descriptionField)
: mapper.getOptions().getObjectFactory().createList(descriptionField);
final List dbValues;
if (dbVal instanceof List) {
dbValues = (List) dbVal;
} else {
dbValues = new BasicDBList();
dbValues.add(dbVal);
}
NoSQLTypedDescriptionField typedDescriptionField = !mapper.isMapped(descriptionField.getField().getType())
&& isMapOrCollection(descriptionField)
&& (descriptionField.getSubType() instanceof ParameterizedType)
? new NoSQLTypedDescriptionField(
(ParameterizedType) descriptionField.getSubType(), descriptionField)
: null;
for (final Object o : dbValues) {
Object newEntity = null;
if (o != null) {
// run converters
if (mapper.getConverters().hasSimpleValueConverter(descriptionField)
|| mapper.getConverters().hasSimpleValueConverter(descriptionField.getSubClass())) {
newEntity = mapper.getConverters().decode(descriptionField.getSubClass(), o, descriptionField);
} else {
newEntity = readMapOrCollectionOrEntity(session, mapper, cache, descriptionField,
typedDescriptionField, (Document) o);
}
}
values.add(newEntity);
}
if (!values.isEmpty() || mapper.getOptions().isStoreEmpties()) {
if (descriptionField.isArray()) {
descriptionField.setObjectValue(entity,
ListUtils.convertToArray(descriptionField.getSubClass(), ListUtils.iterToList(values)));
} else {
if (descriptionField.isList()) {
descriptionField.setObjectValue(entity,new ArrayList(values));
} else {
descriptionField.setObjectValue(entity, values);
}
}
}
}
}
@SuppressWarnings("unchecked")
private void readMap(final NoSQLSession> session, final AbstractNoSQLObjectMapper mapper, final Object entity,
final NoSQLEntityCache cache, final NoSQLDescriptionField descriptionField, final Document dbObject)
throws Exception {
final Document dbObj = (Document) descriptionField.getDbObjectValue(session.getDialect(), dbObject);
if (dbObj != null) {
final Map map = mapper.getOptions().getObjectFactory().createMap(descriptionField);
final NoSQLTypedDescriptionField typedDescriptionField = isMapOrCollection(descriptionField)
? new NoSQLTypedDescriptionField((ParameterizedType) descriptionField.getSubType(),
descriptionField)
: null;
new IterHelper().loopMap(dbObj, new MapIterCallback() {
@Override
public void eval(final Object k, final Object val) {
Object newEntity = null;
// run converters
if (val != null) {
if (mapper.getConverters().hasSimpleValueConverter(descriptionField)
|| mapper.getConverters().hasSimpleValueConverter(descriptionField.getSubClass())) {
newEntity = mapper.getConverters().decode(descriptionField.getSubClass(), val,
descriptionField);
} else {
if (val instanceof Document) {
try {
newEntity = readMapOrCollectionOrEntity(session, mapper, cache, descriptionField,
typedDescriptionField, (Document) val);
} catch (Exception e) {
e.printStackTrace();
}
} else {
newEntity = val;
}
}
}
final Object objKey = mapper.getConverters().decode(descriptionField.getMapKeyClass(), k,
descriptionField);
map.put(objKey, newEntity);
}
});
if (!map.isEmpty() || mapper.getOptions().isStoreEmpties()) {
descriptionField.setObjectValue(entity, map);
}
}
}
private Object readMapOrCollectionOrEntity(final NoSQLSession> session, final AbstractNoSQLObjectMapper mapper,
final NoSQLEntityCache cache, final NoSQLDescriptionField descriptionField,
final NoSQLTypedDescriptionField typedField, final Document dbObj) throws Exception {
if (typedField != null) {
mapper.fromDocument(session, dbObj, typedField, cache);
return typedField.getValue();
} else {
final Object newEntity = mapper.getOptions().getObjectFactory().createInstance(mapper, descriptionField,
dbObj);
return mapper.fromDocument(session, dbObj, newEntity, cache);
}
}
private void writeCollection(final NoSQLDescriptionField descriptionField, final Document dbObject,
final Map involvedObjects, final String name, final Object fieldValue,
final AbstractNoSQLObjectMapper mapper) {
Iterable> coll = null;
if (fieldValue != null) {
if (descriptionField.isArray()) {
coll = Arrays.asList((Object[]) fieldValue);
} else {
coll = (Iterable>) fieldValue;
}
}
if (coll != null) {
final List values = new ArrayList();
for (final Object o : coll) {
if (null == o) {
values.add(null);
} else if (mapper.getConverters().hasSimpleValueConverter(descriptionField)
|| mapper.getConverters().hasSimpleValueConverter(o.getClass())) {
values.add(mapper.getConverters().encode(o));
} else {
final Object val;
if (Collection.class.isAssignableFrom(o.getClass()) || Map.class.isAssignableFrom(o.getClass())) {
val = ((MongoObjectMapper) mapper).toMongoObject(o, true);
} else {
val = mapper.toDocument(o, involvedObjects);
}
if (!shouldSaveClassName(o, val, descriptionField)) {
((Document) val).remove(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME);
}
values.add(val);
}
}
if (!values.isEmpty() || mapper.getOptions().isStoreEmpties()) {
dbObject.put(name, values);
}
}
}
@SuppressWarnings("unchecked")
private void writeMap(final NoSQLDescriptionField descriptionField, final Document dbObject,
final Map involvedObjects, final String name, final Object fieldValue,
final AbstractNoSQLObjectMapper mapper) {
final Map map = (Map) fieldValue;
if (map != null) {
final Document values = new Document();
for (final Map.Entry entry : map.entrySet()) {
final Object entryVal = entry.getValue();
final Object val;
if (entryVal == null) {
val = null;
} else if (mapper.getConverters().hasSimpleValueConverter(descriptionField)
|| mapper.getConverters().hasSimpleValueConverter(entryVal.getClass())) {
val = mapper.getConverters().encode(entryVal);
} else {
if (Map.class.isAssignableFrom(entryVal.getClass())
|| Collection.class.isAssignableFrom(entryVal.getClass())) {
val = ((MongoObjectMapper) mapper).toMongoObject(entryVal, true);
} else {
val = mapper.toDocument(entryVal, involvedObjects);
}
if (!shouldSaveClassName(entryVal, val, descriptionField)) {
if (val instanceof List) {
if (((List>) val).get(0) instanceof Document) {
List list = (List) val;
for (Document o : list) {
o.remove(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME);
}
}
} else {
((Document) val).remove(AbstractNoSQLObjectMapper.CLASS_NAME_FIELDNAME);
}
}
}
final String strKey = mapper.getConverters().encode(entry.getKey()).toString();
values.put(strKey, val);
}
if (!values.isEmpty() || mapper.getOptions().isStoreEmpties()) {
dbObject.put(name, values);
}
}
}
}