You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2012/09/29 18:55:50 UTC
git commit: DELTASPIKE-274 atomic contextual instance creation
Updated Branches:
refs/heads/master b45b2daa9 -> b29dab065
DELTASPIKE-274 atomic contextual instance creation
Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/b29dab06
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/b29dab06
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/b29dab06
Branch: refs/heads/master
Commit: b29dab06520a12cd6cc382df01d79234b406008e
Parents: b45b2da
Author: Mark Struberg <st...@apache.org>
Authored: Sat Sep 29 18:54:35 2012 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Sat Sep 29 18:54:35 2012 +0200
----------------------------------------------------------------------
.../core/util/context/AbstractContext.java | 67 +++++++++++----
.../core/util/context/ContextualInstanceInfo.java | 21 +++--
.../core/util/context/ContextualStorage.java | 66 ++++++++++++++
3 files changed, 132 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b29dab06/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java
index 7d65d44..7a02cf5 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java
@@ -19,10 +19,10 @@
package org.apache.deltaspike.core.util.context;
+import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.BeanManager;
import java.lang.annotation.Annotation;
import java.util.Map;
@@ -32,19 +32,13 @@ import java.util.Map;
public abstract class AbstractContext implements Context
{
/**
- * We need the BeanManager for serialisation and some checks.
- */
- protected BeanManager beanManager;
-
- /**
* The Scope the Context handles
*/
protected Class<? extends Annotation> scope;
- protected AbstractContext(BeanManager beanManager, Class<? extends Annotation> scope, boolean concurrent)
+ protected AbstractContext(Class<? extends Annotation> scope)
{
- this.beanManager = beanManager;
this.scope = scope;
}
@@ -53,7 +47,7 @@ public abstract class AbstractContext implements Context
* contains the items held in the Context.
* @return the underlying storage
*/
- protected abstract ContextualStorage getContextStorage();
+ protected abstract ContextualStorage getContextualStorage();
@Override
@@ -64,15 +58,48 @@ public abstract class AbstractContext implements Context
@Override
- public <T> T get(Contextual<T> component)
+ public <T> T get(Contextual<T> bean)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ checkActive();
+
+ if (getContextualStorage() == null)
+ {
+ return null;
+ }
+
+ Map<Contextual<?>, ContextualInstanceInfo<?>> contextMap = getContextualStorage().getStorage();
+ ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(bean);
+ if (contextualInstanceInfo == null)
+ {
+ return null;
+ }
+
+ return (T) contextualInstanceInfo.getContextualInstance();
}
@Override
- public <T> T get(Contextual<T> component, CreationalContext<T> creationalContext)
+ public <T> T get(Contextual<T> bean, CreationalContext<T> creationalContext)
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ checkActive();
+
+ ContextualStorage storage = getContextualStorage();
+
+ Map<Contextual<?>, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+ ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(bean);
+
+ T instance = null;
+
+ if (contextualInstanceInfo != null)
+ {
+ instance = (T) contextualInstanceInfo.getContextualInstance();
+ }
+
+ if (instance != null)
+ {
+ return instance;
+ }
+
+ return storage.createContextualInstance(bean, creationalContext);
}
/**
@@ -82,7 +109,7 @@ public abstract class AbstractContext implements Context
*/
public boolean destroy(Contextual bean)
{
- ContextualInstanceInfo<?> contextualInstanceInfo = getContextStorage().getStorage().get(bean);
+ ContextualInstanceInfo<?> contextualInstanceInfo = getContextualStorage().getStorage().get(bean);
if (contextualInstanceInfo == null)
{
@@ -99,15 +126,23 @@ public abstract class AbstractContext implements Context
*/
public void destroyAll()
{
- Map<Contextual<?>, ContextualInstanceInfo<?>> storage = getContextStorage().getStorage();
+ Map<Contextual<?>, ContextualInstanceInfo<?>> storage = getContextualStorage().getStorage();
for (Map.Entry<Contextual<?>, ContextualInstanceInfo<?>> entry : storage.entrySet())
{
Contextual bean = entry.getKey();
ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
bean.destroy(contextualInstanceInfo.getContextualInstance(), contextualInstanceInfo.getCreationalContext());
}
+ }
-
+ protected void checkActive()
+ {
+ if (!isActive())
+ {
+ throw new ContextNotActiveException("CDI context with scope annotation @"
+ + scope.getName() + " is not active with respect to the current thread");
+ }
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b29dab06/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java
index 34188c4..090cf2b 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java
@@ -42,12 +42,6 @@ public class ContextualInstanceInfo<T> implements Serializable
- public ContextualInstanceInfo(CreationalContext<T> creationalContext, T contextualInstance)
- {
- this.contextualInstance = contextualInstance;
- this.creationalContext = creationalContext;
- }
-
/**
* @return the CreationalContext of the bean
*/
@@ -57,6 +51,14 @@ public class ContextualInstanceInfo<T> implements Serializable
}
/**
+ * @param creationalContext the CreationalContext of the bean
+ */
+ public void setCreationalContext(CreationalContext<T> creationalContext)
+ {
+ this.creationalContext = creationalContext;
+ }
+
+ /**
* @return the contextual instance itself
*/
public T getContextualInstance()
@@ -64,6 +66,13 @@ public class ContextualInstanceInfo<T> implements Serializable
return contextualInstance;
}
+ /**
+ * @param contextualInstance the contextual instance itself
+ */
+ public void setContextualInstance(T contextualInstance)
+ {
+ this.contextualInstance = contextualInstance;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/b29dab06/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java
index a155f24..3a03fce 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java
@@ -21,6 +21,7 @@ package org.apache.deltaspike.core.util.context;
import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.PassivationCapable;
import java.io.IOException;
@@ -48,6 +49,10 @@ public class ContextualStorage implements Serializable
private boolean concurrent;
+ /**
+ * @param beanManager is needed for serialisation
+ * @param concurrent whether the ContextualStorage might get accessed concurrently by different threads
+ */
public ContextualStorage(BeanManager beanManager, boolean concurrent)
{
this.beanManager = beanManager;
@@ -62,12 +67,23 @@ public class ContextualStorage implements Serializable
}
}
+ /**
+ * @return the underlying storage map.
+ */
public Map<Contextual<?>, ContextualInstanceInfo<?>> getStorage()
{
return contextualInstances;
}
/**
+ * Whether the ContextualStorage might get accessed concurrently by different threads
+ */
+ public boolean isConcurrent()
+ {
+ return concurrent;
+ }
+
+ /**
* Write the whole map to the stream.
* The beans will be stored via it's passivationId as it is
* not guaranteed that a Bean is Serializable in CDI-1.0.
@@ -137,4 +153,54 @@ public class ContextualStorage implements Serializable
}
}
+ /**
+ *
+ * @param bean
+ * @param creationalContext
+ * @param <T>
+ * @return
+ */
+ public <T> T createContextualInstance(Contextual<T> bean, CreationalContext<T> creationalContext)
+ {
+ if (isConcurrent())
+ {
+ // locked approach
+ ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
+
+ ConcurrentHashMap<Contextual<?>, ContextualInstanceInfo<?>> concurrentMap
+ = (ConcurrentHashMap<Contextual<?>, ContextualInstanceInfo<?>>) contextualInstances;
+
+ ContextualInstanceInfo<T> oldInstanceInfo
+ = (ContextualInstanceInfo<T>) concurrentMap.putIfAbsent(bean, instanceInfo);
+
+ if (oldInstanceInfo != null)
+ {
+ instanceInfo = oldInstanceInfo;
+ }
+ synchronized (instanceInfo)
+ {
+ T instance = instanceInfo.getContextualInstance();
+ if (instance == null)
+ {
+ instance = bean.create(creationalContext);
+ instanceInfo.setContextualInstance(instance);
+ instanceInfo.setCreationalContext(creationalContext);
+ }
+
+ return instance;
+ }
+
+ }
+ else
+ {
+ // simply create the contextual instance
+ ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
+ instanceInfo.setCreationalContext(creationalContext);
+ instanceInfo.setContextualInstance(bean.create(creationalContext));
+
+ contextualInstances.put(bean, instanceInfo);
+
+ return instanceInfo.getContextualInstance();
+ }
+ }
}