Skip to content

Commit

Permalink
map by constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
tvd12 committed Dec 15, 2020
1 parent a5ec8ce commit 443d7b0
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.tvd12.properties.file.io.ValueConverter;
import com.tvd12.properties.file.reader.BaseFileReader;
import com.tvd12.properties.file.reader.FileReader;
import com.tvd12.properties.file.reflect.ReflectionClassUtils;
import com.tvd12.properties.file.struct.PropertiesBean;
import com.tvd12.properties.file.util.PropertiesUtil;

Expand Down Expand Up @@ -223,18 +222,34 @@ public <T> T map() {
@SuppressWarnings("unchecked")
public <T> T map(Class<T> clazz) {
this.clazz(clazz);
if(reader == null)
reader = new BaseFileReader();
this.readProperties();
if(clazz != null && Map.class.isAssignableFrom(clazz))
return (T)getProperties();
return (T)properties;
if(propertyAnnotations == null)
propertyAnnotations = new PropertyAnnotations();
return map(
new PropertiesBean(
newBeanInstance(),
mappingLevel,
valueConverter,
propertyAnnotations,
classLoader
));
if(bean != null) {
return map(
new PropertiesBean(
bean,
mappingLevel,
valueConverter,
propertyAnnotations,
classLoader
));
}
else {
return map(
new PropertiesBean(
clazz,
properties,
mappingLevel,
valueConverter,
propertyAnnotations,
classLoader
));
}
}

/**
Expand All @@ -244,44 +259,29 @@ public <T> T map(Class<T> clazz) {
* @param mapping a custom of properties bean mapping
* @return object after mapped
*/
public <T> T map(PropertiesBean mapping) {
if(reader == null)
reader = new BaseFileReader();
mapping.putAll(getProperties());
private <T> T map(PropertiesBean mapping) {
mapping.putAll(properties);
T answer = mapping.getObject();
return answer;

}

/**
* create object to hold data
*
* @return
*/
private Object newBeanInstance() {
if(bean == null)
bean = ReflectionClassUtils.newInstance(clazz);
else
clazz = bean.getClass();
return bean;
}

/**
* read properties file if properties object null
*
* @return properties object
*/
private Properties getProperties() {
private void readProperties() {
try {
if(properties == null)
properties = reader.read(classLoader, propertiesFile);
properties = new Properties();
if(propertiesFile != null)
properties.putAll(reader.read(classLoader, propertiesFile));
if(propertyPrefix != null)
properties = PropertiesUtil.getPropertiesByPrefix(properties, propertyPrefix);
} catch (PropertiesFileException e) {
throw new IllegalStateException(e);
}
PropertiesUtil.decorateProperties(properties);
return properties;
}

}
41 changes: 35 additions & 6 deletions src/main/java/com/tvd12/properties/file/struct/ClassStruct.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.tvd12.properties.file.struct;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.tvd12.properties.file.annotation.PropertyAnnotations;
import com.tvd12.properties.file.mapping.MappingLevel;
import com.tvd12.properties.file.reflect.ReflectionClassUtils;
import com.tvd12.properties.file.util.ReflectionClassUtil;

/**
*
Expand All @@ -30,6 +34,8 @@ public abstract class ClassStruct {
//map of method structure and key
protected final Map<String, MethodStruct> methods;

protected final List<MethodStruct> declaredFieldStructs;

protected final PropertyAnnotations propertyAnnotations;

/**
Expand All @@ -46,9 +52,11 @@ public ClassStruct(
this.mappingLevel = mappingLevel;
this.propertyAnnotations = propertyAnnotations;
this.methods = new HashMap<>();
this.declaredFieldStructs = new ArrayList<>();
this.methodFilter = methodFilter();
this.initWithFields();
this.initWithMethods();
this.initWithDeclaredFields();
}


Expand All @@ -73,6 +81,14 @@ private void initWithMethods() {
addMethod(initWithMethod(method));
}
}

private void initWithDeclaredFields() {
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields) {
if(!Modifier.isStatic(field.getModifiers()))
declaredFieldStructs.add(initWithField(field));
}
}

/**
* Initialize a MethodStruct object of java field
Expand Down Expand Up @@ -133,7 +149,7 @@ protected MethodStruct getMethodStruct(String key) {
* @param method MethodStruct object to add
*/
protected void addMethod(MethodStruct method) {
methods.put(method.getKey(), method);
methods.put(method.getKey(), method);
}

/**
Expand All @@ -146,9 +162,9 @@ protected void addMethod(MethodStruct method) {
protected Set<Field> getAcceptedFields() {
Set<Field> fields;
if(mappingLevel == MappingLevel.ALL)
fields = ReflectionClassUtils.getValidFields(clazz);
fields = ReflectionClassUtil.getValidFields(clazz);
else
fields = ReflectionClassUtils.getFieldsWithAnnotations(
fields = ReflectionClassUtil.getFieldsWithAnnotations(
clazz,
propertyAnnotations.getAnnotationClasses());
return fields;
Expand All @@ -164,9 +180,9 @@ protected Set<Field> getAcceptedFields() {
protected Set<Method> getAcceptedMethods() {
Set<Method> methods;
if(mappingLevel == MappingLevel.ALL)
methods = ReflectionClassUtils.getPublicMethods(clazz);
methods = ReflectionClassUtil.getPublicMethods(clazz);
else
methods = ReflectionClassUtils.getMethodsWithAnnotations(
methods = ReflectionClassUtil.getMethodsWithAnnotations(
clazz,
propertyAnnotations.getAnnotationClasses());
return methods;
Expand Down Expand Up @@ -194,5 +210,18 @@ public int methodCount() {
protected MethodFilter methodFilter() {
return method -> validateMethod(method) && !containsMethod(method);
}

@SuppressWarnings("rawtypes")
public Constructor getNoArgsDeclaredConstructor() {
return ReflectionClassUtil.getNoArgsDeclaredConstructor(clazz);
}

public Constructor<?> getMaxArgsDeclaredConstructor() {
return ReflectionClassUtil.getMaxArgsDeclaredConstructor(clazz);
}

public Object newObjectInstance() {
return ReflectionClassUtil.newInstance(clazz);
}

}
10 changes: 2 additions & 8 deletions src/main/java/com/tvd12/properties/file/struct/MethodStruct.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.lang.reflect.Method;

import com.tvd12.properties.file.annotation.PropertyAnnotations;
import com.tvd12.properties.file.util.PropertiesUtil;

import lombok.AccessLevel;
import lombok.Getter;
Expand Down Expand Up @@ -167,14 +168,7 @@ protected String getPropertyPrefix(boolean guess) {

protected String guestPropertyPrefix() {
String key = getKey();
StringBuilder builder = new StringBuilder();
for(int i = 0 ; i < key.length() ; ++i) {
char ch = key.charAt(i);
if(Character.isUpperCase(ch) && i > 0)
builder.append(".");
builder.append(Character.toLowerCase(ch));
}
return builder.toString();
return PropertiesUtil.getPropertyNameInDotCase(key);
}

}
69 changes: 62 additions & 7 deletions src/main/java/com/tvd12/properties/file/struct/PropertiesBean.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.tvd12.properties.file.struct;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Properties;

import com.tvd12.properties.file.annotation.PropertyAnnotations;
import com.tvd12.properties.file.io.DefaultValueConverter;
import com.tvd12.properties.file.io.ValueConverter;
import com.tvd12.properties.file.mapping.MappingLevel;
import com.tvd12.properties.file.mapping.PropertiesMapper;
import com.tvd12.properties.file.reflect.ReflectionClassUtils;
import com.tvd12.properties.file.util.Logger;
import com.tvd12.properties.file.util.PropertiesUtil;
import com.tvd12.properties.file.util.ReflectionClassUtil;

/**
*
Expand All @@ -37,7 +41,7 @@ public PropertiesBean(
Class<?> clazz,
PropertyAnnotations propertyAnnotations) {
this(
ReflectionClassUtils.newInstance(clazz),
ReflectionClassUtil.newInstance(clazz),
propertyAnnotations
);
}
Expand Down Expand Up @@ -67,6 +71,20 @@ public PropertiesBean(
this.valueConverter = valueConverter != null ? valueConverter : DefaultValueConverter.getInstance();
}

public PropertiesBean(
Class<?> clazz,
Properties properties,
MappingLevel mappingLevel,
ValueConverter valueConverter,
PropertyAnnotations propertyAnnotations,
ClassLoader classLoader) {
this.wrapper = new ClassWrapper(clazz, mappingLevel, propertyAnnotations);
this.valueConverter = valueConverter != null ? valueConverter : DefaultValueConverter.getInstance();
this.classLoader = classLoader;
this.propertyAnnotations = propertyAnnotations;
this.bean = createBean(properties);
}

public <T> T getObject() {
return (T)bean;
}
Expand All @@ -92,6 +110,8 @@ public void put(Object key, Object value, Properties properties) {
}
else {
Field field = methodStruct.getField();
if(Modifier.isFinal(field.getModifiers()))
return;
if(!Modifier.isPublic(field.getModifiers()))
field.setAccessible(true);
field.set(bean, argument);
Expand All @@ -105,7 +125,7 @@ public void put(Object key, Object value, Properties properties) {

public void putAll(Properties properties) {
for(Object key : wrapper.keySet()) {
Object value = properties.get(key);
Object value = PropertiesUtil.getValue(properties, key);
put(key, value, properties);
}
}
Expand All @@ -127,16 +147,21 @@ protected Object transform(
Object v = value;
if(v instanceof String)
v = ((String) value).trim();
return transform(argumentType, v);
return transform(v, argumentType);
}
try {
return new PropertiesMapper()
if(PropertiesUtil.containsPrefix(properties, prefix)) {
return new PropertiesMapper()
.data(properties)
.classLoader(classLoader)
.propertyPrefix(prefix)
.valueConverter(valueConverter)
.propertyAnnotations(propertyAnnotations)
.map(argumentType);
}
else {
return null;
}
}
catch (Exception e) {
if(guessPrefix)
Expand All @@ -146,10 +171,40 @@ protected Object transform(
}
}

protected Object transform(Class newType, Object value) {
protected Object transform(Object value, Class newType) {
return valueConverter.convert(value, newType);
}


protected Object getAndTransform(Properties properties, String key, Class newType) {
Object value = PropertiesUtil.getValue(properties, key);
if(value != null)
value = transform(value, newType);
return value;
}

protected Object createBean(Properties properties) {
Constructor constructor = wrapper.getNoArgsDeclaredConstructor();
if(constructor != null)
return wrapper.newObjectInstance();
return createBeanByMaxArgsConstructor(properties);
}

protected Object createBeanByMaxArgsConstructor(Properties properties) {
Constructor constructor = wrapper.getMaxArgsDeclaredConstructor();
Parameter[] parameters = constructor.getParameters();
List<MethodStruct> declaredFieldStructs = wrapper.declaredFieldStructs;
Object[] args = new Object[constructor.getParameterCount()];
for(int i = 0 ; i < args.length ; ++i) {
Class<?> parameterType = parameters[i].getType();
if(i >= declaredFieldStructs.size()) {
args[i] = PropertiesUtil.defaultValueOf(parameterType);
continue;
}
String key = declaredFieldStructs.get(i).getKey();
args[i] = getAndTransform(properties, key, parameterType);
}
return ReflectionClassUtil.newInstance(constructor, args);
}

protected void printError(String message, Throwable throwable) {
Logger.print(message, throwable);
Expand Down
Loading

0 comments on commit 443d7b0

Please sign in to comment.