[jboss-cvs] JBossAS SVN: r70798 - in projects/ejb3/branches/cluster-dev: cache-jbc2 and 12 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Mar 12 23:27:01 EDT 2008
Author: bstansberry at jboss.com
Date: 2008-03-12 23:27:01 -0400 (Wed, 12 Mar 2008)
New Revision: 70798
Added:
projects/ejb3/branches/cluster-dev/cache-jbc2/
projects/ejb3/branches/cluster-dev/cache-jbc2/pom.xml
projects/ejb3/branches/cluster-dev/cache-jbc2/src/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUAlgorithm.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUPolicy.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ClusteredCacheListener.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ContextInUseException.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStoreSource.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/OwnedItem.java
projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/java/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/resources/
projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/resources/log4j.xml
Log:
[EJBTHREE-1026] Initial checkin of JBC2 stuff
Property changes on: projects/ejb3/branches/cluster-dev/cache-jbc2
___________________________________________________________________
Name: svn:ignore
+ .settings
eclipse-target
target
.classpath
.project
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/pom.xml
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/pom.xml (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/pom.xml 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <!-- Define Parent -->
+ <parent>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-build</artifactId>
+ <version>0.13.0-SNAPSHOT</version>
+ <relativePath>../build/pom.xml</relativePath>
+ </parent>
+
+ <!-- Maven POM Model Version -->
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- Artifact Information -->
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-cache-jbc2</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>JBoss EJB 3.0 JBoss Cache Integration</name>
+ <url>http://labs.jboss.com/jbossejb3/</url>
+ <description>The Java EJB 3.0 JBoss Cache Integration classes</description>
+
+ <properties>
+ <version.org.jboss.cache_jbosscache-core>2.1.0-SNAPSHOT</version.org.jboss.cache_jbosscache-core>
+ </properties>
+
+ <dependencies>
+
+ <!-- EJB3 Cache -->
+ <dependency>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-cache</artifactId>
+ <version>0.14.0-SNAPSHOT</version>
+ </dependency>
+
+ <!-- JBoss Cache -->
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
+ <version>${version.org.jboss.cache_jbosscache-core}</version>
+ </dependency>
+
+ <!-- JUnit -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUAlgorithm.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUAlgorithm.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUAlgorithm.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,106 @@
+/*
+ * 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.ejb3.cache.impl.backing.jbc2;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.eviction.EvictionPolicy;
+import org.jboss.cache.eviction.LRUAlgorithm;
+import org.jboss.cache.lock.TimeoutException;
+import org.jboss.logging.Logger;
+
+/**
+ * LRUAlgorithm subclass that doesn't log an error if it catches
+ * {@link ContextInUseException}.
+ *
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1.1 $
+ */
+public class AbortableLRUAlgorithm extends LRUAlgorithm
+{
+ private static final Logger log = Logger.getLogger(AbortableLRUAlgorithm.class);
+
+ public AbortableLRUAlgorithm()
+ {
+ super();
+ }
+
+ /**
+ * Evict a node from cache.
+ *
+ * @param fqn node corresponds to this fqn
+ * @return True if successful
+ */
+ protected boolean evictCacheNode(Fqn fqn)
+ {
+ if (log.isTraceEnabled())
+ {
+ log.trace("Attempting to evict cache node with fqn of " + fqn);
+ }
+
+ EvictionPolicy policy = region.getEvictionPolicy();
+ try
+ {
+ policy.evict(fqn);
+ }
+ catch (ContextInUseException e)
+ {
+ // Don't log it at any alarming level
+ if (log.isTraceEnabled())
+ log.trace("Eviction of " + fqn + " aborted as bean is in use");
+ return false;
+ }
+ catch (TimeoutException e)
+ {
+ log.warn("Eviction of " + fqn + " timed out, retrying later");
+ log.debug(e, e);
+ return false;
+ }
+ catch (RuntimeException e)
+ {
+ Throwable cause = e.getCause();
+ if (cause instanceof ContextInUseException)
+ {
+ // Don't log it at any alarming level
+ if (log.isTraceEnabled())
+ log.trace("Eviction of " + fqn + " aborted as bean is in use");
+ return false;
+ }
+ log.error("Eviction of " + fqn + " failed", e);
+ return false;
+ }
+ catch (Exception e)
+ {
+ log.error("Eviction of " + fqn + " failed", e);
+ return false;
+ }
+
+ if (log.isTraceEnabled())
+ {
+ log.trace("Eviction of cache node with fqn of " + fqn + " successful");
+ }
+
+ return true;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUPolicy.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUPolicy.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/AbortableLRUPolicy.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,42 @@
+/*
+ * 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.ejb3.cache.impl.backing.jbc2;
+
+import org.jboss.cache.eviction.LRUPolicy;
+
+/**
+ * LRUPolicy subclass with an algorithm that doesn't error log
+ * {@link ContextInUseException}.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1.1 $
+ */
+public class AbortableLRUPolicy extends LRUPolicy
+{
+ public AbortableLRUPolicy()
+ {
+ super();
+ algorithm = new AbortableLRUAlgorithm();
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ClusteredCacheListener.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ClusteredCacheListener.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ClusteredCacheListener.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, 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.ejb3.cache.impl.backing.jbc2;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeActivated;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodePassivated;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.annotation.NodeVisited;
+import org.jboss.cache.notifications.event.NodeActivatedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodePassivatedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+import org.jboss.cache.notifications.event.NodeVisitedEvent;
+
+/**
+ * Single {@link CacheListener} that handles event Fqn parsing and then
+ * delegates to a handler that has registered for the region. Intent is
+ * to do the region-matching work once here, rather than having multiple
+ * listeners registered with the cache.
+ *
+ * @author Brian Stansberry
+ */
+ at CacheListener
+public class ClusteredCacheListener
+{
+ public static interface RegionHandler
+ {
+ void nodeVisited(OwnedItem ownedItem, NodeVisitedEvent event);
+ void nodeModified(OwnedItem ownedItem, NodeModifiedEvent event);
+ void nodeRemoved(OwnedItem ownedItem, NodeRemovedEvent event);
+ void nodeActivated(OwnedItem ownedItem, NodeActivatedEvent event);
+ void nodePassivated(OwnedItem ownedItem, NodePassivatedEvent event);
+ }
+
+ private final Map<Fqn, RegionHandler> handlers = new ConcurrentHashMap<Fqn, RegionHandler>();
+ private final boolean checkBuddy;
+
+ public ClusteredCacheListener(boolean checkBuddy)
+ {
+ this.checkBuddy= checkBuddy;
+ }
+
+ public void addRegionHandler(Fqn region, RegionHandler handler)
+ {
+ handlers.put(region, handler);
+ }
+
+ public boolean removeRegionHandler(Fqn region)
+ {
+ handlers.remove(region);
+ return handlers.size() > 0;
+ }
+
+ private RegionHandler getRegionHandler(OwnedItem oi)
+ {
+ return (oi == null ? null : handlers.get(oi.getRegion()));
+ }
+
+ @NodeVisited
+ public void nodeVisited(NodeVisitedEvent event)
+ {
+ if (event.isPre())
+ return;
+
+ OwnedItem oi = OwnedItem.getOwnedItem(event.getFqn(), checkBuddy);
+ RegionHandler handler = getRegionHandler(oi);
+ if (handler != null)
+ {
+ handler.nodeVisited(oi, event);
+ }
+ }
+
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent event)
+ {
+ if (event.isPre() || NodeModifiedEvent.ModificationType.REMOVE_DATA == event.getModificationType())
+ return;
+
+ OwnedItem oi = OwnedItem.getOwnedItem(event.getFqn(), checkBuddy);
+ RegionHandler handler = getRegionHandler(oi);
+ if (handler != null)
+ {
+ handler.nodeModified(oi, event);
+ }
+ }
+
+ @NodeRemoved
+ public void nodeRemoved(NodeRemovedEvent event)
+ {
+ // Here we only want pre as that's what lets us get the removed data
+ if (!event.isPre())
+ return;
+
+ OwnedItem oi = OwnedItem.getOwnedItem(event.getFqn(), checkBuddy);
+ RegionHandler handler = getRegionHandler(oi);
+ if (handler != null)
+ {
+ handler.nodeRemoved(oi, event);
+ }
+ }
+
+ @NodeActivated
+ public void nodeActivated(NodeActivatedEvent event)
+ {
+ if(event.isPre()) return;
+
+ OwnedItem oi = OwnedItem.getOwnedItem(event.getFqn(), checkBuddy);
+ RegionHandler handler = getRegionHandler(oi);
+ if (handler != null)
+ {
+ handler.nodeActivated(oi, event);
+ }
+ }
+
+ @NodePassivated
+ public void nodePassivated(NodePassivatedEvent event)
+ {
+ if(event.isPre()) return;
+
+ OwnedItem oi = OwnedItem.getOwnedItem(event.getFqn(), checkBuddy);
+ RegionHandler handler = getRegionHandler(oi);
+ if (handler != null)
+ {
+ handler.nodePassivated(oi, event);
+ }
+ }
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ContextInUseException.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ContextInUseException.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/ContextInUseException.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,56 @@
+/*
+ * 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.ejb3.cache.impl.backing.jbc2;
+
+/**
+ * Exception thrown by JBCIntegratedObjectStore if an attempt is made
+ * to passivate a bean that is currently in use.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1.1 $
+ */
+public class ContextInUseException extends RuntimeException
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 7731424431763921352L;
+
+ /**
+ * Create a new ContextInUseException.
+ *
+ */
+ public ContextInUseException()
+ {
+ super();
+ }
+
+ /**
+ * Create a new ContextInUseException.
+ *
+ * @param message
+ */
+ public ContextInUseException(String message)
+ {
+ super(message);
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStore.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,566 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, 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.ejb3.cache.impl.backing.jbc2;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.Region;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.cache.config.BuddyReplicationConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.notifications.event.NodeActivatedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodePassivatedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+import org.jboss.cache.notifications.event.NodeVisitedEvent;
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.AbstractPassivatingIntegratedObjectStore;
+import org.jboss.logging.Logger;
+import org.jboss.util.id.GUID;
+
+/**
+ * JBoss Cache-based implementation of {@link PassivatingIntegratedObjectStore}.
+ *
+ * @author Brian Stansberry
+ */
+public class JBCIntegratedObjectStore<C extends CacheItem, T extends BackingCacheEntry<C>>
+ extends AbstractPassivatingIntegratedObjectStore<C, T>
+{
+ public static final String FQN_BASE = "sfsb";
+
+ private static final String KEY = "item";
+
+ private static final ThreadLocal removedItem = new ThreadLocal();
+
+ /** Depth of fqn element where we store the id. */
+ static final int FQN_SIZE = 4; // depth of fqn that we store the session in.
+ private static final int DEFAULT_BUCKET_COUNT = 100;
+
+ private static final String[] DEFAULT_HASH_BUCKETS = new String[DEFAULT_BUCKET_COUNT];
+
+ static
+ {
+ for (int i = 0; i < DEFAULT_HASH_BUCKETS.length; i++)
+ {
+ DEFAULT_HASH_BUCKETS[i] = String.valueOf(i);
+ }
+ }
+
+ /** The underlying JBC instance */
+ private Cache<Object, T> jbc;
+
+ /** Qualifier used to scope our Fqns */
+ private final Object keyBase;
+
+ private Fqn<Object> cacheNode;
+ private Region region;
+ private ClusteredCacheListener listener;
+ private RegionHandlerImpl regionHandler;
+
+ public static long MarkInUseWaitTime = 15000;
+
+ private final ThreadLocal<Boolean> localActivity = new ThreadLocal<Boolean>();
+ private final Logger log;
+ private String[] hashBuckets = DEFAULT_HASH_BUCKETS;
+ private int createCount = 0;
+ private int passivatedCount = 0;
+ private int removeCount = 0;
+ private boolean usingBuddyRepl;
+ private boolean trackVisits;
+
+ private final ConcurrentMap<OwnedItem, Long> inMemoryItems;
+ private final ConcurrentMap<OwnedItem, Long> passivatedItems;
+
+ public JBCIntegratedObjectStore(Cache jbc,
+ CacheConfig cacheConfig,
+ Object keyBase,
+ String name,
+ boolean forGroups)
+ {
+ super(cacheConfig, name, forGroups);
+
+ assert jbc != null : "jbc is null";
+ assert keyBase != null : "keyBase is null";
+
+ this.jbc = jbc;
+ this.keyBase = keyBase;
+
+ this.log = Logger.getLogger(getClass().getName() + "." + name);
+ this.cacheNode = new Fqn<Object>(new Object[] { FQN_BASE, this.keyBase });
+ BuddyReplicationConfig brc = jbc.getConfiguration().getBuddyReplicationConfig();
+ this.usingBuddyRepl = brc != null && brc.isEnabled();
+
+ this.inMemoryItems = new ConcurrentHashMap<OwnedItem, Long>();
+ this.passivatedItems = new ConcurrentHashMap<OwnedItem, Long>();
+ }
+
+// private EvictionPolicyConfig getEvictionPolicyConfig()
+// {
+// LRUConfiguration epc = new LRUConfiguration();
+// // Override the standard policy class
+// epc.setEvictionPolicyClass(AbortableLRUPolicy.class.getName());
+// epc.setTimeToLiveSeconds((int) getIdleTimeSeconds());
+// epc.setMaxNodes(getMaxSize());
+// return epc;
+// }
+
+ public boolean isClustered()
+ {
+ return jbc.getConfiguration().getCacheMode() != Configuration.CacheMode.LOCAL;
+ }
+
+ public T get(Object key)
+ {
+ T entry = null;
+ Fqn<Object> id = getFqn(key, false);
+ Boolean active = localActivity.get();
+ try
+ {
+ localActivity.set(Boolean.TRUE);
+ // If need be, gravitate
+ if (usingBuddyRepl)
+ {
+ jbc.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+ }
+ entry = (T) jbc.get(id, KEY);
+ }
+ catch (CacheException e)
+ {
+ RuntimeException re = convertToRuntimeException(e);
+ throw re;
+ }
+ finally
+ {
+ localActivity.set(active);
+ }
+
+ if(log.isTraceEnabled())
+ {
+ log.trace("get: retrieved bean with cache id " +id.toString());
+ }
+
+ return entry;
+ }
+
+ public void insert(T entry)
+ {
+ try
+ {
+ putInCache(entry);
+ }
+ catch (CacheException e)
+ {
+ RuntimeException re = convertToRuntimeException(e);
+ throw re;
+ }
+ }
+
+ public void passivate(T entry)
+ {
+ Fqn<Object> id = getFqn(entry.getId(), false);
+ jbc.evict(id);
+ }
+
+ public T remove(Object key)
+ {
+ Fqn<Object> id = getFqn(key, false);
+ try
+ {
+ if(log.isTraceEnabled())
+ {
+ log.trace("remove: cache id " +id.toString());
+ }
+
+ if (usingBuddyRepl)
+ {
+ jbc.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+ }
+ jbc.removeNode(id);
+
+ // Hack! Our cache listener has access to the removed node's data map
+ // so it passes the removed item to us via a thread local.
+ // Otherwise we'd have to do a remove(id, KEY) followed by removeNode(id)
+ T removed = (T) removedItem.get();
+ removedItem.set(null);
+
+ ++removeCount;
+
+ return removed;
+ }
+ catch (CacheException e)
+ {
+ RuntimeException re = convertToRuntimeException(e);
+ throw re;
+ }
+ }
+
+ public void update(T entry)
+ {
+ try
+ {
+ putInCache(entry);
+ }
+ catch (CacheException e)
+ {
+ RuntimeException re = convertToRuntimeException(e);
+ throw re;
+ }
+ }
+
+ public void start()
+ {
+ region = jbc.getRegion(cacheNode, true);
+ // Try to create an eviction region per ejb
+ // BES 2008/03/12 No, let's handle passivation ourselves
+ // since JBC doesn't properly track the buddy-backup region
+// EvictionPolicyConfig epc = getEvictionPolicyConfig();
+// region.setEvictionPolicy(epc);
+
+ // JBCACHE-1136. There's no reason to have state in an inactive region
+ cleanBeanRegion();
+
+ // Transfer over the state for the region
+ region.registerContextClassLoader(Thread.currentThread().getContextClassLoader());
+ region.activate();
+
+ // register to listen for cache events
+
+ for (Object listener : jbc.getCacheListeners())
+ {
+ if (listener instanceof ClusteredCacheListener)
+ {
+ this.listener = (ClusteredCacheListener) listener;
+ break;
+ }
+ }
+ if (listener == null)
+ {
+ listener = new ClusteredCacheListener(usingBuddyRepl);
+ jbc.addCacheListener(listener);
+ }
+
+ regionHandler = new RegionHandlerImpl();
+ listener.addRegionHandler(cacheNode, regionHandler);
+
+ initializeTrackingMaps();
+
+ super.start();
+ }
+
+ private void initializeTrackingMaps()
+ {
+ // First the main tree
+ Node<Object, T> parent = jbc.getNode(cacheNode);
+ analyzeRegionContent(parent);
+
+ // Now any buddy regions
+ if (usingBuddyRepl)
+ {
+ Node<Object, T> bbRoot = jbc.getNode(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
+ if (bbRoot != null)
+ {
+ for (Node<Object, T> bbRegion : bbRoot.getChildren())
+ {
+ Node<Object, T> ourPart = bbRegion.getChild(cacheNode);
+ if (ourPart != null)
+ {
+ analyzeRegionContent(ourPart);
+ }
+ }
+ }
+ }
+
+ // Now, we know any node visits will be from users, so
+ // lets start monitoring them
+ trackVisits = true;
+ }
+
+ private void analyzeRegionContent(Node<Object, T> parent)
+ {
+ for (int i = 0; i < hashBuckets.length; i++)
+ {
+ Node<Object, T> bucket = parent.getChild(hashBuckets[i]);
+ if (bucket == null)
+ continue;
+ Set<Object> childrenNames = bucket.getChildrenNames();
+ for (Object name : childrenNames)
+ {
+ Node<Object, T> child = bucket.getChild(name);
+ if (child == null)
+ continue;
+ T entry = (T) child.get(KEY);
+ if (entry != null)
+ {
+ OwnedItem oi = OwnedItem.getOwnedItem(child.getFqn(), usingBuddyRepl);
+ if (entry.isPrePassivated())
+ {
+ jbc.evict(child.getFqn()); // we'll get a listener event for this
+ }
+ else
+ {
+ long lastUsed = (entry.getLastUsed() == 0) ? System.currentTimeMillis() : entry.getLastUsed();
+ // Use putIfAbsent so we don't overwrite listener events
+ inMemoryItems.putIfAbsent(oi, lastUsed);
+ }
+ }
+ }
+ }
+ }
+
+ public void stop()
+ {
+ // FIXME get the proper ordering vis-a-vis stopping the timeout runner
+
+ if (jbc != null)
+ {
+ // Remove the listener
+ if (listener != null && regionHandler != null && listener.removeRegionHandler(cacheNode))
+ jbc.removeCacheListener(listener);
+
+ // Remove locally. We do this to clean up the persistent store,
+ // which is not affected by the inactivateRegion call below.
+ cleanBeanRegion();
+
+ try {
+ // Remove locally. We do this to clean up the persistent store,
+ // which is not affected by the region.deactivate call below.
+ jbc.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ jbc.removeNode(cacheNode);
+ }
+ catch (CacheException e)
+ {
+ log.error("stop(): can't remove bean from the underlying distributed cache");
+ }
+
+ if (region != null)
+ {
+ region.deactivate();
+ region.unregisterContextClassLoader();
+
+ jbc.removeRegion(region.getFqn());
+ // Clear any queues
+ region.resetEvictionQueues();
+ region = null;
+ }
+ }
+
+ inMemoryItems.clear();
+ passivatedItems.clear();
+
+ super.stop();
+ }
+
+ public int getCacheSize()
+ {
+ int count = 0;
+ try
+ {
+ Set<Object> children = null;
+ for (int i = 0; i < hashBuckets.length; i++)
+ {
+ Node<Object, T> node = jbc.getRoot().getChild(new Fqn<Object>(cacheNode, hashBuckets[i]));
+ if (node != null)
+ {
+ children = node.getChildrenNames();
+ count += (children == null ? 0 : children.size());
+ }
+ }
+ count = count - passivatedCount;
+ }
+ catch (CacheException e)
+ {
+ log.error("Caught exception calculating cache size", e);
+ count = -1;
+ }
+ return count;
+ }
+
+ public int getTotalSize()
+ {
+ return inMemoryItems.size() + passivatedItems.size();
+ }
+
+ public int getCreateCount()
+ {
+ return createCount;
+ }
+
+ public int getPassivatedCount()
+ {
+ return passivatedItems.size();
+ }
+
+ public int getRemoveCount()
+ {
+ return removeCount;
+ }
+
+ public int getAvailableCount()
+ {
+ return -1;
+ }
+
+ public int getCurrentSize()
+ {
+ return inMemoryItems.size();
+ }
+
+ @Override
+ protected void runExpiration()
+ {
+ throw new UnsupportedOperationException("implement me");
+ }
+
+ @Override
+ protected void runPassivation()
+ {
+ throw new UnsupportedOperationException("implement me");
+ }
+
+ private Fqn<Object> getFqn(Object id, boolean regionRelative)
+ {
+ String beanId = id.toString();
+ int index;
+ if (id instanceof GUID)
+ {
+ index = (id.hashCode()& 0x7FFFFFFF) % hashBuckets.length;
+ }
+ else
+ {
+ index = (beanId.hashCode()& 0x7FFFFFFF) % hashBuckets.length;
+ }
+
+ if (regionRelative)
+ return new Fqn<Object>( new Object[] {hashBuckets[index], beanId} );
+ else
+ return new Fqn<Object>(cacheNode, hashBuckets[index], beanId);
+ }
+
+ /**
+ * Creates a RuntimeException, but doesn't pass CacheException as the cause
+ * as it is a type that likely doesn't exist on a client.
+ * Instead creates a RuntimeException with the original exception's
+ * stack trace.
+ */
+ private RuntimeException convertToRuntimeException(CacheException e)
+ {
+ RuntimeException re = new RuntimeException(e.getClass().getName() + " " + e.getMessage());
+ re.setStackTrace(e.getStackTrace());
+ return re;
+ }
+
+ private void cleanBeanRegion()
+ {
+ try {
+ // Remove locally.
+ jbc.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ jbc.removeNode(cacheNode);
+ }
+ catch (CacheException e)
+ {
+ log.error("Can't clean region " + cacheNode + " in the underlying distributed cache", e);
+ }
+ }
+
+ private void putInCache(T entry)
+ {
+ Boolean active = localActivity.get();
+ try
+ {
+ localActivity.set(Boolean.TRUE);
+ jbc.put(getFqn(entry.getId(), false), KEY, entry);
+ }
+ finally
+ {
+ localActivity.set(active);
+ }
+ }
+
+ /**
+ * A CacheListener that allows us to get notifications of passivations and
+ * activations and thus notify the cached StatefulBeanContext.
+ */
+ public class RegionHandlerImpl implements ClusteredCacheListener.RegionHandler
+ {
+ public void nodeVisited(OwnedItem oi, NodeVisitedEvent event)
+ {
+ if (trackVisits)
+ inMemoryItems.put(oi, System.currentTimeMillis());
+ }
+
+ public void nodeModified(OwnedItem oi, NodeModifiedEvent event)
+ {
+ T entry = (T) event.getData().get(KEY);
+ if (entry != null)
+ {
+ long lastUsed = entry.getLastUsed();
+ lastUsed = (lastUsed == 0 ? System.currentTimeMillis() : lastUsed);
+ inMemoryItems.put(oi, lastUsed);
+ }
+ }
+
+ public void nodeRemoved(OwnedItem oi, NodeRemovedEvent event)
+ {
+ inMemoryItems.remove(oi);
+ passivatedItems.remove(oi);
+
+ // Hack! We have access to the data map here; so pass the removed
+ // item to our remove() method via a thread local
+ removedItem.set(event.getData().get(KEY));
+ }
+
+ public void nodeActivated(OwnedItem oi, NodeActivatedEvent event)
+ {
+ T entry = (T) event.getData().get(KEY);
+ if (entry != null)
+ {
+ long lastUsed = entry.getLastUsed();
+ lastUsed = (lastUsed == 0 ? System.currentTimeMillis() : lastUsed);
+ inMemoryItems.put(oi, lastUsed);
+ passivatedItems.remove(oi);
+ }
+ }
+
+ public void nodePassivated(OwnedItem oi, NodePassivatedEvent event)
+ {
+ T entry = (T) event.getData().get(KEY);
+ if (entry != null)
+ {
+ long lastUsed = entry.getLastUsed();
+ lastUsed = (lastUsed == 0 ? System.currentTimeMillis() : lastUsed);
+ passivatedItems.put(oi, lastUsed);
+ inMemoryItems.remove(oi);
+ }
+ }
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStoreSource.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/JBCIntegratedObjectStoreSource.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, 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.ejb3.cache.impl.backing.jbc2;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheManager;
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.SynchronizationCoordinator;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * {@link IntegratedObjectStoreSource} that provides instances of
+ * {@link JBCIntegratedObjectStore}.
+ *
+ * @author Brian Stansberry
+ */
+public class JBCIntegratedObjectStoreSource<T extends CacheItem>
+ implements IntegratedObjectStoreSource<T>
+{
+ private CacheManager cacheManager;
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> createGroupIntegratedObjectStore(String containerName,
+ String cacheConfigName, CacheConfig cacheConfig, TransactionManager transactionManager, SynchronizationCoordinator synchronizationCoordinator)
+ {
+ Cache<Object, Object> jbc = getJBossCache(cacheConfigName);
+
+ String keyBaseSuffix = (containerName == null || containerName.length() == 0) ? "" : "-" + containerName;
+ String keyBase = "GroupCache" + keyBaseSuffix;
+ return new JBCIntegratedObjectStore<T, SerializationGroupImpl<T>>(jbc, cacheConfig, keyBase, keyBase, true);
+ }
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>> createIntegratedObjectStore(String containerName, String cacheConfigName,
+ CacheConfig cacheConfig, TransactionManager transactionManager, SynchronizationCoordinator synchronizationCoordinator)
+ {
+ Cache<Object, Object> jbc = getJBossCache(cacheConfigName);
+
+ return new JBCIntegratedObjectStore<T, SerializationGroupMember<T>>(jbc, cacheConfig, containerName, containerName, false);
+ }
+
+ public CacheManager getCacheManager()
+ {
+ return cacheManager;
+ }
+
+ public void setCacheManager(CacheManager cacheManager)
+ {
+ this.cacheManager = cacheManager;
+ }
+
+ private Cache<Object, Object> getJBossCache(String cacheConfigName)
+ {
+ if (cacheManager == null)
+ throw new IllegalStateException("CacheManager not installed");
+
+ try
+ {
+ return cacheManager.getCache(cacheConfigName, true);
+ }
+ catch (RuntimeException re)
+ {
+ throw re;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Unable to get cache " + cacheConfigName, e);
+ }
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/OwnedItem.java
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/OwnedItem.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/main/java/org/jboss/ejb3/cache/impl/backing/jbc2/OwnedItem.java 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, 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.ejb3.cache.impl.backing.jbc2;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import org.jboss.ejb3.cache.CacheItem;
+
+/**
+ * Encapsulates the identifier for a {@link CacheItem} as well as information
+ * about what node logical "owns" it.
+ *
+ * @author Brian Stansberry
+ */
+public class OwnedItem
+{
+ private static final int FQN_SIZE = JBCIntegratedObjectStore.FQN_SIZE;
+ private static final int KEY_INDEX = FQN_SIZE - 1;
+ private static final int OWNER_INDEX = 1;
+ private static final int BR_FQN_SIZE = FQN_SIZE + OWNER_INDEX + 1;
+ private static final int BR_KEY_INDEX = BR_FQN_SIZE - 1;
+
+ private final String owner;
+ private final Object id;
+ private final Fqn region;
+
+ /**
+ * Generates an OwnedItem from the given Fqn if the Fqn is a logical
+ * child of <code>base</code>
+ *
+ * @param fqn the Fqn
+ * @param base the base Fqn
+ * @param checkBuddy <code>true</code> if it is possible that <code>fqn</code>
+ * belongs to a {@link BuddyManager#BUDDY_BACKUP_SUBTREE_FQN buddy-backup subtree}
+ *
+ * @return an OwnedItem or <code>null</code> if <code>fqn</code> is not a
+ * logical child of <code>base</code>
+ */
+ @SuppressWarnings("unchecked")
+ public static OwnedItem getOwnedItem(Fqn fqn, boolean checkBuddy)
+ {
+ int size = fqn.size();
+ if (size < FQN_SIZE)
+ return null;
+
+ String owner = null;
+ Object key = null;
+ Fqn region = null;
+
+ boolean buddy = checkBuddy && fqn.get(0).equals(BuddyManager.BUDDY_BACKUP_SUBTREE);
+ if (buddy)
+ {
+ if (size == BR_FQN_SIZE)
+ {
+ key = fqn.get(BR_KEY_INDEX);
+ owner = (String) fqn.get(OWNER_INDEX);
+ region = fqn.getSubFqn(OWNER_INDEX, BR_KEY_INDEX);
+ }
+ }
+ else if (size == FQN_SIZE)
+ {
+ region = fqn.getParent();
+ key = fqn.get(KEY_INDEX);
+ }
+
+ return (key == null ? null : new OwnedItem(owner, key, region));
+ }
+
+ public OwnedItem(String owner, Object id, Fqn region)
+ {
+ assert id != null : "id is null";
+ assert region != null : "region is null";
+
+ this.owner = owner;
+ this.id = id;
+ this.region = region;
+ }
+
+ /**
+ * Gets the logical "owner" of the item. A value of <code>null</code>
+ * means either there is no logical owner or this process is the owner.
+ * (Basically it means the item is stored in the main area of a JBoss CAche
+ * tree, not in a named buddy-backup region.)
+ *
+ * @return
+ */
+ public String getOwner()
+ {
+ return owner;
+ }
+
+ /**
+ * Gets the item's unique identifier.
+ */
+ public Object getId()
+ {
+ return id;
+ }
+
+ /**
+ * Gets the base Fqn for the region where the item is cached.
+ */
+ public Fqn getRegion()
+ {
+ return region;
+ }
+
+ public Fqn getFullFqn()
+ {
+ if (owner != null)
+ {
+ Fqn ownerFqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, owner);
+ Fqn base = new Fqn(ownerFqn, region);
+ return new Fqn(base, id);
+ }
+ else
+ {
+ return new Fqn(region, id);
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ if (obj instanceof OwnedItem)
+ {
+ OwnedItem other = (OwnedItem) obj;
+ return (id.equals(other.id) && safeEquals(owner, other.owner));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 17;
+ result += 31 * id.hashCode();
+ result += 31 * (owner == null ? 0 : owner.hashCode());
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return new StringBuilder(getClass().getName())
+ .append("[id=")
+ .append(id)
+ .append(",owner=")
+ .append(owner)
+ .append(",region=")
+ .append(region)
+ .append("]")
+ .toString();
+ }
+
+ private static boolean safeEquals(Object a, Object b)
+ {
+ return (a == b || (a != null && a.equals(b)));
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/resources/log4j.xml
===================================================================
--- projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/resources/log4j.xml (rev 0)
+++ projects/ejb3/branches/cluster-dev/cache-jbc2/src/test/resources/log4j.xml 2008-03-13 03:27:01 UTC (rev 70798)
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- Log4j Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 65339 2007-09-12 16:21:48Z wolfc $ -->
+
+<!--
+ | For more configuration infromation and examples see the Jakarta Log4j
+ | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+ <!-- ================================= -->
+ <!-- Preserve messages in a local file -->
+ <!-- ================================= -->
+
+ <!-- A time/date based rolling appender -->
+ <appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
+ <param name="File" value="target/test.log"/>
+ <param name="Append" value="false"/>
+
+ <!-- Rollover at midnight each day -->
+ <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+ <!-- Rollover at the top of each hour
+ <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
+ -->
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+
+ <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
+ <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+ -->
+ </layout>
+ </appender>
+
+ <!-- A size based file rolling appender
+ <appender name="FILE" class="org.jboss.logging.appender.RollingFileAppender">
+ <param name="File" value="${jboss.server.home.dir}/log/server.log"/>
+ <param name="Append" value="false"/>
+ <param name="MaxFileSize" value="500KB"/>
+ <param name="MaxBackupIndex" value="1"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
+ </layout>
+ </appender>
+ -->
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <!--param name="Threshold" value="FATAL"/-->
+ <param name="Target" value="System.out"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!-- The default pattern: Date Priority [Category] Message\n -->
+ <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+ </layout>
+ </appender>
+
+
+ <!-- ====================== -->
+ <!-- More Appender examples -->
+ <!-- ====================== -->
+
+ <!-- Buffer events and log them asynchronously
+ <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
+ <appender-ref ref="FILE"/>
+ <appender-ref ref="CONSOLE"/>
+ </appender>
+ -->
+
+ <!-- EMail events to an administrator
+ <appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
+ <param name="Threshold" value="ERROR"/>
+ <param name="To" value="admin at myhost.domain.com"/>
+ <param name="From" value="nobody at myhost.domain.com"/>
+ <param name="Subject" value="JBoss Sever Errors"/>
+ <param name="SMTPHost" value="localhost"/>
+ <param name="BufferSize" value="10"/>
+ </appender>
+ -->
+
+ <!-- Syslog events
+ <appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
+ <param name="Facility" value="LOCAL7"/>
+ <param name="FacilityPrinting" value="true"/>
+ <param name="SyslogHost" value="localhost"/>
+ </appender>
+ -->
+
+ <!-- Log events to JMS (requires a topic to be created)
+ <appender name="JMS" class="org.apache.log4j.net.JMSAppender">
+ <param name="Threshold" value="ERROR"/>
+ <param name="TopicConnectionFactoryBindingName" value="java:/ConnectionFactory"/>
+ <param name="TopicBindingName" value="topic/MyErrorsTopic"/>
+ </appender>
+ -->
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <!-- Limit JBoss categories to INFO -->
+ <category name="org.jboss">
+ <priority value="INFO" class="org.jboss.logging.XLevel"/>
+ </category>
+
+ <!-- Increase the priority threshold for the DefaultDS category
+ <category name="DefaultDS">
+ <priority value="FATAL"/>
+ </category>
+ -->
+
+ <!-- Decrease the priority threshold for the org.jboss.varia category
+ <category name="org.jboss.varia">
+ <priority value="DEBUG"/>
+ </category>
+ -->
+
+ <!--
+ | An example of enabling the custom TRACE level priority that is used
+ | by the JBoss internals to diagnose low level details. This example
+ | turns on TRACE level msgs for the org.jboss.ejb.plugins package and its
+ | subpackages. This will produce A LOT of logging output.
+ <category name="org.jboss.system">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+ -->
+
+ <category name="org.jboss.security">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+
+ <category name="org.jboss.tm">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+
+ <category name="org.jboss.ejb3">
+ <priority value="TRACE" class="org.jboss.logging.XLevel"/>
+ </category>
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="FILE"/>
+ </root>
+
+</log4j:configuration>
More information about the jboss-cvs-commits
mailing list