Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I format a string with properties from a bean

I want to create a String using a format, replacing some tokens in the format with properties from a bean. Is there a library that supports this or am I going to have to create my own implementation?

Let me demonstate with an example. Say I have a bean Person;

public class Person {
  private String id;
  private String name;
  private String age;

  //getters and setters
}

I want to be able to specify format strings something like;

"{name} is {age} years old."
"Person id {id} is called {name}."

and automatically populate the format placeholders with values from the bean, something like;

String format = "{name} is {age} old."
Person p = new Person(1, "Fred", "32 years");
String formatted = doFormat(format, person); //returns "Fred is 32 years old."

I've had a look at MessageFormat but this only seems to allow me to pass numeric indexes, not bean properties.

like image 848
Qwerky Avatar asked Jul 18 '11 14:07

Qwerky


People also ask

Can you format strings in Java?

In java, String format() method returns a formatted string using the given locale, specified format string, and arguments. We can concatenate the strings using this method and at the same time, we can format the output concatenated string.

What method is used to format strings?

The String format() Method.

What is format string syntax?

Syntax of string format() function Syntax: { }.format(value) Parameters: value : Can be an integer, floating point numeric constant, string, characters or even variables.


2 Answers

Rolled my own, testing now. Comments welcome.

import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BeanFormatter<E> {

  private Matcher matcher;
  private static final Pattern pattern = Pattern.compile("\\{(.+?)\\}");

  public BeanFormatter(String formatString) {
    this.matcher = pattern.matcher(formatString);
  }

  public String format(E bean) throws Exception {
    StringBuffer buffer = new StringBuffer();

    try {
      matcher.reset();
      while (matcher.find()) {
        String token = matcher.group(1);
        String value = getProperty(bean, token);
        matcher.appendReplacement(buffer, value);
      }
      matcher.appendTail(buffer);
    } catch (Exception ex) {
      throw new Exception("Error formatting bean " + bean.getClass() + " with format " + matcher.pattern().toString(), ex);
    }
    return buffer.toString();
  }

  private String getProperty(E bean, String token) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    Field field = bean.getClass().getDeclaredField(token);
    field.setAccessible(true);
    return String.valueOf(field.get(bean));
  }

  public static void main(String[] args) throws Exception {
    String format = "{name} is {age} old.";
    Person p = new Person("Fred", "32 years", 1);

    BeanFormatter<Person> bf = new BeanFormatter<Person>(format);
    String s = bf.format(p);
    System.out.println(s);
  }

}
like image 146
Qwerky Avatar answered Oct 02 '22 16:10

Qwerky


Yes, it's possible using the Pojomatic library. Implement and plug in your own implementation of PojoFormatter. Pojomator#doToString(T) may be also interesting.

like image 37
Boris Pavlović Avatar answered Oct 02 '22 16:10

Boris Pavlović