org.sfm.reflect.meta.ArrayPropertyFinder Maven / Gradle / Ivy
package org.sfm.reflect.meta;
import java.lang.reflect.Constructor;
import java.util.*;
import org.sfm.reflect.ConstructorDefinition;
import org.sfm.reflect.TypeHelper;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ArrayPropertyFinder implements PropertyFinder {
private final ArrayClassMeta arrayClassMeta;
private final List> elements = new ArrayList>();
public ArrayPropertyFinder(ArrayClassMeta arrayClassMeta) {
this.arrayClassMeta = arrayClassMeta;
}
@Override
public PropertyMeta findProperty(PropertyNameMatcher propertyNameMatcher) {
IndexedColumn indexedColumn = propertyNameMatcher.matchesIndex();
if (indexedColumn == null) {
indexedColumn = extrapolateIndex(propertyNameMatcher);
}
if (indexedColumn == null) {
return null;
}
IndexedElement indexedElement = getIndexedElement(indexedColumn);
if (!indexedColumn.hasSubProperty()) {
return indexedElement.getPropertyMeta();
}
PropertyFinder> propertyFinder = indexedElement.getPropertyFinder();
if (propertyFinder == null) {
return null;
}
PropertyMeta, ?> subProp = propertyFinder.findProperty(indexedColumn.getSubPropertyNameMatcher());
if (subProp == null) {
return null;
}
indexedElement.addProperty(subProp);
return new SubPropertyMeta(arrayClassMeta.getReflectionService(), indexedElement.getPropertyMeta(), subProp);
}
private IndexedElement getIndexedElement(IndexedColumn indexedColumn) {
while (elements.size() <= indexedColumn.getIndexValue()) {
ArrayElementPropertyMeta arrayElementPropertyMeta =
new ArrayElementPropertyMeta("element" + elements.size(), "element" + elements.size(),
arrayClassMeta.getReflectionService(), elements.size(), arrayClassMeta);
elements.add(new IndexedElement(arrayElementPropertyMeta, arrayClassMeta.getElementClassMeta()));
}
return elements.get(indexedColumn.getIndexValue());
}
private IndexedColumn extrapolateIndex(PropertyNameMatcher propertyNameMatcher) {
PropertyMeta property = arrayClassMeta.getElementClassMeta().newPropertyFinder().findProperty(propertyNameMatcher);
if (property != null) {
for (int i = 0; i < elements.size(); i++) {
IndexedElement element = elements.get(i);
if (!element.hasProperty(property)) {
return new IndexedColumn("element" + i, i, propertyNameMatcher);
}
}
return new IndexedColumn("element" + elements.size(), elements.size(), propertyNameMatcher);
}
return null;
}
@Override
public List> getEligibleConstructorDefinitions() {
if (List.class.isAssignableFrom(TypeHelper.toClass(this.arrayClassMeta.getType()))) {
try {
return Arrays.asList(new ConstructorDefinition((Constructor extends T>) ArrayList.class.getConstructor()));
} catch (NoSuchMethodException e) {
throw new Error("Unexpected error " + e, e);
}
} else {
return Collections.emptyList();
}
}
@Override
public Class> getClassToInstantiate() {
return TypeHelper.toClass(arrayClassMeta.getType());
}
public int getLength() {
return elements.size();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy