org.sfm.reflect.PropertyFinder Maven / Gradle / Ivy
package org.sfm.reflect;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.sfm.map.MapperBuildingException;
import org.sfm.reflect.asm.ConstructorDefinition;
import org.sfm.reflect.asm.ConstructorParameter;
import org.sfm.utils.PropertyNameMatcher;
public final class PropertyFinder {
private final List> eligibleConstructorDefinitions;
private final ClassMeta classMeta;
private final Map> subPropertyFinders = new HashMap<>();
public PropertyFinder(ClassMeta classMeta) throws MapperBuildingException {
this.classMeta = classMeta;
this.eligibleConstructorDefinitions = classMeta.getConstructorDefinitions() != null ? new ArrayList<>(classMeta.getConstructorDefinitions()) : null;
}
public PropertyMeta findProperty(final PropertyNameMatcher propertyNameMatcher) {
PropertyMeta prop = null;
// check for constructor
prop = lookForConstructor(propertyNameMatcher);
if (prop == null) {
prop = lookForProperty(propertyNameMatcher);
if (prop == null) {
prop = lookForSubPropertyInConstructors(propertyNameMatcher);
if (prop == null) {
prop = lookForSubProperty(propertyNameMatcher);
} else {
ConstructorPropertyMeta constructorProperty = (ConstructorPropertyMeta) ((SubPropertyMeta)prop).getProperty();
removeNonMatching(constructorProperty.getConstructorParameter());
}
}
} else {
ConstructorPropertyMeta constructorProperty = (ConstructorPropertyMeta) prop;
removeNonMatching(constructorProperty.getConstructorParameter());
}
return prop;
}
public ConstructorPropertyMeta lookForConstructor(final PropertyNameMatcher propertyNameMatcher) {
if (classMeta.getConstructorProperties() != null) {
for (ConstructorPropertyMeta prop : classMeta.getConstructorProperties()) {
if (propertyNameMatcher.matches(prop.getName())
&& hasConstructorMatching(prop.getConstructorParameter())) {
return prop;
}
}
}
return null;
}
public PropertyMeta lookForProperty(final PropertyNameMatcher propertyNameMatcher) {
for (PropertyMeta prop : classMeta.getProperties()) {
if (propertyNameMatcher.matches(prop.getName())) {
return prop;
}
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public PropertyMeta lookForSubPropertyInConstructors(final PropertyNameMatcher propertyNameMatcher) {
if (classMeta.getConstructorProperties() != null) {
for (ConstructorPropertyMeta prop : classMeta.getConstructorProperties()) {
if (propertyNameMatcher.couldBePropertyOf(prop.getName())
&& hasConstructorMatching(prop.getConstructorParameter())) {
PropertyMeta, ?> subProp = lookForSubProperty(propertyNameMatcher, prop);
if (subProp != null) {
return new SubPropertyMeta(classMeta.getReflectionService(), prop, subProp);
}
}
}
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public PropertyMeta lookForSubProperty(final PropertyNameMatcher propertyNameMatcher) {
for (PropertyMeta prop : classMeta.getProperties()) {
if (propertyNameMatcher.couldBePropertyOf(prop.getName())) {
PropertyMeta, ?> subProp = lookForSubProperty(propertyNameMatcher, prop);
if (subProp != null) {
return new SubPropertyMeta(classMeta.getReflectionService(), prop, subProp);
}
}
}
return null;
}
private PropertyMeta, ?> lookForSubProperty(
final PropertyNameMatcher propertyNameMatcher,
final PropertyMeta prop) {
PropertyFinder> subPropertyFinder = subPropertyFinders.get(prop.getName());
if (subPropertyFinder == null) {
subPropertyFinder = new PropertyFinder<>(prop.getClassMeta());
subPropertyFinders.put(prop.getName(), subPropertyFinder);
}
PropertyMeta, ?> subProp = subPropertyFinder.findProperty(propertyNameMatcher);
return subProp;
}
private void removeNonMatching(ConstructorParameter param) {
ListIterator> li = eligibleConstructorDefinitions.listIterator();
while(li.hasNext()){
ConstructorDefinition cd = li.next();
if (!cd.hasParam(param)) {
li.remove();
}
}
}
private boolean hasConstructorMatching(ConstructorParameter param) {
ListIterator> li = eligibleConstructorDefinitions.listIterator();
while(li.hasNext()){
ConstructorDefinition cd = li.next();
if (cd.hasParam(param)) {
return true;
}
}
return false;
}
public PropertyMeta findProperty(String propertyName) {
return findProperty(new PropertyNameMatcher(propertyName));
}
public List> getEligibleConstructorDefinitions() {
return eligibleConstructorDefinitions;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy