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

org.simpleflatmapper.reflect.meta.PropertyFinder Maven / Gradle / Ivy

Go to download

Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.

There is a newer version: 9.0.2
Show newest version
package org.simpleflatmapper.reflect.meta;

import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.getter.NullGetter;
import org.simpleflatmapper.reflect.setter.NullSetter;
import org.simpleflatmapper.util.Predicate;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class PropertyFinder {
	protected final Predicate> propertyFilter;
	private final boolean selfScoreFullName;

	protected PropertyFinder(Predicate> propertyFilter, boolean selfScoreFullName) {
		this.propertyFilter = propertyFilter;
		this.selfScoreFullName = selfScoreFullName;
	}

	public final  PropertyMeta findProperty(PropertyNameMatcher propertyNameMatcher, Object[] properties) {
		return findProperty(propertyNameMatcher, properties, new DefaultPropertyFinderProbe(propertyNameMatcher));
	}
		@SuppressWarnings("unchecked")
	public final  PropertyMeta findProperty(PropertyNameMatcher propertyNameMatcher, Object[] properties, PropertyFinderProbe propertyFinderProbe) {
		MatchingProperties matchingProperties = new MatchingProperties(propertyFilter, propertyFinderProbe);
		lookForProperties(propertyNameMatcher, properties, matchingProperties, PropertyMatchingScore.newInstance(selfScoreFullName), true, IDENTITY_TRANSFORMER);
		return (PropertyMeta)matchingProperties.selectBestMatch();
	}

	public abstract void lookForProperties(
			PropertyNameMatcher propertyNameMatcher,
			Object[] properties, 
			FoundProperty matchingProperties,
			PropertyMatchingScore score,
			boolean allowSelfReference,
			PropertyFinderTransformer propertyFinderTransformer);


	public abstract List getEligibleInstantiatorDefinitions();

    public abstract PropertyFinder getSubPropertyFinder(PropertyMeta owner);
	public abstract PropertyFinder getOrCreateSubPropertyFinder(SubPropertyMeta subPropertyMeta);

	public Predicate> getPropertyFilter() {
		return propertyFilter;
	}

	public abstract Type getOwnerType();

	public boolean selfScoreFullName() {
		return selfScoreFullName;
	}

	protected static class MatchingProperties implements FoundProperty {
		private final List> matchedProperties = new ArrayList>();
		private final Predicate> propertyFilter;
		private final PropertyFinderProbe propertyFinderProbe;

		public MatchingProperties(Predicate> propertyFilter, PropertyFinderProbe propertyFinderProbe) {
			this.propertyFilter = propertyFilter;
			this.propertyFinderProbe = propertyFinderProbe;
		}

		@Override
		public 

> void found(P propertyMeta, Runnable selectionCallback, PropertyMatchingScore score) { if (propertyFilter.test(propertyMeta)) { propertyFinderProbe.found(propertyMeta, score); matchedProperties.add(new MatchedProperty(propertyMeta, selectionCallback, score)); } } public PropertyMeta selectBestMatch() { if (matchedProperties.isEmpty()) return null; Collections.sort(matchedProperties); MatchedProperty selectedMatchedProperty = matchedProperties.get(0); selectedMatchedProperty.select(); propertyFinderProbe.select(selectedMatchedProperty.propertyMeta); return selectedMatchedProperty.propertyMeta; } } private static class MatchedProperty> implements Comparable>{ private final P propertyMeta; private final Runnable selectionCallback; private final PropertyMatchingScore score; private MatchedProperty(P propertyMeta, Runnable selectionCallback, PropertyMatchingScore score) { this.propertyMeta = propertyMeta; this.selectionCallback = selectionCallback; this.score = score; } @Override public int compareTo(MatchedProperty o) { int i = this.score.compareTo(o.score); if (i == 0) { return compare(this.propertyMeta, o.propertyMeta); } else { return i; } } private int compare(PropertyMeta p1, PropertyMeta p2) { if (p1.isConstructorProperty()) { if (!p2.isConstructorProperty()) { return -1; } } else if (p2.isConstructorProperty()) { return 1; } else if (!p1.isSelf()) { if (p2.isSelf()) { return -1; } } else if (!p2.isSelf()) { return 1; } else if (!p1.isSubProperty()) { if (p2.isSubProperty()) { return -1; } } else if (!p2.isSubProperty()) { return 1; } return getterSetterCompare(p1, p2); } private int getterSetterCompare(PropertyMeta p1, PropertyMeta p2) { return nbGetterSetter(p2) - nbGetterSetter(p1); } private int nbGetterSetter(PropertyMeta p) { int c = 0; if (!NullGetter.isNull(p.getGetter())) { c++; } if (!NullSetter.isNull(p.getSetter())) { c++; } return c; } public void select() { if (selectionCallback != null) selectionCallback.run(); } @Override public String toString() { return "MatchedProperty{" + "propertyMeta=" + propertyMeta + ", score=" + score + ":" + nbGetterSetter(propertyMeta) + ", getter=" + propertyMeta.getGetter() + ", setter=" + propertyMeta.getSetter() + '}'; } } public interface FoundProperty {

> void found(P propertyMeta, Runnable selectionCallback, PropertyMatchingScore score); } public void manualMatch(PropertyMeta prop) { if (prop.isSubProperty()) { SubPropertyMeta subPropertyMeta = (SubPropertyMeta) prop; PropertyMeta ownerProperty = subPropertyMeta.getOwnerProperty(); manualMatch(ownerProperty); PropertyFinder subPropertyFinder = getOrCreateSubPropertyFinder(subPropertyMeta); subPropertyFinder.manualMatch(subPropertyMeta.getSubProperty()); } } public interface PropertyFinderTransformer { PropertyFinder apply(PropertyFinder propertyFinder); } public static PropertyFinderTransformer IDENTITY_TRANSFORMER = new PropertyFinderTransformer() { @Override public PropertyFinder apply(PropertyFinder propertyFinder) { return propertyFinder; } @Override public String toString() { return "IDENTITY_TRANSFORMER"; } }; public interface PropertyFinderProbe { void found(PropertyMeta propertyMeta, PropertyMatchingScore score); void select(PropertyMeta propertyMeta); } public static class DefaultPropertyFinderProbe implements PropertyFinderProbe { private static final boolean DEBUG = Boolean.getBoolean("org.simpleflatmapper.probe.propertyFinder"); private final PropertyNameMatcher propertyNameMatcher; public DefaultPropertyFinderProbe(PropertyNameMatcher propertyNameMatcher) { this.propertyNameMatcher = propertyNameMatcher; } @Override public void found(PropertyMeta propertyMeta, PropertyMatchingScore score) { if (DEBUG) { System.out.println("PropertyFinder for '" + propertyNameMatcher + "' - found " + score + " " + propertyMeta.getPath()); } } @Override public void select(PropertyMeta propertyMeta) { if (DEBUG) { System.out.println("PropertyFinder for '" + propertyNameMatcher + "' - select " + propertyMeta.getPath()); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy