org.sfm.reflect.meta.ObjectPropertyFinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simpleFlatMapper Show documentation
Show all versions of simpleFlatMapper Show documentation
Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.
package org.sfm.reflect.meta;
import org.sfm.map.MapperBuildingException;
import org.sfm.reflect.ConstructorDefinition;
import org.sfm.reflect.ConstructorParameter;
import java.util.*;
final class ObjectPropertyFinder implements PropertyFinder {
private final List> eligibleConstructorDefinitions;
private final ObjectClassMeta classMeta;
private final Map> subPropertyFinders = new HashMap>();
ObjectPropertyFinder(ObjectClassMeta classMeta) throws MapperBuildingException {
this.classMeta = classMeta;
this.eligibleConstructorDefinitions = classMeta.getConstructorDefinitions() != null ? new ArrayList>(classMeta.getConstructorDefinitions()) : null;
}
/* (non-Javadoc)
* @see org.sfm.reflect.PropertyFinder#findProperty(org.sfm.utils.PropertyNameMatcher)
*/
@SuppressWarnings("unchecked")
@Override
public PropertyMeta findProperty(final PropertyNameMatcher propertyNameMatcher) {
// check for constructor
PropertyMeta 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).getOwnerProperty();
removeNonMatching(constructorProperty.getConstructorParameter());
}
}
} else {
ConstructorPropertyMeta constructorProperty = (ConstructorPropertyMeta) prop;
removeNonMatching(constructorProperty.getConstructorParameter());
}
return (PropertyMeta) prop;
}
@SuppressWarnings("unchecked")
@Override
public ConstructorPropertyMeta findConstructor(ConstructorDefinition constructorDefinition) {
ConstructorPropertyMeta prop = lookForConstructor(constructorDefinition);
if (prop != null) {
removeNonMatching(prop.getConstructorParameter());
}
return (ConstructorPropertyMeta) prop;
}
private ConstructorPropertyMeta lookForConstructor(final ConstructorDefinition constructorDefinition) {
if (classMeta.getConstructorProperties() != null) {
ConstructorParameter parameter = constructorDefinition.getParameters()[0];
for (ConstructorPropertyMeta prop : classMeta.getConstructorProperties()) {
if (prop.getName().equals(parameter.getName())
&& prop.getConstructorParameter().equals(parameter)) {
return prop;
}
}
}
return null;
}
private ConstructorPropertyMeta lookForConstructor(final PropertyNameMatcher propertyNameMatcher) {
if (classMeta.getConstructorProperties() != null) {
for (ConstructorPropertyMeta prop : classMeta.getConstructorProperties()) {
if (propertyNameMatcher.matches(prop.getColumn())
&& hasConstructorMatching(prop.getConstructorParameter())) {
return prop;
}
}
}
return null;
}
private PropertyMeta lookForProperty(final PropertyNameMatcher propertyNameMatcher) {
for (PropertyMeta prop : classMeta.getProperties()) {
if (propertyNameMatcher.matches(prop.getColumn())) {
return prop;
}
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private PropertyMeta lookForSubPropertyInConstructors(final PropertyNameMatcher propertyNameMatcher) {
if (classMeta.getConstructorProperties() != null) {
for (ConstructorPropertyMeta prop : classMeta.getConstructorProperties()) {
PropertyNameMatcher subPropMatcher = propertyNameMatcher.partialMatch(prop.getColumn());
if (subPropMatcher != null && hasConstructorMatching(prop.getConstructorParameter())) {
PropertyMeta, ?> subProp = lookForSubProperty(subPropMatcher, prop);
if (subProp != null) {
return new SubPropertyMeta(classMeta.getReflectionService(), prop, subProp);
}
}
}
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private PropertyMeta lookForSubProperty(final PropertyNameMatcher propertyNameMatcher) {
for (PropertyMeta prop : classMeta.getProperties()) {
PropertyNameMatcher subPropMatcher = propertyNameMatcher.partialMatch(prop.getColumn());
if (subPropMatcher != null) {
PropertyMeta, ?> subProp = lookForSubProperty(subPropMatcher, 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.getColumn());
if (subPropertyFinder == null) {
subPropertyFinder = prop.getClassMeta().newPropertyFinder();
subPropertyFinders.put(prop.getName(), subPropertyFinder);
}
return subPropertyFinder.findProperty(propertyNameMatcher);
}
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) {
for(ConstructorDefinition cd : eligibleConstructorDefinitions) {
if (cd.hasParam(param)) {
return true;
}
}
return false;
}
@Override
public List> getEligibleConstructorDefinitions() {
return eligibleConstructorDefinitions;
}
}