Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Daniel Henrique Alves Lima
committed
Aug 12, 2011
1 parent
47e438a
commit 1911531
Showing
5 changed files
with
161 additions
and
116 deletions.
There are no files selected for viewing
154 changes: 48 additions & 106 deletions
154
src/groovy/grails/plugin/transaction/handling/ConfigurableTransactionInterceptor.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,142 +1,84 @@ | ||
package grails.plugin.transaction.handling | ||
package grails.plugin.transaction.handling; | ||
|
||
import grails.spring.BeanBuilder.ConfigurableRuntimeBeanReference; | ||
import groovy.util.Eval; | ||
|
||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Method | ||
import java.util.Properties | ||
import java.util.Map; | ||
import java.util.Properties; | ||
|
||
import org.apache.commons.beanutils.BeanUtils; | ||
import org.apache.commons.logging.Log | ||
import org.apache.commons.logging.LogFactory | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
import org.codehaus.groovy.grails.commons.GrailsApplication; | ||
import org.codehaus.groovy.grails.plugins.support.aware.GrailsApplicationAware; | ||
import org.springframework.transaction.interceptor.DefaultTransactionAttribute; | ||
import org.springframework.transaction.interceptor.RollbackRuleAttribute; | ||
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute; | ||
import org.springframework.transaction.interceptor.TransactionAttribute | ||
import org.springframework.transaction.interceptor.TransactionAttributeSource | ||
import org.springframework.transaction.interceptor.TransactionInterceptor | ||
import org.springframework.transaction.support.TransactionTemplate; | ||
import org.springframework.transaction.interceptor.TransactionAttributeSource; | ||
import org.springframework.transaction.interceptor.TransactionInterceptor; | ||
import org.springframework.util.Assert; | ||
|
||
public class ConfigurableTransactionInterceptor extends TransactionInterceptor implements GrailsApplicationAware { | ||
@SuppressWarnings("serial") | ||
class ConfigurableTransactionInterceptor extends TransactionInterceptor | ||
implements GrailsApplicationAware { | ||
|
||
private final Log log = LogFactory.getLog(getClass()) | ||
private Map configuredDefaults = null | ||
private TransactionAttribute defaults | ||
private final Log log = LogFactory.getLog(getClass()); | ||
@SuppressWarnings("rawtypes") | ||
private Map configuredDefaults = null; | ||
|
||
public ConfigurableTransactionInterceptor() { | ||
log.debug("constructor()") | ||
log.debug("constructor()"); | ||
} | ||
|
||
@Override | ||
public void setTransactionAttributeSource( | ||
TransactionAttributeSource transactionAttributeSource) { | ||
log.debug("setTransactionAttributeSource(): transactionAttributeSource ${transactionAttributeSource}") | ||
transactionAttributeSource = new MyTransactionAttributeSource(transactionAttributeSource) | ||
super.setTransactionAttributeSource(transactionAttributeSource) | ||
TransactionAttributeSource transactionAttributeSource) { | ||
log.debug("setTransactionAttributeSource(): transactionAttributeSource ${transactionAttributeSource}"); | ||
transactionAttributeSource = new MyTransactionAttributeSource( | ||
transactionAttributeSource, this.configuredDefaults); | ||
super.setTransactionAttributeSource(transactionAttributeSource); | ||
} | ||
|
||
@Override | ||
public void setTransactionAttributeSources( | ||
TransactionAttributeSource[] transactionAttributeSources) { | ||
log.debug("setTransactionAttributeSources(): transactionAttributeSources ${transactionAttributeSources}") | ||
super.setTransactionAttributeSources(transactionAttributeSources) | ||
TransactionAttributeSource[] transactionAttributeSources) { | ||
log.debug("setTransactionAttributeSources(): transactionAttributeSources ${transactionAttributeSources}"); | ||
super.setTransactionAttributeSources(transactionAttributeSources); | ||
} | ||
|
||
@Override | ||
public void setTransactionAttributes(Properties transactionAttributes) { | ||
log.debug("setTransactionAttributes(): transactionAttributes ${transactionAttributes}") | ||
super.setTransactionAttributes(transactionAttributes) | ||
log.debug("setTransactionAttributes(): transactionAttributes ${transactionAttributes}"); | ||
super.setTransactionAttributes(transactionAttributes); | ||
} | ||
|
||
|
||
|
||
|
||
@Override | ||
public TransactionAttributeSource getTransactionAttributeSource() { | ||
//log.debug('getTransactionAttributeSource(): Begin') | ||
TransactionAttributeSource source = super.getTransactionAttributeSource(); | ||
Assert.notNull source | ||
Assert.isAssignable MyTransactionAttributeSource, source.getClass() | ||
return source | ||
//log.debug('getTransactionAttributeSource(): End') | ||
public TransactionAttributeSource getTransactionAttributeSource() { | ||
// log.debug('getTransactionAttributeSource(): Begin') | ||
TransactionAttributeSource source = super | ||
.getTransactionAttributeSource(); | ||
Assert.notNull(source); | ||
|
||
Assert.isAssignable(MyTransactionAttributeSource.class, | ||
source.getClass()); | ||
|
||
return source; | ||
// log.debug('getTransactionAttributeSource(): End') | ||
} | ||
|
||
@SuppressWarnings("rawtypes") | ||
@Override | ||
public void setGrailsApplication(GrailsApplication grailsApplication) { | ||
configuredDefaults = null | ||
defaults = null | ||
public void setGrailsApplication(GrailsApplication grailsApplication) { | ||
configuredDefaults = null; | ||
if (grailsApplication != null) { | ||
TransactionPropertiesUtil txPropsUtil = new TransactionPropertiesUtil() | ||
Map config = grailsApplication.mergedConfig.asMap(true).grails.plugin.transactionHandling.declarative | ||
if (config && !config.isEmpty()) { | ||
configuredDefaults = txPropsUtil.expand(config) | ||
defaults = new RuleBasedTransactionAttribute() | ||
TransactionPropertiesUtil txPropsUtil = new TransactionPropertiesUtil(); | ||
Map config = (Map) Eval | ||
.x(grailsApplication, | ||
"x.mergedConfig.asMap(true).grails.plugin.transactionHandling.declarative"); | ||
if (config != null && !config.isEmpty()) { | ||
configuredDefaults = txPropsUtil.expand(txPropsUtil | ||
.removePropagationProperties(config)); | ||
} | ||
} | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug("setGrailsApplication(): template ${configuredDefaults}") | ||
log.debug("setGrailsApplication(): template ${configuredDefaults}"); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
protected class MyTransactionAttributeSource implements TransactionAttributeSource { | ||
|
||
private final Map cache = new IdentityHashMap() | ||
protected final TransactionAttributeSource source | ||
|
||
public MyTransactionAttributeSource(TransactionAttributeSource source) { | ||
this.source = source | ||
Assert.notNull(this.source) | ||
} | ||
|
||
@Override | ||
public TransactionAttribute getTransactionAttribute(Method method, Class<?> clazz) { | ||
TransactionAttribute att = this.source.getTransactionAttribute(method, clazz) | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): att ${att}; template ${configuredDefaults}") | ||
} | ||
|
||
if (configuredDefaults != null) { | ||
TransactionAttribute newAtt = cache[att] | ||
if (newAtt == null) { | ||
if (att != null) { | ||
Constructor c = att.getClass().getConstructor(att.getClass()) | ||
newAtt = c.newInstance(att) | ||
} else { | ||
newAtt = new DefaultTransactionAttribute() | ||
} | ||
|
||
for (entry in configuredDefaults.entrySet()) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): key ${entry.key}") | ||
} | ||
|
||
if (newAtt[entry.key] == defaults[entry.key] && entry.value != defaults[entry.key]) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): ${entry.key} = ${entry.value}") | ||
} | ||
newAtt[entry.key] = entry.value | ||
} | ||
} | ||
} | ||
|
||
cache[att] = newAtt | ||
att = newAtt | ||
} | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): att = ${att}") | ||
} | ||
|
||
return att | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
src/groovy/grails/plugin/transaction/handling/MyTransactionAttributeSource.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package grails.plugin.transaction.handling; | ||
|
||
import java.lang.reflect.Constructor | ||
import java.lang.reflect.Method | ||
import java.util.IdentityHashMap | ||
import java.util.Map | ||
|
||
import org.apache.commons.logging.Log | ||
import org.apache.commons.logging.LogFactory | ||
import org.springframework.transaction.interceptor.DefaultTransactionAttribute | ||
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute | ||
import org.springframework.transaction.interceptor.TransactionAttribute | ||
import org.springframework.transaction.interceptor.TransactionAttributeSource | ||
import org.springframework.util.Assert | ||
|
||
|
||
public class MyTransactionAttributeSource implements TransactionAttributeSource { | ||
|
||
private final Log log = LogFactory.getLog(getClass()); | ||
private final Map cache = new IdentityHashMap(); | ||
protected final TransactionAttributeSource source; | ||
private final Map configuredDefaults; | ||
private final TransactionAttribute defaults; | ||
|
||
public MyTransactionAttributeSource(TransactionAttributeSource source, Map configuredDefaults) { | ||
this.source = source; | ||
Assert.notNull(this.source); | ||
this.configuredDefaults = configuredDefaults; | ||
if (this.configuredDefaults != null) { | ||
this.defaults = new RuleBasedTransactionAttribute(); | ||
} else { | ||
this.defaults = null; | ||
} | ||
} | ||
|
||
@Override | ||
public TransactionAttribute getTransactionAttribute(Method method, Class<?> clazz) { | ||
TransactionAttribute att = this.source.getTransactionAttribute(method, clazz) | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): att ${att}; template ${configuredDefaults}") | ||
} | ||
|
||
if (configuredDefaults != null) { | ||
TransactionAttribute newAtt = cache[att] | ||
if (newAtt == null) { | ||
if (att != null) { | ||
Constructor c = att.getClass().getConstructor(att.getClass()) | ||
newAtt = c.newInstance(att) | ||
} else { | ||
newAtt = new DefaultTransactionAttribute() | ||
} | ||
|
||
for (entry in configuredDefaults.entrySet()) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): key ${entry.key}") | ||
} | ||
|
||
if (newAtt[entry.key] == defaults[entry.key] && entry.value != defaults[entry.key]) { | ||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): ${entry.key} = ${entry.value}") | ||
} | ||
newAtt[entry.key] = entry.value | ||
} | ||
} | ||
} | ||
|
||
cache[att] = newAtt | ||
att = newAtt | ||
} | ||
|
||
if (log.isDebugEnabled()) { | ||
log.debug("getTransactionAttribute(): att = ${att}") | ||
} | ||
|
||
return att | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters