Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions documentation/manual/events.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Events are a way for plugins to receive notifications from the framework or other plugins.

The API to send events is pretty straightforward: an event is a `string` and an `Object` (the context).

bc.. import play.PlayPlugin;

...
PlayPlugin.postEvent("something happens", this);

p. Plugins can listen to these events in the the @onEvent@ method:

bc.. public class My Plugin extends PlayPlugin {

@Override
public void onEvent(String message, Object context) {
...
}


h2. Available events

At the moment the following events are sent by Play framework.

Events go in pair signaling the beginning and the end of a framework operation.

Usually the context provided to the before and after events is the same except for JPQL category.
In this case, the before event gives the entity name while the after give the JPQL instance.


| Class | Method | Event | Context |
| Controller | renderTemplate | template.render.before | @string@: the template name |
| | | template.render.after | idem |
| JPABase | _save | JPASupport.objectSaving | @JPABase@: the object |
| | | JPASupport.objectPersisting| idem |
| | | JPASupport.objectPersisted | idem |
| | | JPASupport.objectSaved | idem |
| | _delete | JPASupport.objectDeleting | idem |
| | | JPASupport.objectDeleted | idem |
| JPQL | count | JPQL.count.before | @string@: the entity name |
| | | JPQL.count.after | @JPQL@: the object |
| | findAll | JPQL.findAll.before | idem |
| | | JPQL.findAll.after | idem |
| | findBy | JPQL.findBy.before | idem |
| | | JPQL.findBy.after | idem |
| | find | JPQL.find.before | idem |
| | | JPQL.find.after | idem |
| | all | JPQL.all.before | idem |
| | | JPQL.all.after | idem |
| | delete | JPQL.delete.before | idem |
| | | JPQL.delete.after | idem |
| | deleteAll | JPQL.deleteAll.before | idem |
| | | JPQL.deleteAll.after | idem |
| | findOneBy | JPQL.findOneBy.before | idem |
| | | JPQL.findOneBy.after | idem |
| | create | JPQL.create.before | idem |
| | | JPQL.create.after | |
62 changes: 36 additions & 26 deletions framework/src/play/db/jpa/JPABase.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,50 @@ public class JPABase implements Serializable, play.db.Model {


public void _save() {
boolean saving = false ;
String dbName = JPA.getDBName(this.getClass());
if (!em(dbName).contains(this)) {
saving = true ;
PlayPlugin.postEvent("JPASupport.objectSaving", this);
PlayPlugin.postEvent("JPASupport.objectPersisting", this);
em(dbName).persist(this);
PlayPlugin.postEvent("JPASupport.objectPersisted", this);
}
avoidCascadeSaveLoops.set(new HashSet<JPABase>());
try {
saveAndCascade(true);
} finally {
avoidCascadeSaveLoops.get().clear();
}
try {
em(dbName).flush();
} catch (PersistenceException e) {
if (e.getCause() instanceof GenericJDBCException) {
throw new PersistenceException(((GenericJDBCException) e.getCause()).getSQL(), e);
} else {
throw e;
}
}
avoidCascadeSaveLoops.set(new HashSet<JPABase>());
try {
saveAndCascade(false);
} finally {
avoidCascadeSaveLoops.get().clear();
try{
avoidCascadeSaveLoops.set(new HashSet<JPABase>());
try {
saveAndCascade(true);
} finally {
avoidCascadeSaveLoops.get().clear();
}
try {
em(dbName).flush();
} catch (PersistenceException e) {
if (e.getCause() instanceof GenericJDBCException) {
throw new PersistenceException(((GenericJDBCException) e.getCause()).getSQL(), e);
} else {
throw e;
}
}
avoidCascadeSaveLoops.set(new HashSet<JPABase>());
try {
saveAndCascade(false);
} finally {
avoidCascadeSaveLoops.get().clear();
}
}
finally
{
if( saving )
PlayPlugin.postEvent("JPASupport.objectSaved", this);
}
}

public void _delete() {
String dbName = JPA.getDBName(this.getClass());

try {
PlayPlugin.postEvent("JPASupport.objectDeleting", this);
avoidCascadeSaveLoops.set(new HashSet<JPABase>());
try {
saveAndCascade(true);
Expand All @@ -83,13 +95,14 @@ public void _delete() {
saveAndCascade(false);
} finally {
avoidCascadeSaveLoops.get().clear();
}
PlayPlugin.postEvent("JPASupport.objectDeleted", this);
}
} catch (PersistenceException e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
}
} finally {
PlayPlugin.postEvent("JPASupport.objectDeleted", this);
}
}

public Object _key() {
Expand All @@ -106,9 +119,6 @@ private void saveAndCascade(boolean willBeSaved) {
return;
} else {
avoidCascadeSaveLoops.get().add(this);
if (willBeSaved) {
PlayPlugin.postEvent("JPASupport.objectUpdated", this);
}
}
// Cascade save
try {
Expand Down
62 changes: 48 additions & 14 deletions framework/src/play/db/jpa/JPQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import javax.persistence.Query;

import play.Play;
import play.PlayPlugin;
import play.data.binding.ParamNode;
import play.data.binding.RootParamNode;
import play.db.Configuration;
Expand All @@ -28,25 +29,34 @@ public long count(String entity) {
}

public long count(String dbName, String entity) {
return Long.parseLong(em(dbName).createQuery("select count(*) from " + entity + " e").getSingleResult().toString());
PlayPlugin.postEvent("JPQL.count.before", entity);
long result = Long.parseLong(em(dbName).createQuery("select count(*) from " + entity + " e").getSingleResult().toString());
PlayPlugin.postEvent("JPQL.count.after", this);
return result ;
}

public long count(String entity, String query, Object[] params) {
return count(JPA.DEFAULT, entity, query, params);
}

public long count(String dbName, String entity, String query, Object[] params) {
return Long.parseLong(
PlayPlugin.postEvent("JPQL.count.before", entity);
long result = Long.parseLong(
bindParameters(em(dbName).createQuery(
createCountQuery(dbName, entity, entity, query, params)), params).getSingleResult().toString());
PlayPlugin.postEvent("JPQL.count.after", this);
return result ;
}

public List findAll(String entity) {
return findAll(JPA.DEFAULT, entity);
}

public List findAll(String dbName, String entity) {
return em(dbName).createQuery("select e from " + entity + " e").getResultList();
PlayPlugin.postEvent("JPQL.findAll.before", entity);
List result = em(dbName).createQuery("select e from " + entity + " e").getResultList();
PlayPlugin.postEvent("JPQL.findAll.after", this);
return result ;
}

public JPABase findById(String entity, Object id) throws Exception {
Expand All @@ -62,9 +72,12 @@ public List findBy(String entity, String query, Object[] params) {
}

public List findBy(String dbName, String entity, String query, Object[] params) {
PlayPlugin.postEvent("JPQL.findBy.before", entity);
Query q = em(dbName).createQuery(
createFindByQuery(dbName, entity, entity, query, params));
return bindParameters(q, params).getResultList();
List result = bindParameters(q, params).getResultList();
PlayPlugin.postEvent("JPQL.findBy.after", this);
return result ;
}

public JPAQuery find(String entity, String query, Object[] params) {
Expand All @@ -73,38 +86,50 @@ public JPAQuery find(String entity, String query, Object[] params) {


public JPAQuery find(String dbName, String entity, String query, Object[] params) {
PlayPlugin.postEvent("JPQL.find.before", entity);
Query q = em(dbName).createQuery(
createFindByQuery(dbName, entity, entity, query, params));
return new JPAQuery(
JPAQuery result = new JPAQuery(
createFindByQuery(dbName, entity, entity, query, params), bindParameters(q, params));
PlayPlugin.postEvent("JPQL.find.after", this);
return result ;
}

public JPAQuery find(String entity) {
return find(JPA.DEFAULT, entity);
}

public JPAQuery find(String dbName, String entity) {
PlayPlugin.postEvent("JPQL.find.before", entity);
Query q = em(dbName).createQuery(
createFindByQuery(dbName, entity, entity, null));
return new JPAQuery(
JPAQuery result = new JPAQuery(
createFindByQuery(dbName, entity, entity, null), bindParameters(q));
PlayPlugin.postEvent("JPQL.find.after", this);
return result ;
}

public JPAQuery all(String entity) {
return all(JPA.DEFAULT, entity);
}

public JPAQuery all(String dbName, String entity) {
PlayPlugin.postEvent("JPQL.all.before", entity);
Query q = em(dbName).createQuery(
createFindByQuery(dbName, entity, entity, null));
return new JPAQuery(
JPAQuery result = new JPAQuery(
createFindByQuery(dbName, entity, entity, null), bindParameters(q));
PlayPlugin.postEvent("JPQL.all.after", this);
return result ;
}

public int delete(String dbName, String entity, String query, Object[] params) {
PlayPlugin.postEvent("JPQL.delete.before", entity);
Query q = em(dbName).createQuery(
createDeleteQuery(entity, entity, query, params));
return bindParameters(q, params).executeUpdate();
int result = bindParameters(q, params).executeUpdate();
PlayPlugin.postEvent("JPQL.delete.after", this);
return result ;
}

public int delete(String entity, String query, Object[] params) {
Expand All @@ -113,23 +138,29 @@ public int delete(String entity, String query, Object[] params) {


public int deleteAll(String dbName, String entity) {
PlayPlugin.postEvent("JPQL.deleteAll.before", entity);
Query q = em(dbName).createQuery(
createDeleteQuery(entity, entity, null));
return bindParameters(q).executeUpdate();
int result = bindParameters(q).executeUpdate();
PlayPlugin.postEvent("JPQL.deleteAll.after", this);
return result ;
}

public int deleteAll(String entity) {
return deleteAll(JPA.DEFAULT, entity);
}

public JPABase findOneBy(String dbName, String entity, String query, Object[] params) {
PlayPlugin.postEvent("JPQL.findOneBy.before", entity);
Query q = em(dbName).createQuery(
createFindByQuery(dbName, entity, entity, query, params));
List results = bindParameters(q, params).getResultList();
if (results.size() == 0) {
return null;
}
return (JPABase) results.get(0);
JPABase result = null ;
if (results.size() != 0) {
result = (JPABase) results.get(0);
}
PlayPlugin.postEvent("JPQL.findOneBy.after", this);
return result ;
}

public JPABase findOneBy(String entity, String query, Object[] params) {
Expand All @@ -141,11 +172,14 @@ public JPABase create(String entity, String name, Params params) throws Exceptio
}

public JPABase create(String dbName, String entity, String name, Params params) throws Exception {
PlayPlugin.postEvent("JPQL.create.before", entity);
Object o = Play.classloader.loadClass(entity).newInstance();

RootParamNode rootParamNode = ParamNode.convert(params.all());

return ((GenericModel) o).edit(rootParamNode, name);
JPABase result = ((GenericModel) o).edit(rootParamNode, name);
PlayPlugin.postEvent("JPQL.create.after", this);
return result ;
}

public String createFindByQuery(String dbName, String entityName, String entityClass, String query, Object... params) {
Expand Down
58 changes: 34 additions & 24 deletions framework/src/play/mvc/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import play.Invoker.Suspend;
import play.Logger;
import play.Play;
import play.PlayPlugin;
import play.classloading.ApplicationClasses.ApplicationClass;
import play.classloading.enhancers.ContinuationEnhancer;
import play.classloading.enhancers.ControllersEnhancer.ControllerInstrumentation;
Expand Down Expand Up @@ -663,30 +664,39 @@ protected static void renderTemplate(String templateName, Object... args) {
* @param args The template data.
*/
protected static void renderTemplate(String templateName, Map<String,Object> args) {
// Template datas
Scope.RenderArgs templateBinding = Scope.RenderArgs.current();
templateBinding.data.putAll(args);
templateBinding.put("session", Scope.Session.current());
templateBinding.put("request", Http.Request.current());
templateBinding.put("flash", Scope.Flash.current());
templateBinding.put("params", Scope.Params.current());
templateBinding.put("errors", Validation.errors());
try {
Template template = TemplateLoader.load(template(templateName));
throw new RenderTemplate(template, templateBinding.data);
} catch (TemplateNotFoundException ex) {
if (ex.isSourceAvailable()) {
throw ex;
}
StackTraceElement element = PlayException.getInterestingStackTraceElement(ex);
if (element != null) {
ApplicationClass applicationClass = Play.classes.getApplicationClass(element.getClassName());
if (applicationClass != null) {
throw new TemplateNotFoundException(templateName, applicationClass, element.getLineNumber());
}
}
throw ex;
}
PlayPlugin.postEvent("template.render.before", templateName);
Template template = null ;
try
{
// Template datas
Scope.RenderArgs templateBinding = Scope.RenderArgs.current();
templateBinding.data.putAll(args);
templateBinding.put("session", Scope.Session.current());
templateBinding.put("request", Http.Request.current());
templateBinding.put("flash", Scope.Flash.current());
templateBinding.put("params", Scope.Params.current());
templateBinding.put("errors", Validation.errors());
try {
template = TemplateLoader.load(template(templateName));
throw new RenderTemplate(template, templateBinding.data);
} catch (TemplateNotFoundException ex) {
if (ex.isSourceAvailable()) {
throw ex;
}
StackTraceElement element = PlayException.getInterestingStackTraceElement(ex);
if (element != null) {
ApplicationClass applicationClass = Play.classes.getApplicationClass(element.getClassName());
if (applicationClass != null) {
throw new TemplateNotFoundException(templateName, applicationClass, element.getLineNumber());
}
}
throw ex;
}
}
finally
{
PlayPlugin.postEvent("template.render.after", template);
}
}

/**
Expand Down