All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javers.common.reflection.JaversMember Maven / Gradle / Ivy

package org.javers.common.reflection;

import org.javers.common.collections.Sets;
import org.javers.common.validation.Validate;
import org.javers.core.metamodel.property.MissingProperty;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

/**
 * Enhanced Field or Method, deals with Java type erasure.
 * 

* * A Member (getter or field) inherited from a Generic superclass with actual (return) type resolved. *

* * Formal type parameter of superclass is resolved to actual type argument of subclass. * * @author bartosz walacik */ public abstract class JaversMember { private final T rawMember; //delegate private final Optional resolvedReturnType; private final boolean looksLikeId; private final Map> mirrorMembersMemoized = new ConcurrentHashMap<>(); /** * @param resolvedReturnType nullable */ protected JaversMember(T rawMember, Type resolvedReturnType) { this(rawMember, resolvedReturnType, ReflectionUtil.looksLikeId(rawMember)); } protected JaversMember(final T rawMember, final Type resolvedReturnType, final boolean looksLikeId) { Validate.argumentIsNotNull(rawMember); this.rawMember = rawMember; this.resolvedReturnType = Optional.ofNullable(resolvedReturnType); this.looksLikeId = looksLikeId; setAccessibleIfNecessary(rawMember); } protected abstract Type getRawGenericType(); public abstract Class getRawType(); public T getRawMember() { return rawMember; } public Type getGenericResolvedType() { if (resolvedReturnType.isPresent()) { return resolvedReturnType.get(); } return getRawGenericType(); } public Class getDeclaringClass() { return rawMember.getDeclaringClass(); } public String name() { return rawMember.getName(); } public String propertyName() { return rawMember.getName(); } public Set getAnnotations() { return ReflectionUtil.getAnnotations(rawMember); } public Set> getAnnotationTypes() { return Sets.transform(getAnnotations(), ann -> ann.annotationType()); } public boolean looksLikeId() { return looksLikeId; } public abstract Object getEvenIfPrivate(Object target); public abstract void setEvenIfPrivate(Object target, Object value); void setAccessibleIfNecessary(Member rawMember) { if (!isPublic(rawMember)) { ((AccessibleObject) rawMember).setAccessible(true); //that's Java Reflection API ... } } private boolean isPublic(Member member) { return Modifier.isPublic(member.getModifiers()) && Modifier.isPublic(member.getDeclaringClass().getModifiers()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; JaversMember that = (JaversMember) o; return this.rawMember.equals(that.rawMember) && this.resolvedReturnType.equals(that.resolvedReturnType); } @Override public int hashCode() { return rawMember.hashCode() + resolvedReturnType.hashCode(); } Object getOnMissingProperty(Object onObject) { Optional mirror = mirrorMembersMemoized.computeIfAbsent(onObject.getClass(), c -> ReflectionUtil.getMirrorMember(this, c)); return mirror.map(s -> s.getEvenIfPrivate(onObject)).orElse(MissingProperty.INSTANCE); } public abstract String memberType(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy