blob: 38951739f84c25b88a5df15f0016664a7601288c [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.common.annotations;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.reflect.MethodUtils;
import org.apache.commons.lang3.ClassUtils;
import org.eclipse.osbp.runtime.common.historized.UUIDHist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class DtoUtils.
*/
public class DtoUtils {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(DtoUtils.class);
/** The infos. */
private static Map<Class<?>, Info> INFOS = Collections.synchronizedMap(new HashMap<Class<?>, DtoUtils.Info>());
/**
* Returns the dispose field. Field annotated with {@link Dispose}.
*
* @param clazz
* the clazz
* @return the dispose field
*/
public static Field getDisposeField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDisposeField();
}
/**
* Returns the dispose field. Field annotated with {@link Dirty}.
*
* @param clazz
* the clazz
* @return the dirty field
*/
public static Field getDirtyField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDirtyField();
}
/**
* Returns the domain key field. Field annotated with {@link DomainKey}.
*
* @param clazz
* the clazz
* @return the domain key field
*/
public static Field getDomainKeyField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDomainKeyField();
}
/**
* Returns the id field. Field annotated with {@link Id}.
*
* @param clazz
* the clazz
* @return the id field
*/
public static Field getIdField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getIdField();
}
/**
* Returns the idValidFrom field for historized objects. Field annotated
* with {@link IdValidFrom}.
*
* @param clazz
* the clazz
* @return the idValidFrom field
*/
public static Field getIdValidFromField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getIdValidFromField();
}
public static boolean isUUID(Class<?> clazz) {
Info info = getInfo(clazz);
Field field = info.getIdField();
if (field.getType() == String.class) {
return true;
}
return false;
}
public static Object cloneDto(Object dto) {
Object cloneDto = null;
try {
cloneDto = dto.getClass().newInstance();
Map<String, Field> fields = getAllFieldsAsMap(dto.getClass());
BeanInfo beanInfo = Introspector.getBeanInfo(dto.getClass());
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
Field field = fields.get(pd.getName());
if (field == null || field.isAnnotationPresent(Dispose.class)) {
continue;
}
if (pd.getPropertyType().isAssignableFrom(List.class)) {
continue;
}
pd.getWriteMethod().invoke(cloneDto, pd.getReadMethod().invoke(dto));
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException | IntrospectionException e) {
e.printStackTrace();
}
return cloneDto;
}
/**
* Creates a copy of the given dto and sets a new historized uuid version.
* @param dto
* @return
*/
public static <T> T newHistorizedVersionCopy(T dto){
@SuppressWarnings("unchecked")
T copy = (T) copyDto(dto);
UUIDHist id = (UUIDHist) getIdValue(copy);
setIdValue(copy, id.newVersion());
return copy;
}
public static Object copyDto(Object dto) {
Object copyDto = null;
try {
copyDto = dto.getClass().newInstance();
Map<String, Field> fields = getAllFieldsAsMap(dto.getClass());
BeanInfo beanInfo = Introspector.getBeanInfo(dto.getClass());
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
Field field = fields.get(pd.getName());
if (field == null || field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(Version.class)
|| field.isAnnotationPresent(Dispose.class)) {
continue;
}
if (pd.getPropertyType().isAssignableFrom(List.class)) {
continue;
}
pd.getWriteMethod().invoke(copyDto, pd.getReadMethod().invoke(dto));
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException | IntrospectionException e) {
e.printStackTrace();
}
return copyDto;
}
public static void invokeSetOwner(Object obj, String setterName, Object ref) {
for (Method method : obj.getClass().getDeclaredMethods()) {
if (setterName.equals(method.getName())) {
try {
method.invoke(obj, ref);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return;
}
}
}
/**
* Gets the version field. Field annotated with {@link Version}.
*
* @param clazz
* the clazz
* @return the version field
*/
public static Field getVersionField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getVersionField();
}
/**
* Returns the id field. Field annotated with {@link Id}.
*
* @param dto
* the dto
* @return the id field
*/
public static Object getIdValue(Object dto) {
Info info = getInfo(dto.getClass());
Field f = info.getIdField();
f.setAccessible(true);
try {
return f.get(dto);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setIdValue(Object dto, Object idValue) {
Info info = getInfo(dto.getClass());
Field f = info.getIdField();
f.setAccessible(true);
try {
f.set(dto, idValue);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setVersionValue(Object dto, Object versionValue) {
Info info = getInfo(dto.getClass());
Field f = info.getVersionField();
f.setAccessible(true);
try {
f.set(dto, versionValue);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setCreateUser(Object dto, String user) {
Info info = getInfo(dto.getClass());
Field f = info.getCreateByField();
f.setAccessible(true);
try {
f.set(dto, user);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setUpdateUser(Object dto, String user) {
Info info = getInfo(dto.getClass());
Field f = info.getUpdateByField();
f.setAccessible(true);
try {
f.set(dto, user);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setCreateAt(Object dto, Date date) {
Info info = getInfo(dto.getClass());
Field f = info.getCreateAtField();
f.setAccessible(true);
try {
f.set(dto, date);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static void setUpdateAt(Object dto, Date date) {
Info info = getInfo(dto.getClass());
Field f = info.getUpdateAtField();
f.setAccessible(true);
try {
f.set(dto, date);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static String getCreateUser(Object dto) {
Info info = getInfo(dto.getClass());
Field f = info.getCreateByField();
f.setAccessible(true);
try {
return (String) f.get(dto);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static String getUpdateUser(Object dto) {
Info info = getInfo(dto.getClass());
Field f = info.getUpdateByField();
f.setAccessible(true);
try {
return (String) f.get(dto);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static Date getCreateAt(Object dto) {
Info info = getInfo(dto.getClass());
Field f = info.getCreateAtField();
f.setAccessible(true);
try {
return (Date) f.get(dto);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static Date getUpdateAt(Object dto) {
Info info = getInfo(dto.getClass());
Field f = info.getUpdateAtField();
f.setAccessible(true);
try {
return (Date) f.get(dto);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public static List<Field> getAllFields(Class<?> clazz) {
if (clazz == null) {
return null;
}
List<Field> result = new ArrayList<>();
try {
result.addAll(Arrays.asList(clazz.getDeclaredFields()));
} catch (SecurityException e) {
LOGGER.warn("{}", e);
}
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
List<Field> temp = getAllFields(superClass);
result.addAll(temp);
}
return result;
}
public static Map<String, Field> getAllFieldsAsMap(Class<?> clazz) {
if (clazz == null) {
return null;
}
Map<String, Field> result = new HashMap<>();
try {
for (Field field : clazz.getDeclaredFields()) {
result.put(field.getName(), field);
}
} catch (SecurityException e) {
LOGGER.warn("{}", e);
}
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
Map<String, Field> temp = getAllFieldsAsMap(superClass);
result.putAll(temp);
}
return result;
}
/**
* Returns the field value.
*
* @param instance
* the instance
* @param idProperty
* the id property
* @return the value
*/
public static Object getValue(Object instance, String idProperty) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(instance.getClass());
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (pd.getName().equals(idProperty)) {
Method idMethod = pd.getReadMethod();
return idMethod.invoke(instance);
}
}
} catch (Exception e) {
LOGGER.error("{}", e);
}
return null;
}
/**
* Sets the field value.
*
* @param instance
* the instance
* @param idProperty
* the id property
* @param value
* the value
*/
public static void setValue(Object dto, String idProperty, Object value) {
try {
BeanInfo beanInfo = Introspector.getBeanInfo(dto.getClass());
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (pd.getName().equals(idProperty)
&& (value == null || ClassUtils.isAssignable(pd.getPropertyType(), value.getClass(), true))) {
pd.getWriteMethod().invoke(dto, value);
break;
}
}
} catch (IntrospectionException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
LOGGER.error("{}", e);
}
}
/**
* Returns the domain description field. Field annotated with
* #DomainDescription.
*
* @param clazz
* the clazz
* @return the domain description field
*/
public static Field getDomainDescriptionField(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDomainDescriptionField();
}
/**
* Returns the dispose field. Field annotated with {@link Dirty}.
*
* @param clazz
* the clazz
* @return the dirty getter
*/
public static Method getDirtyGetter(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDirtyGetter();
}
/**
* Returns the dispose field. Field annotated with {@link Dirty}.
*
* @param clazz
* the clazz
* @return the dirty setter
*/
public static Method getDirtySetter(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDirtySetter();
}
/**
* Returns the dispose method. Method annotated with {@link Dispose}.
*
* @param clazz
* the clazz
* @return the dispose method
*/
public static Method getDisposeMethod(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getDisposeMethod();
}
/**
* Returns true, if the given field is a dispose field.
*
* @param clazz
* the clazz
* @param fieldName
* the field name
* @return true, if is dispose field
*/
public static boolean isDisposeField(Class<?> clazz, String fieldName) {
Info info = getInfo(clazz);
return info.getDisposeField() != null ? info.getDisposeField().getName().equals(fieldName) : false;
}
/**
* Returns true, if the given field is a id field.
*
* @param clazz
* the clazz
* @param fieldName
* the field name
* @return true, if is id field
*/
public static boolean isIdField(Class<?> clazz, String fieldName) {
Info info = getInfo(clazz);
return info.getIdField() != null ? info.getIdField().getName().equals(fieldName) : false;
}
/**
* Returns true, if the given field is a domainkey field.
*
* @param clazz
* the clazz
* @param fieldName
* the field name
* @return true, if is domainkey field
*/
public static boolean isDomainkeyField(Class<?> clazz, String fieldName) {
Field dkField = getDomainKeyField(clazz);
return dkField != null && dkField.getName().equals(fieldName);
}
/**
* Returns true, if the given field is a version field.
*
* @param clazz
* the clazz
* @param fieldName
* the field name
* @return true, if is version field
*/
public static boolean isVersionField(Class<?> clazz, String fieldName) {
Info info = getInfo(clazz);
return info.getVersionField() != null ? info.getVersionField().getName().equals(fieldName) : false;
}
/**
* Returns true, if the given field is a dirty field. Dirty fields indicate
* that the dto is dirty.
*
* @param clazz
* the clazz
* @param fieldName
* the field name
* @return true, if is dirty field
*/
public static boolean isDirtyField(Class<?> clazz, String fieldName) {
Info info = getInfo(clazz);
return info.getDirtyField() != null ? info.getDirtyField().getName().equals(fieldName) : false;
}
/**
* Returns true, if the given method is a dispose method.
*
* @param clazz
* the clazz
* @param methodName
* the method name
* @return true, if is dispose method
*/
public static boolean isDisposeMethod(Class<?> clazz, String methodName) {
Info info = getInfo(clazz);
return info.getDisposeField() != null ? info.getDisposeMethod().getName().equals(methodName) : false;
}
/**
* Tries to invoke the dispose method.
*
* @param obj
* the obj
* @return true, if the method could be invoked. False otherwise.
*/
public static boolean invokeDisposeMethod(Object obj) {
Info info = getInfo(obj.getClass());
if (info != null && info.getDisposeMethod() != null) {
try {
info.getDisposeMethod().invoke(obj, new Object[0]);
} catch (IllegalAccessException e) {
return false;
} catch (IllegalArgumentException e) {
return false;
} catch (InvocationTargetException e) {
return false;
}
}
return true;
}
/**
* Tries to invoke the setDirty method.
*
* @param obj
* the obj
* @param value
* the value
* @return true, if the method could be invoked. False otherwise.
*/
public static boolean invokeDirtySetter(Object obj, boolean value) {
Info info = getInfo(obj.getClass());
if (info.getDirtySetter() != null) {
try {
info.getDirtySetter().invoke(obj, new Object[] { value });
} catch (IllegalAccessException e) {
return false;
} catch (IllegalArgumentException e) {
return false;
} catch (InvocationTargetException e) {
return false;
}
}
return true;
}
/**
* Tries to invoke the dirty getter. If there is no dirty getter available,
* the method throws an {@link IllegalAccessException}.
*
* @param obj
* the obj
* @return true, if is dirty
* @throws IllegalAccessException
* the illegal access exception
*/
public static boolean isDirty(Object obj) throws IllegalAccessException {
return invokeDirtyGetter(obj);
}
/**
* Tries to invoke the isDirty method.
*
* @param obj
* the obj
* @return true, if the method could be invoked. False otherwise.
* @throws IllegalAccessException
* the illegal access exception
*/
public static boolean invokeDirtyGetter(Object obj) throws IllegalAccessException {
Info info = getInfo(obj.getClass());
if (info.getDirtySetter() != null) {
try {
return (Boolean) info.getDirtyGetter().invoke(obj, new Object[0]);
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}
}
throw new IllegalAccessException("Not a valid call");
}
/**
* Gets the owner domain references.
*
* @param clazz
* the clazz
* @return the owner domain references
*/
public static List<Field> getOwnerDomainReferences(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getOwnerDomainReferences();
}
/**
* Gets the member domain references.
*
* @param clazz
* the clazz
* @return the member domain references
*/
public static List<Field> getMemberDomainReferences(Class<?> clazz) {
Info info = getInfo(clazz);
return info.getMemberDomainReferences();
}
/**
* Returns the info for the given class.
*
* @param clazz
* the clazz
* @return the info
*/
protected static Info getInfo(Class<?> clazz) {
Info info = INFOS.get(clazz);
if (info == null) {
info = createInfo(clazz);
}
return info;
}
/**
* Creates a new info.
*
* @param clazz
* the clazz
* @return info
*/
private static Info createInfo(Class<?> clazz) {
Info info = new Info();
applyFieldInfo(clazz, info);
applyMethodInfo(clazz, info);
INFOS.put(clazz, info);
return info;
}
/**
* Returns the adapter which has proper type from the given dto. Or
* <code>null</code> if no adapter is available.
*
* @param <A>
* the generic type
* @param type
* the type
* @param dto
* the dto
* @return the adapter
*/
@SuppressWarnings("unchecked")
public static <A> A getAdapter(Class<A> type, Object dto) {
if (type == null || dto == null) {
return null;
}
Info info = getInfo(dto.getClass());
if (info.getPropertyChangeSupportField() == null) {
return null;
}
try {
info.getPropertyChangeSupportField().setAccessible(true);
PropertyChangeSupport changeSupport = (PropertyChangeSupport) info.getPropertyChangeSupportField().get(dto);
if (changeSupport == null) {
return null;
}
for (PropertyChangeListener listener : changeSupport.getPropertyChangeListeners()) {
if (type.isAssignableFrom(listener.getClass())) {
return (A) listener;
}
}
} catch (IllegalArgumentException e) {
LOGGER.error("{}", e);
} catch (IllegalAccessException e) {
LOGGER.error("{}", e);
}
return null;
}
/**
* Registers the adapter as a property changed listener.
*
* @param adapter
* the adapter
* @param dto
* the dto
*/
public static void registerAdapter(PropertyChangeListener adapter, Object dto) {
if (adapter == null || dto == null) {
return;
}
try {
MethodUtils.invokeMethod(dto, "addPropertyChangeListener", adapter);
} catch (SecurityException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (IllegalAccessException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (IllegalArgumentException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (InvocationTargetException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (NoSuchMethodException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
}
}
/**
* Returns true, if the given id is a {@link UUIDHist}.
*
* @param id
* @return
*/
public static boolean isHistorizedId(Object id) {
return id instanceof UUIDHist;
}
/**
* Unregisters the adapter as a property changed listener.
*
* @param adapter
* the adapter
* @param dto
* the dto
*/
public static void unregisterAdapter(PropertyChangeListener adapter, Object dto) {
if (adapter == null || dto == null) {
return;
}
try {
MethodUtils.invokeMethod(dto, "removePropertyChangeListener", adapter);
} catch (SecurityException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (IllegalAccessException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (IllegalArgumentException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (InvocationTargetException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
} catch (NoSuchMethodException e) {
LOGGER.info("Observer for dirtyState handling could not be added for " + dto.getClass().getName());
}
}
public static List<String> getFieldNames(Class<?> clazz) {
List<String> fieldNames = new ArrayList<>();
try {
for (Field field : clazz.getDeclaredFields()) {
fieldNames.add(field.getName());
}
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
fieldNames.addAll(getFieldNames(superClass));
}
} catch (SecurityException e) {
LOGGER.error("{}", e);
}
return fieldNames;
}
/**
* Applies all required field infos to the info object.
*
* @param clazz
* the clazz
* @param info
* the info
*/
private static void applyFieldInfo(Class<?> clazz, Info info) {
try {
info.historized = clazz.isAnnotationPresent(HistorizedObject.class);
info.timedependent = clazz.isAnnotationPresent(TimedependentObject.class);
info.compoundHistKey = info.historized || info.timedependent;
for (Field field : clazz.getDeclaredFields()) {
if (field.getAnnotation(Dispose.class) != null) {
info.disposeField = field;
}
if (field.getAnnotation(DomainKey.class) != null) {
info.domainKeyField = field;
}
if (field.getAnnotation(DomainDescription.class) != null) {
info.domainDescriptionField = field;
}
if (field.getAnnotation(Id.class) != null) {
info.idField = field;
if (info.compoundHistKey) {
Class<?> idType = field.getType();
info.histIdInfo = toHistIdInfo(idType);
}
}
if (field.getAnnotation(Version.class) != null) {
info.versionField = field;
}
if (field.getAnnotation(CreateAt.class) != null) {
info.createAtField = field;
}
if (field.getAnnotation(CreateBy.class) != null) {
info.createByField = field;
}
if (field.getAnnotation(UpdateAt.class) != null) {
info.updateAtField = field;
}
if (field.getAnnotation(UpdateBy.class) != null) {
info.updateByField = field;
}
if (field.getAnnotation(DomainReference.class) != null) {
if (field.getType().isAssignableFrom(List.class)) {
info.memberDomainReferences.add(field);
} else {
info.ownerDomainReferences.add(field);
}
}
if (field.getType() == PropertyChangeSupport.class) {
info.propertyChangeSupportField = field;
}
if (field.getAnnotation(Dirty.class) != null) {
info.dirtyField = field;
try {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
if (pd.getName().equals(info.dirtyField.getName())) {
info.dirtyPropertyDescriptor = pd;
break;
}
}
} catch (IntrospectionException e) {
LOGGER.error("{}", e);
}
}
if (info.disposeField != null && info.dirtyField != null && info.domainKeyField != null
&& info.domainDescriptionField != null && info.idField != null) {
break;
}
}
if (info.disposeField == null || info.domainKeyField == null || info.domainDescriptionField == null
|| info.idField == null) {
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
applyFieldInfo(superClass, info);
}
}
} catch (SecurityException e) {
LOGGER.error("{}", e);
}
}
/**
* Creates an info object for historized and timedependent objects.
*
* @param idType
* @return
*/
private static CompoundHistIdInfo toHistIdInfo(Class<?> idType) {
CompoundHistIdInfo histInfo = new CompoundHistIdInfo();
for (Field field : idType.getDeclaredFields()) {
if (field.getAnnotation(HistUUID.class) != null) {
histInfo.rawUUIDField = field;
} else if (field.getAnnotation(HistValidFrom.class) != null) {
histInfo.rawVersionFromField = field;
}
if (histInfo.rawUUIDField != null && histInfo.rawVersionFromField != null) {
break;
}
}
if (histInfo.rawUUIDField == null || histInfo.rawVersionFromField == null) {
throw new IllegalStateException(
"rawUUID and rawVersionFrom must be present for historized and timedependet objects");
}
return histInfo;
}
/**
* Applies all required field infos to the info object.
*
* @param clazz
* the clazz
* @param info
* the info
*/
private static void applyMethodInfo(Class<?> clazz, Info info) {
try {
for (Method method : clazz.getDeclaredMethods()) {
if (method.getAnnotation(Dispose.class) != null) {
info.disposeMethod = method;
break;
}
}
if (info.disposeMethod == null) {
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
applyMethodInfo(superClass, info);
}
}
} catch (SecurityException e) {
LOGGER.error("{}", e);
}
}
/**
* Find field.
*
* @param clazz
* the clazz
* @param name
* the name
* @return the field
*/
protected static Field findField(Class<?> clazz, String name) {
try {
Field field = clazz.getDeclaredField(name);
return field;
} catch (NoSuchFieldException e) {
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
return findField(superClass, name);
}
} catch (SecurityException e) {
LOGGER.error("{}", e);
}
return null;
}
/**
* The Class Info.
*/
private static class Info {
public boolean historized;
public boolean timedependent;
/**
* Is true, if {@link #historized} or {@link #timedependent} is true.
*/
public boolean compoundHistKey;
public CompoundHistIdInfo histIdInfo;
public Field updateByField;
public Field updateAtField;
public Field createByField;
public Field createAtField;
/** The property change support field. */
private Field propertyChangeSupportField;
/** The dispose field. */
private Field disposeField;
/** The dispose method. */
private Method disposeMethod;
/** The id field. */
private Field idField;
private Field idValidFromField;
/** The dirty field. */
private Field dirtyField;
/** The dirty property descriptor. */
private PropertyDescriptor dirtyPropertyDescriptor;
/** The domain key field. */
private Field domainKeyField;
/** The domain description field. */
private Field domainDescriptionField;
/** The version field. */
private Field versionField;
/**
* The owner domain references = all 1 references of a oneToMany
* relationship.
*/
private List<Field> ownerDomainReferences = new ArrayList<>();
/**
* The member domain references = all n references of a oneToMany
* relationship.
*/
private List<Field> memberDomainReferences = new ArrayList<>();
/**
* Gets the dispose field.
*
* @return the dispose field
*/
public Field getDisposeField() {
return disposeField;
}
/**
* Gets the owner domain references.
*
* @return the owner domain references
*/
public List<Field> getOwnerDomainReferences() {
return ownerDomainReferences;
}
/**
* Gets the member domain references.
*
* @return the member domain references
*/
public List<Field> getMemberDomainReferences() {
return memberDomainReferences;
}
/**
* Gets the version field.
*
* @return the version field
*/
public Field getVersionField() {
return versionField;
}
/**
* Gets the dirty field.
*
* @return the dirty field
*/
public Field getDirtyField() {
return dirtyField;
}
/**
* Gets the dirty getter.
*
* @return the dirty getter
*/
public Method getDirtyGetter() {
return dirtyPropertyDescriptor != null ? dirtyPropertyDescriptor.getReadMethod() : null;
}
/**
* Gets the dirty setter.
*
* @return the dirty setter
*/
public Method getDirtySetter() {
return dirtyPropertyDescriptor != null ? dirtyPropertyDescriptor.getWriteMethod() : null;
}
/**
* Gets the dispose method.
*
* @return the dispose method
*/
public Method getDisposeMethod() {
return disposeMethod;
}
/**
* Gets the domain key field.
*
* @return the domain key field
*/
public Field getDomainKeyField() {
return domainKeyField;
}
/**
* Gets the domain description field.
*
* @return the domain description field
*/
public Field getDomainDescriptionField() {
return domainDescriptionField;
}
/**
* Gets the property change support field.
*
* @return the property change support field
*/
public Field getPropertyChangeSupportField() {
return propertyChangeSupportField;
}
public Field getIdField() {
return idField;
}
public Field getIdValidFromField() {
return idValidFromField;
}
public Field getUpdateByField() {
return updateByField;
}
public Field getUpdateAtField() {
return updateAtField;
}
public Field getCreateByField() {
return createByField;
}
public Field getCreateAtField() {
return createAtField;
}
}
public static class CompoundHistIdInfo {
public Field rawUUIDField;
public Field rawVersionFromField;
}
}