Can a YAML value string be evaluated in Java? - java

Is it possible to pass Java code as a value in a YAML file. For example, something like this:
---
dueDate: "DueDateCalc()"
DueDateCalc() might be a method defined in the Java code that is parsing the YAML. It would then set the Java dueDate property to the return of the predefined DueDateCalc() method.

This is possible within the constraints of Java runtime reflection, however you need to implement it yourself.
For example, your YAML could look like this:
---
dueDate: !call DueDateCalc
!call is a local tag for telling the loading code that the scalar value DueDateCalc should be interpreted as method to be called (this is chosen by you, not something predefined). You can implement this with a custom constructor for the !calc tag that searches for a method with the given name within some given class, and then calls it on some given object.
What about parameters? Well, still possible, but will get ugly fast. First problem is how you define the paramaters:
with nested YAML sequences: !call [MyMethod, [1, 2, 3]]
with a scalar that needs to be parsed: !call MyMethod(1, 2, 3)
The former option lets YAML parse the parameters and you'll get a list; the latter option requires you to parse the method call yourself from the string you get from YAML.
The second problem is to load the values into Java variables so that you can give them as argument list. Java reflection lets you get the method's parameter types and you can use those to load the parameter values. For example, if the first parameter's type is a String, you would parse 1 as a "1", while if it's an int, you can parse 1 as int. This is possible with SnakeYAML's builtin facilities if you're using nested YAML sequences for method call encoding.
This would even work if parameters are class objects with complex structure, you'd just use normal YAML syntax and the objects will be loaded properly. Referring to variables in your code is not directly possible, but you could define another tag !lookup which retrieves values from a given Map structure.
While reflection lets you make method calls, you can not directly evaluate an expression like 6*9. So before you try and implement anything, evaluate which functionality you need and check whether it's doable via reflection.

Related

How to create a map object using Java Expression Language 6 and modify its properties and add new properties?

This question is based on a Java EE 6 Expression Language. This is a workflow-based platform where you can add a step in a process to initialize variables and the value is specified as an expression such as #{ x + y } as backend expression following Java EL Notation pre the webpage below:
https://docs.oracle.com/javaee/6/tutorial/doc/gjddd.html
See the snapshot below for an example of how to initialize variables in a process step.
The problem is that if we use the "dot notation" to create a map object, it doesn't work. It will actually create a basic flat variable such as a String or Number with the "dot" in the field name. What I am looking for is a method to initialize a Map Object which then can be accessed in JavaScript using JSON. All built-in MAP objects will eventually appear as JSON in the front-end application (under JavaScript). The problem is that I am unable to create a new MAP object and add or modify properties. I can only initialize flat variables like String or Number.
Is there a method to use Java Expression Language to initialize such a map object in a variable?
Update 1
I did research and looks like have a clue what to do. I can use an existing Java Bean to add a static function that will take input of string key=value, key=value... representing the map and reruns a new Map object with the type of map with wild cards such as Map <?,?>.
Now I need help to verify this approach. How to convert a string of key=value, key=value... to a map?
I'm researching this now.

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)))".

How to parse OWL2 file with OWLAPI - AnnotationProperties

I have an OWL file (OWL2) that I need to parse and ultimately write the data into some file. The file contains AnnotationProperties, DataProperties, ObjectProperties and Classes.
My first aim is to try to list out the property information as much as possible. i.e. for AnnotationProperties to see if I can print out the name of the property and the "value".
Similarly, to be able to display the class details i.e. for each class, the name of the class, the properties i.e. data or object properties of the class. I'm not sure how to do this and any reading I've done so far is confusing because it seems to talk about instances, which I don't believe are present in the file. Also, the OWLAPI javadoc and documentation and such are not very helpful with the kind of methods I might have to be calling.
E.g. if I had the following AnnotationProperty:
<owl:AnnotationProperty rdf:about="&xxx;SOME_ID">
<ABC rdf:datatype="xsd;string">1235412</ABC>
</owl:AnnotationProperty>
ontology.getAnnotationPropertiesInSignature() would get me a set of AnnotationProperties and I can iterate and say property.getIRI().getFragment() to see the SOME_ID, but now how would I obtain and display the inner contents i.e. the ABC-1235412 ? Similarly, any help on how to obtain the information of a class i.e. display or show its properties and restrictions is appreciated.
The fragment you're showing does not create an annotation assertion axiom with property SOME_ID, it is instead an annotation on the property SOME_ID itself. The triple looks like this:
SOME_ID ABC "1235412"^^xsd:int
From your description of what you're trying to do, you /need/ instances - values for any property (annotation, object or data property) are expressed through assertions, i.e., axioms which refer to an individual (or instance - the two names refer to the same concept).
E.g.,
Ignazio hasAge "38"^^xsd:int
would be a data or annotation property assertion on the individual Ignazio with value 38.
To access these assertions, you can use
OWLIndividual ignazio = ...
ontology.getAnnotationAssertionAxioms(ignazio);
To access annotations like the one you show, i.e., on the annotatio property itself:
OWLAnnotationProperty some_id = ...
ontology.getAnnotationAssertionAxioms(some_id.getIRI());

what is session.selectOne(String arg0, Objectarg1);?

i am new to MyBatis,i am unable to find tutorials to learn,present i am going to start working on MyBatis with Spring,i had used session.selectOne(String arg0, Object arg1) but i am not able to understand how it works and what it will do with the second parameter that is Object arg1.
can any one help in this.
thank you
The second argument to selectOne and selectList is for a parameter. It can be a primitive if you have very simple needs in your query, say a single integer, or for more complicated queries requiring many values to be interpolated, a bean class instance with the values populated as needed (and containing the proper getters and setters).
In your mapper file you then define the type of the parameter via the parameter attribute, and can then interpolate either inline or with escaping (the former for things that should never be escaped, such as variable table or column names, and the latter for things which should always be escaped, such as values in a WHERE clause).
See the MyBatis doc for more detail:
http://mybatis.github.io/mybatis-3/java-api.html
Response to comments from OP:
MapBuilder must be custom code related to Map data structures. There's an ImmutableMap.Builder as part of Guava, but that doesn't seem like what this is. I don't think it's related to Mybatis per se.
It looks like that code is just building up a Map object, and then passing it off to the selectOne query for use within the query definition in the mapper (instead of a custom bean class).
What's the definition on LoginMapper.getUserByUsername in your mapper? In that definition, the contents of the map object are likely being interpolated into the query so dynamic values can be included.

Accessing Map elements via Enum key in Freemarker

I'm trying to access elements in a HashMap.
The keys of this HashMap are defined by an Enum.
After going through the documentation, I figured that in order to be able to access the Enum, I have to send it to Freemarker like so:
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel enumModels = wrapper.getEnumModels();
TemplateHashModel fieldTypeModel = (TemplateHashModel)enumModels.get("com.example.MinisiteFieldType");
root.put("fieldtypes", fieldTypeModel);
In my .ftl I tried the following:
${myelement.mymap[fieldtypes.SEOTEXT]}
However I get:
Expression myelement.mymap[fieldtypes.SEOTEXT] is undefined on line X...
I wanted to make sure I mapped the enum correctly, so I tried:
${fieldtypes.SEOTEXT}
This didn't print anything, leaving me wondering wether it got through, or simply couldn't be printed.
In Java debug, just before inserting the TemplateHashModel in my root Map, 'fieldTypeModel' is filled with the correct data...
Any help would be appreciated!
Bart
I suspect your problem is that by using the [] syntax to access your map, you're implicitly telling Freemarker to treat it as a hash. That may not work as you'd expect -- the hash will probably represent the Map object, mapping 'size' and 'containsKey' and so forth to Java methods. Instead, try:
${myelement.mymap.get(fieldtypes.SEOTEXT)}
As a side note, I've never tried accessing enums by the method you describe, but there's another way to access Java constants from a template that doesn't require Java code, so the following should also work:
${myelement.mymap.get(stack.findValue("#com.example.MinisiteFieldType#SEOTEXT"))}

Categories