/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.cluster.clusteredentity.classloader;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.PreDestroy;
import javax.ejb.Remote;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheManager;
import org.jboss.cache.Fqn;
import org.jboss.cache.notifications.annotation.CacheListener;
import org.jboss.cache.notifications.annotation.NodeCreated;
import org.jboss.cache.notifications.annotation.NodeModified;
import org.jboss.cache.notifications.annotation.NodeVisited;
import org.jboss.cache.notifications.event.NodeCreatedEvent;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
import org.jboss.cache.notifications.event.NodeVisitedEvent;
import org.jboss.ejb3.annotation.RemoteBinding;
import org.jboss.ha.framework.server.CacheManagerLocator;
import org.jboss.logging.Logger;
/**
* Comment
*
* @author Brian Stansberry
* @version $Revision: 60233 $
*/
@Stateful
@Remote(EntityQueryTest.class)
@RemoteBinding(jndiBinding="EntityQueryTestBean/remote")
public class EntityQueryTestBean implements EntityQueryTest
{
private static final Logger log = Logger.getLogger(EntityQueryTestBean.class);
@PersistenceContext
private EntityManager manager;
private String cacheConfigName;
private transient Cache<Object, Object> cache;
private MyListener listener;
public EntityQueryTestBean()
{
}
public void getCache(boolean optimistic)
{
if (optimistic)
cacheConfigName = "optimistic-shared";
else
cacheConfigName = "pessimistic-shared";
try
{
//Just to initialise the cache with a listener
Cache<Object, Object> cache = getCache();
listener = new MyListener();
cache.addCacheListener(listener);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
public void updateAccountBranch(Integer id, String branch)
{
Account account = (Account) manager.find(Account.class, id);
account.setBranch(branch);
}
public int getCountForBranch(String branch, boolean useNamed, boolean useRegion)
{
if (useNamed)
return getCountForBranchViaNamedQuery(branch, useRegion);
else
return getCountForBranchViaLocalQuery(branch, useRegion);
}
private int getCountForBranchViaLocalQuery(String branch, boolean useRegion)
{
Query query = manager.createQuery("select account from Account as account where account.branch = ?1");
query.setParameter(1, branch);
if (useRegion)
{
query.setHint("org.hibernate.cacheRegion", "AccountRegion");
}
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
return query.getResultList().size();
}
private int getCountForBranchViaNamedQuery(String branch, boolean useRegion)
{
String queryName = useRegion ? "account.bybranch.namedregion"
: "account.bybranch.default";
Query query = manager.createNamedQuery(queryName);
query.setParameter(1, branch);
return query.getResultList().size();
}
/* (non-Javadoc)
* @see org.jboss.ejb3.test.clusteredentity.EntityQueryTest#createAccount(org.jboss.ejb3.test.clusteredentity.AccountHolderPK, Integer, Integer)
*/
public void createAccount(AccountHolderPK pk, Integer id, Integer openingBalance, String branch)
{
Account account = new Account();
account.setId(id);
account.setAccountHolder(pk);
account.setBalance(openingBalance);
account.setBranch(branch);
manager.persist(account);
}
public void updateAccountBalance(Integer id, Integer newBalance)
{
Account account = (Account) manager.find(Account.class, id);
account.setBalance(newBalance);
}
public String getBranch(AccountHolderPK pk, boolean useNamed, boolean useRegion)
{
if (useNamed)
return getBranchViaNamedQuery(pk, useRegion);
else
return getBranchViaLocalQuery(pk, useRegion);
}
private String getBranchViaLocalQuery(AccountHolderPK pk, boolean useRegion)
{
Query query = manager.createQuery("select account.branch from Account as account where account.accountHolder = ?1");
query.setParameter(1, pk);
if (useRegion)
{
query.setHint("org.hibernate.cacheRegion", "AccountRegion");
}
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
return (String) query.getResultList().get(0);
}
/* (non-Javadoc)
* @see org.jboss.ejb3.test.clusteredentity.EntityQueryTest#getPostCodeViaNamedQuery(org.jboss.ejb3.test.clusteredentity.AccountHolderPK, boolean)
*/
private String getBranchViaNamedQuery(AccountHolderPK pk, boolean useRegion)
{
String queryName = useRegion ? "account.branch.namedregion"
: "account.branch.default";
Query query = manager.createNamedQuery(queryName);
query.setParameter(1, pk);
return (String) query.getResultList().get(0);
}
public int getTotalBalance(AccountHolderPK pk, boolean useNamed, boolean useRegion)
{
if (useNamed)
return getTotalBalanceViaNamedQuery(pk, useRegion);
else
return getTotalBalanceViaLocalQuery(pk, useRegion);
}
private int getTotalBalanceViaLocalQuery(AccountHolderPK pk, boolean useRegion)
{
Query query = manager.createQuery("select account.balance from Account as account where account.accountHolder = ?1");
query.setParameter(1, pk);
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
return totalBalances(query);
}
private int getTotalBalanceViaNamedQuery(AccountHolderPK pk, boolean useRegion)
{
String queryName = useRegion ? "account.totalbalance.namedregion"
: "account.totalbalance.default";
Query query = manager.createNamedQuery(queryName);
query.setParameter(1, pk);
return totalBalances(query);
}
private int totalBalances(Query balanceQuery)
{
List results = balanceQuery.getResultList();
int total = 0;
if (results != null)
{
for (Iterator it = results.iterator(); it.hasNext();)
{
total += ((Integer) it.next()).intValue();
System.out.println("Total = " + total);
}
}
return total;
}
public boolean getSawRegionModification(String regionName)
{
return getSawRegion(regionName, listener.modified);
}
public boolean getSawRegionAccess(String regionName)
{
return getSawRegion(regionName, listener.accessed);
}
private boolean getSawRegion(String regionName, Set<Fqn<String>> sawEvent)
{
boolean saw = false;
for (Iterator<Fqn<String>> it = sawEvent.iterator(); it.hasNext();)
{
Fqn<String> modified = (Fqn<String>) it.next();
if (modified.toString().indexOf(regionName) > -1)
{
it.remove();
saw = true;
}
}
return saw;
}
public void cleanup()
{
internalCleanup();
}
private void internalCleanup()
{
if (manager != null)
{
Query query = manager.createQuery("select account from Account as account");
List accts = query.getResultList();
if (accts != null)
{
for (Iterator it = accts.iterator(); it.hasNext();)
{
try
{
Account acct = (Account) it.next();
log.info("Removing " + acct);
manager.remove(acct);
}
catch (Exception ignored) {}
}
}
}
}
@PreDestroy
@Remove
public void remove(boolean removeEntities)
{
if (removeEntities)
{
try
{
internalCleanup();
}
catch (Exception e)
{
log.error("Caught exception in remove", e);
}
}
try
{
listener.clear();
getCache().removeCacheListener(listener);
}
catch (Exception e)
{
log.error("Caught exception in remove", e);
}
try
{
if (cache != null)
CacheManagerLocator.getCacheManagerLocator().getCacheManager(null).releaseCache(cacheConfigName);
}
catch (Exception e)
{
log.error("Caught exception releasing cache", e);
}
}
private Cache<Object, Object> getCache() throws Exception
{
if (cache == null && cacheConfigName != null)
{
CacheManager cm = CacheManagerLocator.getCacheManagerLocator().getCacheManager(null);
cache = cm.getCache(cacheConfigName, true);
cache.start();
}
return cache;
}
@CacheListener
public class MyListener
{
HashSet<Fqn<String>> modified = new HashSet<Fqn<String>>();
HashSet<Fqn<String>> accessed = new HashSet<Fqn<String>>();
public void clear()
{
modified.clear();
accessed.clear();
}
@NodeModified
public void nodeModified(NodeModifiedEvent event)
{
if (!event.isPre())
{
Fqn<String> fqn = event.getFqn();
System.out.println("MyListener - Modified node " + fqn.toString());
modified.add(fqn);
}
}
@NodeCreated
public void nodeCreated(NodeCreatedEvent event)
{
if (!event.isPre())
{
Fqn<String> fqn = event.getFqn();
System.out.println("MyListener - Created node " + fqn.toString());
modified.add(fqn);
}
}
@NodeVisited
public void nodeVisited(NodeVisitedEvent event)
{
if (!event.isPre())
{
Fqn<String> fqn = event.getFqn();
System.out.println("MyListener - Visited node " + fqn.toString());
accessed.add(fqn);
}
}
}
}