Reputation: 39889
Here's my Model's parent :
abstract public class ApiModel {
// Problem 1
public static ExpressionList<Model> find() {
return null;
}
public static <T extends Model> T findById(Long id) {
return null;
}
}
A Model :
public class MyModel extends ApiModel {
private static Model.Finder<Long,MyModel> find = new Model.Finder(Long.class, MyModel.class);
public static ExpressionList<MyModel> find() {
return find.where();
}
public static MyModel findById(Long id) {
return find.byId(id);
}
}
The parent's Controller :
public class ApiController<T extends ApiModel> extends Controller {
public Result list() {
// Problem 2
ExpressionList<T> list = T.find();
return ok(Json.toJson(list.orderBy("name"), 10));
}
public Result create() {
return update(null);
}
public Result details(Long id) {
// Problem 3
T model = T.findById(id);
// ...
return ok(result);
}
public Result update(Long id) {
// Problem 4
Form<T> form = form(T.class).bindFromRequest();
T model = form.get();
// Problem 5
T.save();
// ...
return ok(result);
}
public Result delete(Long id) {
// ...
return ok(result);
}
}
A Controller
public class AController extends ApiController<MyModel> {
public final static AController rest = new AController();
private AController() {}
}
The problems I face :
find()
to returns ExpressionList<T extends Model>
, but if I put this, I have an error..class
of this one. But how can I do then ?@Entity
, I can't use it here, it's not recognized :/I think everything is related. Maybe I poorly designed my code ?
Here's the reason of that kind of structure. I'm using PlayFramework (that have static controllers) and I like to do inheritance and thus generic models. But for that, I need instance and not static reference, thus the public final static AController rest
. But then, I can't access static context of the Model (find
& findById
). So I made ApiModel. But it doesn't help more either.
Upvotes: 2
Views: 477
Reputation: 421
From my point of view, it should be a bad idea to do that. You can use normal methods in play, you just need to reference the method in the route list with a @
in the beginning.
So, if you have a controller this way:
public class MyController extends Controller {
public Result index() {
return TODO;
}
}
You can use like this in your routers:
GET / @controllers.MyController.index()
Upvotes: 0
Reputation: 1993
You do not need the ApiModel
class if your rewrite a little ApiController
:
public class ApiController<T extends Model> extends Controller {
private Model.Finder<Long,T> finder;
private final Class<T> modelClass;
public ApiController(Class<T> modelClass) {
this.modelClass = modelClass;
finder = new Model.Finder(Long.class, modelClass);
}
public Result list() {
ExpressionList<T> list = finder.where();
return ok(Json.toJson(list.orderBy("name"), 10));
}
public Result details(Long id) {
T model = finder.findById(id);
// ...
return ok(result);
}
public Result update(Long id) {
// Problem 1
Form<T> form = form(modelClass).bindFromRequest();
T model = form.get();
T.save();
// ...
return ok(result);
}
...
}
public class AController extends ApiController<MyModel> {
public final static AController rest = new AController();
private AController() {
super(MyModel.class);
}
}
Upvotes: 2
Reputation: 147164
I don't know why you need those static methods in ApiModel
.
You should be able to endow ApiController
with the Class
for T
.
public class ApiController<T extends ApiModel> extends Controller {
private final Class<T> tClass;
ApiController(Class<T> tClass) {
this.tClass = tClass;
}
public class AController extends ApiController<MyModel> {
....
private AController() {
super(MyModel.class);
}
Upvotes: 0