This question already has answers here:
What are some valid uses for spEL (Spring Expression Language) ?
(2 answers)
Closed 7 years ago.
I am trying to learn Spring, so from here I got this example,
ExpressionParser parser = new SpelExpressionParser();
// evals to "Hello World"
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();
But I didn't understand it exact usage, 'cause I can better declare it as
String helloWorld = "Hello World";
So what is the exact use of above SpEL?
Where can I use it better way?
That particular SpEL is useless. It's useful when the expression that you pass to the parser comes from some external source, such as an annotation value or an XML attribute. A comprehensive explanation of ELs is way too broad for Stack Overflow, but I suggest looking at Thymeleaf for an example of how EL can be useful.
(Note also that it's much better to use getValue(String.class) instead of casting, both because it's safer and because you can take advantage of automatic type conversion.)
Spring Expression Language is used mainly in view layer like JSP, Thymeleaf. You can manipulate java object easily in view layer with SpEL. If you want to evaluate SpEL expression in java layer, you can use ExpressionParser to get the outcome.
Generally we want to keep view layer as much clean as possible(Don't want to evaluate complex logical operation). But sometimes little manipulation is must needed. In that case SpEL becomes handy.
Related
Edit: I have rewritten the question to hopefully make it more understandable.
I do not want to overload!
If you have the following code:
ImmutableObject mutableReference = new ImuttableObject();
mutableReference = mutableReference.doStuff(args);
Can a compile time or pre-compile time process replace defined text formats? For example:
DEFINE X.=Y AS X = X.Y
could replace
mutableReference .= doStuff(args) with mutableReference = mutableReference.doStuff(args);
So some process knows that the code before ".=" is X and after is Y. Similar to syntactic sugar, before compiling or during, just replace X.=Y with X = X.Y.
Below is the old version of the question.
I have the following "form" of code for lack of a better word.
turnStates = turnStates.add(currentState); // log end of turn state.
//turnStates.=add(currentState);
//turnStates=.add(currentState);
Where turnStates can be a reference to any immutable object.
I would like it to look like the code commented out or similar.
Much like integers that have ++ and += I'd like a way to write my own for my immutables.
I think I recall some pre-processor stuff from C++ that I think could replace predefined text for code snippets. I was wondering if there was a way in java to define a process for replacing my desired code for the working code at compile time.
I'm sure you could make the IDE do it, but then you can't share the code with others not running a pre-configured IDE.
Edit:
turnStates is immutable and returns a different object on a call to add. It is test code and I have my reasons why a list, or as it is at the moment acting more like a stack, is immutable. Irrelevant for the question as I could simply replace it with
player = player.doSomething(args) where doSomething(args) returns a Player instance. Player is just a small part of the model and is costless to be immutable.
I know Overloads and syntax can't be changed in Java. As I tried to portray originally, sorry if it didn't come across this way is:
I was hoping that I wasn't aware of a syntax to do with maybe the # sign that could replace text before compiling. So for example:
DEFINE X.=Y AS X = X.Y where X = turnStates and Y = add() in my example.
But as the answer I upvoted said. I'll check out Scala as the answer seems to be no.
No. Java explicitly does not support operator overloading for user defined data types. However, scala is a JVM hosted language and does.
Unlike C++,Java doesn't support operator overloading.But Scala or Groovy does.
Scala can be integrated into Java but the operator overloading integration part is still not directly supported by Java as you will not be able to use the operator itself but something like #eq(...) for the "=" operator.
Check this link out for a little more detail if you want to know about Scala integration into java
Bottom line:
operator overloading is not supported by Java
And if your project requires a lot of vector addition, substraction,etc. i.e. lot of custom operators then a good suggestion would be using C# as your choice of language which is a Java like language
I have a filtering application written in Java that will allow me to filter companies based on their fundamentals (e.g. pretax profit, dividend yield etc.).
I have created a filtering engine that, at the moment is hard-coded to take filters that have been given at compile time.
What I want to do is open up a web service where I can pass in JSON to run the filtering using filters defined and passed in at runtime.
To do this I need to somehow convert strings into Java code.
So for example the following string in JSON:
current.preTaxProfit > previous.preTaxProfit
into Java code like this:
return current.getPreTaxProfit() > previous.getPreTaxProfit();
The main issue I am having is parsing mathematical strings such as:
current.preTaxProfit > (previous.preTaxProfit * 1.10)
Things could get very complex very quickly, especially when it comes to inner brackets and such, and adhering to BODMAS.
Are there any libraries out there specifically for parsing mathematical strings, or does anyone know any good resources that could help me?
For example, I have found this:
Javaassist: http://davidwinterfeldt.blogspot.co.uk/2009/02/genearting-bytecode.html
Does anyone have any experience of using Javaassist? In my architecture I pass in objects ith 'callback' methods implemented, so the ability to create entire classes and methods could useful.
Two possibilities:
the Java Scripting API:
the EL, Expression Language.
The scripting API might be most fast to get results from, but EL is nicer.
Consider using of an expression language, for instance JEXL.
If you put current and previous into the context, just evaluate:
current.preTaxProfit > (previous.preTaxProfit * 1.10)
Complete example:
// create context
JexlContext jc = new MapContext();
context.set("current", someObject);
context.set("previous", anotherObject);
// create expression
String jexlExp = "current.preTaxProfit > (previous.preTaxProfit * 1.10)";
Expression e = jexl.createExpression(jexlExp);
// evaluate
Object result = e.evaluate(jc);
I watched the Oracle OTN Virtual Event: Java SE and JavaFX 2.0 (28 Feb 2012) and while talking about the new diamond operator (that Map<String, List<String>> myMap = new HashMap<>(); thing) the speaker mentioned that it was not as simpleto implement than one might think, as it is not a simple token replacement.
My question is why? Why can't be this implemented as simply taking the string from the variable's declaration and put it into the diamond operator?
I didn't implement it either, so I can only guess.
But usually the reason these things are more complex than they seem is that first inspection only looks at the most common (or most publicized) use case. In this case it's the one you mentioned. In theory that should be easy to specify exactly and it should be rather easy to implement in a compiler.
However, the diamond operator (which is not technically a operator, by the way) can be used in different ways as well:
someMethodWithGenericArguments(new HashMap<>());
new SomeGenericClass(new HashMap<>());
T foo = new SomethingRelatedToT<>(); // where T is a generic type parameter
In those cases a simple token replacement obviously no longer works, you need actual type inference involving real type analysis (i.e. it's on an entirely different abstraction level as a simple token replacement would be).
Something which Java doesn't do (which many languages have) is implied types based on usage. i.e. Java doesn't imply a require type based on how it is used.
e.g.
Type a = b;
The type of a and the type of b are independent and no assumptions are made about b based on the type of a.
MethodHandles are showing signs of supporting this. The return type use can be based on context, but this is a runtime feature.
In conclusion, my assumption is; It was hard to implement in Java because the language didn't support any like it. If the language used feature like this all the time, the approach to take would be understood (in term of defining a spec of how it should work) and supported by the tools in the compiler.
I want an expression language that runs on the JVM and includes support for
math expressions, including operator priority
string expressions, like substring, etc
supports named functions
this allows me to decorate and control exactly who and what functions can be executed.
read/write variables that are "typeless" / allow type conversion in a controlled manner.
does not allow arbitary java scriptlets.
it should not be possible to include constructs like new Someclass()
cannot execute arbitrary static or otherwise method
does not allow any OGNL like expressions.
I only want to functions I map to be available.
support for control constructs like if this then that is for the moment optional.
must be embeddable.
This previous stackoverflow question is similar, but:
does not really answer "how" or "what" as does the above,
allows java object expressions, throwing an exception from a SecurityManager to stop method execution, which is nasty and wrong.
java object like expressions should be an error at parse time.
jexel seem to be closest possible match, but License is a bit horrible (GPL/Commercial).
If you only want the scripts to output text, then Apache Velocity fit's your constraints quite well. It runs in an environment where it only has access to the objects you give it, but can do things like basic math.
The Apache license is a bit friendlier than GPL too.
I've been using Lisp on and off, and I'm catching up with clojure.
The good thing about clojure is that I can use all the java functions naturally, and the bad thing about clojure is also that I have to know java function naturally.
For example, I had to spend some time (googling) to find square function in Java (Math/sqrt in clojure notation).
Could you recommend me some good information resource for Java functions (libraries) for clojure users that are not so familiar with Java?
It can be anything - good books, webpages, forums or whatever.
I had similar problems when I first started using Clojure. I had done some Java development years ago, but was still pretty unfamiliar with the libraries out there.
Intro
I find the easiest way to use Java is to not really use it. I think a book would be a little bit much to just get started using Java from Clojure. There isn't that much you really need to know, unless you really start getting down into the JVM/Java libraries. Let me explain.
Spend more time learning how to use Clojure inside and out, and become familiar with Clojure-Contrib. For instance, sqrt is in generic.math-functions in clojure.contrib.
Many of the things you'll need are in fact already in Clojure–but still plenty are not.
Become familiar with calling conventions and syntactic sugar in Clojure for using Java. e.g. Math/sqrt, as per your example, is calling the static method (which just a function, basically) sqrt from the class Math.
Anyway, here's a guide that should help you get started if you find yourself really needing to use Java. I'm going to assume you've done some imperative OO programming, but not much else. And even if you haven't, you should be okay.
Isaac's Clojurist's Guide to Java
Classes
A class is a bundle of methods (functions which act on the class) that
can also be a data type: e.g. to create a new class of the type Double : (Double. 1.2) which initializes the class Double (the period is the syntactic sugar for calling the class constructor methods, which initialize the class with the values you provide) with the value 1.2.
Now, look at the Double class in the Java 6 API:
Double
public Double(double value)
Constructs a newly allocated Double object that represents the
primitive double argument.
Parameters:
value - the value to be represented by the Double.
So you can see what happened there. You "built" a new Double with value 1.2, which is a double. A little confusing there, but really a Double is a class that represents a Double and can do things relating to doubles.
Static Methods
For instance, to parse a Double value out of a string, we can use the static method (meaning we don't need a particular instance of Double, we can just call it like we called sqrt) parseDouble(String s):
(Double/parseDouble "1.2") => 1.2
Not to tricky there.
Nonstatic Methods
Say we want to use a Java class that we initialized to something. Not too difficult:
(-> (String. "Hey there") ;; make a new String object
(.toUpperCase)) ;; pass it to .toUpperCase (look up -> to see what it does)
;; toUpperCase is a non-static method
=> "HEY THERE"
So now we've used a method which is not static, and which requires a real, live String object to deal with. Let's look at how the docs say it works:
toUpperCase
public String toUpperCase()
Converts all of the characters in this String to upper case using
the rules of the default locale. This method is equivalent to
toUpperCase(Locale.getDefault()).
Returns:
the String, converted to uppercase.
So here we have a method which returns a string (as shown by the "String" after the public in the definition, and takes no parameters. But wait! It does take a parameter. In Python, it'd be the implicit parameter self: this is called this in Java.
We could also use the method like this: (.toUpper (String. "Hey there")) and get the same result.
More on Methods
Since you deal with mutable data and classes in Java, you need to be able to apply functions to Classes (instances of Classes, really) and not expect a return value.
For instance, say we're dealing with a JFrame from the javax.swing library. We might need to do a number of things to it, not with it (you generally operate with values, not on them in functional languages). We can, like this:
(doto (JFrame. "My Frame!");; clever name
(.setContentPane ... here we'd add a JPanel or something to the JFrame)
(.pack) ;; this simply arranges the stuff in the frame–don't worry about it
(.setVisibleTrue)) ;; this makes the Frame visible
doto just passes its first argument to all the other functions you supply it, and passes it as the first argument to them. So here we're just doing a lot of things to the JFrame that don't return anything in particular. All these methods are listed as methods of the JFrame in the documentation (or its superclasses… don't worry about those yet).
Wrapping up
This should prepare you for now exploring the JavaDocs yourself. Here you'll find everything that is available to you in a standard Java 1.6 install. There will be new concepts, but a quick Google search should answer most of your questions, and you can always come back here with specific ones.
Be sure to look into the other important Clojure functions like proxy and reify as well as extend-type and its friends. I don't often use them, but when I need to, they can be invaluable. I still am understanding them myself, in fact.
There's a ton out there, but it's mostly a problem of volume rather than complexity. It's not a bad problem to have.
Additional reading:
Static or Nonstatic? ;; a guide to statis vs. nonstatic methods
The Java Class Library ;; an overview of what's out there, with a nice picture
The JavaDocs ;; linked above
Clojure Java Interop Docs ;; from the Clojure website
Best Java Books ;; as per clartaq's answer
Really, any good Java book can get you started. See for example the answer to the question about the
best Java book people have read so far. There are lots of good sources there.
Once you have a little Java under you belt, using it is all just a matter of simple Clojure syntax.
Mastering the content of the voluminous Java libraries is a much bigger task than figuring out how to use them in Clojure.
My first question would be: what do you exactly need? There are many Java libraries out there. Or do you just need the standard libraries? In that case the answer given by dbyrne should be enough.
Keep in mind that in general you are better of using the Clojure data structures like sequences instead of the Java equivalents.
Start with the Sun (now Oracle) Java Tutorials: http://download.oracle.com/javase/tutorial/index.html
Then dive into the Java 6 API docs:
http://download-llnw.oracle.com/javase/6/docs/
Then ask questions on #clojure IRC or the mailing list, and read blogs.
For a deep dive into Java the language, I recommend Bruce Eckel's free Thinking in Java:
http://www.mindview.net/Books/TIJ/
I think the plain old Java 6
API Specification should be pretty much all you need.