org.simpleflatmapper.reflect.meta.AbstractIndexPropertyFinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sfm-reflect Show documentation
Show all versions of sfm-reflect Show documentation
Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.
package org.simpleflatmapper.reflect.meta;
import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.property.ArrayIndexStartAtProperty;
import java.lang.reflect.Type;
import java.util.*;
public abstract class AbstractIndexPropertyFinder extends PropertyFinder {
protected final ClassMeta classMeta;
protected final Map> elements;
public AbstractIndexPropertyFinder(ClassMeta classMeta, boolean selfScoreFullName) {
this(classMeta);
}
public AbstractIndexPropertyFinder(ClassMeta classMeta) {
super();
this.elements = new HashMap>();
this.classMeta = classMeta;
}
@SuppressWarnings("unchecked")
@Override
public void lookForProperties(
PropertyNameMatcher propertyNameMatcher,
Object[] properties, FoundProperty matchingProperties,
PropertyMatchingScore score,
boolean allowSelfReference,
PropertyFinderTransformer propertyFinderTransformer, TypeAffinityScorer typeAffinityScorer, PropertyFilter propertyFilter, ShortCircuiter shortCircuiter) {
IndexedColumn indexedColumn = propertyNameMatcher.matchIndex();
if (indexedColumn != null) {
int startIndex = 0;
for(Object prop : properties) {
if (prop instanceof ArrayIndexStartAtProperty) {
startIndex = ((ArrayIndexStartAtProperty)prop).startIndex;
break;
}
}
indexedColumn = indexedColumn.alignTo(startIndex);
lookForAgainstColumn(indexedColumn, properties, matchingProperties, score.arrayIndex(indexedColumn, scoreFullName()), propertyFinderTransformer, typeAffinityScorer, propertyFilter, shortCircuiter);
}
if (indexedColumn == null || indexedColumn.partial) {
extrapolateIndex(propertyNameMatcher, properties, matchingProperties, score.speculative(), propertyFinderTransformer, typeAffinityScorer, propertyFilter, shortCircuiter);
speculativeMatching(propertyNameMatcher, properties, matchingProperties, score.speculative(), propertyFinderTransformer, typeAffinityScorer, propertyFilter, shortCircuiter);
}
}
protected boolean scoreFullName() {
return false;
}
@SuppressWarnings("unchecked")
protected void lookForAgainstColumn(IndexedColumn indexedColumn, Object[] properties, final FoundProperty matchingProperties, PropertyMatchingScore score,
PropertyFinderTransformer propertyFinderTransformer, TypeAffinityScorer typeAffinityScorer, PropertyFilter propertyFilter, ShortCircuiter shortCircuiter) {
if (indexedColumn == null || !isValidIndex(indexedColumn)) {
// no index found
return;
}
final IndexedElement indexedElement = getIndexedElement(indexedColumn);
if (indexedElement == null) return;
if (indexedColumn.getSubPropertyNameMatcher() == null) {
matchingProperties.found(indexedElement.getPropertyMeta(), new Runnable() {
@Override
public void run() {
if (!indexedElement.hasProperty(SelfPropertyMeta.PROPERTY_PATH)) {
indexedElement.addProperty(SelfPropertyMeta.PROPERTY_PATH);
}
}
}, score.self(indexedElement.getPropertyMeta(), null, ""), typeAffinityScorer);
return ;
}
final PropertyFinder> eltPropertyFinder = indexedElement.getPropertyFinder();
if (eltPropertyFinder == null) {
return;
}
propertyFinderTransformer.apply(eltPropertyFinder)
.lookForProperties(indexedColumn.getSubPropertyNameMatcher(),
properties, new FoundProperty() {
@Override
public void found(final PropertyMeta propertyMeta, final Runnable selectionCallback, final PropertyMatchingScore score, TypeAffinityScorer typeAffinityScorer) {
PropertyMeta subProperty = new SubPropertyMeta(classMeta.getReflectionService(), indexedElement.getPropertyMeta(), propertyMeta);
matchingProperties.found(subProperty, new Runnable() {
@Override
public void run() {
selectionCallback.run();
indexedElement.addProperty(propertyMeta);
}
}, score, typeAffinityScorer);
}
}, score.matches(indexedElement.getPropertyMeta(), indexedColumn.getSubPropertyNameMatcher(),new PropertyNameMatch(indexedColumn.getIndexProperty(), indexedColumn.getIndexProperty(), indexedColumn.getSubPropertyNameMatcher(),0,0 ) ), true, propertyFinderTransformer, typeAffinityScorer, propertyFilter, shortCircuiter);
}
private void speculativeMatching(PropertyNameMatcher propertyNameMatcher, Object[] properties, FoundProperty foundProperty, PropertyMatchingScore score, PropertyFinderTransformer propertyFinderTransformer, TypeAffinityScorer typeAffinityScorer, PropertyFilter propertyFilter, ShortCircuiter shortCircuiter) {
// try to match against prefix
PropertyNameMatch speculativeMatch = propertyNameMatcher.speculativeMatch();
if (speculativeMatch != null) {
extrapolateIndex(speculativeMatch.getLeftOverMatcher(), properties, foundProperty, score.speculative(), propertyFinderTransformer, typeAffinityScorer, propertyFilter, shortCircuiter);
}
}
protected abstract boolean isValidIndex(IndexedColumn indexedColumn);
protected abstract IndexedElement getIndexedElement(IndexedColumn indexedColumn);
protected abstract void extrapolateIndex(PropertyNameMatcher propertyNameMatcher, Object[] properties, FoundProperty foundProperty, PropertyMatchingScore score, PropertyFinderTransformer propertyFinderTransformer, TypeAffinityScorer typeAffinityScorer, PropertyFilter propertyFilter, ShortCircuiter shortCircuiter);
@Override
public List getEligibleInstantiatorDefinitions() {
return classMeta.getInstantiatorDefinitions();
}
@Override
public Type getOwnerType() {
return classMeta.getType();
}
@Override
public PropertyFinder> getSubPropertyFinder(PropertyMeta, ?> owner) {
PropertyFinder> ie = lookForPropertyFinder(owner);
if (ie != null) return ie;
throw new IllegalArgumentException("Unexpected owner " + owner);
}
private PropertyFinder> lookForPropertyFinder(PropertyMeta, ?> owner) {
ArrayList indicies = new ArrayList(elements.keySet());
Collections.sort(indicies);
for(Integer key : indicies) {
IndexedElement ie = elements.get(key);
if (indexMatches(ie.getPropertyMeta(), owner)) {
return ie.getPropertyFinder();
}
}
return null;
}
protected abstract boolean indexMatches(PropertyMeta propertyMeta, PropertyMeta, ?> owner);
@Override
public PropertyFinder> getOrCreateSubPropertyFinder(SubPropertyMeta, ?, ?> subPropertyMeta) {
PropertyMeta, ?> ownerProperty = subPropertyMeta.getOwnerProperty();
PropertyFinder> ie = lookForPropertyFinder(ownerProperty);
if (ie != null) return ie;
return registerProperty(subPropertyMeta);
}
protected abstract PropertyFinder> registerProperty(SubPropertyMeta, ?, ?> subPropertyMeta);
}