Configurable (e.g. XML) Java Bean to Bean Mapping Framework - java

I'm looking for a Bean to Bean Mapping Java Framework that their mapping rules could be defined outside/not in java code. The source and target beans has n subBeans so the mapping rules could be a little bit complex (not a simple one-to-one mapping).
A little overview about the process:
It's Simple ETL process but with a configurable mapping logic.
I use Spring Batch to load a multiline record (fixed lenght file) into a bean. Its just a representation of the record as an javabean to use it as base for the defined mapping rules. the result of this mapping is another javabean that is completly different build as the source one. And here I would like to use a generic mapping framework between this to java beans.
The Spring Batch part is completly clear and implemented.
Of course I could defined it hardcoded in java but for transparence reasons I have to export this mapping logic outside the java code.
Does anyone know a such framework? Does one exists? I found Dozer but I think I can't define some complex mapping rules in their XML.

Maybe. I would use the Java Scripting API for this. It allows you to load scripts (JavaScript, Beanshell, Groovy, whatever) and run them. You could put a line of input (or the whole model) in a variable and the script could then create the new object structure.

try to use JMapper Framework.
In XML you can write STATIC and DYNAMIC conversion using placeholders to use values and names of the fields, for example if you need to get and set values from a map the code is the follows:
<conversion name="fromMapToAll" from="map" type="DYNAMIC">
return (${destination.type}) ${source}.get("${destination.name}");
</conversion>
<conversion name="fromAllToMap" to="map" type="DYNAMIC">
${destination}.put("${source.name}",${source});
return ${destination};
</conversion>
see the wiki page for more info.

Related

Generate POJO from .yaml

I'm looking for a solution which automatically generates POJO classfiles from a given .yaml-Files but have not found anything like this yet.
I can not imagine that it should be the only way to write these classes yourself.
The problem is that YAML describes objects, not classes. In general, you cannot automatically derive a POJO structure from a given YAML file. Take, for example, this YAML:
one: foo
two: bar
In YAML, this is a mapping with scalar keys and values. However, there are multiple possibilities to map it to Java. Here are two:
HashMap<String, String>
class Root {
String one;
String bar;
}
To know which one is the right mapping, you would need a schema definition like those for XML. Sadly, YAML currently does not provide a standard way of defining a schema. Therefore, you define the schema by writing the class hierarchy your YAML should be deserialised into.
So, in contrary to what you may think, writing the POJOs is not a superfluous action that could be automated, but instead is a vital step for including YAML in your application.
Note: In the case that you actually want to use YAML to define some data layout and then generate Java source code from it, that is of course possible. However, you'd need to be much more precise in your description to get help on that.
As pointed out in the comments by Jack Flamp, you can use an online tool (jsonschema2pojo) to convert a sample yaml file to its equivalent POJO classes. This tool can convert json or yaml data to corresponding POJO classes and I have used it successfully in the past.
That being said, the tool is forced to make certain "assumptions" when you are using a yaml file(instead of yaml schema). So, it would be a good idea to look at the generated classes carefully before you start using them.
You can find more information about how to use this online tool from its wiki page.
The Accepted Answer is incomplete.
You can try to use https://editor.swagger.io/
After importing yaml file You can generate Java REST Client project through menu with correspondent POJO classes.

Play Model Objects from External API

I'm new in Play 2 Framework v. 2.1.1 with Java and I'm looking for the best way to do the following without duplicating code.
To simplify, I have a Play 2 backoffice that uses an external API. I don't manage this API, but I call REST Services to perform operations over the api.
This API's objects are exactly the same as Play 2 Model Objects. But I don't want to duplicate the api objects to add Play validations and other annotations.
Is there any way to add this type of behavior using configuration files? I'm thinking about something like Hibernate hbm's for example.
For example:
Object in the unmanaged api: (I omit getters and setters for simplicity)
public class Entity{
public String field1;
public String field2;
}
Object that I want to avoid: (I omit getters and setters for simplicity)
public class Entity1{
#Required
#NonEmpty
#MinLength(3)
public String field1;
#Required
#NonEmpty
public String field2;
}
Config example: (I need something like this)
<class name="Entity1">
<property name="field1" >
<required/>
<nonEmpty/>
<minLength value="3"/>
</property>
<property name="field2" >
<required/>
<nonEmpty/>
</property>
</class>
Using annotations seems better than using xmls or any other configuration file, so I don't necessarily want to use configuration files, I'm open to any suggestions to solve this problem.
Thanks
I can't see how duplicating the API model in a non typesafe descriptor like XML is better than using a typesafe language. Moreover, I would not want to couple my model and application to a model from the API under my control.
I think it is far better to duplicate the model in Java/Scala and use a simple bean copier like dozer to move between the two.
One problem is ebean as the persistence provider - in ebean there is no way to externalize the bean persistence configuration as it is possible in hibernate (except for sql queries). Is a switch of the persistence provider possible? Play seems to allow that.
Since you wrote that you are unable to modify the entities source code and you don't want to copy the source, the only other possibility I see is bytecode enhancement.
What you need is a library that would allow you to externalize annotations in a xml file. This library would use the instrumentation api, read the xml file at jvm statup and modify the bytecode of each listed class in order to add annotations to the class and fields at runtime.
There are two problems with this approach:
There is no such library (at least I couldn't find it)
Play and EBean use their own agent / classloader in order to allow hot deployment and persistence
The first problem is the easy and fun part, see for example https://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html. With javaassist it is easy to add annotations to classes and fields. The mapping from xml to annotations is straight foreward. And it would be a nice open source project.
The second problem looks much harder, because you must install your annotation agent so that it executes before play and ebean start to parse the annotations.
It is not clear to me why can't add annotations in your own app, but if you have such constraints why don't you just extend the class, override the variables, add the annotations, and use that as an EBean model?
Play has dynamic forms, which let you validate against a map of key,value pairs. If validation is what you want you could copy an entity's data to a map and validate that.
Simple answer: There is not always code duplication also if the code lines are the same.
Robert C. Martin shows this in one of his talks: the single responsible principle. There are two ways to break this principle: On the one hand two responsibilities in one code fragment on the other hand one responsibility handled independently bei two code fragments.
Code duplication is a matter responsibility and semantics not of code lines that are the same (which may be at most an indicator for having code duplication).
In your case the responsibilities are clearly separated: You have an external API and your code. So there is no code duplication.

struts2 conversation and validation

I am working on a struts2 project that has interdependent forms.
I found struts2-conversation, stepped through their simple-example
and understood the conversation mechanism this far (please correct me if I got something wrong):
The Controller is mapped in the struts.xml
It holds the serializable ConversationContext and the Storing-Service
The ConversationContext holds POJOs mapped on forms by naming convention
Now my question is where to put the validation?
In this structure the controller is only one extending ConversationSupport and thereby ActionSupport supplying the validate, prepare and addField- & ActionError methods.
But validating within the controller would mean to validate the whole context, which does not really serve the issue.
I tried validation through annotation within the POJOs, within the context as described above which gives me some NullPointerException as if the context wasn't flushed and I think the xml-validation approach of struts2 is just too stiff. (btw how to let the generated javascripts be minified before being served? And why is there so many options?)
Mark's conversation-interceptor approach had similar problems coming up which's workarounds I didn't really get. Maybe you can help me there.
If you would like to use annotations on your model classes, it works fine with the plugin (as do the other validation approaches).
To validate your model, add #VisitorFieldValidator to the getModel() method in your controller. In the example app, you would then also add #VisitorFieldValidator to the getContact() and getPreferences() methods. Then you can use the validation annotations on the fields you wish to validate.
The service in the example is just there as a simple example of using an injected service in a Struts2 controller and how that can integrate easily with the conversation framework, but it is not directly related or needed (and I would recommend using either Spring, Guice, or CDI for dependency injection in the real world).
The ConversationContext class is intended mostly for internal use by the framework. You should be able to avoid interacting with it by using the annotations and conventions. Unless you simply wish to be adventurous.
To use XML validation in the example app, you would have to change the package name to remove the "struts2" word in order for the Struts2 resource loading tool to load the XML.

Spring 3 Properties File Per Controller

I was wondering if Spring has a properties files mechanism similar to Struts2 where it looks for a properties file first in the same package as the controller and then moves up the package structure until it finds the properties file or property.
I want to define a property file per controller, but I rather not have to wire them up together, if possible. Is there some convention that can be followed that would associate the properties file with the controller? The properties file resolution should also work correctly when resolving locales.
For example, if I define a property called "title" in several prop files, I want the correct one to resolve in the JSP based on which controller handled the request.
ControllerA RETURNS ViewA USES PropA.title
ControllerB RETURNS ViewB USES PropB.title
I was successful in auto wiring a Property file to a controller's Model attribute and display values in JSP. I was also able to specify a ResourceBundleMessageSource in the configuration and then display values from it in JSP.
Out of the box, not that I know of.... but you can easily write one, if that's what you really want!
Spring has things like BeanFactoryPostProcessor which lets you do things like this with your BeanFactory/ApplicationContext. I'm thinking BeanFactoryPostProcessor would fit the bill here - you could 'post process' a bean by looking for a properties file on the classpath, grabbing the properties, and applying them to the bean.
I'll say this though - Spring is usually meant to be fairly non-invasive. If you want something like this to become part of your design, you might want to think of a way to do this in pure Java, rather than using Spring. For example, create your own Factory and implement and unit test it separately. Require your app to use this Factory to get your business objects.
In other words, you can probably do it in Spring - but it isn't always the best approach. It does sound like it could be the most convenient, in your case, but I haven't see the details of what you're setting and where. Just food for thought..

How to move to XML configurations

I am required to move some of our application configuration classes to XMLs. The classes mainly have enums, which are used by other classes. These enums are extensively used in our application.
For instance, we have classes like
enum ColumnType{
type1("Type1"),type2("type2"),type3("type3")
}
Also we need these types to instantiate classes.
for instance,
Processor p = new StringValueProcessor(ColumnType.type1);
How can I move this to an XML file without changing the dependecies in my application?
Edit:
It is not mandatory to keep these enums and I don't want to compile the code against the classes created from xml. The config needs to be dynamic, that's the whole point of moving to XML, so that we can configure things in XML and there is no need of compiling and re-deploying.
My main concern is to be able to restrict instances for all column types to one and make them accessible throughout my application.
Edit: After thinking over the design for some more time, I have narrowed down to two essential requirements.
1) I would define some xml tags with some properties and I would need to convert it to object
2) I would also define some tags (the way servlets are defined in web.xml) and I would need to initialise the corresponding class
3) I would further define some mapping tags which will map the objects created in step 1) to instances initialised in step 2). This should be converted to java HashMap, where there can be only one instance of objects defined in step 1) but there will be a new instance of objects defined in step 2) for each mapping.
Is there a framework which can provide this functionality out-of-the-box?
You can use the XML files to generate the enums. This has to be done at compile/build time, or you cannot use them in your code like the second example (as they don't exist at compile time)
Why do you want to migrate the enums to XML?
I think the answer your looking for is to use JAXB. It lets you turn XML into POJOs and vice-versa. It even has some functionality for using enums. All you have to do is add some annotations to your java and you can convert to and from XML.
By using annotations, you won't affect any existing functionality.

Categories

Resources