diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java index cd360f51f5..b6fbbf6335 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java @@ -22,6 +22,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Record information about the configuration class to be converted + */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface Config { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigFiled.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigFiled.java index d12b464edc..7a24e39aca 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigFiled.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigFiled.java @@ -17,11 +17,16 @@ package org.apache.eventmesh.common.config; +import org.apache.eventmesh.common.config.convert.ConvertValue.DefaultConverter; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Record information about the field in the configuration class to be converted + */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.FIELD}) public @interface ConfigFiled { @@ -37,4 +42,11 @@ * @return Whether to reload. This parameter is used when other fields are associated */ boolean reload() default false; + + /** + * In some special cases, used to specify the converter class of the field + * + * @return field converter + */ + Class converter() default DefaultConverter.class; } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java index c00fd276d8..05500a074a 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java @@ -17,12 +17,11 @@ package org.apache.eventmesh.common.config; -import org.apache.eventmesh.common.utils.Convert; +import org.apache.eventmesh.common.config.convert.Convert; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Objects; @@ -35,9 +34,9 @@ */ public interface FileLoad { - static final PropertiesFileLoad PROPERTIES_FILE_LOAD = new PropertiesFileLoad(); + PropertiesFileLoad PROPERTIES_FILE_LOAD = new PropertiesFileLoad(); - static final YamlFileLoad YAML_FILE_LOAD = new YamlFileLoad(); + YamlFileLoad YAML_FILE_LOAD = new YamlFileLoad(); public static FileLoad getFileLoad(String fileType) { if (Objects.equals("properties", fileType)) { @@ -48,15 +47,15 @@ public static FileLoad getFileLoad(String fileType) { return PROPERTIES_FILE_LOAD; } - public static PropertiesFileLoad getPropertiesFileLoad() { + static PropertiesFileLoad getPropertiesFileLoad() { return PROPERTIES_FILE_LOAD; } - public static YamlFileLoad getYamlFileLoad() { + static YamlFileLoad getYamlFileLoad() { return YAML_FILE_LOAD; } - public T getConfig(ConfigInfo configInfo) throws IOException; + T getConfig(ConfigInfo configInfo) throws IOException; class PropertiesFileLoad implements FileLoad { @@ -70,12 +69,12 @@ public T getConfig(ConfigInfo configInfo) throws IOException { return (T) properties; } - return (T) convert.createObject(configInfo, properties); + return (T) convert.doConvert(configInfo, properties); } @SuppressWarnings("unchecked") public T getConfig(Properties properties, ConfigInfo configInfo) { - return (T) convert.createObject(configInfo, properties); + return (T) convert.doConvert(configInfo, properties); } } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/Convert.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/Convert.java new file mode 100644 index 0000000000..84fbdc380e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/Convert.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert; + +import org.apache.eventmesh.common.config.ConfigInfo; + +import java.util.Properties; + +/** + * Used to convert Config properties + */ +public class Convert { + + public Object doConvert(ConfigInfo configInfo, Properties properties) { + Class clazz = configInfo.getClazz(); + ConvertInfo convertInfo = new ConvertInfo(); + convertInfo.setConfigInfo(configInfo); + convertInfo.setProperties(properties); + convertInfo.setClazz(clazz); + + ConvertValue clazzConverter = ConverterMap.getClazzConverter(clazz); + return clazzConverter.convert(convertInfo); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertInfo.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertInfo.java new file mode 100644 index 0000000000..c3a867da9e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertInfo.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert; + +import org.apache.eventmesh.common.config.ConfigInfo; + +import java.lang.reflect.Field; +import java.util.Properties; + +import lombok.Data; + +/** + * Records the information about the field to be converted + */ +@Data +public class ConvertInfo { + char hump; + String key; + Field field; + Object value; + Class clazz; + Properties properties; + ConfigInfo configInfo; +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertValue.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertValue.java new file mode 100644 index 0000000000..be3d1228f6 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConvertValue.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert; + +import java.util.Properties; + +/** + * convert convertInfo to obj + * + * @param obj type + */ +public interface ConvertValue { + + T convert(ConvertInfo convertInfo); + + /** + * @return Whether can to process null values + */ + default boolean canHandleNullValue() { + return false; + } + + /** + * @return The value converter needs + */ + default Object processFieldValue(Properties config, String key) { + return config.getProperty(key); + } + + class DefaultConverter implements ConvertValue { + + @Override + public Object convert(ConvertInfo convertInfo) { + return null; + } + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java new file mode 100644 index 0000000000..6ee613d5a7 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert; + +import org.apache.eventmesh.common.config.ConfigFiled; +import org.apache.eventmesh.common.config.convert.converter.BaseDataTypeConverter; +import org.apache.eventmesh.common.config.convert.converter.DateConverter; +import org.apache.eventmesh.common.config.convert.converter.EnumConverter; +import org.apache.eventmesh.common.config.convert.converter.IPAddressConverter; +import org.apache.eventmesh.common.config.convert.converter.ListConverter; +import org.apache.eventmesh.common.config.convert.converter.LocalDateConverter; +import org.apache.eventmesh.common.config.convert.converter.LocalDateTimeConverter; +import org.apache.eventmesh.common.config.convert.converter.MapConverter; +import org.apache.eventmesh.common.config.convert.converter.ObjectConverter; +import org.apache.eventmesh.common.config.convert.converter.PropertiesConverter; +import org.apache.eventmesh.common.config.convert.converter.StringConverter; + +import java.lang.reflect.Field; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; +import java.util.TreeMap; +import java.util.Vector; + +import inet.ipaddr.IPAddress; + +/** + * Use to map the field clazz and the converter for the field clazz + */ +public class ConverterMap { + + private static final ObjectConverter objectConverter = new ObjectConverter(); + + private static final Map, ConvertValue> classToConverter = new HashMap<>(); + + static { + register(new EnumConverter(), Enum.class); + register(new DateConverter(), Date.class); + register(new StringConverter(), String.class); + register(new LocalDateConverter(), LocalDate.class); + register(new IPAddressConverter(), IPAddress.class); + register(new PropertiesConverter(), Properties.class); + register(new LocalDateTimeConverter(), LocalDateTime.class); + register(new ListConverter(), List.class, ArrayList.class, LinkedList.class, Vector.class); + register(new MapConverter(), Map.class, HashMap.class, TreeMap.class, LinkedHashMap.class); + register(new BaseDataTypeConverter.CharacterConverter(), Character.class, char.class); + register(new BaseDataTypeConverter.ByteConverter(), Byte.class, byte.class); + register(new BaseDataTypeConverter.ShortConverter(), Short.class, short.class); + register(new BaseDataTypeConverter.IntegerConverter(), Integer.class, int.class); + register(new BaseDataTypeConverter.LongConverter(), Long.class, long.class); + register(new BaseDataTypeConverter.FloatConverter(), Float.class, float.class); + register(new BaseDataTypeConverter.DoubleConverter(), Double.class, double.class); + register(new BaseDataTypeConverter.BooleanConverter(), Boolean.class, boolean.class); + } + + public static void register(ConvertValue convertValue, Class... clazzs) { + for (Class clazz : clazzs) { + classToConverter.put(clazz, convertValue); + } + } + + /** + * Get the converter for the field + * + * @param field The field to be parsed + * @return the converter for the field + */ + public static ConvertValue getFieldConverter(Field field) { + Class clazz = field.getType(); + ConfigFiled configFiled = field.getAnnotation(ConfigFiled.class); + + Class converter1 = configFiled.converter(); + if (!converter1.equals(ConvertValue.DefaultConverter.class)) { + if (!classToConverter.containsKey(converter1)) { + try { + ConvertValue convertValue = (ConvertValue) converter1.newInstance(); + register(convertValue, converter1); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return classToConverter.get(converter1); + } + + return getClazzConverter(clazz); + } + + /** + * Get the converter for the clazz + * + * @param clazz The clazz to be parsed + * @return the converter for the clazz + */ + public static ConvertValue getClazzConverter(Class clazz) { + ConvertValue converter = classToConverter.get(clazz); + if (Objects.isNull(converter)) { + if (clazz.isEnum()) { + converter = classToConverter.get(Enum.class); + } else { + converter = objectConverter; + } + } + + return converter; + } + + public static Map, ConvertValue> getClassToConverter() { + return classToConverter; + } + + public static ObjectConverter getObjectConverter() { + return objectConverter; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java new file mode 100644 index 0000000000..053580c46f --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +import java.util.Objects; + +/** + * Config field conversion class for base data types + */ +public class BaseDataTypeConverter { + + public static class CharacterConverter implements ConvertValue { + + @Override + public Character convert(ConvertInfo convertInfo) { + String value = (String) convertInfo.getValue(); + + return value.charAt(0); + } + } + + public static class BooleanConverter implements ConvertValue { + + @Override + public Boolean convert(ConvertInfo convertInfo) { + String value = (String) convertInfo.getValue(); + if (Objects.equals(value.length(), 1)) { + return Objects.equals(convertInfo.getValue(), "1") ? Boolean.TRUE : Boolean.FALSE; + } + + return Boolean.valueOf((String) convertInfo.getValue()); + } + } + + public static class ByteConverter implements ConvertValue { + + @Override + public Byte convert(ConvertInfo convertInfo) { + return Byte.valueOf((String) convertInfo.getValue()); + } + } + + public static class ShortConverter implements ConvertValue { + + @Override + public Short convert(ConvertInfo convertInfo) { + return Short.valueOf((String) convertInfo.getValue()); + } + } + + public static class IntegerConverter implements ConvertValue { + + @Override + public Integer convert(ConvertInfo convertInfo) { + return Integer.valueOf((String) convertInfo.getValue()); + } + } + + public static class LongConverter implements ConvertValue { + + @Override + public Long convert(ConvertInfo convertInfo) { + return Long.valueOf((String) convertInfo.getValue()); + } + } + + public static class FloatConverter implements ConvertValue { + + @Override + public Float convert(ConvertInfo convertInfo) { + return Float.valueOf((String) convertInfo.getValue()); + } + } + + public static class DoubleConverter implements ConvertValue { + + @Override + public Double convert(ConvertInfo convertInfo) { + return Double.valueOf((String) convertInfo.getValue()); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/DateConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/DateConverter.java new file mode 100644 index 0000000000..4a864eb6b2 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/DateConverter.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Config field conversion class for Date + */ +public class DateConverter implements ConvertValue { + + @Override + public Date convert(ConvertInfo convertInfo) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + try { + return sdf.parse((String) convertInfo.getValue()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/EnumConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/EnumConverter.java new file mode 100644 index 0000000000..513adf101e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/EnumConverter.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +/** + * Config field conversion class for Enum + */ +public class EnumConverter implements ConvertValue> { + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public Enum convert(ConvertInfo convertInfo) { + Class enumType = (Class) convertInfo.getField().getType(); + String name = (String) convertInfo.getValue(); + + return Enum.valueOf(enumType, name); + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/IPAddressConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/IPAddressConverter.java new file mode 100644 index 0000000000..ee3ebae8c5 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/IPAddressConverter.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +import inet.ipaddr.AddressStringException; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; + +/** + * Config field conversion class for IPAddress + */ +public class IPAddressConverter implements ConvertValue { + + @Override + public IPAddress convert(ConvertInfo convertInfo) { + try { + return new IPAddressString((String) convertInfo.getValue()).toAddress(); + } catch (AddressStringException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java new file mode 100644 index 0000000000..fb7a2b0664 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; +import org.apache.eventmesh.common.config.convert.ConverterMap; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import com.google.common.base.Splitter; + +/** + * Config field conversion class for List + */ +public class ListConverter implements ConvertValue> { + + public String separator = ","; + + @Override + public boolean canHandleNullValue() { + return true; + } + + public String getSeparator() { + return separator; + } + + @Override + public List convert(ConvertInfo convertInfo) { + return convert(convertInfo, this.getSeparator()); + } + + @SuppressWarnings("unchecked") + public List convert(ConvertInfo convertInfo, String separator) { + try { + if (convertInfo.getValue() == null) { + return new ArrayList<>(); + } + List list; + if (Objects.equals(convertInfo.getField().getType(), List.class)) { + list = new ArrayList<>(); + } else { + list = (List) convertInfo.getField().getType().newInstance(); + } + + Type parameterizedType = ((ParameterizedType) convertInfo.getField() + .getGenericType()).getActualTypeArguments()[0]; + + ConvertValue clazzConverter = ConverterMap.getClazzConverter((Class) parameterizedType); + + List values = Splitter.on(separator).omitEmptyStrings().trimResults() + .splitToList((String) convertInfo.getValue()); + for (String value : values) { + convertInfo.setValue(value); + list.add(clazzConverter.convert(convertInfo)); + } + + return list; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + public static class ListConverterSemi extends ListConverter { + public String separator = ";"; + + public String getSeparator() { + return separator; + } + + @Override + public List convert(ConvertInfo convertInfo) { + return super.convert(convertInfo, this.getSeparator()); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateConverter.java new file mode 100644 index 0000000000..b8c19ee0ea --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateConverter.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +/** + * Config field conversion class for LocalDate + */ +public class LocalDateConverter implements ConvertValue { + + @Override + public LocalDate convert(ConvertInfo convertInfo) { + String value = (String) convertInfo.getValue(); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + return LocalDate.parse(value, timeFormatter); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateTimeConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateTimeConverter.java new file mode 100644 index 0000000000..e2423397e6 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/LocalDateTimeConverter.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Config field conversion class for LocalDateTime + */ +public class LocalDateTimeConverter implements ConvertValue { + + @Override + public LocalDateTime convert(ConvertInfo convertInfo) { + String value = (String) convertInfo.getValue(); + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + return LocalDateTime.parse(value, timeFormatter); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/MapConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/MapConverter.java new file mode 100644 index 0000000000..0902a758f7 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/MapConverter.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; +import org.apache.eventmesh.common.config.convert.ConverterMap; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Config field conversion class for Map + */ +public class MapConverter implements ConvertValue> { + + @Override + public boolean canHandleNullValue() { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public Map convert(ConvertInfo convertInfo) { + try { + String key = convertInfo.getKey() + convertInfo.getHump(); + Map map; + if (Objects.equals(Map.class, convertInfo.getField().getType())) { + map = new HashMap<>(); + } else { + map = (Map) convertInfo.getField().getType().newInstance(); + } + Type parameterizedType = ((ParameterizedType) convertInfo.getField().getGenericType()).getActualTypeArguments()[1]; + ConvertValue clazzConverter = ConverterMap.getClazzConverter((Class) parameterizedType); + + for (Map.Entry entry : convertInfo.getProperties().entrySet()) { + String propertiesKey = entry.getKey().toString(); + if (propertiesKey.startsWith(key)) { + String value = entry.getValue().toString(); + convertInfo.setValue(value); + map.put(propertiesKey.replace(key, ""), clazzConverter.convert(convertInfo)); + } + } + return map; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java new file mode 100644 index 0000000000..3b1ce04a94 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.Config; +import org.apache.eventmesh.common.config.ConfigFiled; +import org.apache.eventmesh.common.config.ConfigInfo; +import org.apache.eventmesh.common.config.NotNull; +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; +import org.apache.eventmesh.common.config.convert.ConverterMap; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Locale; +import java.util.Objects; +import java.util.Properties; + +import org.assertj.core.util.Strings; + +import com.google.common.base.Preconditions; + +/** + * Config field conversion class for Configuration class + */ +public class ObjectConverter implements ConvertValue { + + private String prefix; + + private ConvertInfo convertInfo; + + private Object object; + + private char hump; + + private Class clazz; + + private void init(ConfigInfo configInfo) { + String prefix = configInfo.getPrefix(); + if (Objects.nonNull(prefix)) { + this.prefix = prefix.endsWith(".") ? prefix : prefix + "."; + } + this.hump = Objects.equals(configInfo.getHump(), ConfigInfo.HUMP_ROD) ? '_' : '.'; + this.clazz = convertInfo.getClazz(); + this.convertInfo.setHump(this.hump); + } + + @Override + public Object convert(ConvertInfo convertInfo) { + try { + this.convertInfo = convertInfo; + this.object = convertInfo.getClazz().newInstance(); + this.init(convertInfo.getConfigInfo()); + this.setValue(); + + Class superclass = convertInfo.getClazz(); + for (; ; ) { + superclass = superclass.getSuperclass(); + if (Objects.equals(superclass, Object.class) || Objects.isNull(superclass)) { + break; + } + + this.clazz = superclass; + this.prefix = null; + Config[] configArray = clazz.getAnnotationsByType(Config.class); + if (configArray.length != 0 && !Strings.isNullOrEmpty(configArray[0].prefix())) { + String prefix = configArray[0].prefix(); + this.prefix = prefix.endsWith(".") ? prefix : prefix + "."; + this.hump = Objects.equals(configArray[0].hump(), ConfigInfo.HUMP_ROD) ? '_' : '.'; + this.convertInfo.setHump(this.hump); + } + + this.setValue(); + } + + return object; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void setValue() throws Exception { + boolean needReload = Boolean.FALSE; + + for (Field field : this.clazz.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + field.setAccessible(true); + + ConvertInfo convertInfo = this.convertInfo; + ConfigFiled configFiled = field.getAnnotation(ConfigFiled.class); + if (Objects.isNull(configFiled)) { + continue; + } + + String key = this.buildKey(field, configFiled); + needReload = this.checkNeedReload(needReload, configFiled); + + ConvertValue convertValue = ConverterMap.getFieldConverter(field); + + Properties properties = convertInfo.getProperties(); + Object fieldValue = convertValue.processFieldValue(properties, key); + + if (!checkFieldValueBefore(field, key, convertValue, fieldValue)) { + continue; + } + convertInfo.setValue(fieldValue); + convertInfo.setField(field); + convertInfo.setKey(key); + Object convertedValue = convertValue.convert(convertInfo); + + if (!checkFieldValueAfter(field, key, convertedValue)) { + continue; + } + field.set(object, convertedValue); + } + + reloadConfigIfNeed(needReload); + } + + private void reloadConfigIfNeed(boolean needReload) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (needReload) { + Method method = this.clazz.getDeclaredMethod("reload", null); + method.setAccessible(true); + method.invoke(this.object, null); + } + } + + private boolean checkFieldValueAfter(Field field, String key, Object convertedValue) { + if (Objects.isNull(convertedValue)) { + NotNull notNull = field.getAnnotation(NotNull.class); + if (Objects.nonNull(notNull)) { + Preconditions.checkState(true, key + " is invalidated"); + } + + return false; + } + + return true; + } + + private boolean checkFieldValueBefore(Field field, String key, ConvertValue convertValue, Object fieldValue) { + if (Objects.isNull(fieldValue) && !convertValue.canHandleNullValue()) { + NotNull notNull = field.getAnnotation(NotNull.class); + if (Objects.nonNull(notNull)) { + Preconditions.checkState(true, key + " is invalidated."); + } + + return false; + } + + return true; + } + + private boolean checkNeedReload(boolean needReload, ConfigFiled configFiled) { + if (!needReload && configFiled != null && configFiled.reload()) { + needReload = Boolean.TRUE; + } + + if (needReload) { + try { + this.clazz.getDeclaredMethod("reload", null); + } catch (NoSuchMethodException e) { + throw new RuntimeException("The field needs to be reloaded, but the reload method cannot be found.", e); + } + } + + return needReload; + } + + private String buildKey(Field field, ConfigFiled configFiled) { + String key; + StringBuilder keyPrefix = new StringBuilder(Objects.isNull(prefix) ? "" : prefix); + + if (configFiled == null || configFiled.field().isEmpty()) { + key = this.getKey(field.getName(), hump, keyPrefix); + } else { + key = keyPrefix.append(configFiled.field()).toString(); + } + + return key; + } + + private String getKey(String fieldName, char spot, StringBuilder key) { + boolean currency = false; + int length = fieldName.length(); + for (int i = 0; i < length; i++) { + char c = fieldName.charAt(i); + boolean b = i < length - 1 && fieldName.charAt(i + 1) > 96; + + if (currency) { + if (b) { + key.append(spot); + key.append((char) (c + 32)); + currency = false; + } else { + key.append(c); + } + } else { + if (c > 96) { + key.append(c); + } else { + key.append(spot); + if (b) { + key.append((char) (c + 32)); + } else { + key.append(c); + currency = true; + } + } + } + } + + return key.toString().toLowerCase(Locale.ROOT); + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/PropertiesConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/PropertiesConverter.java new file mode 100644 index 0000000000..704bd3930d --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/PropertiesConverter.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; +import org.apache.eventmesh.common.utils.PropertiesUtils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Properties; + +/** + * Config field conversion class for Properties, by prefix + */ +public class PropertiesConverter implements ConvertValue { + + @Override + public Properties convert(ConvertInfo convertInfo) { + try { + return (Properties) convertInfo.getValue(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public Object processFieldValue(Properties config, String prefix) { + if (StringUtils.isBlank(prefix)) { + return null; + } + Properties to = new Properties(); + + return PropertiesUtils.getPropertiesByPrefix(config, to, prefix); + } +} \ No newline at end of file diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/StringConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/StringConverter.java new file mode 100644 index 0000000000..e0c4022dde --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/StringConverter.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.common.config.convert.converter; + +import org.apache.eventmesh.common.config.convert.ConvertInfo; +import org.apache.eventmesh.common.config.convert.ConvertValue; + +/** + * Config field conversion class for String + */ +public class StringConverter implements ConvertValue { + + @Override + public String convert(ConvertInfo convertInfo) { + return (String) convertInfo.getValue(); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/Convert.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/Convert.java deleted file mode 100644 index 29ad97c6f7..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/Convert.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.common.utils; - -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.common.config.ConfigFiled; -import org.apache.eventmesh.common.config.ConfigInfo; -import org.apache.eventmesh.common.config.NotNull; - -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Properties; -import java.util.TreeMap; -import java.util.Vector; - -import org.assertj.core.util.Strings; - -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; - -import lombok.Data; - -import inet.ipaddr.AddressStringException; -import inet.ipaddr.IPAddress; -import inet.ipaddr.IPAddressString; - -public class Convert { - - private final Map, ConvertValue> classToConvert = new HashMap<>(); - - private final ConvertValue convertEnum = new ConvertEnum(); - - { - this.register(new ConvertCharacter(), Character.class, char.class); - this.register(new ConvertByte(), Byte.class, byte.class); - this.register(new ConvertShort(), Short.class, short.class); - this.register(new ConvertInteger(), Integer.class, int.class); - this.register(new ConvertLong(), Long.class, long.class); - this.register(new ConvertFloat(), Float.class, float.class); - this.register(new ConvertDouble(), Double.class, double.class); - this.register(new ConvertBoolean(), Boolean.class, boolean.class); - this.register(new ConvertDate(), Date.class); - this.register(new ConvertString(), String.class); - this.register(new ConvertLocalDate(), LocalDate.class); - this.register(new ConvertLocalDateTime(), LocalDateTime.class); - this.register(new ConvertList(), List.class, ArrayList.class, LinkedList.class, Vector.class); - this.register(new ConvertMap(), Map.class, HashMap.class, TreeMap.class, LinkedHashMap.class); - this.register(new ConvertIPAddress(), IPAddress.class); - this.register(new ConvertProperties(), Properties.class); - } - - - public Object createObject(ConfigInfo configInfo, Properties properties) { - ConvertInfo convertInfo = new ConvertInfo(); - convertInfo.setConfigInfo(configInfo); - convertInfo.setProperties(properties); - convertInfo.setClazz(configInfo.getClazz()); - - ConvertValue convertValue = classToConvert.get(configInfo.getClazz()); - if (Objects.nonNull(convertValue)) { - return convertValue.convert(convertInfo); - } - - ConvertObject convertObject = new ConvertObject(); - return convertObject.convert(convertInfo); - } - - - public void register(ConvertValue convertValue, Class... clazzs) { - for (Class clazz : clazzs) { - classToConvert.put(clazz, convertValue); - } - } - - /** - * convert convertInfo to obj - * - * @param obj type - */ - public interface ConvertValue { - - default boolean isNotHandleNullValue() { - return true; - } - - T convert(ConvertInfo convertInfo); - } - - private class ConvertObject implements ConvertValue { - - private String prefix; - - private ConvertInfo convertInfo; - - private Object object; - - private char hump; - - private Class clazz; - - private void init(ConfigInfo configInfo) { - String prefix = configInfo.getPrefix(); - if (Objects.nonNull(prefix)) { - this.prefix = prefix.endsWith(".") ? prefix : prefix + "."; - } - this.hump = Objects.equals(configInfo.getHump(), ConfigInfo.HUMP_ROD) ? '_' : '.'; - this.clazz = convertInfo.getClazz(); - this.convertInfo.setHump(this.hump); - } - - @Override - public Object convert(ConvertInfo convertInfo) { - try { - this.convertInfo = convertInfo; - this.object = convertInfo.getClazz().newInstance(); - this.init(convertInfo.getConfigInfo()); - this.setValue(); - - Class superclass = convertInfo.getClazz(); - for (; ; ) { - superclass = superclass.getSuperclass(); - if (Objects.equals(superclass, Object.class) || Objects.isNull(superclass)) { - break; - } - - this.clazz = superclass; - this.prefix = null; - Config[] configArray = clazz.getAnnotationsByType(Config.class); - if (configArray.length != 0 && !Strings.isNullOrEmpty(configArray[0].prefix())) { - String prefix = configArray[0].prefix(); - this.prefix = prefix.endsWith(".") ? prefix : prefix + "."; - this.hump = Objects.equals(configArray[0].hump(), ConfigInfo.HUMP_ROD) ? '_' : '.'; - this.convertInfo.setHump(this.hump); - } - - this.setValue(); - } - - return object; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private void setValue() throws Exception { - boolean needReload = Boolean.FALSE; - - for (Field field : this.clazz.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) { - continue; - } - field.setAccessible(true); - - ConvertInfo convertInfo = this.convertInfo; - String key; - ConfigFiled configFiled = field.getAnnotation(ConfigFiled.class); - StringBuilder keyPrefix = new StringBuilder(Objects.isNull(prefix) ? "" : prefix); - if (configFiled == null || configFiled.field().equals("")) { - key = this.getKey(field.getName(), hump, keyPrefix); - } else { - key = keyPrefix.append(configFiled.field()).toString(); - } - // todo configFiled.reload() verify - if (!needReload && configFiled != null && configFiled.reload()) { - needReload = Boolean.TRUE; - } - - Class clazz = field.getType(); - ConvertValue convertValue = classToConvert.get(clazz); - Properties properties = convertInfo.getProperties(); - if (clazz.isEnum()) { - String value = properties.getProperty(key); - convertInfo.setValue(value); - convertValue = convertEnum; - } else if (convertValue instanceof ConvertProperties) { - Properties value = getPropertiesByPrefix(properties, key); - convertInfo.setValue(value); - } else if (Objects.isNull(convertValue)) { - if (Objects.equals("ConfigurationWrapper", clazz.getSimpleName())) { - continue; - } - convertValue = new ConvertObject(); - convertInfo = new ConvertInfo(); - if (clazz.isMemberClass()) { - convertInfo.setClazz(Class.forName(clazz.getName())); - } else { - convertInfo.setClazz(field.getType()); - } - convertInfo.setProperties(properties); - convertInfo.setConfigInfo(this.convertInfo.getConfigInfo()); - } else { - String value = properties.getProperty(key); - if (Objects.isNull(value) && convertValue.isNotHandleNullValue()) { - NotNull notNull = field.getAnnotation(NotNull.class); - if (Objects.nonNull(notNull)) { - Preconditions.checkState(true, key + " is invalidated"); - } - continue; - } - convertInfo.setValue(value); - } - - if (Objects.isNull(convertInfo.getValue())) { - continue; - } - - convertInfo.setField(field); - convertInfo.setKey(key); - Object value = convertValue.convert(convertInfo); - - if (Objects.isNull(value)) { - NotNull notNull = field.getAnnotation(NotNull.class); - if (Objects.nonNull(notNull)) { - Preconditions.checkState(true, key + " is invalidated"); - } - continue; - } - field.set(object, value); - } - - if (!needReload) { - return; - } - Method method = this.clazz.getDeclaredMethod("reload", null); - method.setAccessible(true); - method.invoke(this.object, null); - } - - public String getKey(String fieldName, char spot, StringBuilder key) { - boolean currency = false; - int length = fieldName.length(); - for (int i = 0; i < length; i++) { - char c = fieldName.charAt(i); - boolean b = i < length - 1 && fieldName.charAt(i + 1) > 96; - - if (currency) { - if (b) { - key.append(spot); - key.append((char) (c + 32)); - currency = false; - } else { - key.append(c); - } - } else { - if (c > 96) { - key.append(c); - } else { - key.append(spot); - if (b) { - key.append((char) (c + 32)); - } else { - key.append(c); - currency = true; - } - } - } - } - - return key.toString().toLowerCase(Locale.ROOT); - } - } - - private static class ConvertCharacter implements ConvertValue { - - @Override - public Character convert(ConvertInfo convertInfo) { - String value = (String) convertInfo.getValue(); - return value.charAt(0); - } - } - - private static class ConvertBoolean implements ConvertValue { - - @Override - public Boolean convert(ConvertInfo convertInfo) { - String value = (String) convertInfo.getValue(); - if (Objects.equals(value.length(), 1)) { - return Objects.equals(convertInfo.getValue(), "1") ? Boolean.TRUE : Boolean.FALSE; - } - return Boolean.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertByte implements ConvertValue { - - @Override - public Byte convert(ConvertInfo convertInfo) { - return Byte.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertShort implements ConvertValue { - - @Override - public Short convert(ConvertInfo convertInfo) { - return Short.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertInteger implements ConvertValue { - - @Override - public Integer convert(ConvertInfo convertInfo) { - return Integer.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertLong implements ConvertValue { - - @Override - public Long convert(ConvertInfo convertInfo) { - return Long.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertFloat implements ConvertValue { - - @Override - public Float convert(ConvertInfo convertInfo) { - return Float.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertDouble implements ConvertValue { - - @Override - public Double convert(ConvertInfo convertInfo) { - return Double.valueOf((String) convertInfo.getValue()); - } - } - - private static class ConvertString implements ConvertValue { - - @Override - public String convert(ConvertInfo convertInfo) { - return (String) convertInfo.getValue(); - } - } - - private static class ConvertDate implements ConvertValue { - - @Override - public Date convert(ConvertInfo convertInfo) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - try { - return sdf.parse((String) convertInfo.getValue()); - } catch (ParseException e) { - throw new RuntimeException(e); - } - } - } - - private static class ConvertLocalDate implements ConvertValue { - - @Override - public LocalDate convert(ConvertInfo convertInfo) { - return LocalDate.parse((String) convertInfo.getValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd")); - } - - } - - private static class ConvertLocalDateTime implements ConvertValue { - - @Override - public LocalDateTime convert(ConvertInfo convertInfo) { - return LocalDateTime.parse((String) convertInfo.getValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - } - - } - - private static class ConvertEnum implements ConvertValue> { - - @SuppressWarnings({"unchecked", "rawtypes"}) - @Override - public Enum convert(ConvertInfo convertInfo) { - return Enum.valueOf((Class) convertInfo.getField().getType(), (String) convertInfo.getValue()); - } - - } - - private class ConvertList implements ConvertValue> { - - public boolean isNotHandleNullValue() { - return false; - } - - @SuppressWarnings("unchecked") - @Override - public List convert(ConvertInfo convertInfo) { - try { - if (convertInfo.getValue() == null) { - return new ArrayList<>(); - } - List values = Splitter.on(",").omitEmptyStrings().trimResults().splitToList((String) convertInfo.getValue()); - List list; - if (Objects.equals(convertInfo.getField().getType(), List.class)) { - list = new ArrayList<>(); - } else { - list = (List) convertInfo.getField().getType().newInstance(); - } - - Type parameterizedType = ((ParameterizedType) convertInfo.getField().getGenericType()).getActualTypeArguments()[0]; - ConvertValue convert = classToConvert.get(parameterizedType); - if (Objects.isNull(convert)) { - throw new RuntimeException("convert is null"); - } - - for (String value : values) { - convertInfo.setValue(value); - list.add(convert.convert(convertInfo)); - } - - return list; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private class ConvertMap implements ConvertValue> { - - public boolean isNotHandleNullValue() { - return false; - } - - @SuppressWarnings("unchecked") - @Override - public Map convert(ConvertInfo convertInfo) { - try { - String key = convertInfo.getKey() + convertInfo.getHump(); - Map map; - if (Objects.equals(Map.class, convertInfo.getField().getType())) { - map = new HashMap<>(); - } else { - map = (Map) convertInfo.getField().getType().newInstance(); - } - Type parameterizedType = ((ParameterizedType) convertInfo.getField().getGenericType()).getActualTypeArguments()[1]; - ConvertValue convert = classToConvert.get(parameterizedType); - if (Objects.isNull(convert)) { - throw new RuntimeException("convert is null"); - } - for (Entry entry : convertInfo.getProperties().entrySet()) { - String propertiesKey = entry.getKey().toString(); - if (propertiesKey.startsWith(key)) { - String value = entry.getValue().toString(); - convertInfo.setValue(value); - map.put(propertiesKey.replace(key, ""), convert.convert(convertInfo)); - } - } - return map; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private static class ConvertIPAddress implements ConvertValue { - - @Override - public IPAddress convert(ConvertInfo convertInfo) { - try { - return new IPAddressString((String) convertInfo.getValue()).toAddress(); - } catch (AddressStringException e) { - throw new RuntimeException(e); - } - } - } - - private static class ConvertProperties implements ConvertValue { - - @Override - public Properties convert(ConvertInfo convertInfo) { - - try { - return (Properties) convertInfo.getValue(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private static Properties getPropertiesByPrefix(Properties properties, String prefix) { - if (StringUtils.isBlank(prefix)) { - return null; - } - Properties to = new Properties(); - return PropertiesUtils.getPropertiesByPrefix(properties, to, prefix); - } - - @Data - static class ConvertInfo { - char hump; - String key; - Field field; - Object value; - Class clazz; - Properties properties; - ConfigInfo configInfo; - } -}