Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit abd54e8

Browse files
authored
Merge pull request #19 from shiva2991/dateSupport
java.util.Date support using Spring's CustomDateEditor
2 parents 42fb7d3 + 7977ed9 commit abd54e8

File tree

8 files changed

+123
-29
lines changed

8 files changed

+123
-29
lines changed

README.md

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ These properties also auto reload if the given properties file changes during ru
77
<pre>
88
@ReloadableProperty("dynamicProperty.longValue")
99
private long primitiveWithDefaultValue = 55;
10-
10+
1111
@ReloadableProperty("dynamicProperty.substitutionValue")
1212
private String stringProperty;
1313

@@ -58,41 +58,43 @@ A set of integration and unit tests can be found in _src/test/java_ (tests) & _s
5858

5959
### Future Changes ###
6060
* Ability to use Spring Expression language to map properties files
61-
* Support for Java 7 Data and Time classes
61+
* Support for Java 7 Date and Time classes
6262
* Include the ability to define a database driven properties source not just properties files
6363
* Implement error recovery inside PropertiesWatcher.class, including better thread recovery
64-
* Ability to perform additional re-bind logic when a property is changed, i.e. if a class has an open DB connection whcih needs tobe re-established using newly set properties.
64+
* Ability to perform additional re-bind logic when a property is changed, i.e. if a class has an open DB connection which needs to be re-established using newly set properties.
6565
* Replace callback Properties EventHandler with Guava EventBus
6666
* Ability to configure usage via spring's @Configuration
6767

6868
### Contributions ###
69-
* Thankyou [normanatashbar](https://github.com/normanatashbar) for adding composite string replacement
69+
* Thank you [normanatashbar](https://github.com/normanatashbar) for adding composite string replacement
70+
* Thank you [shiva2991](https://github.com/normanatashbar) for adding java.util.Date type conversion.
7071

7172
### Supported Property Type Conversions Available ###
72-
* Joda Time Library (2.1) - [link](http://joda-time.sourceforge.net/)
73-
* LocalDate.class
74-
* LocalTime.class
75-
* LocalDateTime.class
76-
* Period.class
73+
* LocalDate.class
74+
* LocalTime.class
75+
* LocalDateTime.class
76+
* Period.class
7777

7878

7979
* Spring Supported (3.1.2-RELEASE)
80-
* String.class
81-
* boolean.class, Boolean.class
82-
* byte.class, Byte.class
83-
* char.class, Character.class
84-
* short.class, Short.class
85-
* int.class, Integer.class
86-
* long.class, Long.class
87-
* float.class, Float.class
88-
* double.class, Double.class
80+
* String.class
81+
* Date.class
82+
* boolean.class, Boolean.class
83+
* byte.class, Byte.class
84+
* char.class, Character.class
85+
* short.class, Short.class
86+
* int.class, Integer.class
87+
* long.class,Long.class
88+
* float.class, Float.class
89+
* double.class, Double.class
8990

9091
### Dependencies ###
9192

9293
#### Core ####
9394
* Java 7 SDK
9495
* Spring (3.2.5-RELEASE)
9596
* Google Guava (14.0.1)
97+
* Joda Time Library (2.1) - [link](http://joda-time.sourceforge.net/)
9698

9799
#### Logging ####
98100
* logback (1.0.13)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.morgan.design.properties.conversion;
2+
3+
import java.beans.PropertyEditor;
4+
import java.util.Map;
5+
6+
import org.springframework.beans.PropertyEditorRegistrar;
7+
import org.springframework.beans.PropertyEditorRegistry;
8+
9+
public class CustomEditorsRegistrar implements PropertyEditorRegistrar {
10+
11+
private Map<Class<?>, PropertyEditor> extraEditors;
12+
13+
public CustomEditorsRegistrar(Map<Class<?>, PropertyEditor> extraEditors)
14+
{
15+
this.extraEditors = extraEditors;
16+
}
17+
18+
@Override
19+
public void registerCustomEditors(PropertyEditorRegistry registry) {
20+
for (Map.Entry<Class<?>, PropertyEditor> entry : extraEditors.entrySet()) {
21+
registry.registerCustomEditor(entry.getKey(), entry.getValue());
22+
}
23+
}
24+
25+
}

src/main/java/com/morgan/design/properties/conversion/DefaultPropertyConversionService.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
import java.lang.reflect.Field;
44
import java.util.Map;
55

6+
import javax.annotation.PostConstruct;
7+
68
import org.joda.time.LocalDate;
79
import org.joda.time.LocalDateTime;
810
import org.joda.time.LocalTime;
911
import org.joda.time.Period;
1012
import org.springframework.beans.SimpleTypeConverter;
13+
import org.springframework.beans.TypeConverter;
1114
import org.springframework.beans.factory.BeanInitializationException;
15+
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
1217
import org.springframework.stereotype.Component;
1318

1419
import com.google.common.base.Function;
@@ -25,16 +30,22 @@
2530
@Component
2631
public class DefaultPropertyConversionService implements PropertyConversionService {
2732

33+
@Autowired
34+
private ConfigurableBeanFactory configurableBeanFactory;
35+
private static TypeConverter DEFAULT;
2836
private static Map<Class<? extends Object>, Function<Object, ?>> CONVERTS = Maps.newHashMap();
2937
static {
3038
CONVERTS.put(Period.class, new PeriodConverter());
3139
CONVERTS.put(LocalDateTime.class, new LocalDateTimeConverter());
3240
CONVERTS.put(LocalDate.class, new LocalDateConverter());
3341
CONVERTS.put(LocalTime.class, new LocalTimeConverter());
3442
}
35-
36-
private static SimpleTypeConverter DEFAULT = new SimpleTypeConverter();
37-
43+
44+
@PostConstruct
45+
public void init() {
46+
DEFAULT = configurableBeanFactory.getTypeConverter();
47+
}
48+
3849
@Override
3950
public Object convertPropertyForField(final Field field, final Object property) {
4051
try {

src/main/resources/spring/spring-defaultConfiguration.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,35 @@
1111
class="com.morgan.design.properties.conversion.DefaultPropertyConversionService"
1212
id="conversionService" />
1313

14+
<!-- register property editors for date and other types -->
15+
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
16+
<property name="propertyEditorRegistrars">
17+
<array>
18+
<ref bean="customEditorRegistrar"/>
19+
</array>
20+
</property>
21+
</bean>
22+
23+
<!-- bean that helps to add as many editors as we require -->
24+
<bean id="customEditorRegistrar" class="com.morgan.design.properties.conversion.CustomEditorsRegistrar">
25+
<constructor-arg>
26+
<map>
27+
<entry key="java.util.Date" value-ref="dateEditor"/>
28+
</map>
29+
</constructor-arg>
30+
</bean>
31+
32+
<!-- spring's default date property editor -->
33+
<bean id="dateEditor"
34+
class="org.springframework.beans.propertyeditors.CustomDateEditor">
35+
<constructor-arg>
36+
<bean class="java.text.SimpleDateFormat">
37+
<constructor-arg value="dd-MM-yyyy" />
38+
</bean>
39+
</constructor-arg>
40+
<constructor-arg value="true" />
41+
</bean>
42+
1443
<bean
1544
class="com.morgan.design.properties.event.GuavaPropertyChangedEventNotifier"
1645
autowire="constructor" id="eventNotifier">

src/test/java/com/morgan/design/properties/conversion/DefaultPropertyConversionServiceUnitTest.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@
33
import static org.hamcrest.Matchers.is;
44
import static org.junit.Assert.assertThat;
55

6+
import java.text.ParseException;
7+
import java.text.SimpleDateFormat;
8+
import java.util.Date;
9+
610
import org.joda.time.LocalDate;
711
import org.joda.time.LocalDateTime;
812
import org.joda.time.LocalTime;
913
import org.joda.time.Period;
10-
import org.junit.Before;
1114
import org.junit.Test;
15+
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.test.context.ContextConfiguration;
17+
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
1218

13-
public class DefaultPropertyConversionServiceUnitTest {
19+
@ContextConfiguration(locations = {"classpath:/spring/spring-reloadablePropertyPostProcessorIntTest.xml"})
20+
public class DefaultPropertyConversionServiceUnitTest extends AbstractJUnit4SpringContextTests {
1421

22+
@Autowired
1523
private PropertyConversionService conversionService;
1624

17-
@Before
18-
public void setUp() throws Exception {
19-
this.conversionService = new DefaultPropertyConversionService();
20-
}
21-
2225
@Test
2326
public void shouldConvertPeriodForPropertyForField() throws NoSuchFieldException, SecurityException {
2427
assertThat((Period) convertPropertyForField("period", "24:00:00"), is(new Period(24, 0, 0, 0)));
@@ -52,11 +55,18 @@ public void shouldConvertBooleanValue() throws NoSuchFieldException, SecurityExc
5255
assertThat((Boolean) convertPropertyForField("booleanValue", "true"), is(true));
5356
}
5457

58+
@Test
59+
public void shouldConvertDateValue() throws NoSuchFieldException, SecurityException, ParseException {
60+
Date expected = new SimpleDateFormat("dd-MM-yyyy").parse("9-4-2017");
61+
assertThat((Date) convertPropertyForField("dateValue", "9-4-2017"), is(expected));
62+
}
63+
5564
static class TestObject {
5665
Period period = new Period();
5766
LocalTime localTime = new LocalTime();
5867
LocalDate localDate = new LocalDate();
5968
LocalDateTime localDateTime = new LocalDateTime();
69+
Date dateValue = new Date();
6070
boolean booleanValue;
6171
}
6272

src/test/java/com/morgan/design/properties/internal/ReloadablePropertyPostProcessorIntTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
import java.math.BigDecimal;
77
import java.math.BigInteger;
8+
import java.text.ParseException;
9+
import java.text.SimpleDateFormat;
10+
import java.util.Date;
811

912
import org.joda.time.LocalDate;
1013
import org.joda.time.LocalDateTime;
@@ -98,5 +101,10 @@ public void shouldInjectLocalDateTimeValue() {
98101
public void shouldInjectLocalTimeValue() {
99102
assertThat(this.bean.getLocalTimeProperty(), is(new LocalTime(12, 22, 45)));
100103
}
101-
104+
105+
@Test
106+
public void shouldInjectDateValue() throws ParseException {
107+
Date d = new SimpleDateFormat("dd-MM-yyyy").parse("14-4-2017"); // exception is never throw
108+
assertThat(this.bean.getDateProperty(), is(d));
109+
}
102110
}

src/test/java/com/morgan/design/properties/testBeans/AutowiredPropertyBean.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.math.BigDecimal;
44
import java.math.BigInteger;
5+
import java.util.Date;
56

67
import org.joda.time.LocalDate;
78
import org.joda.time.LocalDateTime;
@@ -71,6 +72,10 @@ public class AutowiredPropertyBean {
7172

7273
@ReloadableProperty("dynamicProperty.localTimeValue")
7374
private LocalTime localTimeProperty;
75+
76+
// java date
77+
@ReloadableProperty("dynamicProperty.dateValue")
78+
private Date dateProperty;
7479

7580
// recursive substitution
7681

@@ -151,4 +156,7 @@ public String getSubstitutedProperty() {
151156
return this.substitutedProperty;
152157
}
153158

159+
public Date getDateProperty() {
160+
return this.dateProperty;
161+
}
154162
}

src/test/resources/test-files/example.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ dynamicProperty.booleanValue=true
1313
dynamicProperty.localDateTimeValue=2009-07-05 12:56:02
1414
invalid.period=12:22:
1515
dynamicProperty.bigIntegerValue=224411
16+
dynamicProperty.dateValue=14-4-2017

0 commit comments

Comments
 (0)