Skip to content

Instantly share code, notes, and snippets.

@leon
Created February 8, 2013 06:25
Show Gist options
  • Save leon/4737063 to your computer and use it in GitHub Desktop.
Save leon/4737063 to your computer and use it in GitHub Desktop.
Play-Scalr Image Ebean Entity
package models;
import java.util.*;
import javax.persistence.*;
import com.avaje.ebean.Expr;
import com.avaje.ebean.Query;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import play.data.validation.Constraints;
import play.db.ebean.*;
import play.mvc.Http;
@Entity
public class Detail extends Model {
@Id
public Long id;
public String productId;
@Constraints.Required
public String name;
@Column(length = 1000)
public String description;
@ManyToOne
public DetailGroup group;
// Make shure you have this cascade or the yaml loader won't be able to save your images and you will get an error
@ManyToOne(cascade = CascadeType.PERSIST)
public Image image;
public Detail() {}
public Detail(String name, DetailGroup detailGroup) {
this.name = name;
this.group = detailGroup;
}
/*
Query
*/
public static Finder<Long, Detail> find = new Finder<Long, Detail>(Long.class, Detail.class);
public static Query<Detail> query(Long id) {
return find
.fetch("group")
.where()
.eq("id", id)
.query();
}
public static Query<Detail> queryByTerm(String term) {
String t = "%" + term + "%";
return Detail.find.where(Expr.or(
Expr.ilike("name", t),
Expr.ilike("productId", t)
));
}
}
package controllers;
import actions.Secured;
import com.avaje.ebean.Expr;
import models.*;
import org.codehaus.jackson.node.ObjectNode;
import play.data.Form;
import play.i18n.Messages;
import play.libs.Json;
import play.mvc.*;
import views.html.detail.*;
import java.util.List;
import static play.data.Form.form;
@Security.Authenticated(Secured.class)
public class Details extends Controller {
public static Result editImage(Long detailId) {
Detail detail = Detail.query(detailId).findUnique();
if (detail == null) return notFound("Detail not found");
Http.MultipartFormData body = request().body().asMultipartFormData();
Http.MultipartFormData.FilePart part = body.getFile("image");
if (part == null)
return badRequest();
Image image;
try {
image = new Image(part, "default");
} catch (IllegalArgumentException ex) {
return badRequest(ex.getLocalizedMessage());
}
// See if there already is such an image
Image oldImage = Image.find.byId(image.id);
if (oldImage == null)
image.save();
else
image.update();
detail.image = image;
detail.update();
ObjectNode result = Json.newObject();
result.put("name", image.id);
result.put("url", se.digiplant.scalr.routes.ScalrResAssets.at(image.id, 250, 250).url());
return ok(result);
}
}
package models;
import com.google.common.base.Joiner;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import play.api.Play;
import play.data.validation.Constraints;
import play.db.ebean.Model;
import play.mvc.Http;
import se.digiplant.res.Res;
import javax.imageio.ImageIO;
import javax.persistence.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@Entity
public class Image extends Model {
@Id
@Column(length = 50)
public String id;
@Constraints.Required
@Column(length = 20, nullable = false)
public String source;
@Column(length = 20, nullable = false)
public String mimetype;
@Transient
private File file;
public File getFile() {
if (file == null) file = Res.get(id, source);
return file;
}
@Column(nullable = false)
public int width = 0;
@Column(nullable = false)
public int height = 0;
public Image() {}
/**
* Takes a Play FilePart directly from the request body
*/
public Image(Http.MultipartFormData.FilePart part, String source) throws IllegalArgumentException {
String[] imageTypes = new String[]{"image/jpeg", "image/png", "image/gif"};
if (!ArrayUtils.contains(imageTypes, part.getContentType())) {
throw new IllegalArgumentException("File must be of the following type: " + Joiner.on(",").join(imageTypes));
}
this.id = Res.put(part, source);
this.source = source;
this.mimetype = part.getContentType();
}
/**
* Used by the yaml initial data loader mostly
*/
public Image(String path, String source) {
File f = Play.current().getFile(path);
if (!f.exists())
throw new IllegalArgumentException("File must exist: " + path);
this.id = Res.put(f, source);
this.source = source;
this.mimetype = detectMimeType(f);
calculateImageSize();
}
@Override
public void save() {
calculateImageSize();
super.save();
}
@Override
public void update() {
calculateImageSize();
super.update();
}
public String getExtension() {
return FilenameUtils.getExtension(id);
}
private void calculateImageSize() {
if (id == null) return;
BufferedImage source = null;
try {
source = ImageIO.read(getFile());
this.width = source.getWidth();
this.height = source.getHeight();
} catch(Exception ex){
this.width = 0;
this.height = 0;
}
finally {
source = null;
}
}
private String detectMimeType(File f) {
String ext = FilenameUtils.getExtension(f.getName());
switch(ext) {
case "jpg":
case "jpeg":
return "image/jpeg";
case "png":
return "image/png";
case "gif":
return "image/gif";
}
return null;
}
/*
Query
*/
public static Finder<String, Image> find = new Finder<String, Image>(String.class, Image.class);
}
detailGroups:
- &floorsDetailGroup !!models.DetailGroup
name: Floors
details:
- !!models.Detail
group: *floorsDetailGroup
name: Marble
description: Real marble tiles have a beautiful, unique look like no other surface, with all their whirling patterns and shade variations.
image: !!models.Image [ mock/images/marble.jpg, default ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment