Java string formatting using class attributes

I have a class with attribute and getter method:

public Class MyClass { private String myValue = "foo"; public String getMyValue(); } 

I would like to be able to use the foo value in a formatted string as such:

 String someString = "Your value is {myValue}." String result = Formatter.format(someString, new MyClass()); // result is now "Your value is foo." 

That is, I would like to have some function like .format above, which takes a format string that defines the properties on any object, and an instance with these properties and formats the string accordingly.

Is it possible to accomplish this feat in Java?

+4
source share
4 answers

You can use JUEL for this. This is an implementation of the Java Expression Language. the code is quite compact and looks like this:

 ExpressionFactory factory = new ExpressionFactoryImpl(); // create a context and add a Person object to the context, this variable will be used // in the property replacement // objects of type Person have two fields: firstName and lastName SimpleContext context = new SimpleContext(); Person person = new Person("John", "Doe"); context.setVariable("person", factory.createValueExpression(person, Person.class)); // create the expression String expr = "My name is ${person.firstName} ${person.lastName}"; ValueExpression e = factory.createValueExpression(context, expr, String.class); // evaluate the expression System.out.println(e.getValue(context)); 

which prints "My name is John Doe"

note that you can also use an expression like this: '$ {firstName}' instead of '$ {person.firstName}', but then you will have to write and provide a custom resolver (javax.el.ELResolver) for the variable and property resolution

+3
source

(My other answer is probably useful if you are already using struts.)

Similar to sdb answer, apache JEXL .

The UnifiedJEXL class provides UnifiedJEXL functionality, so you can write ( as shown in javadocs ):

 JexlEngine jexl = new JexlEngine(); UnifiedJEXL ujexl = new UnifiedJEXL(jexl); UnifiedJEXL.Expression expr = ujexl.parse("Hello ${user}"); String hello = expr.evaluate(context, expr).toString(); 

( expr not only looks strange, is passed as a parameter to the method itself, but is not really needed as a parameter)

The context setting is shown earlier on the same page:

 // Create a context and add data JexlContext jc = new MapContext(); jc.set("foo", new Foo() ); 

You will also need either a Commons entry, or you can configure JEXL to use your own registrar.


So, to get closer to what you requested, you can create:

 public class Formatter { public static String format(String format, Object ... inputs) { JexlContext context = new MapContext(); for (int i=0;i<inputs.length;i++) { context.set("_" + (i+1), inputs[i] ); } JexlEngine jexl = new JexlEngine(); UnifiedJEXL ujexl = new UnifiedJEXL(jexl); UnifiedJEXL.Expression expr = ujexl.parse(format); return expr.evaluate(context).toString(); } } 

and name him

 String someString = "Your value is ${_1.myValue}."; String result = Formatter.format(someString, new MyClass()); 

At this point, result is "Your value is foo."

+2
source

It is theoretically possible with a stack-based analyzer to determine the holders of values ​​in a string combined with reflection (or, better, checking a Javabean API, such as Commons BeanUtils ) to get the values ​​of the bean properties.

Unfortunately, there is no ready-made or third-party API if you were looking for it. This is an interesting question.

0
source

You can create it using struts2 / xwork / OGNL, as shown below (copied from a letter from Vlad )

 public static String translateOgnl(String message, Map<Object, Object> args) { OgnlValueStack stack = new OgnlValueStack(); stack.push(args); return TextParseUtil.translateVariables(message, stack); } 

javadocs for TextParseUtil.translateVariables() say

Converts all instances of $ {...} into an expression into the value returned by calling ValueStack.findValue(java.lang.String) . If the element is not found on the stack (returns null), then the whole variable $ {...} is not displayed, as if the element was on the stack, but returned an empty string.

0
source

Source: https://habr.com/ru/post/1305618/


All Articles