2011-07-18 18 views
7

Chcę utworzyć ciąg przy użyciu formatu, zastępując niektóre tokeny w formacie właściwościami z komponentu bean. Czy istnieje biblioteka, która to wspiera, czy też będę musiała stworzyć własną implementację?Jak sformatować ciąg z właściwościami z fasoli?

Pozwolę sobie przedstawić sytuację na przykładzie. Powiedz, że mam fasolę Person;

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

    //getters and setters 
} 

Chcę móc określić ciągi formatów coś jak;

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

i automatycznie wypełniają symbole zastępcze formatem z fasoli, coś w stylu;

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." 

miałem spojrzeć na MessageFormat ale to wydaje się tylko pozwala mi przejść indeksów liczbowych, a nie właściwości fasoli.

+0

Wygląda na to, że chcesz mieć groovy, a nie Javę. –

+0

Czy to jest Struts, czy próbujesz odwołać się do tego jak do stylu programowania .NET? –

Odpowiedz

2

Przetoczyłem własne, testując teraz. Komentarze mile widziane.

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); 
    } 

} 
0

naprawdę nie wiem, jak skomplikowany jest model jesteś do konsumpcji, ale jeśli chcemy mieć do czynienia z obiektem drzew Chciałbym zaimplementować własną formatowania przy użyciu Jexl jako języka wyrażają dynamiczne ten sposób:

  1. Initialize jednoelementowy silnik Jexl
  2. Wypełnij MapContext wszystkimi obiektami, które chcesz spożyć podczas formatowania ciągów znaków.
  3. Oceń poprzednie utworzone wyrażenia na mapie kontekstowej obiektu.

Dobrą rzeczą w Jexl jest to, że pozwala używać wywołań metod, a nie tylko właściwości.

Mam nadzieję, że to pomaga.

0

Nie dość blisko, ale można spojrzeć na StringTemplate Twój fasola:

public static class User { 
    public int id; // template can directly access via u.id 
    private String name; // template can't access this 
    public User(int id, String name) { this.id = id; this.name = name; } 
    public boolean isManager() { return true; } // u.manager 
    public boolean hasParkingSpot() { return true; } // u.parkingSpot 
    public String getName() { return name; } // u.name 
    public String toString() { return id+":"+name; } // u 
} 

Następnie można uczynić go tak:

ST st = new ST("<b>$u.id$</b>: $u.name$", '$', '$'); 
st.add("u", new User(999, "parrt")); 
String result = st.render(); // "<b>999</b>: parrt" 

przykładowy kod powyżej pochodzą z ST4 Introduction

Powiązane problemy