Using Odata4j to create abstract syntax tree for Query Parameter expressions - java

Im exposing REST services through use of Sprint MVC 4.0 framework and I try following Odata specification for the Query Parameters such as $filter, $search and $orderBy. Each of these contains expressions that I need to parse, build abstract syntax trees and validate. They are all retrieved as String.
I do not need all the constructions that are defined in the Odata grammer (http://docs.oasis-open.org/odata/odata/v4.0/cos01/abnf/odata-abnf-construction-rules.txt), I just pick the ones that are relevant for my uses cases (very few actually)
I would like some tip on how to parse and build the abstract tree in a easy way and if Odata4j might be used as a Utility library to do this job for me? I would like to avoid dragging bunch of new dependencies to odata4j, since I will only use small piece of the code.

You can certainly use odata4j for building ASTs for query parameters. I've done that for exactly the purposes you cite. I split off the query parameters, and then split again on '&' to get parameters. For each of these I inspect the parameter name ($select, $filter, etc.) and then based on that use the corresponding OptionsQueryParser static method on the value, returning an number, or list, or AST specific to that query parameter. For expression ASTs, look at PrintExpressionVisitor and use that as a pattern for writing your own visitor to walk the AST.

Related

When is expression used in mapStruct?

I am getting started with MapStruct. I am unable to understand when do we use "expression" tag in MapStruct? Why do we have certain mappings where we use "target" tag and "expression" tag? Does it mean that expressions are used when you want to map two or more fields within a bean to a single property/field in the target as mentioned in the documentation "http://mapstruct.org/documentation/stable/reference/html/#expressions"
Expressions are used when you can't map a source - to a target property or when a constant does not apply. MapStruct envisioned that several language could be used to address expressions. However, only plain java is implemented (hence "java(... )" ). EL was envisioned but not yet realised.
A typical use case that I use is generating a UUID. But even there you could try the new #Context to achieve that goal.
Remember, the stuff within the brackets is put directly in the generated code. The IDE can't check its correctness, and you will only spot problems during compilation.
Expressions are IMHO a fallback means / gap filler for stuff that is not yet implemented in MapStruct.
Note: Mapping target-to-source by means of a custom method as suggested in the other answers can be done automatically. MapStruct will recognised the signature (return type, source type) and call your custom method. You can do this in the same interface (default method) or in a used mapper.
In general, MapStruct expressions are used when you simple cannot write a MapStruct mapper. They should be used as a fallback approach when the library doesn't apply to your use-case.
For example, -- as the documentation says -- when a mapping requires more than one source variable, an expression can be used to "inject" them to a mapper method.
Another use case is when the source variable you need to use -- say bar -- is not a part of the source class but a member of one of its variables (here, classVar). You would map it to the target field foo using a custom myCustomMethod method with #Mapping(target="foo", expression="java(myCustomMethod(source.classVar.bar)))".

Elasticsearch, Nested "ANDS" and "ORS"

I am having some difficulty structuring the exact Elasticsearch query that I am looking for, specifically using the java api.
It seems like if I construct a fieldsearch using the java api, I can only use a single field and a single term. If I use a querystring, it looks like I can apply an entire query to a set of fields. What I want to do is apply a specific query to one field, and another query to a different field.
This is confusing I know. This is the type of query I would like to construct
(name contains "foo" or name contains "bar") AND ( date equals today)
I am really loving Elasticsearch for it's speed and flexibility, but the docs on http://www.elasticsearch.org/ are kind of tough to parse (I noticed "introduction" and "concepts" have no links, but the API section does) If anyone has some good resources on mastering these queries, I'd love to see them. Thanks!
Sounds like a bool query with 2 must clause:
matchQuery("name", "foo bar")
rangeQuery("date").from("2013-02-05").to("2013-02-06")
Does it help?

Elasticsearch Java API - fuzzy search with max_expansion

How can I translate the "more complex" fuzzy example from the QueryDSL guide into Java?
What I have so far is this: (Which works fine, but for example I'm unable to find the builder methods for "max_expansion", which would allow me to restrict the query)
QueryBuilders.fuzzyQuery("name", "kimchy")
Any pointers into the right direction are appreciated.
It supposed to be QueryBuilders.fuzzyQuery("name", "kimchy").maxExpansion(5). But, unfortunately, the maxExpansion() method is currently missing. So, until this pull request is merged, the only way to send this query is by expressing it directly in json. You can do it using XContentBuilder.
Construct a Lucene FuzzyQuery directly, then you can pass that option into a constructor arg.

Tool for "internalisation" of an external DSL in Java

I am developing and maintaining a database-abstraction library called jOOQ, which aims to "internalise" SQL as an external DSL into Java. The goal of this endeavour is to allow for type-safely constructing and executing all possible SQL syntax elements of the most popular RDBMS. jOOQ's internal DSL is becoming more and more complex, and I'd like to get a formal hold of it. The idea is that I would like to be able to have some sort of formal definition of SQL as input, e.g.
select ::= subquery [ for-update-clause ]
subquery ::= SELECT [ { ALL | DISTINCT | UNIQUE } ] select-list
[ FROM table-reference ] ..
select-list ::= expression [ [ AS ] alias ] [, expression ... ]
expression ::= ...
alias ::= ...
table-reference ::= ...
The input could also be defined in XML or any other descriptive meta-language. Once I have that input, I'd like to generate from that input a set of Java interfaces, that model the defined syntax in Java. Example interfaces would be:
// The first "step" of query creation is modelled with this interface
interface Select0 {
// The various SELECT keywords are modelled with methods
// returning the subsequent generated syntax-element
Select1 select(Expression...);
Select1 selectAll(Expression...);
Select1 selectDistinct(Expression...);
Select1 selectUnique(Expression...);
}
// The second "step" of query creation is optional, hence it
// inherits from the third "step"
interface Select1 extends Select2 {
// Here a FROM clause may be added optionally
Select2 from(TableReference...);
}
// To keep it simple, the third "step" is the last for this example
interface Select2 extends SelectEnd {
// WHERE, CONNECT BY, PIVOT, UNPIVOT, GROUP BY, HAVING, ORDER BY, etc...
}
With the above interfaces, it will be possible to construct SQL queries in Java, like jOOQ already allows to do today:
create.select(ONE, TWO).from(TABLE)...
create.selectDistinct(ONE, TWO).from(TABLE)...
// etc...
Also, I'd like to exclude some syntax elements for some specific builds. E.g. when I build jOOQ for exclusive use with MySQL, there is no need to support for the SQL MERGE statement.
Is there any existing library implementing such a general approach in order to formally internalise and external DSL to Java? Or should I roll my own?
What you are really trying to do is to translate generic SQL into calls on your internal APIs. Seems reasonable.
To do that, you need a parser for "generic SQL", and a means to generate code from that parser. Typically you need the parser to build an abstract syntax tree, you pretty much need a symbol table (so that you know what things are table names, what are column names, and whether those column names are from table A or table B, so somewhere you need access to the SQL DDL that define the data model.... which requires you parse SQL again :).
With the AST and the symbol table, you can generate code a lot of ways, but a simple method is to walk the AST an translate constructs as you encounter them. This won't allow for building optimized queries; that requires more complex code generation, but I'd expect it to be adequate if supported by appropriate API functions you supply.
Actual code generation could be done by just printing Java text; if you go the ANTLR route you'll have to do something like this. An alternative is to literally transform the SQL code fragments (as ASTs) into Java code fragments (as ASTs). The latter scheme gives you more control (you can actually do transformations on Java code fragments if they are ASTs) and if done right, can be checked by a code generation tool.
Our DMS Software Reengineering Toolkit would be a good foundation for this. DMS provides an ecosystem for building translation tools, including robust parser machinery, symbol table support, surface-syntax pattern-directed translation rules, and has generic SQL (SQL 2011, the standard) as an available, tested parser, as well as Java, to be used on the code generation side.

How to avoid a large if-else statement in Java

I'm developing a framework in java which relies on a number of XML files with large number of parameters.
When reading the parameters from the XML file, I have to have a large if-else statement to decide what the parameters is and then call appropriate methods.
Is this normal? to have a large if-else statement?
I am thinking that there is a simple and neater way of doing this, e.g. Java XML mapping or Java Reflections? is this the answer? if so, can you please provide examples of how this is done so I don't have to rely on a large if-else statement?
Thanks!
You want to first create an interface:
public interface XMLParameterHandler {
public handle_parameter (String XMLData);
}
Next you want to create a map:
private Map<string, XMLParameterHandler> handlers;
...and initialize it with one of the relevant Map implementations:
this.handlers = new HashMap<>();
You need to implement the interface on a number of classes, one for each parameter you intend to handle. This is a good use of inner classes. Insert each of these implemented handerls into the map:
handlers.put ("Param1", new XMLParam1HandlerImpl());
handlers.put ("Param2", new XMLParam2HandlerImpl());
Then you can call the handler from the xml processing loop:
handlers.get (paramValue).handle_parameter(XmlData);
There is JAXB (http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding) for mapping java class to xml.
But you can't map methods with it: you only can map attributes to xml file values (deserialize parameters from xml).
i recommend to use Map, that have parameter as key and xml entry as value(not whole xml)
Reflection would be one approach. Perhaps combined with a custom annotation on the target method to indicate which parameter to pass to that method. This is an advanced technique, though.
A more standard technique would be to use a map, where the key is the attribute name, and the value is an instance of an implementation of some interface you define, like AttributeHandler. The implementations then contain the code for each attribute. This involves writing a lot of little classes, but you can do them as anonymous classes to save space and keep the code inline.
a large if-else statement to decide what the parameters is and then call appropriate methods
You could instead use the Strategy design pattern, with one Strategy object per parameter, and use a map from the parameter name to the Strategy object to use. I've found this approach useful for even a moderately complicated application of XML.
It sounds to me as if you want a data-driven rule-based approach to writing your application, rather like you get in XSLT. One way of achieving this is to write it in XSLT instead of Java - XSLT, after all, was specifically designed for processing XML, while Java wasn't. If you can't do that, you could study how XSLT does it using rules and actions, and emulate this design in your Java code.
N functions with M parameters can always be implemented with a single function with M + 1 parameters.
If you need a big if then else statement to decide which method to dispatch to, then you can just add a parameter to your method and call a single method.
You shouldn't need an if-then-else statement to bind the parameter values.
If there is complex logic dependent on the particular parameter values, you might use a table driven approach. You can map various combinations of paramemter values into equivalence classes, then variouos equivalence class combinations into a row in a table with a unique id, then have a switch statement based on that unique id.

Categories