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

org.sfm.reflect.meta.ObjectClassMeta 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: 1.10.3
Show newest version
package org.sfm.reflect.meta;

import org.sfm.map.MapperBuildingException;
import org.sfm.reflect.*;
import org.sfm.utils.ErrorHelper;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.*;

public final class ObjectClassMeta implements ClassMeta {

	public static final String[] EMPTY_STRING_ARRAY = new String[0];
	private final List> properties;
	private final List> constructorProperties;
	private final List instantiatorDefinitions;

	
	private final ReflectionService reflectService;
	private final Type target;

	private final Map fieldAliases;
	
	public ObjectClassMeta(Type target, ReflectionService reflectService) throws MapperBuildingException {
		this.target = target;
		this.reflectService = reflectService;
		try {
            this.instantiatorDefinitions = reflectService.extractConstructors(target);
            this.constructorProperties = Collections.unmodifiableList(listProperties(instantiatorDefinitions));
		} catch(Exception e) {
            ErrorHelper.rethrow(e);
			throw new IllegalStateException();
		}
		this.fieldAliases = Collections.unmodifiableMap(aliases(reflectService, TypeHelper.toClass(target)));
		this.properties = Collections.unmodifiableList(listProperties(reflectService, target));
	}

    public ObjectClassMeta(Type target,
                           List instantiatorDefinitions,
                           List> constructorProperties,
                           List> properties,
                           ReflectionService reflectService) {
        this.target = target;
        this.properties = properties;
        this.constructorProperties = constructorProperties;
        this.instantiatorDefinitions = instantiatorDefinitions;
        this.fieldAliases = Collections.unmodifiableMap(aliases(reflectService, TypeHelper.toClass(target)));
        this.reflectService = reflectService;
    }

    private Map aliases(final ReflectionService reflectService, Class target) {
		final Map map = new HashMap();
		
		ClassVisitor.visit(target, new FieldAndMethodCallBack() {
			@Override
			public void method(Method method) {
				String alias = reflectService.getColumnName(method);
				if (alias != null) {
					map.put(SetterHelper.getPropertyNameFromMethodName(method.getName()), alias);
				}
			}
			
			@Override
			public void field(Field field) {
				String alias = reflectService.getColumnName(field);
				if (alias != null) {
					map.put(field.getName(), alias);
				}
			}
		});
		
		return map;
	}

	private List> listProperties(List instantiatorDefinitions) {
		if (instantiatorDefinitions == null) return null;
		
		List> constructorProperties = new ArrayList>();
		for(InstantiatorDefinition cd : instantiatorDefinitions) {
			for(Parameter param : cd.getParameters()) {
				String paramName = param.getName();
                constructorProperties.add(constructorMeta(param, paramName));
			}
		}
		return constructorProperties;
	}

    private 

ConstructorPropertyMeta constructorMeta(Parameter param, String paramName) { Class tClass = TypeHelper.toClass(this.target); return new ConstructorPropertyMeta(paramName, reflectService, param, tClass); } private List> listProperties(final ReflectionService reflectService, Type targetType) { final Class target = TypeHelper.toClass(targetType); final List> properties = new ArrayList>(); final Map, Type> typeVariableTypeMap = TypeHelper.getTypesMap(targetType, target); ClassVisitor.visit(target, new FieldAndMethodCallBack() { @Override public void method(Method method) { final String name = method.getName(); if (SetterHelper.methodModifiersMatches(method.getModifiers()) && SetterHelper.isSetter(name)) { final String propertyName = SetterHelper.getPropertyNameFromMethodName(name); int indexOfProperty = findProperty(properties, propertyName); Type resolvedType = method.getGenericParameterTypes()[0]; if (resolvedType instanceof TypeVariable) { Type mappedType = typeVariableTypeMap.get(resolvedType); if (mappedType != null) { resolvedType = mappedType; } } MethodPropertyMeta propertyMeta = new MethodPropertyMeta(propertyName, reflectService, method, resolvedType); if (indexOfProperty == -1) { properties.add(propertyMeta); } else { properties.set(indexOfProperty, propertyMeta); } } } @Override public void field(Field field) { final String name = field.getName(); if (SetterHelper.fieldModifiersMatches(field.getModifiers())) { int indexOfProperty = findProperty(properties, name); if (indexOfProperty == -1) { Type resolvedType = field.getGenericType(); if (resolvedType instanceof TypeVariable) { Type mappedType = typeVariableTypeMap.get(resolvedType); if (mappedType != null) { resolvedType = mappedType; } } properties.add(new FieldPropertyMeta(field.getName(), reflectService, field, resolvedType)); } } } private int findProperty(List> properties, String name) { for(int i = 0; i < properties.size(); i++) { if (properties.get(i).getName().equals(name)) { return i; } } return -1; } }); return properties; } protected String getAlias(String propertyName) { String columnName = this.fieldAliases.get(propertyName); if (columnName == null) { columnName = propertyName; } return columnName; } @Override public List getInstantiatorDefinitions() { return instantiatorDefinitions; } List> getProperties() { return properties; } List> getConstructorProperties() { return constructorProperties; } @Override public ReflectionService getReflectionService() { return reflectService; } @Override public PropertyFinder newPropertyFinder() { return new ObjectPropertyFinder(this); } @Override public Type getType() { return target; } @Override public String[] generateHeaders() { List strings = new ArrayList(); for(PropertyMeta cpm : constructorProperties) { extractProperties(strings, cpm); } for(PropertyMeta cpm : properties) { extractProperties(strings, cpm); } return strings.toArray(EMPTY_STRING_ARRAY); } private void extractProperties(List properties, PropertyMeta cpm) { String prefix = cpm.getName(); ClassMeta classMeta = cpm.getClassMeta(); if (classMeta != null) { for(String prop : classMeta.generateHeaders()) { String name = prop.length() == 0 ? prefix : prefix + "_" + prop; if (!properties.contains(name)) { properties.add(name); } } } else { if (!properties.contains(prefix)) { properties.add(prefix); } } } @Override public boolean isLeaf() { return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy