java equivalent to C# ExpandoObject - java

C# code example:
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.Number = 12;
MyDynamic.MyMethod = new Func<int>(() =>
{
return 55;
});
Console.WriteLine(MyDynamic.MyMethod());
Java: ?
Any ideas why java doesn't have support for this scenario?

Java is much more strict in this case. So the short answer is no, Java doesn't have an Expando. The syntax just doesn't support that.
However there is an Expando in Groovy which is a dynamic language on top of Java.
BTW, If you're using Expando for tests, there are a lot of various Mock related solutions: EasyMock, Mockito, JMock to name a few.

Related

Scala - runtime String template

I want to do exactly what java's String Template does, but in scala. This library however does not work with case classes:
case class Obj(str:String)
val st = new ST("xx $obj.str$ xx",'$','$')
st.add("obj",Obj("replacement"))
st.render() //returns "xx xx"
ST tries to find property "str" with reflection, but it just does not work with scala.
How can I achieve it without ST?
Try to create your class like this:
case class Obj(#BeanProperty str: String)
Here is the scala doc: http://www.scala-lang.org/api/current/#scala.beans.BeanProperty
Also you can take a look at the project Scalasti which is a interface for StringTemplate: http://software.clapper.org/scalasti/
It's built into the language (in an extendable way). Just
val obj = Obj("replacement")
s"xx ${obj.str} xx"
You can have any Scala expression inside ${...}.
See http://docs.scala-lang.org/overviews/core/string-interpolation.html (or just search for "Scala string interpolation") for more.

How to use an array value as field in Java? a1.section[2] = 1;

New to Java, and can't figure out what I hope to be a simple thing.
I keep "sections" in an array:
//Section.java
public static final String[] TOP = {
"Top News",
"http://www.mysite.com/RSS/myfeed.csp",
"top"
};
I'd like to do something like this:
Article a1 = new Article();
a1.["s_" + section[2]] = 1; //should resolve to a1.s_top = 1;
But it won't let me, as it doesn't know what "section" is. (I'm sure seasoned Java people will cringe at this attempt... but my searches have come up empty on how to do this)
Clarification:
My article mysqlite table has fields for the "section" of the article:
s_top
s_sports
...etc
When doing my import from an XML file, I'd like to set that field to a 1 if it's in that category. I could have switch statement:
//whatever the Java version of this is
switch(section[2]) {
case "top": a1.s_top = 1; break;
case "sports": a1.s_sports = 1; break;
//...
}
But I thought it'd be a lot easier to just write it as a single line:
a1["s_"+section[2]] = 1;
In Java, it's a pain to do what you want to do in the way that you're trying to do it.
If you don't want to use the switch/case statement, you could use reflection to pull up the member attribute you're trying to set:
Class articleClass = a1.getClass();
Field field = articleClass.getField("s_top");
field.set(a1, 1);
It'll work, but it may be slow and it's an atypical approach to this problem.
Alternately, you could store either a Map<String> or a Map<String,Boolean> inside of your Article class, and have a public function within Article called putSection(String section), and as you iterate, you would put the various section strings (or string/value mappings) into the map for each Article. So, instead of statically defining which sections may exist and giving each Article a yes or no, you'd allow the list of possible sections to be dynamic and based on your xml import.
Java variables are not "dynamic", unlink actionscript for exemple. You cannot call or assign a variable without knowing it at compile time (well, with reflection you could but it's far to complex)
So yes, the solution is to have a switch case (only possible on strings with java 1.7), or using an hashmap or equivalent
Or, if it's about importing XML, maybe you should take a look on JAXB
If you are trying to get an attribute from an object, you need to make sure that you have "getters" and "setters" in your object. You also have to make sure you define Section in your article class.
Something like:
class Article{
String section;
//constructor
public Article(){
};
//set section
public void setSection(Section section){
this.section = section;
}
//get section
public String getSection(){
return this.section;
}

Creating meta language with Java

guys! I need to create some sort of meta language which I could embed in XML and then parse with Java. For example:
<code>
[if value1>value2 then "Hello, Bob!" else "Hello, Jack"]
</code>
or
<code>
[if value1+2>value2 return true]
</code>
I need to implement conditional statements,arithmetics.
Any suggestions where should I start looking?
Java has a built-in JavaScript interpreter:
ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("JavaScript");
jsEngine.put("value1", 8);
jsEngine.put("value2", 9);
String script = "if(value1 + 2 > value2) {'Foo'} else {'Bar'}";
final Object result = jsEngine.eval(script);
System.out.println(result); //yields "Foo" String
Of course you are free to both load the script from anywhere you need and to provide it with any context (value and value2 in this example) you want.
See also Scripting for the Java Platform article.
A user here, Bart Kiers. Wrote a tutorial about creating a simple language in Java with ANTLR.
Java has a scripting API that you could use for this. Lookup the API documentation of the package javax.script.
You could include code in for example JavaScript in the code element, and execute that using the scripting API.
If you really want to develop your own language, start off with the interpreter pattern. If you just want to leverage somebody else's language in your Java code, look to integration ala JSP style embedded languages.
It is almost certain that a homemade language would suck, especially in the long run, so don't roll something on your own.
There are several jsp-like frameworks available, maybe one of those would do the trick:
JSTL/JSP EL (Expression Language) in a non JSP (standalone) context

Create a string with the result of an expression and the expression that originated the value. Is it possible?

Like
String r = SomeThing.toExecString("new Object().toString()");
And when executed the value of r would be:
"new Object().toString() = java.lang.Object#c5e3974"
Is this even possible at all? Would it need a bunch of reflection? A built in compiler maybe?
ScriptEngine engine = new ScriptEngineManager().getEngineByName("beanshell");
Object result = engine.eval("new Object().toString();");
System.out.println(result);
You may get close to what you want using BeanShell. I ran the above code with Java 6 with BeanShell 2.0b4 and the JSR 223-based bsh-engine.jar engine on the classpath.
There is a great post here:
Generating Static Proxy Classes - http://www.javaspecialists.eu/archive/Issue180.html
Part one is enough for what you asked, I think
Don't know if you really wanted this. But your problem would be solved with this method:
String toExecString( String code ) {
return String.format(
"\"%s\" = %s#%x",
code,
code.getClass().getName(),
code.hashCode()
);
}

Boolean Expression Evaluation in Java

I'm looking for a relatively simpler (when compared with writing a parser) way to evaluate boolean expressions in Java, and I do not want to use the JEP library.
I have a String expression like: (x > 4 || x < 8 && p > 6) and my aim is to replace the variables with values.
Is there a way by which I can evaluate this expression?
Bear in mind that this can be any level deep so writing a parser would be very complex.
Use Apache Commons Jexl; which is exactly designed for such requirement.
http://commons.apache.org/jexl/
Using jexl (http://commons.apache.org/jexl/), you can accomplish this like this
JexlEngine jexl = new JexlEngine();
jexl.setSilent(true);
jexl.setLenient(true);
Expression expression = jexl.createExpression("(a || b && (c && d))");
JexlContext jexlContext = new MapContext();
//b and c and d should pass
jexlContext.set("b",true);
jexlContext.set("c",true);
jexlContext.set("d",true);
assertTrue((Boolean)expression.evaluate(jexlContext));
jexlContext = new MapContext();
//b and c and NOT d should be false
jexlContext.set("b",true);
jexlContext.set("c",true);
//note this works without setting d to false on the context
//because null evaluates to false
assertFalse((Boolean)expression.evaluate(jexlContext));
You could use the scripting engine in Java6 and the choose any of the popular scripting languages like Scala, Ruby, Python, Groovy, and Javascript. Than all you have to do is make sure the expression you want to evaluate is in the right language. Groovy is probably the easiest and will integrate best.
I have used this method successfully for a feature offering capabilities much like a formula / calculated column in a popular spreadsheet application.
Here is the latest resources for expression evaluation framework
The information page is at http://expressionoasis.vedantatree.com/
JUEL provides an implementation of Java's Unified Expression Language without being explicitly tied to JSP. Here's its Quick Start guide, expression evaluation (#3 on that page) is the part you're interested in.
Alternatively, Spring 3.0 provides its own (though somewhat similar) expression language. This option only makes sense if you're already using Spring, though - I wouldn't pull it in just for EL.
Try http://code.google.com/p/xpressionengine/ for open source implementation
I found the libraries listed here too complicated for my needs. I ended up using Fscript:
http://fscript.sourceforge.net/
There is a API available at http://lts.online.fr/dev/java/math.evaluator/
Example:
MathEvaluator m = new MathEvaluator("-5-6/(-2) + sqr(15+x)");
m.addVariable("x", 15.1d);
System.out.println( m.getValue() );
try Janino
http://docs.codehaus.org/display/JANINO/Home
It is very simple to use eg (taken from http://docs.codehaus.org/display/JANINO/Basic):
// Compile the expression once; relatively slow.
ExpressionEvaluator ee = new ExpressionEvaluator(
"c > d ? c : d", // expression
int.class, // expressionType
new String[] { "c", "d" }, // parameterNames
new Class[] { int.class, int.class } // parameterTypes
);
// Evaluate it with varying parameter values; very fast.
Integer res = (Integer) ee.evaluate(
new Object[] { // parameterValues
new Integer(10),
new Integer(11),
}
);
System.out.println("res = " + res);
You could try this library https://github.com/Shy-Ta/expression-evaluator-demo - the read me has a fair number of examples. The library uses java and groovy.
In addition to supporting this use case, it also supports a lot of other excel like functions. Also, it is very simple to add new functions as demonstrated in the example.
ExpressionsEvaluator evalExpr = ExpressionsFactory.create("(x > 4 || x < 8 && p > 6)");
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("x", 100);
variables.put("p", 10);
evalExpr.eval();

Categories

Resources