/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.pojo.impl;
import java.lang.reflect.Field;
import java.util.List;
import org.jboss.aop.Advised;
import org.jboss.aop.Domain;
import org.jboss.aop.InstanceAdvisor;
import org.jboss.aop.advice.Interceptor;
import org.jboss.cache.Fqn;
import org.jboss.cache.pojo.PojoCacheException;
import org.jboss.cache.pojo.annotation.TxUndo;
import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
/**
* Utility class for method wrappers that we are interested to rollback (i.e., rollback).
*
* @author Ben Wang
* @version $Id: PojoUtil.java 4012 2007-06-13 00:08:59Z jgreene $
*/
public class PojoUtil
{
private static final String BindingName = "ReentrancyStopperInterceptor.";
@TxUndo
public void attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
{
_attachInterceptor(pojo, advisor, interceptor);
}
@TxUndo
public void detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
{
_detachInterceptor(advisor, interceptor);
}
public void undoAttachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
{
_detachInterceptor(advisor, interceptor);
}
public void undoDetachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
{
Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
if (pojo == null)
{
throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
}
_attachInterceptor(pojo, advisor, interceptor);
}
@TxUndo
public void inMemorySubstitution(Object obj, Field field, Object newValue)
{
_inMemorySubstitution(obj, field, newValue);
}
public void undoInMemorySubstitution(Object obj, Field field, Object oldValue)
{
_inMemorySubstitution(obj, field, oldValue);
}
private void _attachInterceptor(Object pojo, InstanceAdvisor advisor, Interceptor interceptor)
{
advisor.appendInterceptor(interceptor);
}
private Domain getInstanceDomain(Object obj)
{
Advised advised = ((Advised) obj);
InstanceAdvisor advisor = advised._getInstanceAdvisor();
return advisor.getDomain();
}
private void _inMemorySubstitution(Object obj, Field field, Object newValue)
{
try
{
field.set(obj, newValue);
}
catch (IllegalAccessException e)
{
throw new PojoCacheException(
"PojoUtil.inMemorySubstitution(): Can't swap out the class of field \" " +
"+field.getLastElementAsString()," + e);
}
}
private void _detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor)
{
advisor.removeInterceptor(interceptor.getName());
// retrieve pojo
Object pojo = ((CacheFieldInterceptor) interceptor).getAopInstance().get();
if (pojo == null)
{
throw new PojoCacheException("PojoUtil.detachInterceptor(): null pojo");
}
}
@TxUndo
public int incrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
return _incrementReferenceCount(sourceFqn, count, refList);
}
public int undoIncrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
return _decrementReferenceCount(sourceFqn, count, refList);
}
private int _incrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
refList.add(sourceFqn);
return count + 1;
}
@TxUndo
public int decrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
return _decrementReferenceCount(sourceFqn, count, refList);
}
public int undoDecrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
return _incrementReferenceCount(sourceFqn, count, refList);
}
private int _decrementReferenceCount(Fqn sourceFqn, int count, List refList)
{
refList.remove(sourceFqn);
return count - 1;
}
}