Author: fdesbois Date: 2010-05-08 20:46:01 +0200 (Sat, 08 May 2010) New Revision: 1941 Url: http://nuiton.org/repositories/revision/topia/1941 Log: Add test for TopiaContextFactory, optimize also some code Added: trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java 2010-05-08 16:05:12 UTC (rev 1940) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java 2010-05-08 18:46:01 UTC (rev 1941) @@ -25,20 +25,23 @@ package org.nuiton.topia; +import org.apache.commons.collections.map.AbstractReferenceMap; +import org.apache.commons.collections.map.ReferenceMap; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.TopiaUtil; + import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; -import java.util.Map.Entry; -import org.apache.commons.collections.map.AbstractReferenceMap; -import org.apache.commons.collections.map.ReferenceMap; -import org.nuiton.topia.framework.TopiaContextImpl; -import org.nuiton.topia.framework.TopiaUtil; - /** * TODO-FD20100507 : Need javadoc + translate the one on methods. - * + * <p/> * Created: 3 janv. 2006 21:19:37 * * @author poussin <poussin@codelutin.com> @@ -47,24 +50,27 @@ */ public class TopiaContextFactory { - static final private String DEFAULT_CONFIG_PROPERTIES = + private static final Log log = LogFactory.getLog(TopiaContextFactory.class); + + private static final String DEFAULT_CONFIG_PROPERTIES = "TopiaContextImpl.properties"; - /** - * Cache contenant tous les contexts deja créé. - */ - static protected Map<Properties, TopiaContextImpl> contextCache = + /** Cache contenant tous les contexts deja créé. */ + protected static Map<Properties, TopiaContextImpl> contextCache = new ReferenceMap(AbstractReferenceMap.HARD, - AbstractReferenceMap.SOFT); + AbstractReferenceMap.SOFT); /** - * Permet de connaitre la liste des contexts encore en memoire, utile - * pour du debuggage + * Permet de connaitre la liste des contexts encore en memoire, utile pour + * du debuggage. + * * @return la liste des urls de connexion */ - static public List<String> getContextOpened() { + public static List<String> getContextOpened() { List<String> result = new ArrayList<String>(); for (Entry<Properties, TopiaContextImpl> e : contextCache.entrySet()) { + // Useless test : will never happened that e.getValue() is null, + // not allowed for {@link AbstractReferenceMap#SOFT}. if (e.getValue() != null) { result.add(e.getKey().getProperty("hibernate.connection.url")); } @@ -77,27 +83,40 @@ * * @param context closed */ - static public void removeContext(TopiaContext context) { - Properties key = null; - for (Entry<Properties, TopiaContextImpl> e : contextCache.entrySet()) { - if (e.getValue() == context) { - key = e.getKey(); - break; + public static void removeContext(TopiaContext context) { +// Properties key = null; +// for (Entry<Properties, TopiaContextImpl> e : contextCache.entrySet()) { +// if (e.getValue() == context) { +// key = e.getKey(); +// break; +// } +// } +// if (key != null) { +// contextCache.remove(key); +// } + + // Replaced by more powerful algorithm using iterator to remove context + + Iterator<TopiaContextImpl> it = contextCache.values().iterator(); + + boolean removed = false; + while (it.hasNext() && !removed) { + TopiaContextImpl curr = it.next(); + if (curr == context) { + it.remove(); + removed = true; } } - if (key != null) { - contextCache.remove(key); - } } /** * Utilise par defaut le fichier de propriete TopiaContextImpl.properties - * + * * @return the context using the default configuration file * @throws TopiaNotFoundException Si le fichier de configuration par defaut - * n'est pas retrouvé. + * n'est pas retrouvé. */ - static public TopiaContext getContext() throws TopiaNotFoundException { + public static TopiaContext getContext() throws TopiaNotFoundException { Properties config = TopiaUtil.getProperties(DEFAULT_CONFIG_PROPERTIES); TopiaContext result = getContext(config); return result; @@ -108,12 +127,12 @@ * fois le meme objet config, on obtient la meme instance de * TopiaContextImpl. Si le context qui devrait etre retourné est ferme, * alors un nouveau est creer et retourné. - * + * * @param config the configuration of the context * @return Un TopiaContext ouvert * @throws TopiaNotFoundException if any pb */ - static public TopiaContext getContext(Properties config) + public static TopiaContext getContext(Properties config) throws TopiaNotFoundException { // Put all properties from a hierarchy in the current properties object. // Resolve problem with hibernate which used iterator to get properties @@ -123,9 +142,15 @@ config.setProperty(key, config.getProperty(key)); } TopiaContextImpl result = contextCache.get(config); - if (result == null || result.isClosed()) { + // useless test, context is automatically removed from Factory when closed + if (result == null/* || result.isClosed()*/) { result = new TopiaContextImpl(config); + if (log.isDebugEnabled()) { + log.debug("instantiate new topiaContext : " + result); + } contextCache.put((Properties) config.clone(), result); + } else if (log.isDebugEnabled()) { + log.debug("topiaContext found : " + result); } return result; } 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-05-08 16:05:12 UTC (rev 1940) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-05-08 18:46:01 UTC (rev 1941) @@ -813,7 +813,7 @@ hibernateFactory.close(); closed = true; TopiaContextFactory.removeContext(this); - log.debug("TopiaContext finalized"); + log.debug("TopiaContext removed"); } } } Added: trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java (rev 0) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java 2010-05-08 18:46:01 UTC (rev 1941) @@ -0,0 +1,156 @@ +package org.nuiton.topia; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.nuiton.topia.framework.TopiaContextImpl; + +import java.util.List; +import java.util.Properties; + +/** + * Created: 8 mai 2010 + * + * @author fdesbois <fdesbois@codelutin.com> + * @version $Id$ + */ +public class TopiaContextFactoryTest { + + private static final Log log = + LogFactory.getLog(TopiaContextFactoryTest.class); + + protected Properties properties; + + @Before + public void setUp() throws Exception { + properties = new Properties(); + properties.setProperty("prop1", "value1"); + properties.setProperty("prop2", "value2"); + TopiaContextFactory.contextCache.clear(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetContextOpened() throws Exception { + log.info("## testGetContextOpened"); + + /** PREPARE DATA **/ + String databaseName = "h2data-testGetContextByPropertie"; + String url = "jdbc:h2:file:target/surefire-data/" + databaseName; + properties.setProperty("hibernate.connection.url", url); + + TopiaContextImpl test = new TopiaContextImpl(properties); + TopiaContextFactory.contextCache.put(properties, test); + + /** EXEC METHOD **/ + List<String> result = TopiaContextFactory.getContextOpened(); + Assert.assertEquals(1, result.size()); + Assert.assertEquals(url, result.get(0)); + } + + @Test + public void testRemoveContext() throws Exception { + log.info("## testRemoveContext"); + + /** PREPARE DATA **/ + TopiaContextImpl test = new TopiaContextImpl(properties); + TopiaContextFactory.contextCache.put(properties, test); + + /** EXEC METHOD **/ + TopiaContextFactory.removeContext(test); + Assert.assertEquals(0, TopiaContextFactory.contextCache.size()); + } + + //@Test + public void testGetContext() throws Exception { + // TODO-fdesbois-20100508 : only used TopiaUtil.getProperties, need tests for this method + } + + @Test + public void testGetContextByProperties() throws Exception { + log.info("## testGetContextByProperties"); + + /** PREPARE DATA **/ + Properties propertiesParent = new Properties(properties); + propertiesParent.setProperty("prop3", "value3"); + + Properties propertiesAll = new Properties(); + propertiesAll.setProperty("prop1", "value1"); + propertiesAll.setProperty("prop2", "value2"); + propertiesAll.setProperty("prop3", "value3"); + + /** EXEC METHOD **/ + + log.info("test 0 : add null properties"); + try { + TopiaContextFactory.getContext(null); + } catch (Exception eee) { + Assert.assertEquals(NullPointerException.class, eee.getClass()); + } + + log.info("test 1 : add new properties, will instantiate a new" + + " TopiaContext"); + TopiaContext test1 = TopiaContextFactory.getContext(propertiesParent); + Assert.assertNotNull(test1); + Assert.assertEquals(1, TopiaContextFactory.contextCache.size()); + + log.info("test 2 : with same properties, will retrieve existing" + + " TopiaContext"); + TopiaContext test2 = TopiaContextFactory.getContext(propertiesParent); + Assert.assertEquals(test1, test2); + Assert.assertEquals(1, TopiaContextFactory.contextCache.size()); + + log.info("test 3 : use other properties, will instantiate a different" + + "TopiaContext"); + TopiaContext test3 = TopiaContextFactory.getContext(properties); + log.debug("cache size : " + TopiaContextFactory.contextCache.size()); + log.debug("result : " + test1); + log.debug("result3 : " + test3); + Assert.assertNotSame(test1, test3); + Assert.assertEquals(2, TopiaContextFactory.contextCache.size()); + + log.info("test 4 : use other properties but equivalent to existing " + + "TopiaContext"); + // Test flating of properties + TopiaContext test4 = TopiaContextFactory.getContext(propertiesAll); + Assert.assertEquals(test1, test4); + Assert.assertEquals(2, TopiaContextFactory.contextCache.size()); + + log.info("test5a : reinstantiate new TopiaContext after one is closed."); + // TEST + // Strange behavior the closed flag of context stay true if + // hibernateFactory is not loaded from real properties +// test1.closeContext(); +// Assert.assertTrue(test1.isClosed()); + + // Add properties for Hibernate to have real opened topiaContext + String databaseName = "h2data-testGetContextByPropertie"; + properties.setProperty("hibernate.connection.username", "sa"); + properties.setProperty("hibernate.connection.password", ""); + properties.setProperty("hibernate.connection.driver_class", "org.h2.Driver"); + properties.setProperty("hibernate.connection.url", + "jdbc:h2:file:target/surefire-data/" + databaseName); + + + TopiaContext test5 = TopiaContextFactory.getContext(properties); + Assert.assertNotSame(test1, test5); + Assert.assertEquals(3, TopiaContextFactory.contextCache.size()); + + log.info("test5b : beginTransaction to properly close the context"); + test5.beginTransaction(); + + test5.closeContext(); + + TopiaContext result = TopiaContextFactory.getContext(properties); + Assert.assertNotSame(test5, result); + Assert.assertEquals(3, TopiaContextFactory.contextCache.size()); + + + } +} Property changes on: trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL