JavaBeans PropertyEditor


The PropertyEditor class converts a property’s value to and from its native type representation into a String. Originally, this was conceived as a way to allow property values to be entered, as String values, into an editor and transform them into the correct types. However, because PropertyEditors are inherently lightweight classes, they have found uses in many different settings, including Spring.


The Built-in PropertyEditors


Spring comes with several built-in PropertyEditor implementations that are preregistered with the BeanFactory.


Using the Built-in PropertyEditors


public class PropertyEditorBean {
private Class cls;
private File file;
private URL url;
private Locale locale;
private Properties properties;
private String[] strings;
private byte[] bytes;
private Pattern pattern;
public void setPattern(Pattern pattern) {
System.out.println("Setting pattern: " + pattern);
this.pattern = pattern;
}
public void setClass(Class cls) {
System.out.println("Setting class: " + cls.getName());
this.cls = cls;
}
public void setFile(File file) {
System.out.println("Setting file: " + file.getName());
this.file = file;
}
public void setLocale(Locale locale) {
System.out.println("Setting locale: " + locale.getDisplayName());
this.locale = locale;
}
public void setProperties(Properties properties) {
System.out.println("Loaded " + properties.size() + " properties");
this.properties = properties;
}
public void setStrings(String[] strings) {
System.out.println("Loaded " + strings.length + " Strings");
this.strings = strings;
}
public void setUrl(URL url) {
System.out.println("Setting URL: " + url.toExternalForm());
this.url = url;
}
public void setBytes(byte[] bytes) {
System.out.println("Adding " + bytes.length + " bytes");
this.bytes = bytes;
}
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(
new ClassPathResource("/META-INF/spring/pedemo-context.xml")
);
PropertyEditorBean bean = (PropertyEditorBean) factory
.getBean("builtInSample");
}
}


Configuration Using PropertyEditors


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="builtInSample"
class="com.apress.prospring2.ch04.pe.PropertyEditorBean">
<property name="bytes" value="Hello, World"/>
<property name="class" value="java.lang.String"/>
<property name="file" value="/tmp"/>
<property name="locale" value="en_GB"/>
<property name="pattern" value="^(.*)quot;/>
<property name="properties">
<value>
a=b
c=d
</value>
</property>
<property name="strings" value="Aleksa,Ani,Jessica,Jan"/>
<property name="url" value="http://www.cakesolutions.net"/>
</bean>
</beans>

Although all the properties on the PropertyEditorBean are not String values, the values for the properties are specified as simple strings. Running this example yields the following output

Adding 12 bytes
Setting class: java.lang.String
Setting file: tmp
Setting locale: English (United Kingdom)
Setting pattern: ^(.*)$
Loaded 2 properties
Loaded 4 Strings
Setting URL: http://www.cakesolutions.net


Creating a Custom PropertyEditor

The Simple Implementation of the Complex Class


public final class Complex {
private double re;
private double im;
public Complex(Double re, Double im) {
if (re != null) this.re = re;
if (im != null) this.im = im;
}
public double getRe() {
return re;
}
public double getIm() {
return im;
}
public Complex add(Complex rhs) {
return new Complex(this.re + rhs.re, this.im + rhs.im);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("(").append(this.re);
if (this.im > 0) sb.append("+");
sb.append(this.im).append(")");
return sb.toString();
}
}



The ComplexPropertyEditor Class


public class ComplexPropertyEditor extends PropertyEditorSupport {
private static final String MINUS_SIGN = "-";
private static final String COMPLEX_UNIT = "j";
private static final Pattern COMPLEX_PATTERN =
Pattern.compile("([+\\-])?([0-9.]+)([j]?)", Pattern.CASE_INSENSITIVE);
public void setAsText(String s) throws IllegalArgumentException {
Matcher matcher = COMPLEX_PATTERN.matcher(s);
Double re = null;
Double im = null;
while (matcher.find()) {
if (COMPLEX_UNIT.equalsIgnoreCase(matcher.group(3))) {
im = getValue(matcher);
} else {
re = getValue(matcher);
}
}
if (re == null && im == null) {
throw new IllegalArgumentException(
"Cannot convert value " + s + " to " + Complex.class.getName());
} else {
setValue(new Complex(re, im));
}
}
private double getValue(Matcher matcher) {
double d;
d = Double.parseDouble(matcher.group(2));
if (MINUS_SIGN.equals(matcher.group(1))) d = -d;
return d;
}
}


The CustomEditorExample Bean


public class CustomEditorDemo {
private Complex[] values;
public static void main(String[] args) {
ConfigurableListableBeanFactory factory = new XmlBeanFactory(
new ClassPathResource("/META-INF/spring/pedemo2-context.xml")
);
factory.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Complex.class,
new ComplexPropertyEditor());
}
});
CustomEditorDemo bean =
(CustomEditorDemo) factory.getBean("exampleBean");
System.out.println(bean.sum());
}
private Complex sum() {
Complex result = new Complex(0d, 0d);
for (Complex value : this.values) {
result = result.add(value);
}
return result;
}
public void setValues(Complex[] values) {
this.values = values;
}
}



Using CustomEditorConfigurer


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="customEditorConfigurer"
class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.apress.prospring2.ch04.pe.Complex">
<bean class="com.apress.prospring2.ch04.pe.➥
ComplexPropertyEditor"/>
</entry>
</map>
</property>
</bean>
<bean id="exampleBean" class="com.apress.prospring2.ch04.pe.CustomEditorDemo">
<property name="values">
<list>
<value>10</value>
<value>-10j</value>
<value>10+30j</value>
</list>
</property>
</bean>
</beans>



The CustomEditorExample Class


public class CustomEditorDemo {
private Complex[] values;
public static void main(String[] args) {
ConfigurableListableBeanFactory factory = new XmlBeanFactory(
new ClassPathResource("/META-INF/spring/pedemo2-context.xml")
);
CustomEditorConfigurer configurer =
(CustomEditorConfigurer)factory.getBean("customEditorConfigurer");
configurer.postProcessBeanFactory(factory);
CustomEditorDemo bean =
(CustomEditorDemo) factory.getBean("exampleBean");
System.out.println(bean.sum());
}
private Complex sum() {
Complex result = new Complex(0d, 0d);
for (Complex value : this.values) {
result = result.add(value);
}
return result;
}
public void setValues(Complex[] values) {
this.values = values;
}
}

Leave a Reply

Subscribe to Posts | Subscribe to Comments

About This Site

Howdy! My name is Suersh Rohan and I am the developer and maintainer of this blog. It mainly consists of my thoughts and opinions on the technologies I learn,use and develop with.

Blog Archive

Powered by Blogger.

- Copyright © My Code Snapshots -Metrominimalist- Powered by Blogger - Designed by Suresh Rohan -