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 java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
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> constructorDefinitions;

	
	private final ReflectionService reflectService;
	private final Type target;

	private final Map fieldAliases;
	
	public ObjectClassMeta(Type target, ReflectionService reflectService) throws MapperBuildingException {
		this.reflectService = reflectService;
		try {
			this.constructorDefinitions = reflectService.extractConstructors(target);
			this.constructorProperties = Collections.unmodifiableList(listProperties(constructorDefinitions));
		} catch(Exception e) {
			throw new MapperBuildingException(e.getMessage(), e);
		}
		this.fieldAliases = Collections.unmodifiableMap(aliases(reflectService, TypeHelper.toClass(target)));
		this.properties = Collections.unmodifiableList(listProperties(reflectService, TypeHelper.toClass(target)));
		this.target = target;
	}
	
	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> constructorDefinitions) {
		if (constructorDefinitions == null) return null;
		
		Set properties = new HashSet();
		List> constructorProperties = new ArrayList>();
		for(ConstructorDefinition cd : constructorDefinitions) {
			for(ConstructorParameter param : cd.getParameters()) {
				String paramName = param.getName();
				if (!properties.contains(paramName)) {
					constructorProperties.add(new ConstructorPropertyMeta(paramName, paramName, reflectService, param));
					properties.add(paramName);
				}
			}
		}
		return constructorProperties;
	}

	private List> listProperties(final ReflectionService reflectService, Class target) {
		final List> properties = new ArrayList>();

		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);

                    MethodPropertyMeta propertyMeta = new MethodPropertyMeta(propertyName, getAlias(propertyName), reflectService, method);
                    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) {
                        properties.add(new FieldPropertyMeta(field.getName(), getAlias(name), reflectService, field));
                    }
				}
			}

            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;
	}


	private String getAlias(String propertyName) {
		String columnName = this.fieldAliases.get(propertyName);
		if (columnName == null) {
			columnName = propertyName;
		}
		return columnName;
	}

	List> getConstructorDefinitions() {
		return constructorDefinitions;
	}

	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 = prefix + "_" + prop;
                if (!properties.contains(name)) {
                    properties.add(name);
                }
            }
        } else {
            if (!properties.contains(prefix)) {
                properties.add(prefix);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy