r1906 - trunk/topia-persistence/src/main/java/org/nuiton/topia/framework
Author: fdesbois Date: 2010-04-21 18:01:01 +0200 (Wed, 21 Apr 2010) New Revision: 1906 Log: Ano #546 : - getChildContext() is used to make a thread-safe copy of the childContext set. This method need to be used when iteration is needed on childContext (no local copy is needed anymore). - Use Collections methods to avoid warning on childContext instantiation Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-04-20 13:08:06 UTC (rev 1905) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-04-21 16:01:01 UTC (rev 1906) @@ -25,7 +25,6 @@ package org.nuiton.topia.framework; -import org.apache.commons.collections.set.MapBackedSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.topia.TopiaContext; @@ -83,9 +82,11 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -93,7 +94,6 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.zip.GZIPInputStream; -import org.apache.commons.collections.set.SynchronizedSet; import org.nuiton.topia.persistence.TopiaDAOImpl; import static org.nuiton.i18n.I18n._; @@ -162,13 +162,22 @@ * cache des DAO deja chargé pour ce context */ protected Map<Class<? extends TopiaEntity>, TopiaDAO<? extends TopiaEntity>> daoCache = new HashMap<Class<? extends TopiaEntity>, TopiaDAO<? extends TopiaEntity>>(); + /** - * Set des sous context creer avec un beginTransaction et donc sur lequel - * nous sommes listener + * Set of child context created with {@link #beginTransaction()}. We are + * listener on these context. + * A WeakHashMap is used to remove old context automically when it's not + * used anymore. The {@link #finalize} method will be executed when Garbage + * collector is called when reference is removed. + * The set is synchronized in case of using multi-threading. + * @see Collections#synchronizedSet(Set) + * @see Collections#newSetFromMap(Map) */ - // by sletellier 24/09/09 : Fix concurent acces error -// protected Set<TopiaContextImplementor> childContext = MapBackedSet.decorate(new WeakHashMap<TopiaContextImplementor, Object>()); - protected Set<TopiaContextImplementor> childContext = SynchronizedSet.decorate(MapBackedSet.decorate(new WeakHashMap<TopiaContextImplementor, Object>())); + protected final Set<TopiaContextImplementor> childContext = + Collections.synchronizedSet( + Collections.newSetFromMap( + new WeakHashMap<TopiaContextImplementor, Boolean>())); + /** key: service name; value: service instance */ protected Map<String, TopiaService> services; /** */ @@ -326,7 +335,14 @@ @Override public Set<TopiaContextImplementor> getChildContext() { - return childContext; + // FD-20100421 : Ano #546 + // Copy the childContext into a new set + final Set<TopiaContextImplementor> values; + // Synchronize copy to be thread-safe during iteration + synchronized (childContext) { + values = new HashSet<TopiaContextImplementor>(childContext); + } + return values; } protected void addChildContext(TopiaContextImplementor child) { @@ -707,26 +723,22 @@ @Override public void closeContext() throws TopiaException { - // 20060926 poussin: Si si on peut, ca ferme en fait tous les enfants et c tout - // if (getRootContext() == this) { - // throw new TopiaException( - // "Vous ne pouvez pas fermer le root context"); - // } + // Throw exception if context is already closed checkClosed(_("topia.persistence.error.context.already.closed")); -// checkClosed("Ce contexte a deja ete ferme"); - // suppression des contexts fils - TopiaContextImplementor[] childs = childContext.toArray(new TopiaContextImplementor[childContext.size()]); - for (TopiaContextImplementor child : childs) { + // FD-20100421 : Ano #546 : no need to copy childContext, the + // {@link #getChildContext()} provides a thread-safe copy to iterate + // on it. +// TopiaContextImplementor[] children = childContext.toArray( +// new TopiaContextImplementor[childContext.size()]); + + // Remove all children context + for (TopiaContextImplementor child : getChildContext()) { + // Avoid to have exception from checkClosed method on child if (!child.isClosed()) { child.closeContext(); } } - // for (Iterator iter = childContext.iterator(); iter.hasNext();) { - // TopiaContextImplementor child = (TopiaContextImplementor) iter.next(); - // child.closeContext(); - // iter.remove(); - // } // on se desenregistre du context pere et on ferme les connexions si // on est pas le root context Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java 2010-04-20 13:08:06 UTC (rev 1905) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java 2010-04-21 16:01:01 UTC (rev 1906) @@ -58,6 +58,8 @@ public interface TopiaContextImplementor extends TopiaContext { /** + * Retrieve a thread-safe copy of children context set. + * * @return Returns the childContext. */ Set<TopiaContextImplementor> getChildContext(); Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java 2010-04-20 13:08:06 UTC (rev 1905) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java 2010-04-21 16:01:01 UTC (rev 1906) @@ -531,11 +531,12 @@ protected TopiaContextImplementor getContext( TopiaContextImplementor parent, Session hibernate) { TopiaContextImplementor result = null; - // on copie la liste pour evite les acces concurrent (parcours durant la - // creation d'un sous context) - Set<TopiaContextImplementor> contextChilds = new HashSet<TopiaContextImplementor>(parent.getChildContext()); - for (TopiaContextImplementor context : contextChilds) { + // FD-20100421 : Ano #546 : no need to copy childContext, the + // {@link #getChildContext()} provides a thread-safe copy to iterate + // on it. +// Set<TopiaContextImplementor> contextChilds = new HashSet<TopiaContextImplementor>(parent.getChildContext()); + for (TopiaContextImplementor context : parent.getChildContext()) { // by sletellier 24/09/09 : Fix concurent acces error // ArrayList<TopiaContextImplementor> children = new ArrayList(parent.getChildContext());
participants (1)
-
fdesbois@users.nuiton.org