Diego D
Diego D

Reputation: 1755

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

Upvotes: 14

Views: 517

Answers (5)

oopexpert
oopexpert

Reputation: 755

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.

Upvotes: 0

dres
dres

Reputation: 1211

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.

Upvotes: 1

IanRae
IanRae

Reputation: 293

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.

Upvotes: 0

k9m
k9m

Reputation: 295

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?

Upvotes: 0

Sebastian Baltes
Sebastian Baltes

Reputation: 512

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:

  1. There is no such library (at least I couldn't find it)
  2. 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.

Upvotes: 0

Related Questions