RemoteLazyLoadingTest : Creating application configuration programmatically
authorCherian Mathew <c.mathew@bgbm.org>
Thu, 20 Feb 2014 16:37:36 +0000 (16:37 +0000)
committerCherian Mathew <c.mathew@bgbm.org>
Thu, 20 Feb 2014 16:37:36 +0000 (16:37 +0000)
AbstractPersistentCollection, AbstractLazyInitializer : Copied aspect code here
CdmApplicationRemoteConfiguration : overriding datasource since it is not required in remoting
remotingApplicationContext : added autowiring config

eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/lazyloading/CdmLazyLoader.java
eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
eu.etaxonomy.taxeditor.cdmlib/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml
eu.etaxonomy.taxeditor.cdmlib/src/test/java/eu/etaxonomy/taxeditor/remoting/RemoteLazyLoadingTest.java

index 1c80eeb7524a907fda1ed17189beaff4fce0ce8a..8eccee824f628d72509228d00dcb7e2e6fd61416 100644 (file)
@@ -10,6 +10,8 @@
 \r
 package eu.etaxonomy.cdm.api.application;\r
 \r
+import javax.sql.DataSource;\r
+\r
 import org.hibernate.SessionFactory;\r
 \r
 import org.apache.log4j.Logger;\r
@@ -90,6 +92,11 @@ public class CdmApplicationRemoteConfiguration extends CdmApplicationDefaultConf
        public IEditGeoService getEditGeoService() {\r
                return this.editGeoService;\r
        }\r
+       \r
+       @Override\r
+       public void setDataSource(DataSource dataSource) {        \r
+    }\r
+       \r
        @Override\r
        public void setTransactionManager(PlatformTransactionManager transactionManager) {        \r
     }\r
index 60e55d7db9a1b7c878af4a100be22946d00bdb33..e98d40df7db0f293682d58f91da538d3f74caa1a 100644 (file)
@@ -155,8 +155,7 @@ public class CdmLazyLoader {
                if(pc != null) {
                        if(pc instanceof PersistentSet || pc instanceof PersistentSortedSet) {
                                return "set";
-                       }
-                       
+                       }                       
                        if(pc instanceof PersistentList) {
                                return "list";
                        }
index adbbd466f536a1520f0a72e92624ffa85afda23e..44d62da34e42162bf4f78f664f56984f6b694f3d 100644 (file)
 package org.hibernate.collection.internal;
 
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import javax.naming.NamingException;
 
@@ -58,6 +64,10 @@ import org.hibernate.pretty.MessageHelper;
 import org.hibernate.type.Type;
 import org.jboss.logging.Logger;
 
+import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
+import eu.etaxonomy.cdm.api.service.ICommonService;
+import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
+
 /**
  * Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
  *
@@ -545,16 +555,18 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
                if ( initialized ) {
                        return;
                }
-
-               withTemporarySessionIfNeeded(
-                               new LazyInitializationWork<Object>() {
-                                       @Override
-                                       public Object doWork() {
-                                               session.initializeCollection( AbstractPersistentCollection.this, writing );
-                                               return null;
-                                       }
-                               }
-               );
+               // Adding remote call
+               remoteInitialize();
+               
+//             withTemporarySessionIfNeeded(
+//                             new LazyInitializationWork<Object>() {
+//                                     @Override
+//                                     public Object doWork() {
+//                                             session.initializeCollection( AbstractPersistentCollection.this, writing );
+//                                             return null;
+//                                     }
+//                             }
+//             );
        }
 
        private void throwLazyInitializationExceptionIfNotConnected() {
@@ -1171,5 +1183,101 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
                this.owner = owner;
        }
 
+       /** Below is section of code which makes remote service calls */
+       
+       private static ICdmApplicationConfiguration configuration;
+
+       
+       public static void setConfiguration(ICdmApplicationConfiguration conf) {
+               configuration = conf;
+       }
+       
+       private void remoteInitialize() {
+               
+               if (getOwner() != null && !wasInitialized()) {                  
+                       
+                       try {
+                               String role = getRole();
+                               String fieldName = role.substring(role.lastIndexOf(".") + 1);
+                               log.info("--> Remote Lazy Initializing " + getRole() + " , field : " + fieldName);
+                               Object owner = getOwner();
+                               
+                               if(configuration == null) {
+                                       throw new HibernateException("CdmApplicationRemoteConfiguration not initialized (null)");
+                               }
+                               ICommonService commonService = configuration.getCommonService();
+                               if(commonService == null) {
+                                       throw new HibernateException("commonService not initialized (null)");
+                               }
+                               
+                               PersistentCollection col = commonService.initializeCollection(this); 
+                               afterInitialize();
+
+                               Class<?> clazz = getClass();
+                               if (clazz != null) {    
+                                       CollectionField cf = getCollectionField(col);
+                                       Field field = clazz.getDeclaredField(cf.getFieldName());
+                                       field.setAccessible(true);
+                                       field.set(this, cf.getCollection());                           
+                               }               
+                       } catch (Exception ex) {
+                               log.warn(ex.getMessage());
+                       }                       
+               }
+       }
+       
+       private CollectionField getCollectionField(PersistentCollection pc) {
+               if(pc != null) {
+                       if(pc instanceof PersistentSet) {
+                               return new CollectionField(new HashSet((Set)pc), "set");
+                       }
+                       if(pc instanceof PersistentSortedSet) {
+                               return new CollectionField(new TreeSet((Set)pc), "set");
+                       }
+                       if(pc instanceof PersistentList) {
+                               return new CollectionField(new ArrayList((List)pc), "list");
+                       }
+                       if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
+                               return new CollectionField(new HashMap((Map)pc), "map");
+                       }
+                       if(pc instanceof PersistentSortedMap) {
+                               return new CollectionField(new TreeMap((Map)pc), "map");
+                       }
+               }
+               return null;
+       }
+       
+       private String getCollectionFieldName(PersistentCollection pc) {
+               if(pc != null) {
+                       if(pc instanceof PersistentSet || pc instanceof PersistentSortedSet) {
+                               return "set";
+                       }                       
+                       if(pc instanceof PersistentList) {
+                               return "list";
+                       }
+                       if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
+                               return "map";
+                       }
+               }
+               return null;
+       }
+       
+       private class CollectionField {
+               private Object col;
+               private String fieldName;
+               public CollectionField(Object col, String fieldName) {
+                       this.col = col;
+                       this.fieldName = fieldName;
+               }
+               
+               public Object getCollection() {
+                       return this.col;
+               }
+               
+               public String getFieldName() {
+                       return this.fieldName;
+               }
+       }
+       
 }
 
index b9068070c858b024527627b692f156f1fc38ce78..57d166b254bd0e32e68fbff3eeab0cca71df2f00 100644 (file)
@@ -38,7 +38,13 @@ import org.hibernate.engine.spi.SessionImplementor;
 import org.hibernate.internal.SessionFactoryRegistry;
 import org.hibernate.persister.entity.EntityPersister;
 import org.jboss.logging.Logger;
+import org.springframework.beans.factory.annotation.Autowire;
 import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
+import eu.etaxonomy.cdm.api.service.ICommonService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
 
 /**
  * Convenience base class for lazy initialization handlers.  Centralizes the basic plumbing of doing lazy
@@ -47,7 +53,8 @@ import org.springframework.beans.factory.annotation.Configurable;
  *
  * @author Gavin King
  */
-@Configurable(dependencyCheck = true)
+@Component
+@Configurable(dependencyCheck = true,autowire = Autowire.BY_TYPE)
 public abstract class AbstractLazyInitializer implements LazyInitializer {
        private static final Logger log = Logger.getLogger( AbstractLazyInitializer.class );
 
@@ -158,6 +165,9 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
 
        @Override
        public final void initialize() throws HibernateException {
+               if( !initialized) {
+                       remoteInitialize();
+               }
                if ( !initialized ) {
                        if ( specjLazyLoad ) {
                                specialSpecjInitialization();
@@ -407,4 +417,40 @@ public abstract class AbstractLazyInitializer implements LazyInitializer {
        public void setUnwrap(boolean unwrap) {
                this.unwrap = unwrap;
        }
+       
+       /** Below is section of code which makes remote service calls */
+       
+       private static ICdmApplicationConfiguration configuration;
+       
+       public static void setConfiguration(ICdmApplicationConfiguration conf) {
+               configuration = conf;
+       }
+       
+       
+       private void remoteInitialize() {               
+               
+               if(isUninitialized()) {                         
+                       int classid = ((Integer)getIdentifier()).intValue();
+                       System.out.print("--> Remote Lazy Initializing" + getEntityName() + " with id " + classid);
+                       Class clazz;
+                       try {
+                               clazz = (Class<? extends CdmBase>) Class.forName(getEntityName());
+                       } catch (ClassNotFoundException e) {
+                               throw new HibernateException("Class for " + getEntityName() + " not found", e);
+                       }
+                       if(configuration == null) {
+                               throw new HibernateException("CdmApplicationRemoteConfiguration not initialized (null)");
+                       }
+                       ICommonService commonService = configuration.getCommonService();
+                       if(commonService == null) {
+                               throw new HibernateException("commonService not initialized (null)");
+                       }
+                       
+                       CdmBase cdmBase = CdmBase.deproxy(commonService.find(clazz,classid),clazz);
+                       setImplementation(cdmBase);
+                       System.out.println("....Done");
+               }
+       }
+       
+       
 }
index df3383767f583445cca58a9ae87c46f1729d35fa..a4819b226cf98266382f24a10902db4693015c84 100644 (file)
@@ -10,7 +10,8 @@
 \r
     <!--  <bean id="remoteTermInitializer" class="eu.etaxonomy.cdm.remote.service.RemoteTermInitializer"/>-->\r
         \r
-       \r
+       <context:annotation-config/>\r
+       \r
        <context:component-scan base-package="eu/etaxonomy/cdm/api/application">\r
                <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.api\.application\.CdmApplicationDefaultConfiguration" /> \r
        </context:component-scan>\r
@@ -19,7 +20,6 @@
 \r
        <import resource="classpath:/eu/etaxonomy/cdm/httpInvokerServiceClients.xml"/>\r
 \r
-\r
        <!-- EditGeoService was moved to ext. Therefore it will not be found by the default component scan.
        We added it here because the Editor needs it. However, this is only a temporary solution.
        In the future we want to pass in an application context with the editor. -->\r
index 23b43151a45467ebb5242bdf20c1b3746ad69803..288ead0574a55544d7cfd8f1b14e2ad5bc43d20f 100644 (file)
@@ -14,87 +14,73 @@ import java.util.Iterator;
 import java.util.Set;
 import java.util.UUID;
 
+import org.hibernate.collection.internal.AbstractPersistentCollection;
+import org.hibernate.proxy.AbstractLazyInitializer;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
 import org.unitils.UnitilsJUnit4;
 import org.unitils.database.annotations.Transactional;
 import org.unitils.database.util.TransactionMode;
 import org.unitils.spring.annotation.SpringApplicationContext;
 import org.unitils.spring.annotation.SpringBeanByType;
 
+import eu.etaxonomy.cdm.api.application.CdmApplicationController;
+import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
 import eu.etaxonomy.cdm.api.service.ITaxonService;
+import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
+import eu.etaxonomy.cdm.database.DataSourceNotFoundException;
+import eu.etaxonomy.cdm.database.ICdmDataSource;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.name.NonViralName;
 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
 
 
+
 /**
  * This test class is a testing ground for solving the hibernate lazy loading problem using aspects
+ * 
+ * FIXME:Remoting Neet to be able to launch a cdm server here a-la CdmIntegrationTests
+ * To execute this test you need a local eclipse jetty cdmserver already running.
+ * The data used in this test corresponds to the cyprus db, so the data should be changed to 
+ * suit the target datasource 
  *
  * @author c.mathew
  *
  */
-@SpringApplicationContext("classpath:/eu/etaxonomy/cdm/remotingApplicationContext.xml")
+//@SpringApplicationContext("classpath:/eu/etaxonomy/cdm/remotingApplicationContext.xml")
 @Transactional(TransactionMode.DISABLED)
 public class RemoteLazyLoadingTest extends UnitilsJUnit4 {
        
-       @SpringBeanByType
+       //@SpringBeanByType
        private ITaxonService taxonService;
        
        private UUID taxonUuid1 = UUID.fromString("8217ef77-2ab1-4318-bd67-ccd0cdef07c4");
        private UUID taxonUuid2 = UUID.fromString("ef96fafa-7750-4141-b31b-1ad1daab3e76");
        
+       ICdmApplicationConfiguration applicationController;
+       
        /**
+        * @throws DataSourceNotFoundException 
         */
-       
-//     @Test
-//     public void testLazyLoading(){          
-//
-//             Taxon taxon = (Taxon)taxonService.find(taxonUuid1);
-//             System.out.println("Taxon title : " + taxon.getTitleCache());
-//             taxon.setTitleCache("Taxon Title Cache 1");             
-//             taxonService.merge(taxon);
-//             
-//             NonViralName nvn = CdmBase.deproxy(taxon.getName(),NonViralName.class);
-//
-//             
-//             System.out.println("name : " + nvn.getTitleCache());
-//             nvn.setTitleCache("Taxon Name Title Cache 1");
-//             taxonService.merge(taxon);
-//             
-//             Reference ref = taxon.getSec();
-//             System.out.println("Secundum : " + ref.getTitleCache());
-//             
-//             Rank rank = nvn.getRank();
-//             System.out.println("rank : " + rank.getTitleCache());
-//             
-//             Set<SynonymRelationship> synRelations = taxon.getSynonymRelations();
-//             Iterator<SynonymRelationship> srItr = synRelations.iterator();
-//             while(srItr.hasNext()) {
-//                     SynonymRelationship sr = srItr.next();
-//                     System.out.println("Synonym Relationship : " + sr.getType().getTitleCache());
-//                     sr.getType().setTitleCache(sr.getType().getTitleCache() + "*");
-//             }
-//             taxonService.merge(taxon);
-//             
-//             Set<TaxonRelationship> taxonRelationsFrom = taxon.getRelationsFromThisTaxon();
-//             Iterator<TaxonRelationship> trItrFrom = taxonRelationsFrom.iterator(); 
-//             while(trItrFrom.hasNext()) {
-//                     TaxonRelationship tr = trItrFrom.next();
-//                     System.out.println("Taxon From Relationship : " + tr.getType().getTitleCache());
-//                     tr.getType().setTitleCache(tr.getType().getTitleCache() + "*");
-//             }
-//             taxonService.merge(taxon);
-//             Set<TaxonRelationship> taxonRelationsTo = taxon.getRelationsToThisTaxon();
-//             Iterator<TaxonRelationship> trItrTo = taxonRelationsTo.iterator(); 
-//             while(trItrTo.hasNext()) {
-//                     TaxonRelationship tr = trItrTo.next();
-//                     System.out.println("Taxon To Relationship : " + tr.getType().getTitleCache());
-//                     tr.getType().setTitleCache(tr.getType().getTitleCache() + "*");
-//             }
-//             taxonService.merge(taxon);
-//     }
+       @Before
+       public void initializeContext() throws DataSourceNotFoundException {
+       Resource DEFAULT_APPLICATION_CONTEXT = new ClassPathResource(
+                       "/eu/etaxonomy/cdm/remotingApplicationContext.xml");
+       ICdmDataSource datasource = CdmPersistentDataSource.NewInstance("local-cyprus");
+       ICdmApplicationConfiguration applicationController = 
+                       CdmApplicationController.NewInstance(DEFAULT_APPLICATION_CONTEXT, 
+                                       datasource, 
+                                       null,
+                                       false, 
+                                       null);
+       AbstractLazyInitializer.setConfiguration(applicationController);
+       AbstractPersistentCollection.setConfiguration(applicationController);
+       taxonService = applicationController.getTaxonService();
+       }
        
        @Test
        public void testCDMEntityGet() {