Author: fdesbois Date: 2010-05-10 18:40:22 +0200 (Mon, 10 May 2010) New Revision: 1951 Url: http://nuiton.org/repositories/revision/topia/1951 Log: - TopiaContextImplTest : All tests done for Services - Clean javadocs + improve some errors managment Added: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/package-info.java Removed: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TestService.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 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/resources/i18n/topia-persistence-fr_FR.properties trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2010-05-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -108,12 +108,13 @@ Class<E> interfaceService); /** - * Return the service. + * Return the service. This service must be valid with public static final + * SERVICE_NAME property. * * @param <E> type of service - * @param interfaceService fqn of the service + * @param interfaceService class of the service * @return the service - * @throws TopiaNotFoundException if service is can't be retrieved + * @throws TopiaNotFoundException if service can't be retrieved */ <E extends TopiaService> E getService(Class<E> interfaceService) throws TopiaNotFoundException; @@ -167,10 +168,21 @@ * @param topiaId l'id de l'entite recherche * @return l'entite trouvee (ou null si non trouve) * @throws TopiaException if any exception + * @deprecated since 2.4, use {@link #findById(String)} instead */ + @Deprecated TopiaEntity findByTopiaId(String topiaId) throws TopiaException; /** + * Retrieve {@link TopiaEntity} using its unique {@code id}. + * + * @param id unique identifier of the entity in all the application. + * @return the entity found or null if not + * @throws TopiaException for errors on retrieving the entity + */ + TopiaEntity findById(String id) throws TopiaException; + + /** * Permet de faire une requete HQL hibernate directement sur la base. * * @param hql la requete a faire 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-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -188,11 +188,17 @@ /** Liste des classes perssitance */ protected List<Class<?>> persistenceClasses = new ArrayList<Class<?>>(); + /** Default constructor, useful for tests. */ + protected TopiaContextImpl() { + } + /** - * constructeur utilisé par la factory pour creer les contexts initiaux + * Constructor used by {@link TopiaContextFactory} to initialize rootContext + * using {@code config}. * - * @param config - * @throws TopiaNotFoundException + * @param config for the new root context + * @throws TopiaNotFoundException if one of persistent class from + * configuration is not found */ public TopiaContextImpl(Properties config) throws TopiaNotFoundException { this.config = config; @@ -202,13 +208,13 @@ postInitServices(services); } - /** - * Default constructor, useful for tests. - */ - protected TopiaContextImpl() { - + protected String getProperExceptionMessage(Throwable eee) { + return eee.getClass().getSimpleName() + " : " + + eee.getMessage(); } + /* -------------------- SERVICES MANAGMENT -------------------------------*/ + protected Map<String, TopiaService> loadServices(Properties config) { Map<String, TopiaService> result = new HashMap<String, TopiaService>(); // recherche des services present dans la config @@ -231,7 +237,7 @@ } catch (Throwable eee) { String message = I18n._("topia.persistence.error.service.unknown", - key, classService); + key, classService); if (log.isDebugEnabled()) { log.debug(message, eee); } else if (log.isErrorEnabled()) { @@ -261,16 +267,8 @@ } } - @Override - public Map<String, TopiaService> getServices() { - TopiaContextImplementor parent = getParentContext(); - - Map<String, TopiaService> result = null; - if (parent != null) { - result = parent.getServices(); - } else { - result = services; - } + protected TopiaService getService(String name) { + TopiaService result = getServices().get(name); return result; } @@ -279,24 +277,34 @@ return result; } - protected TopiaService getService(String name) { - TopiaService result = getServices().get(name); - return result; + /** + * Retrieve service name using SERVICE_NAME static field on service + * interface. + * + * @param interfaceService class of the service + * @param <E> type of the service that extends {@link + * TopiaService} + * @return the service name + * @throws IllegalAccessException if field SERVICE_NAME can't be accessed + * @throws NoSuchFieldException if no field SERVICE_NAME is defined + */ + protected <E extends TopiaService> String getServiceName( + Class<E> interfaceService) + throws IllegalAccessException, NoSuchFieldException { + Field f = interfaceService.getField("SERVICE_NAME"); + String name = (String) f.get(null); + return name; } @Override - public <E extends TopiaService> boolean serviceEnabled( - Class<E> interfaceService) { - boolean result = false; - try { - Field f = interfaceService.getField("SERVICE_NAME"); - String name = (String) f.get(null); - result = serviceEnabled(name); - } catch (Exception eee) { - if (log.isWarnEnabled()) { - log.warn(I18n._("topia.persistence.warn.service.not.found", - interfaceService, eee.getMessage()), eee); - } + public Map<String, TopiaService> getServices() { + TopiaContextImplementor parent = getParentContext(); + + Map<String, TopiaService> result = null; + if (parent != null) { + result = parent.getServices(); + } else { + result = services; } return result; } @@ -305,50 +313,71 @@ * Take one service, this service must be valid service interface with * public static final SERVICE_NAME declaration. * - * @param <E> - * @throws TopiaNotFoundException + * @param <E> type of the service that extends {@link TopiaService} + * @throws TopiaNotFoundException if an error appears or service not found. + * @see #getServiceName(Class) */ @Override public <E extends TopiaService> E getService(Class<E> interfaceService) throws TopiaNotFoundException { + E result = null; try { - Field f = interfaceService.getField("SERVICE_NAME"); - String name = (String) f.get(null); - E result = (E) getService(name); - if (result == null) { - throw new TopiaNotFoundException( - I18n._("topia.persistence.error.service.not.found", - interfaceService)); - } - return result; + String name = getServiceName(interfaceService); + result = (E) getService(name); } catch (Exception eee) { throw new TopiaNotFoundException( I18n._("topia.persistence.error.service.not.retreaved", - interfaceService, eee.getMessage()), eee); + interfaceService, getProperExceptionMessage(eee)), + eee); } + if (result == null) { + throw new TopiaNotFoundException( + I18n._("topia.persistence.error.service.not.found", + interfaceService)); + } + return result; } @Override + public <E extends TopiaService> boolean serviceEnabled( + Class<E> interfaceService) { + boolean result = false; + try { + String name = getServiceName(interfaceService); + result = serviceEnabled(name); + } catch (Exception eee) { + String message = I18n._("topia.persistence.warn.service.not.found", + interfaceService, getProperExceptionMessage(eee)); + if (log.isDebugEnabled()) { + log.debug(message, eee); + } else if (log.isWarnEnabled()) { + log.warn(message); + } + } + return result; + } + + @Override public Collection<TopiaService> getAllServices() { Collection<TopiaService> result = getServices().values(); return result; } + /* -------------------- CONTEXT HIERARCHY MANAGMENT ----------------------*/ + /** - * Constructeur utilisé par le beginTransaction pour créer le context fils. + * Constructor used by {@link #beginTransaction()} to instantiate child from + * {@code parentContext}. * - * @param parentContext - * @throws HibernateException - * @throws TopiaNotFoundException + * @param parentContext context parent of the new TopiaContext child */ - protected TopiaContextImpl(TopiaContextImplementor parentContext) - throws HibernateException, TopiaNotFoundException { + protected TopiaContextImpl(TopiaContextImplementor parentContext) { this.parentContext = parentContext; } @Override public Set<TopiaContextImplementor> getChildContext() { - // FD-20100421 : Ano #546 + // fdesbois-20100421 : Ano #546 // Copy the childContext into a new set final Set<TopiaContextImplementor> values; // Synchronize copy to be thread-safe during iteration @@ -364,8 +393,7 @@ @Override public void removeChildContext(TopiaContextImplementor child) { - // On ne retire les fils que si ce contexte n'est pas deja ferme. - // Permet d'eviter les acces concurrentiels + // Remove child only if this context is not already closed. if (!closed) { childContext.remove(child); } @@ -393,6 +421,8 @@ return config; } + /* -------------------- HIBERNATE MANAGMENT -----------------------------*/ + @Override public void createSchema() throws TopiaException { try { @@ -571,7 +601,7 @@ String listPersistenceClasses = getConfig().getProperty( TOPIA_PERSISTENCE_CLASSES, ""); - for (TopiaService service : getAllServices()) { + for (TopiaService service : getServices().values()) { Class<?>[] classes = service.getPersistenceClasses(); // certains service n'ont pas de classe persistantes @@ -610,6 +640,8 @@ return hibernateConfiguration; } + /* -------------------- CHILD CONTEXT AND DAOS --------------------------*/ + /* * (non-Javadoc) * @@ -668,7 +700,7 @@ /* * (non-Javadoc) * - * @see org.nuiton.topia.TopiaContext#beginTransaction() + * @see TopiaContext#beginTransaction() */ @Override @@ -702,7 +734,7 @@ /* * (non-Javadoc) * - * @see org.nuiton.topia.TopiaContext#commitTransaction() + * @see TopiaContext#commitTransaction() */ @Override @@ -748,7 +780,7 @@ /* * (non-Javadoc) * - * @see org.nuiton.topia.TopiaContext#rollbackTransaction() + * @see TopiaContext#rollbackTransaction() */ @Override @@ -829,7 +861,7 @@ /** * Pour le context root on ferme tous les fils, et la factory hibernate * - * @see java.lang.Object#finalize() + * @see Object#finalize() */ @Override protected void finalize() throws Throwable { @@ -852,26 +884,33 @@ } } + /* -------------------- GLOBAL OPERATIONS ON SCHEMA ----------------------*/ + /* (non-Javadoc) - * @see org.nuiton.topia.TopiaContext#findByTopiaId(java.lang.String) + * @see TopiaContext#findByTopiaId(java.lang.String) */ @Override public TopiaEntity findByTopiaId(String topiaId) throws TopiaException { + TopiaEntity result = findById(topiaId); + return result; + } + + @Override + public TopiaEntity findById(String id) throws TopiaException { checkClosed(I18n._( "topia.persistence.error.unsupported.operation.on.closed.context", - "findByTopiaId")); + "findById")); - TopiaEntity result; - Class<TopiaEntity> entityClass = TopiaId.getClassName(topiaId); + Class<TopiaEntity> entityClass = TopiaId.getClassName(id); TopiaDAO<TopiaEntity> dao = getDAO(entityClass); - result = dao.findByTopiaId(topiaId); + TopiaEntity result = dao.findById(id); return result; } /* * (non-Javadoc) - * @see org.nuiton.topia.TopiaContext#find(java.lang.String, java.lang.Object[]) + * @see TopiaContext#find(java.lang.String, java.lang.Object[]) */ @Override @@ -932,7 +971,7 @@ /** * Execute HQL operation on data (Update, Delete) * - * @param hql HQL query + * @param hql HQL query * @param args arguments for query * @return The number of entities updated or deleted. * @throws TopiaException 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-05-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -120,6 +120,11 @@ Map<String, TopiaService> getServices(); + /** + * @return a collection of {@link TopiaService} + * @deprecated since 2.4 : useless method, use {@link #getServices()} instead + */ + @Deprecated Collection<TopiaService> getAllServices(); List<Class<?>> getPersistenceClasses(); Modified: trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties =================================================================== --- trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties 2010-05-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties 2010-05-10 16:40:22 UTC (rev 1951) @@ -20,14 +20,14 @@ topia.persistence.error.rootContext.access=Vous \u00EAtes sur le root context, vous devez ouvrir une transaction pour pouvoir acc\u00E9der aux donn\u00E9es. topia.persistence.error.service.not.found=Le service %1$s n'est pas disponible topia.persistence.error.service.not.retreaved=La service %1$s n'a pas pu \u00EAtre r\u00E9cup\u00E9r\u00E9 pour la raison suivante \: %2$s -topia.persistence.error.service.unknown=Le service de clef %1$s et de classe %2$s n'est pas connu +topia.persistence.error.service.unknown=Le service '%1$s' ayant pour classe '%2$s' n'est pas connu topia.persistence.error.unsupported.class=La classe %1$s n'est pas support\u00E9e par ce TopiaContext, vous avez sans doute oubli\u00E9 d'ajouter son mapping topia.persistence.error.unsupported.operation.on.closed.context=Ce contexte a \u00E9t\u00E9 ferm\u00E9, impossible de r\u00E9aliser l'op\u00E9ration %1$s topia.persistence.error.unsupported.operation.on.root.context=Vous \u00EAtes sur le root context l'op\u00E9ration %1$s est impossible topia.persistence.error.update.schema=Le sch\u00E9ma n'a pas pu \u00EAtre mis \u00E0 jour pour la raison suivante \: %2$s -topia.persistence.service.loaded=Le service %1$s charg\u00E9 par %2$s +topia.persistence.service.loaded=Service '%1$s' charg\u00E9 par '%2$s' topia.persistence.supported.classes.for.context=Classes support\u00E9es par ce TopiaContext \: %1$s -topia.persistence.warn.service.not.found=Le nom du service %1$s n'a pas \u00E9t\u00E9 trouv\u00E9 pour la raison suivante \: %2$s -topia.persistence.warn.service.not.loaded=Le service de clef %1$s a un nom de service %2$ diff\u00E9rent\! (service d\u00E9sactiv\u00E9) -topia.persistence.warn.service.not.postInit=Le service %1$s n'a pas pu \u00EAtre initialis\u00E9 (service d\u00E9sactiv\u00E9) -topia.persistence.warn.service.not.preInit=Le service %1$s n'a pas pu \u00EAtre finalis\u00E9 (service d\u00E9sactiv\u00E9) +topia.persistence.warn.service.not.found=Le nom du service '%1$s' n'a pas \u00E9t\u00E9 trouv\u00E9 pour la raison suivante \: %2$s +topia.persistence.warn.service.not.loaded=Le service de cl\u00E9 '%1$s' a un nom de service '%2$s' diff\u00E9rent \! (service d\u00E9sactiv\u00E9) +topia.persistence.warn.service.not.postInit=Le service '%1$s' n'a pas pu \u00EAtre initialis\u00E9 (service d\u00E9sactiv\u00E9) +topia.persistence.warn.service.not.preInit=Le service '%1$s' n'a pas pu \u00EAtre finalis\u00E9 (service d\u00E9sactiv\u00E9) Deleted: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TestService.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TestService.java 2010-05-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TestService.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -1,36 +0,0 @@ -package org.nuiton.topia.framework; - -import org.junit.Ignore; - -/** - * TestService which implements {@link TopiaService} to test loading from - * {@link TopiaContextImplTest#testLoadServices()}. - * - * Created: 10 mai 2010 - * - * @author fdesbois <fdesbois@codelutin.com> - * @version $Id$ - */ -@Ignore -public class TestService implements TopiaService { - - @Override - public String getServiceName() { - return "test"; - } - - @Override - public Class<?>[] getPersistenceClasses() { - return new Class<?>[0]; - } - - @Override - public boolean preInit(TopiaContextImplementor context) { - return true; - } - - @Override - public boolean postInit(TopiaContextImplementor context) { - return true; - } -} Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java 2010-05-10 14:33:00 UTC (rev 1950) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -8,7 +8,11 @@ import org.junit.BeforeClass; import org.junit.Test; import org.nuiton.i18n.I18n; +import org.nuiton.topia.TopiaNotFoundException; +import org.nuiton.topiatest.service.FakeService; +import org.nuiton.topiatest.service.TestService; +import java.util.Collection; import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -80,19 +84,66 @@ // TODO-fdesbois-20100510 : need integration tests for all existing topia services } -// @Test -// public void testGetServices() throws Exception { -// } + @Test + public void testGetServices() throws Exception { + log.info("## testGetServices"); + + /** PREPARE DATA **/ + properties.setProperty("topia.service.test", + TestService.class.getName()); + + // Calling the constructor with properties will load the services + TopiaContextImpl context = new TopiaContextImpl(properties); + + // Instantiate a child context and set its parent + TopiaContextImpl child = new TopiaContextImpl(context); + + /** EXEC METHOD **/ + log.info("test 1 : with child context"); + Map<String, TopiaService> test1 = child.getServices(); + Assert.assertEquals(1, test1.size()); + Assert.assertTrue(test1.containsKey("test")); + + log.info("test 2 : test serviceEnabled method"); + boolean test2 = child.serviceEnabled("test"); + Assert.assertTrue(test2); + + log.info("test 3 : test getService method"); + TopiaService test3 = child.getService("test"); + Assert.assertEquals(TestService.class, test3.getClass()); + + log.info("test 4 : test serviceEnabled from class TestService"); + boolean test4 = child.serviceEnabled(TestService.class); + Assert.assertTrue(test4); + + log.info("test 5 : test getService from class TestService"); + TestService test5 = child.getService(TestService.class); + Assert.assertNotNull(test5); + + log.info("test 6 : test serviceEnabled error with class FakeService"); + // FakeService doesn't contains property SERVICE_NAME used by + // serviceEnabled method + // Even it's properly loaded the serviceEnabled method will return false + properties.clear(); + properties.setProperty("topia.service.fake", + FakeService.class.getName()); + TopiaContextImpl otherContext = new TopiaContextImpl(properties); + + boolean test6 = otherContext.serviceEnabled(FakeService.class); + Assert.assertFalse(test6); + + log.info("test 7 : test getService with error TopiaNotFoundException" + + " : service not loaded"); + // TestService is not loaded in otherContext + try { + TestService test7 = otherContext.getService(TestService.class); + } catch (Exception eee) { + log.error(eee.getClass().getSimpleName() + " : " + eee.getMessage()); + Assert.assertEquals(TopiaNotFoundException.class, eee.getClass()); + } + } // // @Test -// public void testServiceEnabled() throws Exception { -// } -// -// @Test -// public void testGetService() throws Exception { -// } -// -// @Test // public void testGetAllServices() throws Exception { // } // Added: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java (rev 0) +++ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -0,0 +1,40 @@ +package org.nuiton.topiatest.service; + +import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.TopiaContextImplTest; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.framework.TopiaService; + +/** + * FakeService which implements {@link TopiaService} to test existing service + * from {@link TopiaContextImplTest#testGetServices()}. This fake service + * doesn't contains property SERVICE_NAME used by {@link + * TopiaContextImpl#serviceEnabled(Class)}. + * <p/> + * Created: 10 mai 2010 + * + * @author fdesbois <fdesbois@codelutin.com> + * @version $Id$ + */ +public class FakeService implements TopiaService { + + @Override + public String getServiceName() { + return "fake"; + } + + @Override + public Class<?>[] getPersistenceClasses() { + return new Class<?>[0]; + } + + @Override + public boolean preInit(TopiaContextImplementor context) { + return true; + } + + @Override + public boolean postInit(TopiaContextImplementor context) { + return true; + } +} Property changes on: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Copied: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java (from rev 1950, trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TestService.java) =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java (rev 0) +++ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -0,0 +1,43 @@ +package org.nuiton.topiatest.service; + +import org.junit.Ignore; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.framework.TopiaContextImplTest; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.framework.TopiaService; + +/** + * TestService which implements {@link TopiaService} to test loading from {@link + * TopiaContextImplTest#testLoadServices()}. + * <p/> + * Created: 10 mai 2010 + * + * @author fdesbois <fdesbois@codelutin.com> + * @version $Id$ + */ +@Ignore +public class TestService implements TopiaService { + + /** Needed field to use {@link TopiaContext#serviceEnabled(Class)} * */ + public static final String SERVICE_NAME = "test"; + + @Override + public String getServiceName() { + return SERVICE_NAME; + } + + @Override + public Class<?>[] getPersistenceClasses() { + return new Class<?>[0]; + } + + @Override + public boolean preInit(TopiaContextImplementor context) { + return true; + } + + @Override + public boolean postInit(TopiaContextImplementor context) { + return true; + } +} Property changes on: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/package-info.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/package-info.java (rev 0) +++ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/package-info.java 2010-05-10 16:40:22 UTC (rev 1951) @@ -0,0 +1,5 @@ +/** + * This package contains classes which implements {@link + * org.nuiton.topia.framework.TopiaService} to test services API. + */ +package org.nuiton.topiatest.service; \ No newline at end of file Property changes on: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/package-info.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL