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.
com.landawn.abacus.core.EntityUtil Maven / Gradle / Ivy
/*
* Copyright (c) 2015, Haiyang Li.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.landawn.abacus.core;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.landawn.abacus.DirtyMarker;
import com.landawn.abacus.annotation.Internal;
import com.landawn.abacus.metadata.EntityDefinition;
import com.landawn.abacus.metadata.Property;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.Objectory;
// TODO: Auto-generated Javadoc
/**
*
* @author Haiyang Li
* @since 0.8
*/
@Internal
public final class EntityUtil {
private static final String DOUBLE_BRACKET = "{}";
private EntityUtil() {
// no instance.
}
/**
*
* @param
* @param entityDef
* @param entity
* @return
*/
public static T clone(EntityDefinition entityDef, T entity) {
if (entity == null) {
return null;
}
Collection propNames = EntityManagerUtil.getSignedPropNames(entityDef, entity);
return copy(entityDef, entity, propNames, true);
}
/**
*
* @param
* @param entityDef
* @param entity
* @return
*/
public static T copy(EntityDefinition entityDef, T entity) {
return copy(entityDef, entity, null);
}
/**
*
* @param
* @param entityDef
* @param entity
* @param propNames
* @return
*/
public static T copy(EntityDefinition entityDef, T entity, Collection propNames) {
if (entity == null) {
return null;
}
if (propNames == null) {
propNames = EntityManagerUtil.getSignedPropNames(entityDef, entity);
}
return copy(entityDef, entity, propNames, false);
}
/**
*
* @param
* @param entityDef
* @param entity
* @param propNames
* @param isDeepCopy
* @return
*/
private static T copy(EntityDefinition entityDef, T entity, Collection propNames, boolean isDeepCopy) {
@SuppressWarnings("unchecked")
T copy = (T) N.newEntity(entity.getClass(), entityDef.getName());
MapEntity mapEntity = (entity instanceof MapEntity) ? (MapEntity) entity : null;
MapEntity copyOfMapEnity = (mapEntity == null) ? null : (MapEntity) copy;
Property prop = null;
Object propValue = null;
EntityDefinition columnEntityDef = null;
for (String propName : propNames) {
prop = entityDef.getProperty(propName);
if (mapEntity == null) {
propValue = EntityManagerUtil.getPropValueByMethod(entity, prop);
} else {
propValue = mapEntity.get(propName);
}
if (isDeepCopy && (propValue != null) && prop.getColumnType().isEntity()) {
columnEntityDef = prop.getColumnEntityDef();
if (prop.isCollection() && propValue instanceof Collection) {
@SuppressWarnings("unchecked")
Collection c = (Collection) propValue;
@SuppressWarnings("unchecked")
Collection newC = N.newInstance(c.getClass());
for (Object e : c) {
if (e == null) {
newC.add(e);
} else {
newC.add(clone(columnEntityDef, e));
}
}
propValue = newC;
} else {
propValue = clone(columnEntityDef, propValue);
}
}
if (copyOfMapEnity == null) {
EntityManagerUtil.setPropValueByMethod(copy, prop, propValue);
} else {
copyOfMapEnity.set(propName, propValue);
}
}
if (entity instanceof DirtyMarker) {
DirtyMarker anEntity = (DirtyMarker) entity;
DirtyMarker anCopy = (DirtyMarker) copy;
DirtyMarkerUtil.dirtyPropNames(anCopy).clear();
DirtyMarkerUtil.markDirty(anCopy, DirtyMarkerUtil.dirtyPropNames(anEntity), true);
DirtyMarkerUtil.setVersion(anCopy, anEntity.version());
}
return copy;
}
/**
*
* @param
* @param entityDef
* @param sourceEntity
* @param targetClass
* @return
*/
public static T transfer(EntityDefinition entityDef, Object sourceEntity, Class targetClass) {
return transfer(entityDef, sourceEntity, null, targetClass);
}
/**
*
* @param
* @param entityDef
* @param sourceEntity
* @param propNames
* @param targetClass
* @return
*/
@SuppressWarnings({ "unchecked" })
public static T transfer(EntityDefinition entityDef, Object sourceEntity, Collection propNames, Class targetClass) {
if (sourceEntity == null) {
return null;
}
T targetEntity = N.newEntity(targetClass, entityDef.getName());
if (propNames == null) {
propNames = EntityManagerUtil.getSignedPropNames(entityDef, sourceEntity);
}
Class targetEntityClass = (Class) targetEntity.getClass();
MapEntity sourceMapEntity = (sourceEntity instanceof MapEntity) ? (MapEntity) sourceEntity : null;
MapEntity targetMapEntity = (targetEntity instanceof MapEntity) ? (MapEntity) targetEntity : null;
if (targetMapEntity != null) {
if (sourceMapEntity != null) {
for (String propName : propNames) {
targetMapEntity.set(propName, sourceMapEntity.get(propName));
}
} else {
Property prop = null;
Object propValue = null;
for (String propName : propNames) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
targetMapEntity.set(propName, propValue);
}
}
} else {
Property prop = null;
Object propValue = null;
Class> propEntityClass = null;
EntityDefinition columnEntityDef = null;
for (String propName : propNames) {
prop = entityDef.getProperty(propName);
if (sourceMapEntity == null) {
propValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
} else {
propValue = sourceMapEntity.get(propName);
}
if ((propValue != null) && prop.getColumnType().isEntity()) {
columnEntityDef = prop.getColumnEntityDef();
if (prop.isCollection() && propValue instanceof Collection) {
Class> propEleClass = getPropEleClass(targetEntityClass, prop);
Collection c = (Collection) propValue;
Collection newC = N.newInstance(c.getClass());
for (Object e : c) {
if (e == null || e.getClass().equals(propEleClass)) {
newC.add(e);
} else {
newC.add(transfer(columnEntityDef, e, propEleClass));
}
}
propValue = newC;
} else {
propEntityClass = prop.getGetMethod(targetEntityClass).getReturnType();
if (!propEntityClass.equals(propValue.getClass())) {
propValue = transfer(columnEntityDef, propValue, propEntityClass);
}
}
}
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, propValue);
}
}
if (targetEntity instanceof DirtyMarker) {
DirtyMarker anTargetDirtyMarker = (DirtyMarker) targetEntity;
DirtyMarkerUtil.markDirty(anTargetDirtyMarker, false);
if (sourceEntity instanceof DirtyMarker) {
DirtyMarker anSourceDirtyMarker = (DirtyMarker) sourceEntity;
DirtyMarkerUtil.markDirty(anTargetDirtyMarker, DirtyMarkerUtil.dirtyPropNames(anSourceDirtyMarker), true);
DirtyMarkerUtil.setVersion(anTargetDirtyMarker, anSourceDirtyMarker.version());
}
}
return targetEntity;
}
/**
*
* @param entityDef
* @param sourceEntity
* @return
*/
@SuppressWarnings("unchecked")
public static MapEntity disassemble(EntityDefinition entityDef, Object sourceEntity) {
if (sourceEntity == null) {
return null;
}
MapEntity targetEntity = new MapEntity(entityDef.getName());
MapEntity sourcerMapEntity = (sourceEntity instanceof MapEntity) ? (MapEntity) sourceEntity : null;
Collection signedPropNames = EntityManagerUtil.getSignedPropNames(entityDef, sourceEntity);
Property prop = null;
Object propValue = null;
EntityDefinition columnEntityDef = null;
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
if (sourcerMapEntity == null) {
propValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
} else {
propValue = sourcerMapEntity.get(propName);
}
if ((propValue != null) && !(propValue instanceof MapEntity) && prop.getColumnType().isEntity()) {
columnEntityDef = prop.getColumnEntityDef();
if (prop.isCollection() && propValue instanceof Collection) {
Collection propEntityList = (Collection) N.newInstance(propValue.getClass());
for (Object e : (Collection) propValue) {
if (e == null || e instanceof MapEntity) {
propEntityList.add(e);
} else {
propEntityList.add(disassemble(columnEntityDef, e));
}
}
propValue = propEntityList;
} else {
propValue = disassemble(columnEntityDef, propValue);
}
}
targetEntity.set(propName, propValue);
}
return targetEntity;
}
/**
*
* @param
* @param entityDef
* @param sourceEntity
* @param targetClass
* @return
*/
@SuppressWarnings("unchecked")
public static T assemble(EntityDefinition entityDef, MapEntity sourceEntity, Class targetClass) {
if (sourceEntity == null) {
return null;
}
T targetEntity = N.newEntity(targetClass, entityDef.getName());
Property prop = null;
Object propValue = null;
Class> propEntityClass = null;
EntityDefinition columnEntityDef = null;
for (String propName : DirtyMarkerUtil.signedPropNames(sourceEntity)) {
prop = entityDef.getProperty(propName);
propValue = sourceEntity.get(propName);
if ((propValue != null) && prop.getColumnType().isEntity()) {
columnEntityDef = prop.getColumnEntityDef();
if (prop.isCollection() && propValue instanceof Collection) {
Class> propEleClass = getPropEleClass(targetClass, prop);
Collection c = (Collection) propValue;
Collection newC = N.newInstance(c.getClass());
for (Object e : c) {
if (e == null || e.getClass().equals(propEleClass) || !(e instanceof MapEntity)) {
newC.add(e);
} else {
newC.add(assemble(columnEntityDef, (MapEntity) e, propEleClass));
}
}
propValue = newC;
} else {
propEntityClass = prop.getGetMethod(targetClass).getReturnType();
if (!propEntityClass.equals(propValue.getClass()) && propValue instanceof MapEntity) {
propValue = assemble(columnEntityDef, (MapEntity) propValue, propEntityClass);
}
}
}
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, propValue);
}
return targetEntity;
}
/**
*
* @param entityDef
* @param sourceEntity
* @param targetEntity
*/
public static void refresh(EntityDefinition entityDef, Object sourceEntity, Object targetEntity) {
if (sourceEntity == null) {
return;
}
Collection signedPropNames = EntityManagerUtil.getSignedPropNames(entityDef, sourceEntity);
if (targetEntity instanceof MapEntity) {
MapEntity targetMapEntity = (MapEntity) targetEntity;
if (sourceEntity instanceof MapEntity) {
MapEntity sourceMapEntity = (MapEntity) sourceEntity;
for (String propName : signedPropNames) {
targetMapEntity.set(propName, sourceMapEntity.get(propName));
}
} else {
Property prop = null;
Object propValue = null;
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
targetMapEntity.set(propName, propValue);
}
}
} else if (sourceEntity instanceof MapEntity) {
MapEntity sourceMapEntity = (MapEntity) sourceEntity;
Property prop = null;
Object propValue = null;
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
propValue = sourceMapEntity.get(propName);
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, propValue);
}
} else {
Property prop = null;
Object propValue = null;
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, propValue);
}
}
if (targetEntity instanceof DirtyMarker) {
DirtyMarker anTargetEntity = (DirtyMarker) targetEntity;
DirtyMarkerUtil.markDirty(anTargetEntity, signedPropNames, false);
if (sourceEntity instanceof DirtyMarker) {
DirtyMarkerUtil.setVersion(anTargetEntity, ((DirtyMarker) sourceEntity).version());
}
}
}
/**
*
* @param entityDef
* @param sourceEntity
* @param targetEntity
* @param ignoreNullValue
* @param ignoreEqualValue
*/
public static void merge(EntityDefinition entityDef, Object sourceEntity, Object targetEntity, boolean ignoreNullValue, boolean ignoreEqualValue) {
if (sourceEntity == null) {
return;
}
final Map sourceMap = sourceEntity instanceof Map ? (Map) sourceEntity : null;
final MapEntity sourceMapEntity = (sourceEntity instanceof MapEntity) ? (MapEntity) sourceEntity : null;
final MapEntity targetMapEntity = (targetEntity instanceof MapEntity) ? (MapEntity) targetEntity : null;
Property prop = null;
Object sourcePropValue = null;
Object targetPropValue = null;
Collection idPropNames = entityDef.getIdPropertyNameList();
Collection signedPropNames = sourceMap != null ? sourceMap.keySet() : EntityManagerUtil.getSignedPropNames(entityDef, sourceEntity);
if (sourceEntity instanceof DirtyMarker) {
final Collection dirtyPropNames = DirtyMarkerUtil.dirtyPropNames((DirtyMarker) sourceEntity);
for (String propName : signedPropNames) {
if ((idPropNames.size() > 0) && idPropNames.contains(propName)) {
continue;
}
prop = entityDef.getProperty(propName);
if (dirtyPropNames.contains(propName)) {
if (sourceMapEntity == null) {
sourcePropValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
} else {
sourcePropValue = sourceMapEntity.get(propName);
}
if (sourcePropValue == null && ignoreNullValue) {
continue;
}
if (ignoreEqualValue) {
if (targetMapEntity == null) {
targetPropValue = EntityManagerUtil.getPropValueByMethod(targetEntity, prop);
} else {
targetPropValue = targetMapEntity.get(propName);
}
if (N.equals(sourcePropValue, targetPropValue)) {
continue;
}
}
if (targetMapEntity == null) {
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, sourcePropValue);
} else {
targetMapEntity.set(propName, sourcePropValue);
}
} else if (prop.getColumnType().isEntity()) {
if (sourceMapEntity == null) {
sourcePropValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
} else {
sourcePropValue = sourceMapEntity.get(propName);
}
if (sourcePropValue == null) {
continue;
}
if (ignoreEqualValue) {
if (targetMapEntity == null) {
targetPropValue = EntityManagerUtil.getPropValueByMethod(targetEntity, prop);
} else {
targetPropValue = targetMapEntity.get(propName);
}
if (N.equals(sourcePropValue, targetPropValue)) {
continue;
}
}
boolean isUpdatedProp = false;
if (prop.isCollection() && sourcePropValue instanceof Collection) {
@SuppressWarnings("unchecked")
Collection c = (Collection) sourcePropValue;
for (Object e : c) {
if (e instanceof DirtyMarker) {
isUpdatedProp = DirtyMarkerUtil.isDirty((DirtyMarker) e);
} else {
isUpdatedProp = e != null;
}
if (isUpdatedProp) {
break;
}
}
} else {
if (sourcePropValue instanceof DirtyMarker) {
isUpdatedProp = DirtyMarkerUtil.isDirty((DirtyMarker) sourcePropValue);
} else {
isUpdatedProp = true;
}
}
if (isUpdatedProp) {
if (targetMapEntity == null) {
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, sourcePropValue);
} else {
targetMapEntity.set(propName, sourcePropValue);
}
}
}
}
} else if (sourceMap != null) {
for (String propName : signedPropNames) {
if ((idPropNames.size() > 0) && idPropNames.contains(propName)) {
continue;
}
prop = entityDef.getProperty(propName);
sourcePropValue = sourceMap.get(propName);
if (ignoreEqualValue) {
if (targetMapEntity == null) {
targetPropValue = EntityManagerUtil.getPropValueByMethod(targetEntity, prop);
} else {
targetPropValue = targetMapEntity.get(propName);
}
if (N.equals(sourcePropValue, targetPropValue)) {
continue;
}
}
if (targetMapEntity == null) {
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, sourcePropValue);
} else {
targetMapEntity.set(propName, sourcePropValue);
}
}
} else {
for (String propName : signedPropNames) {
if ((idPropNames.size() > 0) && idPropNames.contains(propName)) {
continue;
}
prop = entityDef.getProperty(propName);
sourcePropValue = EntityManagerUtil.getPropValueByMethod(sourceEntity, prop);
if (sourcePropValue == null) {
continue;
}
if (ignoreEqualValue) {
if (targetMapEntity == null) {
targetPropValue = EntityManagerUtil.getPropValueByMethod(targetEntity, prop);
} else {
targetPropValue = targetMapEntity.get(propName);
}
if (N.equals(sourcePropValue, targetPropValue)) {
continue;
}
}
if (targetMapEntity == null) {
EntityManagerUtil.setPropValueByMethod(targetEntity, prop, sourcePropValue);
} else {
targetMapEntity.set(propName, sourcePropValue);
}
}
}
}
/**
*
* @param entityDef
* @param thisEntity
* @return
*/
public static int hashCode(EntityDefinition entityDef, Object thisEntity) {
int h = 17;
h = (h * 31) + entityDef.getName().hashCode();
Collection signedPropNames = EntityManagerUtil.getSignedPropNames(entityDef, thisEntity);
List idPropNames = entityDef.getIdPropertyNameList();
Property prop = null;
Object propValue = null;
for (String propName : idPropNames) {
if (signedPropNames.contains(propName)) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValue(thisEntity, prop);
h = (h * 31) + N.hashCode(propValue);
}
}
for (String propName : signedPropNames) {
if (!idPropNames.contains(propName)) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValue(thisEntity, prop);
h = (h * 31) + N.hashCode(propValue);
}
}
return h;
}
/**
*
* @param entityDef
* @param entity
* @param anObject
* @return true, if successful
*/
public static boolean equals(EntityDefinition entityDef, Object entity, Object anObject) {
if (entity == anObject) {
return true;
}
if (((entity == null) && (anObject != null)) || ((entity != null) && (anObject == null))) {
return false;
}
if (!entity.getClass().equals(anObject.getClass())) {
return false;
}
if (entity instanceof MapEntity) {
final MapEntity anMapEntity = (MapEntity) entity;
final MapEntity anotherMapEntity = (MapEntity) anObject;
final Set signedPropNames = N.newHashSet(DirtyMarkerUtil.signedPropNames(anMapEntity));
signedPropNames.addAll(DirtyMarkerUtil.signedPropNames(anotherMapEntity));
Collection idPropNames = entityDef.getIdPropertyNameList();
Object propValue = null;
Object anotherPropValue = null;
for (String propName : idPropNames) {
if (signedPropNames.contains(propName)) {
propValue = anMapEntity.get(propName);
anotherPropValue = anotherMapEntity.get(propName);
if (!(N.equals(propValue, anotherPropValue))) {
return false;
}
}
}
for (String propName : signedPropNames) {
propValue = anMapEntity.get(propName);
anotherPropValue = anotherMapEntity.get(propName);
if (!(N.equals(propValue, anotherPropValue))) {
return false;
}
}
} else {
Set signedPropNames = N.newHashSet(EntityManagerUtil.getSignedPropNames(entityDef, entity));
signedPropNames.addAll(EntityManagerUtil.getSignedPropNames(entityDef, anObject));
Collection idPropNames = entityDef.getIdPropertyNameList();
Property prop = null;
Object propValue = null;
Object anotherPropValue = null;
for (String propName : idPropNames) {
if (signedPropNames.contains(propName)) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValueByMethod(entity, prop);
anotherPropValue = EntityManagerUtil.getPropValueByMethod(anObject, prop);
if (!(N.equals(propValue, anotherPropValue))) {
return false;
}
}
}
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
propValue = EntityManagerUtil.getPropValueByMethod(entity, prop);
anotherPropValue = EntityManagerUtil.getPropValueByMethod(anObject, prop);
if (!(N.equals(propValue, anotherPropValue))) {
return false;
}
}
}
return true;
}
/**
*
* @param entityDef
* @param thisEntity
* @return
*/
public static String toString(EntityDefinition entityDef, Object thisEntity) {
Collection signedPropNames = EntityManagerUtil.getSignedPropNames(entityDef, thisEntity);
if (signedPropNames.size() == 0) {
return DOUBLE_BRACKET;
}
final StringBuilder sb = Objectory.createStringBuilder();
final boolean hasIdProperty = entityDef.getIdPropertyList().size() > 0;
Property prop = null;
Object propValue = null;
int index = 0;
sb.append('{');
if (hasIdProperty) {
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
if (prop.isId()) {
if (index++ > 0) {
sb.append(", ");
}
propValue = EntityManagerUtil.getPropValue(thisEntity, prop);
sb.append(prop.getName());
sb.append('=');
sb.append(N.toString(propValue));
}
}
}
for (String propName : signedPropNames) {
prop = entityDef.getProperty(propName);
if (!prop.isId()) {
if (index++ > 0) {
sb.append(", ");
}
propValue = EntityManagerUtil.getPropValue(thisEntity, prop);
sb.append(prop.getName());
sb.append('=');
sb.append(N.toString(propValue));
}
}
sb.append('}');
String st = sb.toString();
Objectory.recycle(sb);
return st;
}
/**
* Gets the prop ele class.
*
* @param
* @param entityClass
* @param prop
* @return
*/
@SuppressWarnings("unchecked")
private static T getPropEleClass(Class> entityClass, Property prop) {
Method method = prop.getSetMethod(entityClass);
Class> propValueClass = null;
if (prop.isCollection()) {
propValueClass = (Class>) ((ParameterizedType) (method.getGenericParameterTypes()[0])).getActualTypeArguments()[0];
} else {
propValueClass = method.getParameterTypes()[0];
}
return (T) propValueClass;
/*
* String propClassName = prop.getColumnEntityDefinition().getName(); propClassName =
* propClassName.replace(PERIOD, DOLLAR); propClassName = (clazz.getPackage() == null) ? propClassName :
* (clazz.getPackage() .getName() + PERIOD + propClassName);
*
* try { return (T) N.forClass(propClassName); } catch (ClassNotFoundException e) { throw new
* RuntimeException(e); }
*/
}
}