JAXB Factory for JPA entities - java

In most of my previous projects I have two domain models, one with JAXB annotations and the other one with JPA annotations. I know they can combined into one model with both annotations in the same class, but in my experiences the tradeoffs with this approach always came to the conclusion to separate them. Another advantage of a separate approach is the ability to create the JAXB classes with a XSD and easily link in XSDs from other projects.
In most cases I need factory classes being able for flexible creation of JAXB representations of my entities, e.g.
public class UserFactory
{
public UserFactory(User queryUser, String lang)
{
this.queryUser=queryUser;
this.lang=lang;
}
public JaxbUser getUser(JpaUser jpaUser)
{
JaxbUser jaxbUser = new JaxbUser();
if(queryUser.isSetId()){jaxbUser.setId(jpaUser.getId());}
if(queryUser.isSetEmail()){jaxbUser.setEmail(jpaUser.getEmail());}
if(queryUser.isSetRoles())
{
RolesFactory f = new RolesFactory(queryUser.getRoles(),lang);
jaxbUser.setRoles(f.getRoles(jpaUser.getRoles()));
}
return jaxbUser;
}
}
I create a UserFactory with an individual template queryUser and the desired lang for entities supporting different languages. The template is checked during creation of the result for specific fields or additional factories and the resulting object is created. The query is defined in a XML file like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<query lang="en">
<user id="1">
<roles>
<role code="code"/>
</roles>
</user>
</query>
With this methodology I have a powerful and flexible tool to create customized XML, despite all drawback of maintaining two domain models and the factory classes. I know there are many frameworks or libraries available which I never have heard about, so here my question:
Is there something available similar to my approach?

There are basically two options:
JPA and JAXB annotations on the same classes (see Hyperjaxb3 or DataNucleus)
Or you keepm the separated and write code to map one onto another
I personally do not see much added value in the cross-model mapping code. Usage of factories also does not seem too innovative, it is just a question of programming technique which you use to map one onto another.

Related

Creating a network of objects from custom XML config with Spring

I have a custom XML config defining a kind of network like this
S1 ---- O1 ---- O2 ---- O3 ---- T1
\
+--- O4 ---- O5 ------------ T2
\
S2---+- O6 --+- O7 ------------ T4
/ /
S3-+ /
/
S4 ------+
Where
S is some kind of data source, like a web socket
O is an operator processing the data
T is the target or data sink
These elements are represented with xml blocks like this:
<source name="S1" address="ws://example/1" type="websocket" dataType="double" />
<operator name="O6" type="threshold">
<input name="S1"/>
<input name="S2"/>
<input name="S3"/>
<property name="threshold" value="10.34" />
<property name="window" value="10.0" />
</operator>
<sink name="T1" type="database">
<input name="O3"/>
</sink>
The dependencies are constructor parameters. My example operator O6 would have a constructor like this:
class ThresholdOperator extends Operator<Boolean> {
public ThresholdOperator(
String name, // "O6"
List<DataSource> sources, // [S1, S2, S3]
double threshold, // 10.34
double window) { // 10.0
...
There could be multiple instances of this class with different constructor parameters. It is possible that a class has more than one constructor. The type parameter of the base class is the output type.
The type attribute determines what concrete class has to be instantiated. The dataType attribute of the source decides which kind of converter (here String to Double) should be injected.
To create the instances I need to figurare out a dependency graph and start instantiating the objects without other objects from my graph as dependency (the sources in this case), then I would create the objects which depend only on objects created in the first step and so on.
So I would basically reinvent something like Spring for my special use case. Is there a way to leverage Spring to create and wire objects in my case? A somewhat crude hack would be to transform my xml config to a beans.xml. But maybe there is a better way using BeanFactory or the like. Or would it be possible to create the Spring meta-model directly?
I'm using Spring 4.3 but the RC of Spring 5 could be an option, if it would help.
Another alternative not yet mentioned here is using XSLT.
The idea is to define xsl that maps your domain-specific xml to spring beans xml (XSLT+XPath should be more than enough to cover your case).
You can then read domain-specific xml, transform it with that xsl and feed the result to spring.
Have a look on StaticApplicationContext. It is stated in the docs that it is:
Mainly useful for testing.
... but it is a full fledged application context that has support for programmatic bean registration.
You can read your domain-specific xml and define beans based on it inside StaticApplicationContext.
This blog post can give you an idea on how to use StaticApplicationContext to define beans with references and constructor args.
A simpler approach to instantiate your objects from the document would be to either
create an XML Schema describing your data format and using JAXB to create your Java classes
annotate your existing Java classes with JAXB annotations
The "crud" hack approach may be a better approach but instead of converting your config xml to beans xml file manually, I suggest you to look at the Extensible XML authoring approach.
The configuration parser, a.k.a. bean definition parser, allows you to build the bean definitions which will eventually be used your application's spring context to instantiate the beans.
This should also eliminate the needs of figuring out the dependency hierarchy manually and instantiation of objects yourself.
Hope it answer your question.

Troubles with WADL / generated XSD using Jersey with a contract-first approach

I have been working on a REST web service using Jersey for a few days now, and managed to have all CRUD operations working, with several exchange formats: XML, JSON, Google Protobuf.
However I am facing some issues related to automatically generated WADL and XSD.
Context
To define the objects exchanged in these three formats, I have followed a "contract-first" approach:
from a XSD I wrote, I generated my model classes using JAXB;
from an equivalent proto file I wrote, I generated the Google Protobuf classes (and internally have a way to convert these to the JAXB-generated objects, in order to have one unique model).
However, as I would like my users to be able to generate their classes too, I would like to share these schema files (.xsd and .proto) and have them well integrated with the automatically generated WADL.
For that purpose, thanks to this wiki page:
I have exposed the two files under
/schema/schema.xsd
/schema/schema.proto
I have added an application-grammar file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<grammars xmlns="http://wadl.dev.java.net/2009/02"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xi="http://www.w3.org/1999/XML/xinclude">
<include href="../schema/schema.xsd" />
</grammars>
I have added a customized WADL generator:
public class RichWadlGeneratorConfig extends WadlGeneratorConfig {
#Override
public List<WadlGeneratorDescription> configure() {
return generator(WadlGeneratorApplicationDoc.class)
.prop("applicationDocsStream", "application-doc.xml")
.generator(WadlGeneratorGrammarsSupport.class)
.prop("grammarsStream", "application-grammars.xml")
.descriptions();
}
}
This way the below appears in the WADL, when I hit /rest/application.wadl:
<grammars>
<include href="../schema/schema.xsd"/>
<include href="application.wadl/xsd0.xsd">
<doc title="Generated" xml:lang="en"/>
</include>
</grammars>
Problem
/rest/application.wadl/xsd0.xsd is automatically generated from my classes, but is quite different from what I initially had in schema.xsd.
In addition to that, calling a tool like wadl2java on this WADL fails miserably, presumably because
/schema/schema.xsd, and
/rest/application.wadl/xsd0.xsd
are now conflicting (two definitions for the same objects).
Questions
Is there a way to disable the generation and diffusion of this automatically generated XSD?
(As I don't need it since I'm following this "contract-first" approach)
If not, is there a way to "override" its content with my manually written XSD when /rest/application.wadl/xsd0.xsd is hit?
(I have googled around and found about WadlResource, to generate customized WADL, but found nothing about the XSD generation itself)
Thanks in advance for your help!
M.
Edit
1) I raised the issue to the Jersey team and got a reply:
http://java.net/projects/jersey/lists/users/archive/2012-06/message/8
2) I raised a ticket (JERSEY-1230), according to Pavel's instructions.
I am currently following up to either submit a fix myself or get a fix from the Jersey team.
1.14-SNAPSHOT should allow you to do this:
public class SampleWadlGeneratorConfig extends WadlGeneratorConfig {
#Override
public List<WadlGeneratorDescription> configure() {
return generator( WadlGeneratorApplicationDoc.class )
.prop( "applicationDocsStream", "application-doc.xml" )
.generator( WadlGeneratorGrammarsSupport.class )
.prop( "grammarsStream", "application-grammars.xml" )
.prop("overrideGrammars", true) // !!!
.generator( WadlGeneratorResourceDocSupport.class )
.prop( "resourceDocStream", "resourcedoc.xml" )
.descriptions();
}
}
when overrideGrammars is set to true, Jersey generated grammars won't be included in returned WADL.

JAX-WS and Enunciate - How to change Enunciate's default XSD naming convention

I'm using Enunciate to generate a SOAP endpoint for a Wicket web application I am working on and I have a couple of questions that I haven't figured out the solution to yet.
1 How do I change the name of the xsd files? I've looked through the FAQ and it tells me to do something similar to this:
<xml>
<schema namespace="http://api.example.com/data" file="data.xsd"/>
</xml>
However, I haven't quite figured out how to set the targetNamespace for my data objects. I've done this for my service via #WebService ( targetNamespace="blah" ), but how do I annotate my data objects to let Enunciate know which namespace they should belong to?
2 Enunciate generates my XSDs just fine, but I don't particularily like the element names it uses. I have a ServiceRequest and ServiceResponse object. The ServiceRequest object has a List of User objects. The ServiceResponse has a list of Group objects. Enunciate suggests that every "User" object within the ServiceRequest should be using the tag "<users>". I feel that it would make more sense to use the singular form, "<user>" since the tag does in fact only contain a single user. Is it possible to change this behaviour, and if so, how?
Thanks in advance.
So just to be clear, with the exception of the question about naming your schema files, your questions are really more about JAXB than they are about Enunciate. JAXB is the spec that defines how your Java objects are (de)serialized to/from XML and Enunciate conforms to that spec.
Anyway, the easiest way to apply a namespace to your Java objects is with a package-info.java file in the package of your Java classes. Annotate your package with #XmlSchema and set the namespace to be the value you want.
Customizing how your accessors are serialized to/from XML can be done with the #XmlElement annotation, e.g.:
public class MyClass {
...
#XmlElement (name="user")
List<User> users;
...
}
Here are the JAXB javadocs
https://jaxb.dev.java.net/nonav/2.1.9/docs/api/
Or google for a good JAXB tutorial.

Easiest parser in Java for xml to generate code for newcomer in xml

Guys I'm new to xml in Java.
I have the following task. I need to parse some xml files (specificallyh xcb-proto [X11]) to generate the equivalent request protocol in java. There is already a well defined xsd and the respective xml for the protocol. What is the best and easiest approach/parser to solve this?
Example of existant xml content:
<request name="SetScreenSaver" opcode="107">
<pad bytes="1" />
<field type="INT16" name="timeout" />
<field type="INT16" name="interval" />
<field type="CARD8" name="prefer_blanking" enum="Blanking" />
<field type="CARD8" name="allow_exposures" enum="Exposures" />
</request>
This will generate a Java DOM (?) Object. And them with this I need to generate the given code in Java. For this case is:
Desired output:
public void setScreenSaver(int timeout, int interval, int preferBlanking, int allowExposures) {
RequestOutputStream o = outputStream;
synchronized (o) {
o.beginRequest(107, 0, 1); // Major Opcode , Minor Opcode, ReqLength
o.writeInt16(timeout);
o.writeInt16(interval);
o.writeInt8(preferBlanking);
o.writeInt8(allowExposures);
o.send();
}
}
It seems that XSOM is the one that gives the easier approach...
PS: I have never manipulated xml files in Java :3
You should look into JAXB. It comes with a utility that will generate all your Java code using the .XSD file to determine the structure.
Even with an XSD parser, this is never going to be an easy task, especially if the schema uses some of the more difficult aspects of the XSD language.
If this is a once-off task and the XSDs are not huge, then you are probably better of just writing the Java code by hand.
EDIT
I can think of one roundabout approach using Eclipse / EMF that might simplify things:
Use the EMF tooling to create a EMF ECore model from the XSD. This gives you an in-memory "object model" analogous to simple UML.
Using EMF infrastructure (e.g. JET), create a custom generator that traverses the ECore model and generates your target code.
The XSD to ECore also gives you (for free) generated classes for representing your XML in memory, editing it in a tree editor and reading/writing the XML. Associated technologies deal with persistence in a database, validation, model-to-model transformation, and other things.

Java: which configuration framework to use?

I need to decide which configuration framework to use. At the moment I am thinking between using properties files and XML files. My configuration needs to have some primitive grouping, e.g. in XML format would be something like:
<configuration>
<group name="abc">
<param1>value1</param1>
<param2>value2</param2>
</group>
<group name="def">
<param3>value3</param3>
<param4>value4</param4>
</group>
</configuration>
or a properties file (something similar to log4j.properties):
group.abc.param1 = value1
group.abc.param2 = value2
group.def.param3 = value3
group.def.param4 = value4
I need bi-directional (read and write) configuration library/framework. Nice feature would be - that I could read out somehow different configuration groups as different objects, so I could later pass them to different places, e.g. - reading everything what belongs to group "abc" as one object and "def" as another. If that is not possible I can always split single configuration object into smaller ones myself in the application initialization part of course.
Which framework would best fit for me?
Since you are saying that it is possible to also store objects in the config, I would suggest this:
http://commons.apache.org/configuration/
The simplest way to do this would be to use Simple XML. It can bind XML to Java POJOs in a very simple manner. Also, it is much faster than other such XML binding frameworks.
http://simple.sourceforge.net
Only 270K with no dependencies.
Please take a look at this URL: http://issues.apache.org/jira/browse/CONFIGURATION-394
The Configuration framework which we're looking for it is something on top of Apache Commons Configuration and must support Concurrency Issues, JMX issues and most of stores(e.g .properties file, .xml files or PreferencesAPI).
What weblogic team provides on 'Administration Console' is intersting which through it you can have transactional(atomic) updates on configurations so that are registered listeners be notified.
The Apache guys insist that this project is out of scopes of Commons Configuration, maybe!
I've attached a simple configuration framework, take look please

Categories