OGNL Hello World in Java - ognl

I need to use OGNL for reading some properties from Java object. OGNL is completely new thing to me. The documentation available for OGNL is OGNL's website is really confusing to me.
So anyone can provide a simple HelloWorld example for using OGNL (or any link to a tutorial is also helpful).

Try this:
Dimension d = new Dimension(2,2);
String expressionString = "width";
Object expr = Ognl.parseExpression(expressionString);
OgnlContext ctx = new OgnlContext();
Object value = Ognl.getValue(expr, ctx, d);
System.out.println("Value: " + value);

If the intention is only to read properties from an object then PropertyUtils.getProperty (from commons-beanutils) may suffice. However, if the intention is to evaluate conditionals and such, then Ognl may benefit.
Here is the same Dimension example with a boolean:
Dimension d = new Dimension();
d.setSize(100,200) ;// width and height
Map<String,Object> map = new HashMap<String,Object>();
map.put("dimension", d);
String expression = "dimension.width == 100 && dimension.height == 200";
Object exp = Ognl.parseExpression(expression);
Boolean b = (Boolean) Ognl.getValue(exp,map);
// b would evaluate to true in this case

OGNL allows you to access objects fields and methods via string expressions which becomes very useful when you have lose coupled architecture between data and it's consumers. It's using reflection under the hood but definitely speeds up development compared to a pure reflection approach.
Some one line examples
System.out.println(Ognl.getValue("x", new Point(5,5)));
System.out.println(Ognl.getValue("size", new ArrayList<Object>()));
Documentation already has a number of basic and more advanced ognl expressions.

Here is an example helloworld for jython (python that compiles to java).
from ognl import Ognl, OgnlContext
from java.lang import String
exp = Ognl.parseExpression("substring(2, 5)")
print Ognl.getValue(exp, OgnlContext(), String("abcdefghj"))

Related

Saxon - s9api - setParameter as node and access in transformation

we are trying to add parameters to a transformation at the runtime. The only possible way to do so, is to set every single parameter and not a node. We don't know yet how to create a node for the setParameter.
Current setParameter:
QName TEST XdmAtomicValue 24
Expected setParameter:
<TempNode> <local>Value1</local> </TempNode>
We searched and tried to create a XdmNode and XdmItem.
If you want to create an XdmNode by parsing XML, the best way to do it is:
DocumentBuilder db = processor.newDocumentBuilder();
XdmNode node = db.build(new StreamSource(
new StringReader("<doc><elem/></doc>")));
You could also pass a string containing lexical XML as the parameter value, and then convert it to a tree by calling the XPath parse-xml() function.
If you want to construct the XdmNode programmatically, there are a number of options:
DocumentBuilder.newBuildingStreamWriter() gives you an instance of BuildingStreamWriter which extends XmlStreamWriter, and you can create the document by writing events to it using methods such as writeStartElement, writeCharacters, writeEndElement; at the end call getDocumentNode() on the BuildingStreamWriter, which gives you an XdmNode. This has the advantage that XmlStreamWriter is a standard API, though it's not actually a very nice one, because the documentation isn't very good and as a result implementations vary in their behaviour.
Another event-based API is Saxon's Push class; this differs from most push-based event APIs in that rather than having a flat sequence of methods like:
builder.startElement('x');
builder.characters('abc');
builder.endElement();
you have a nested sequence:
Element x = Document.elem('x');
x.text('abc');
x.close();
As mentioned by Martin, there is the "sapling" API: Saplings.doc().withChild(elem(...).withChild(elem(...)) etc. This API is rather radically different from anything you might be familiar with (though it's influenced by the LINQ API for tree construction on .NET) but once you've got used to it, it reads very well. The Sapling API constructs a very light-weight tree in memory (hance the name), and converts it to a fully-fledged XDM tree with a final call of SaplingDocument.toXdmNode().
If you're familiar with DOM, JDOM2, or XOM, you can construct a tree using any of those libraries and then convert it for use by Saxon. That's a bit convoluted and only really intended for applications that are already using a third-party tree model heavily (or for users who love these APIs and prefer them to anything else).
In the Saxon Java s9api, you can construct temporary trees as SaplingNode/SaplingElement/SaplingDocument, see https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/sapling/SaplingDocument.html and https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/sapling/SaplingElement.html.
To give you a simple example constructing from a Map, as you seem to want to do:
Processor processor = new Processor();
Map<String, String> xsltParameters = new HashMap<>();
xsltParameters.put("foo", "value 1");
xsltParameters.put("bar", "value 2");
SaplingElement saplingElement = new SaplingElement("Test");
for (Map.Entry<String, String> param : xsltParameters.entrySet())
{
saplingElement = saplingElement.withChild(new SaplingElement(param.getKey()).withText(param.getValue()));
}
XdmNode paramNode = saplingElement.toXdmNode(processor);
System.out.println(paramNode);
outputs e.g. <Test><bar>value 2</bar><foo>value 1</foo></Test>.
So the key is to understand that withChild() returns a new SaplingElement.
The code can be compacted using streams e.g.
XdmNode paramNode2 = Saplings.elem("root").withChild(
xsltParameters
.entrySet()
.stream()
.map(p -> Saplings.elem(p.getKey()).withText(p.getValue()))
.collect(Collectors.toList())
.toArray(SaplingElement[]::new))
.toXdmNode(processor);
System.out.println(paramNode2);

JNA pointer to pointer mapping

I am working on a Java binding for the excellent libvips
Using this function all is fine:
VipsImage *in;
in = vips_image_new_from_file( test.jpg, NULL )
vips_image_write_to_file( in, "out.jpg", NULL )
So mapped in Java:
Pointer vips_image_new_from_file(String filename,String params);
But I have a problem when the parameter like this:
VipsImage *in;
VipsImage *out;
vips_invert( in, &out, NULL )
vips_image_write_to_file( out, "out.jpg", NULL )
I have tried:
int vips_resize(Pointer in, PointerByReference out, Double scale, String params);
Pointer in = vips_image_new_from_file("file.png",null);
PointerByReference ptr1 = new PointerByReference();
vips_invert(in, ptr1, null);
vips_image_write_to_file( ptr1.getValue(), "fileout.png", null);
But doesn't work. The ptr1.getValue() does not contains the expected result.
How can I do it?
Thanks
I'm the libvips maintainer, a Java binding would be great!
But I think you might be taking the wrong approach. I think you are trying a straight wrap of the C API, but that's going to be tricky to do well, since it makes use of a lot of C-isms that don't map well to Java. For example, in C you can write:
VipsImage *image;
if (!(image = vips_image_new_from_file("somefile.jpg",
"shrink", 2,
"autorotate", TRUE,
NULL)))
error ...;
ie. the final NULL marks the end of a varargs name / value list. Here I'm asking the jpeg loader to do a x2 shrink during load, and to apply any Orientation tags it finds in the EXIF.
libvips has a lower-level API based on GObject which is much easier to bind to. There's some discussion and example code in this issue, where someone is making a C# binding using p/invoke.
https://github.com/jcupitt/libvips/issues/558
The code for the C++ and PHP bindings might be a useful reference:
https://github.com/jcupitt/libvips/tree/master/cplusplus
https://github.com/jcupitt/php-vips-ext
That's a PHP binding for the entire library in 1800 lines of C.
I'd be very happy to help if I can. Open an issue on the libvips tracker:
https://github.com/jcupitt/libvips/issues

How to access the methods for a higher rule?

During writing validation rules a came across the problem that I need some content from a rule in my grammar which is hierarchically higher than the one I pass to my validationMethod.
I know that I can refer to a "higher" rule with .eContainer but then I don't have a clue how to access the values I want to.
For example I have the following grammar snippet:
rule1:
name=ID content=rule2
;
rule2:
<<whatever content>>
;
If I have a normal validationMethod with the argument rule1 then I can access the name via .name but when I give rule2 as an argument and then referring to rule via .eConatiner the .name method does not exist.
Greetings Krzmbrzl
EObject is the root class of all AST node classes. It comes from the EMF Ecore framework which is used by Xtext to generate the AST implementation. Therefore, the EObject class contains a lot of the tree structure features, e.g., iterating through a tree. The EObject.eContainer() method returns an element of type EObject which actually is the super type of the type of the actual returned object. To get access to methods of the next higher element, you have to cast the eContainers methods result like this:
#Check
public void check(rule2 r2) {
EObject o = r2.eContainer();
rule1 r1 = (rule1) o;
String r1Name = r1.getName();
}
If the type of the parent object is ambigous, you should test whether the actual type is the expected with an instanceof expression:
#Check
public void check(rule2 r2) {
EObject o = r2.eContainer();
if (o instanceof rule1) {
rule1 r1 = (rule1) o;
String r1Name = r1.getName();
}
}
Xtend provide the same instanceof-expression like Java. But if the object to be checked definetly can have more then a few types, you can use Xtends really powerful switch expression. It supports so called type guards. You can switch over any object and instead of case value: guards simply write the a concrete type:
switch (anyAbstractTypeObject) {
ConcreteSubtypeA: {...}
ConcreteSubtypeB: {...}
}
This is an elegant shorthand if-instanceof-eleseif-... in Xtend.

how do i create a computational expression that takes parameters?

I want to create a couple of computational expressions that would be used to access the database and return a list of items like so (I also have questions in the code comments):
let foo x y z = proc "foo" {
let! cmd = proc.CreateCommand() // can I do this?
do! In "x" DbType.Int32 // would i gain anything by replacing DbType with a union
// type since the names would match actual data types?
do! In "y" DbType.String 15;
cmd?x <- x
cmd?y <- y
use! r = cmd.ExecuteReader() // would this be bad form for creating a workflow builder?
return! r {
let item = MyItem()
do! item.a <- r.GetInt32("a")
do! item.a <- r.GetString("b")
do! item.c <- r.GetDateTime("c")
yield! item
}
}
How can I create a workflow builder such that an instance of it takes a parameter?
let proc name = ProcedureBuilder(connStr, factory) // how do I do this?
Yes, you can do this. You can use computation expression syntax after any expression with a type statically known to expose the right methods. So the following code works (but doesn't do anything particularly interesting):
let f x = async
let v = f "test" { return 1 }
Here, f has type 'a -> AsyncBuilder, so f "test" has type AsyncBuilder and can be followed with computation expression syntax. Your example of let proc name = ProcedureBuilder(connStr, factory) is perfectly fine, assuming that ProcedureBuilder is defined appropriately, though you presumably want name to appear somewhere in the constructor arguments.
The answer from Keith (kvb) is correct - you can use parameterized computation builders. The syntax of computation expressions is:
<expr> { <cexpr> }
So, the builder can be created by any expression. Usually, it is some value (e.g. async) but it can be a function call or even a constructor call. When using this, you would typically define a parameterized builder and then pass the argument to a constructor using a function (as #kvb suggests).
I actually wrote an example of this, not a long time ago, so I can share an example where - I think - this is quite useful. You can find it on F# snippets: http://fssnip.net/4z
The example creates a "special" asynchronous computation builder for ASP.NET MVC that behaves just like standard async. The only difference is that it adds Run member that uses AsyncManager (provided by ASP.NET) to execute the workflow.
Here are some relevant parts from the snippet:
/// A computation builder that is almost the same as stnadard F# 'async'.
/// The differnece is that it takes an ASP.NET MVC 'AsyncManager' as an
/// argumnet and implements 'Run' opration, so that the workflow is
/// automatically executed after it is created (using the AsyncManager)
type AsyncActionBuilder(asyncMgr:Async.AsyncManager) =
// (Omitted: Lots of boilerplate code)
/// Run the workflow automatically using ASP.NET AsyncManager
member x.Run(workflow) =
// Use 'asyncMgr' to execute the 'workflow'
The snippet wraps the construction in a base class, but you could define a function:
let asyncAction mgr = new AsyncActionBuilder(mgr)
And then use it to define asynchronous action in ASP.NET MVC:
member x.LengthAsync(url:string) = asyncAction x.AsyncManager {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
return html.Length }

Implementing Indexer in F#

I am trying to convert this C# code to F#:
double[,] matrix;
public Matrix(int rows, int cols)
{
this.matrix = new double[rows, cols];
}
public double this[int row, int col]
{
get
{
return this.matrix[row, col];
}
set
{
this.matrix[row, col] = value;
}
}
Basically my biggest problem is creating the indexer in F#. I couldn't find anything that I could apply in this situation anywhere on the web. I included a couple of other parts of the class in case incorporating the indexer into a Matrix type isn't obvious. So a good answer would include how to make a complete type out of the three pieces here, plus anything else that may be needed. Also, I am aware of the matrix type in the F# powerpack, however I am trying to learn F# by converting C# projects I understand into F#.
Thanks in advance,
Bob
F# calls them "indexed properties"; here is the MSDN page. In F# they work slightly differently - each indexed property has a name.
However, there is a default one called "Item". So an implementation of your example would look like this:
member this.Item
with get(x,y) = matrix.[(x,y)]
and set(x,y) value = matrix.[(x,y)] <- value
Then this is accessed via instance.[0,0]. If you have named it something other than "Item", you would access it with instance.Something[0,0].

Resources