package models; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import java.util.UUID; import javax.persistence.Basic; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import javax.persistence.Version; import play.Logger; import play.Logger.ALogger; import play.data.validation.Constraints.Required; import play.db.ebean.Model; import play.utils.dao.TimestampModel; import plugins.S3Plugin; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; @Entity @Table(name="TBL_S3FILE") @SuppressWarnings("serial") public class S3File extends Model implements TimestampModel<UUID> { private static ALogger log = Logger.of(S3File.class); @Id public UUID id; @Required private String bucket; @Basic public String parent; @Required public String name; @Basic private Date createdOn; @Basic private Date updatedOn; @Version private int revision; @Transient private S3Input input; public String getBucket() { return bucket; } @Override public UUID getKey() { return id; } public void setKey(UUID id) { this.id = id; } public Date getCreatedOn() { return createdOn; } public void setCreatedOn(Date createdOn) { this.createdOn = createdOn; } public Date getUpdatedOn() { return updatedOn; } public void setUpdatedOn(Date updatedOn) { this.updatedOn = updatedOn; } public int getRevision() { return revision; } public void setRevision(int revision) { this.revision = revision; } public void setInput(S3Input input) { this.input = input; } public void setInputFromFile(File file) { this.input = new S3InputFile(file); } public void setInputFromData(byte[] data) { this.input = new S3InputData(data); } public URL getUrl() { StringBuilder sb = new StringBuilder("http://").append(bucket) .append(".s3.amazonaws.com/").append(getActualFileName()); try { return new URL(sb.toString()); } catch (MalformedURLException e) { e.printStackTrace(); return null; } } private String getActualFileName() { StringBuilder sb = new StringBuilder(); if (parent != null && !"".equals(parent)) { sb.append(parent).append("/"); } sb.append(id).append("/").append(name); return sb.toString(); } @Override public void save() { AmazonS3 amazonS3 = S3Plugin.amazonS3; if (amazonS3 == null) { log.error("Could not save because amazonS3 was null"); throw new RuntimeException("Could not save"); } else { this.bucket = S3Plugin.getBucket(); super.save(); // assigns an id if (log.isDebugEnabled()) log.debug("bucket : " + bucket); if (log.isDebugEnabled()) log.debug("file : " + input); String filename = getActualFileName(); if (log.isDebugEnabled()) log.debug("filename : " + filename); PutObjectRequest putObjectRequest = input.getPutObjectRequest(); putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); // public for all amazonS3.putObject(putObjectRequest); // upload file } } @Override public void delete() { AmazonS3 amazonS3 = S3Plugin.amazonS3; if (amazonS3 == null) { log.error("Could not delete because amazonS3 was null"); throw new RuntimeException("Could not delete"); } else { amazonS3.deleteObject(bucket, getActualFileName()); super.delete(); } } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("S3File [id=").append(id).append(", name=").append(name) .append(", input=").append(input).append(", URL=").append(getUrl()).append("]"); return builder.toString(); } interface S3Input { PutObjectRequest getPutObjectRequest(); } class S3InputFile implements S3Input { private File file; public S3InputFile(File file) { this.file = file; } public PutObjectRequest getPutObjectRequest() { return new PutObjectRequest(bucket, getActualFileName(), file); } } class S3InputData implements S3Input { private byte[] data; public S3InputData(byte[] data) { this.data = data; } public PutObjectRequest getPutObjectRequest() { Long contentLength = Long.valueOf(data.length); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(contentLength); InputStream is = new ByteArrayInputStream(data); String fn = getActualFileName(); return new PutObjectRequest(bucket, fn, is, metadata); } } }