merge from trunk
authorCherian Mathew <c.mathew@bgbm.org>
Tue, 11 Nov 2014 17:59:01 +0000 (17:59 +0000)
committerCherian Mathew <c.mathew@bgbm.org>
Tue, 11 Nov 2014 17:59:01 +0000 (17:59 +0000)
77 files changed:
.gitattributes
.gitignore
eu.etaxonomy.taxeditor.remoting/.classpath [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/.project [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/.svnignore [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/META-INF/MANIFEST.MF [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/build.properties [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/lib/.svnignore [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/pom.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmClientCacheException.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheKey.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCachingUtils.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelCacher.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelFieldPropertyFromClass.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmRemoteCacheManager.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmPersistentRemoteSource.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSource.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceBase.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceException.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/ICdmRemoteSource.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmRemotingException.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/RemotingTestPluginActivator.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmClientSessionException.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySession.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySessionManager.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/ISessionEventListener.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/cdmlib-ehcache.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/config.properties [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/httpInvokerServiceClients.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/localApplicationContext.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_persistence_security.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_services_security.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmModelGetMethodCacherTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/exception/CDMServerException.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/BaseRemotingTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CDMServer.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmPersistentRemoteSourceTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmRemoteSourceTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/HttpInvokerServicesTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmServiceCacherTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemoteLazyLoadingTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemotePersistentCollectionTest.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/remoting/session/MockSessionOwner.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/cdmlib-ehcache.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/datasources.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/cdm.datasources.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/testRemotingApplicationContext.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.h2.db [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.trace.db [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties [new file with mode: 0644]
eu.etaxonomy.taxeditor.remoting/src/test/resources/unitils.properties [new file with mode: 0644]

index 7955a88cd84bc5e97af2e4ead816ffb273b0a174..0361e5956d45bedee638dc6614e58354d81c2137 100644 (file)
@@ -1004,6 +1004,81 @@ eu.etaxonomy.taxeditor.printpublisher/src/main/java/eu/etaxonomy/taxeditor/print
 eu.etaxonomy.taxeditor.printpublisher/src/main/java/eu/etaxonomy/taxeditor/printpublisher/wizard/SelectServiceWizardPage.java -text
 eu.etaxonomy.taxeditor.printpublisher/src/main/java/eu/etaxonomy/taxeditor/printpublisher/wizard/SelectStylesheetWizardPage.java -text
 eu.etaxonomy.taxeditor.printpublisher/src/main/java/eu/etaxonomy/taxeditor/printpublisher/wizard/SelectTaxaWizardPage.java -text
+eu.etaxonomy.taxeditor.remoting/.classpath -text
+eu.etaxonomy.taxeditor.remoting/.project -text
+eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.jdt.core.prefs -text
+eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.pde.core.prefs -text
+eu.etaxonomy.taxeditor.remoting/.svnignore -text
+eu.etaxonomy.taxeditor.remoting/META-INF/MANIFEST.MF -text
+eu.etaxonomy.taxeditor.remoting/build.properties -text
+eu.etaxonomy.taxeditor.remoting/lib/.svnignore -text
+eu.etaxonomy.taxeditor.remoting/pom.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmClientCacheException.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheKey.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCachingUtils.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelCacher.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelFieldPropertyFromClass.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmRemoteCacheManager.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmPersistentRemoteSource.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSource.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceBase.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceException.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/ICdmRemoteSource.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmRemotingException.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/RemotingTestPluginActivator.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmClientSessionException.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySession.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySessionManager.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/ISessionEventListener.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/cdmlib-ehcache.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/config.properties -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/httpInvokerServiceClients.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/localApplicationContext.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_persistence_security.xml -text
+eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_services_security.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmModelGetMethodCacherTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/exception/CDMServerException.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/BaseRemotingTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CDMServer.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmPersistentRemoteSourceTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmRemoteSourceTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/CdmServerTestManager.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/httpinvoker/HttpInvokerServicesTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/CdmServiceCacherTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemoteLazyLoadingTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/lazyloading/RemotePersistentCollectionTest.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/taxeditor/remoting/session/MockSessionOwner.java -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/cdmlib-ehcache.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/datasources.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/cdm.datasources.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.readPolytmousKeyData.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/polytomouskey/PolytomousKeyTest.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/cdm/testRemotingApplicationContext.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/AbstractLazyInitializerTest.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/eu/etaxonomy/taxeditor/lazyloading/CdmEntityCacherTest.xml -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.h2.db -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/h2/cdmTest.trace.db -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/log4j.properties -text
+eu.etaxonomy.taxeditor.remoting/src/test/resources/unitils.properties -text
 eu.etaxonomy.taxeditor.store/.classpath -text
 eu.etaxonomy.taxeditor.store/.project -text
 eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF -text
index 5c8b928b8e9810e6ba3615b0efdeead665c5c54d..000adc05f15f4ef02806aa2daf2685871378c5ee 100644 (file)
@@ -31,6 +31,12 @@ eu.etaxonomy.taxeditor.navigation/.settings
 eu.etaxonomy.taxeditor.navigation/target
 eu.etaxonomy.taxeditor.printpublisher/.settings
 eu.etaxonomy.taxeditor.printpublisher/target
+eu.etaxonomy.taxeditor.remoting/*.log
+eu.etaxonomy.taxeditor.remoting/.settings
+eu.etaxonomy.taxeditor.remoting/lib
+eu.etaxonomy.taxeditor.remoting/lib/*.jar
+eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/cdmlib-remote-webapp.war
+eu.etaxonomy.taxeditor.remoting/target
 eu.etaxonomy.taxeditor.store/.settings
 eu.etaxonomy.taxeditor.store/hibernate.log
 eu.etaxonomy.taxeditor.store/target
diff --git a/eu.etaxonomy.taxeditor.remoting/.classpath b/eu.etaxonomy.taxeditor.remoting/.classpath
new file mode 100644 (file)
index 0000000..cfd2ac5
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry including="**/*.java" kind="src" path="src/main/java"/>
+       <classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
+       <classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
+       <classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
+       <classpathentry exported="true" kind="lib" path="lib/aspectjrt-1.7.1.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/c3p0-0.9.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/ehcache-core-2.4.3.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hamcrest-core-1.3.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/jboss-logging-3.1.3.GA.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/jboss-transaction-api_1.1_spec-1.0.0.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/jdom-1.1.3.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/junit-4.11.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/log4j-1.2.17.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/spring-security-config-3.1.3.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/spring-security-core-3.1.3.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/spring-security-remoting-3.1.3.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/unitils-core-3.4.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/commons-logging-1.1.1.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/commons-lang-2.6.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/aopalliance-1.0.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/joda-time-2.1.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/lsid-client-1.1.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/lucene-core-3.6.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/lsid-server-1.1.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/slf4j-api-1.7.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/javassist-3.17.1-GA.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/unitils-spring-3.4.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/unitils-database-3.4.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/commons-dbcp-1.4.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/commons-pool-1.5.4.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/unitils-dbmaintainer-3.4.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/h2-1.4.181.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/unitils-dbunit-3.4.2.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-jpa-2.0-api-1.0.1.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-commons-annotations-4.0.1.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-core-4.1.10.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-entitymanager-4.1.10.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-envers-4.1.10.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/hibernate-search-engine-4.2.0.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.context-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.aop-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.aspects-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.beans-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.core-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.expression-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.jdbc-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.orm-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.transaction-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.web-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/dbunit-2.4.9.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/opencsv-2.4.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/dom4j-1.6.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/cdmlib-commons-3.4.0-SNAPSHOT.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/cdmlib-ext-3.4.0-SNAPSHOT.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/cdmlib-model-3.4.0-SNAPSHOT.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/cdmlib-services-3.4.0-SNAPSHOT.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/usertype.jodatime-2.0.1.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/usertype.spi-2.0.1.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/cdmlib-persistence-3.4.0-SNAPSHOT.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/wsdl4j-1.6.3.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/validation-api-1.1.0.Final.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.context.support-3.2.2.RELEASE.jar"/>
+       <classpathentry exported="true" kind="lib" path="lib/org.springframework.test-3.2.2.RELEASE.jar"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/eu.etaxonomy.taxeditor.remoting/.project b/eu.etaxonomy.taxeditor.remoting/.project
new file mode 100644 (file)
index 0000000..a73967e
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>eu.etaxonomy.taxeditor.remoting</name>
+       <comment>Holds all UI tests for the Taxonomic Editor. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.pde.PluginNature</nature>
+       </natures>
+</projectDescription>
diff --git a/eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.jdt.core.prefs b/eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..c537b63
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.pde.core.prefs b/eu.etaxonomy.taxeditor.remoting/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..f29e940
--- /dev/null
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/eu.etaxonomy.taxeditor.remoting/.svnignore b/eu.etaxonomy.taxeditor.remoting/.svnignore
new file mode 100644 (file)
index 0000000..d9c99e9
--- /dev/null
@@ -0,0 +1,4 @@
+lib
+*.log
+target
+.settings
diff --git a/eu.etaxonomy.taxeditor.remoting/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.remoting/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..0ce2724
--- /dev/null
@@ -0,0 +1,77 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: UI Test Bundle
+Bundle-SymbolicName: eu.etaxonomy.taxeditor.remoting;singleton:=true
+Bundle-Version: 3.4.0.qualifier
+Bundle-Activator: eu.etaxonomy.taxeditor.remoting.RemotingTestPluginActivator
+Bundle-Vendor: EDIT
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: eu.etaxonomy.cdm.api.application,
+ eu.etaxonomy.cdm.remote,
+ eu.etaxonomy.taxeditor.httpinvoker,
+ org.hibernate.collection.internal,
+ org.hibernate.proxy
+Bundle-ClassPath: lib/aspectjrt-1.7.1.jar,
+ lib/c3p0-0.9.2.jar,
+ lib/ehcache-core-2.4.3.jar,
+ lib/hamcrest-core-1.3.jar,
+ lib/jboss-logging-3.1.3.GA.jar,
+ lib/jboss-transaction-api_1.1_spec-1.0.0.Final.jar,
+ lib/jdom-1.1.3.jar,
+ lib/junit-4.11.jar,
+ lib/log4j-1.2.17.jar,
+ lib/spring-security-config-3.1.3.RELEASE.jar,
+ lib/spring-security-core-3.1.3.RELEASE.jar,
+ lib/spring-security-remoting-3.1.3.RELEASE.jar,
+ lib/unitils-core-3.4.2.jar,
+ lib/commons-logging-1.1.1.jar,
+ lib/commons-lang-2.6.jar,
+ lib/aopalliance-1.0.jar,
+ lib/joda-time-2.1.jar,
+ lib/lsid-client-1.1.2.jar,
+ lib/lucene-core-3.6.2.jar,
+ lib/lsid-server-1.1.2.jar,
+ lib/slf4j-api-1.7.2.jar,
+ lib/javassist-3.17.1-GA.jar,
+ lib/unitils-spring-3.4.2.jar,
+ lib/unitils-database-3.4.2.jar,
+ lib/commons-dbcp-1.4.jar,
+ lib/commons-pool-1.5.4.jar,
+ lib/unitils-dbmaintainer-3.4.2.jar,
+ lib/h2-1.4.181.jar,
+ lib/unitils-dbunit-3.4.2.jar,
+ lib/hibernate-jpa-2.0-api-1.0.1.Final.jar,
+ lib/hibernate-commons-annotations-4.0.1.Final.jar,
+ lib/hibernate-core-4.1.10.Final.jar,
+ lib/hibernate-entitymanager-4.1.10.Final.jar,
+ lib/hibernate-envers-4.1.10.Final.jar,
+ lib/hibernate-search-engine-4.2.0.Final.jar,
+ lib/org.springframework.context-3.2.2.RELEASE.jar,
+ lib/org.springframework.aop-3.2.2.RELEASE.jar,
+ lib/org.springframework.aspects-3.2.2.RELEASE.jar,
+ lib/org.springframework.beans-3.2.2.RELEASE.jar,
+ lib/org.springframework.core-3.2.2.RELEASE.jar,
+ lib/org.springframework.expression-3.2.2.RELEASE.jar,
+ lib/org.springframework.jdbc-3.2.2.RELEASE.jar,
+ lib/org.springframework.orm-3.2.2.RELEASE.jar,
+ lib/org.springframework.transaction-3.2.2.RELEASE.jar,
+ lib/org.springframework.web-3.2.2.RELEASE.jar,
+ lib/cdmlib-persistence-3.3.8-SNAPSHOT.jar,
+ lib/dbunit-2.4.9.jar,
+ lib/opencsv-2.4.jar,
+ lib/dom4j-1.6.jar,
+ lib/cdmlib-commons-3.4.0-SNAPSHOT.jar,
+ lib/cdmlib-ext-3.4.0-SNAPSHOT.jar,
+ lib/cdmlib-model-3.4.0-SNAPSHOT.jar,
+ lib/cdmlib-services-3.4.0-SNAPSHOT.jar,
+ lib/usertype.jodatime-2.0.1.jar,
+ lib/usertype.spi-2.0.1.jar,
+ lib/cdmlib-persistence-3.4.0-SNAPSHOT.jar,
+ lib/wsdl4j-1.6.3.jar,
+ lib/validation-api-1.1.0.Final.jar,
+ lib/org.springframework.context.support-3.2.2.RELEASE.jar,
+ lib/org.springframework.test-3.2.2.RELEASE.jar
+Import-Package: org.osgi.framework
+Require-Bundle: org.eclipse.osgi
+
diff --git a/eu.etaxonomy.taxeditor.remoting/build.properties b/eu.etaxonomy.taxeditor.remoting/build.properties
new file mode 100644 (file)
index 0000000..be9b439
--- /dev/null
@@ -0,0 +1,70 @@
+output.. = target/classes/
+bin.includes = META-INF/,\
+               lib/aspectjrt-1.7.1.jar,\
+               lib/c3p0-0.9.2.jar,\
+               lib/ehcache-core-2.4.3.jar,\
+               lib/hamcrest-core-1.3.jar,\
+               lib/jboss-logging-3.1.3.GA.jar,\
+               lib/jboss-transaction-api_1.1_spec-1.0.0.Final.jar,\
+               lib/jdom-1.1.3.jar,\
+               lib/junit-4.11.jar,\
+               lib/log4j-1.2.17.jar,\
+               lib/spring-security-config-3.1.3.RELEASE.jar,\
+               lib/spring-security-core-3.1.3.RELEASE.jar,\
+               lib/spring-security-remoting-3.1.3.RELEASE.jar,\
+               lib/unitils-core-3.4.2.jar,\
+               lib/commons-logging-1.1.1.jar,\
+               lib/commons-lang-2.6.jar,\
+               lib/aopalliance-1.0.jar,\
+               lib/joda-time-2.1.jar,\
+               lib/lsid-client-1.1.2.jar,\
+               lib/lucene-core-3.6.2.jar,\
+               lib/lsid-server-1.1.2.jar,\
+               lib/slf4j-api-1.7.2.jar,\
+               lib/javassist-3.17.1-GA.jar,\
+               src/main/resources/etc/jetty/cdmlib-remote-webapp.war,\
+               lib/unitils-spring-3.4.2.jar,\
+               lib/unitils-database-3.4.2.jar,\
+               lib/commons-dbcp-1.4.jar,\
+               lib/commons-pool-1.5.4.jar,\
+               lib/unitils-dbmaintainer-3.4.2.jar,\
+               lib/h2-1.4.181.jar,\
+               lib/unitils-dbunit-3.4.2.jar,\
+               lib/hibernate-jpa-2.0-api-1.0.1.Final.jar,\
+               lib/hibernate-commons-annotations-4.0.1.Final.jar,\
+               lib/hibernate-core-4.1.10.Final.jar,\
+               lib/hibernate-entitymanager-4.1.10.Final.jar,\
+               lib/hibernate-envers-4.1.10.Final.jar,\
+               lib/hibernate-search-engine-4.2.0.Final.jar,\
+               lib/org.springframework.context-3.2.2.RELEASE.jar,\
+               lib/org.springframework.aop-3.2.2.RELEASE.jar,\
+               lib/org.springframework.aspects-3.2.2.RELEASE.jar,\
+               lib/org.springframework.beans-3.2.2.RELEASE.jar,\
+               lib/org.springframework.core-3.2.2.RELEASE.jar,\
+               lib/org.springframework.expression-3.2.2.RELEASE.jar,\
+               lib/org.springframework.jdbc-3.2.2.RELEASE.jar,\
+               lib/org.springframework.orm-3.2.2.RELEASE.jar,\
+               lib/org.springframework.transaction-3.2.2.RELEASE.jar,\
+               lib/org.springframework.web-3.2.2.RELEASE.jar,\
+               src/main/resources/etc/jetty/jetty-runner-9.1.5.v20140505.jar,\
+               lib/cdmlib-persistence-3.3.8-SNAPSHOT.jar,\
+               lib/dbunit-2.4.9.jar,\
+               lib/opencsv-2.4.jar,\
+               src/test/resources/h2/,\
+               src/test/resources/log4j.properties,\
+               lib/dom4j-1.6.jar,\
+               lib/cdmlib-commons-3.4.0-SNAPSHOT.jar,\
+               lib/cdmlib-ext-3.4.0-SNAPSHOT.jar,\
+               lib/cdmlib-model-3.4.0-SNAPSHOT.jar,\
+               lib/cdmlib-services-3.4.0-SNAPSHOT.jar,\
+               lib/usertype.jodatime-2.0.1.jar,\
+               lib/usertype.spi-2.0.1.jar,\
+               lib/cdmlib-persistence-3.4.0-SNAPSHOT.jar,\
+               lib/wsdl4j-1.6.3.jar,\
+               lib/validation-api-1.1.0.Final.jar,\
+               src/main/resources/eu/etaxonomy/cdmlib/,\
+               lib/org.springframework.context.support-3.2.2.RELEASE.jar,\
+               src/main/resources/cdmlib-ehcache.xml,\
+               src/test/resources/cdmlib-ehcache.xml,\
+               lib/org.springframework.test-3.2.2.RELEASE.jar
+bin.excludes = src/test/
diff --git a/eu.etaxonomy.taxeditor.remoting/lib/.svnignore b/eu.etaxonomy.taxeditor.remoting/lib/.svnignore
new file mode 100644 (file)
index 0000000..d392f0e
--- /dev/null
@@ -0,0 +1 @@
+*.jar
diff --git a/eu.etaxonomy.taxeditor.remoting/pom.xml b/eu.etaxonomy.taxeditor.remoting/pom.xml
new file mode 100644 (file)
index 0000000..80d66e0
--- /dev/null
@@ -0,0 +1,580 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+
+       <parent>
+               <groupId>eu.etaxonomy</groupId>
+               <artifactId>taxeditor-parent</artifactId>
+               <version>3.4.0-SNAPSHOT</version>
+       </parent>
+       <modelVersion>4.0.0</modelVersion>
+       <artifactId>eu.etaxonomy.taxeditor.remoting</artifactId>
+       <packaging>eclipse-plugin</packaging>
+       <name>Remoting Bundle</name>
+       <description>Remoting Plugin Taxonomic Editor</description>
+
+       <build>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-surefire-plugin</artifactId>
+                                       <version>2.7</version>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-dependency-plugin</artifactId>
+                               <version>2.4</version>
+                               <executions>
+                                       <execution>
+                                               <id>copy-dependencies</id>
+                                               <phase>validate</phase>
+                                               <goals>
+                                                       <goal>copy-dependencies</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <excludeArtifactIds>
+                                                               cdmlib-remote-webapp
+                                                       </excludeArtifactIds>
+                                                       <includeArtifactIds>
+                                                               cdmlib-services,cdmlib-commons,cdmlib-persistence,cdmlib-ext,cdmlib-model
+                                                       </includeArtifactIds>
+                                                       <outputDirectory>${basedir}/lib</outputDirectory>
+                                                       <overWriteReleases>true</overWriteReleases>
+                                                       <overWriteSnapshots>true</overWriteSnapshots>
+                                                       <excludeTransitive>true</excludeTransitive>
+                                               </configuration>
+                                       </execution>
+                                       <execution>
+                                               <id>copy-dependency-war</id>
+                                               <phase>validate</phase>
+                                               <goals>
+                                                       <goal>copy-dependencies</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <includeArtifactIds>
+                                                               cdmlib-remote-webapp
+                                                       </includeArtifactIds>
+                                                       <outputDirectory>
+                                                               ${basedir}/src/main/resources/etc/jetty
+                                                       </outputDirectory>
+                                                       <overWriteReleases>true</overWriteReleases>
+                                                       <overWriteSnapshots>true</overWriteSnapshots>
+                                                       <excludeTransitive>true</excludeTransitive>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-antrun-plugin</artifactId>
+                               <version>1.7</version>
+                               <executions>
+                                       <execution>
+                                               <id>update-snapshot-jar-names</id>
+                                               <phase>validate</phase>
+                                               <goals>
+                                                       <goal>run</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <target>
+                                                               <echo>Anonymizing war</echo>
+                                                               <move todir="./src/main/resources/etc/jetty">
+                                                                       <fileset dir="./src/main/resources/etc/jetty" />
+                                                                       <mapper type="regexp"
+                                                                               from="(^cdmlib\-.*)\-[0-9]\.[0-9]\.[0-9]\-SNAPSHOT(\.war)" to="\1\2" />
+                                                               </move>
+                                                               <move todir="./src/main/resources/etc/jetty">
+                                                                       <fileset dir="./src/main/resources/etc/jetty" />
+                                                                       <mapper type="regexp"
+                                                                               from="(^cdmlib\-.*)\-[0-9]\.[0-9]\.[0-9]\-[0-9.-]+(\.war)" to="\1\2" />
+                                                               </move>
+                                                               <echo>Update cdmlib jars to SNAPSHOT when build with
+                                                                       timestamp
+                                                               </echo>
+                                                               <move todir="./lib">
+                                                                       <fileset dir="./lib" />
+                                                                       <mapper type="regexp"
+                                                                               from="(^cdmlib\-.*\-[0-9]\.[0-9]\.[0-9]\-)[0-9.-]+(\.jar)" to="\1SNAPSHOT\2" />
+                                                               </move>
+                                                               <move todir="./lib">
+                                                                       <fileset dir="./lib" />
+                                                                       <mapper type="regexp"
+                                                                               from="(^cdmlib\-.*\-[0-9]\.[0-9]\.[0-9]\-)[0-9.-]+(\-sources\.jar)"
+                                                                               to="\1SNAPSHOT\2" />
+                                                               </move>
+                                                       </target>
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+       <profiles>
+               <profile>
+                       <id>cleanCdmlibJars</id>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <artifactId>maven-clean-plugin</artifactId>
+                                               <version>2.3</version>
+                                               <configuration>
+                                                       <filesets>
+                                                               <fileset>
+                                                                       <directory>${basedir}/lib</directory>
+                                                                       <includes>
+                                                                               <include>cdmlib-*</include>
+                                                                       </includes>
+                                                                       <followSymlinks>false</followSymlinks>
+                                                               </fileset>
+                                                       </filesets>
+                                               </configuration>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+               <profile>
+                       <id>cleanAllJars</id>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <artifactId>maven-clean-plugin</artifactId>
+                                               <version>2.3</version>
+                                               <configuration>
+                                                       <filesets>
+                                                               <fileset>
+                                                                       <directory>${basedir}/lib</directory>
+                                                                       <includes>
+                                                                               <include>*</include>
+                                                                       </includes>
+                                                                       <followSymlinks>false</followSymlinks>
+                                                               </fileset>
+                                                       </filesets>
+                                               </configuration>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+               <profile>
+                       <id>copyAllJars</id>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <groupId>org.apache.maven.plugins</groupId>
+                                               <artifactId>maven-dependency-plugin</artifactId>
+                                               <version>2.4</version>
+                                               <executions>
+                                                       <execution>
+                                                               <id>copy-all-dependencies</id>
+                                                               <phase>validate</phase>
+                                                               <goals>
+                                                                       <goal>copy-dependencies</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <excludeArtifactIds>
+                                                                               cdmlib-remote-webapp
+                                                                       </excludeArtifactIds>
+                                                                       <outputDirectory>${basedir}/lib</outputDirectory>
+                                                                       <overWriteReleases>true</overWriteReleases>
+                                                                       <overWriteSnapshots>true</overWriteSnapshots>
+                                                                       <excludeTransitive>true</excludeTransitive>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+       </profiles>
+       <repositories>
+               <repository>
+                       <id>SpringSource Enterprise Bundle Repository - External Bundle
+                               Milestones
+                       </id>
+                       <url>http://repository.springsource.com/maven/bundles/milestone
+                       </url>
+               </repository>
+               <repository>
+                       <id>SpringSource Enterprise Bundle Repository - SpringSource
+                               Bundle
+                               Releases
+                       </id>
+                       <url>http://repository.springsource.com/maven/bundles/release
+                       </url>
+               </repository>
+               <repository>
+                       <id>SpringSource Enterprise Bundle Repository - External Bundle
+                               Releases
+                       </id>
+                       <url>http://repository.springsource.com/maven/bundles/external
+                       </url>
+               </repository>
+       </repositories>
+       <dependencies>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-remote-webapp</artifactId>
+                       <version>${cdmlib.version}</version>
+                       <type>war</type>
+               </dependency>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-services</artifactId>
+                       <version>${cdmlib.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-commons</artifactId>
+                       <version>${cdmlib.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-persistence</artifactId>
+                       <version>${cdmlib.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-ext</artifactId>
+                       <version>${cdmlib.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>eu.etaxonomy</groupId>
+                       <artifactId>cdmlib-model</artifactId>
+                       <version>${cdmlib.version}</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.unitils</groupId>
+                       <artifactId>unitils-core</artifactId>
+                       <version>3.4.2</version>
+               </dependency>
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-server</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-util</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-xml</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-servlet</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-webapp</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-security</artifactId> -->
+               <!-- <version>9.1.3.v20140225</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-http</artifactId> -->
+               <!-- <version>${jetty.version}</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.eclipse.jetty</groupId> -->
+               <!-- <artifactId>jetty-io</artifactId> -->
+               <!-- <version>${jetty.version}</version> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>javax.servlet</groupId> -->
+               <!-- <artifactId>javax.servlet-api</artifactId> -->
+               <!-- <version>3.1.0</version> -->
+               <!-- </dependency> -->
+
+               <!-- <dependency> -->
+               <!-- <groupId>javax.servlet</groupId> -->
+               <!-- <artifactId>jsp-api</artifactId> -->
+               <!-- <version>2.0</version> -->
+               <!-- </dependency> -->
+
+               <dependency>
+                       <groupId>net.sf.ehcache</groupId>
+                       <artifactId>ehcache-core</artifactId>
+                       <version>2.4.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-core</artifactId>
+                       <version>4.1.10.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate.common</groupId>
+                       <artifactId>hibernate-commons-annotations</artifactId>
+                       <version>4.0.1.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-search-engine</artifactId>
+                       <version>4.2.0.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate.javax.persistence</groupId>
+                       <artifactId>hibernate-jpa-2.0-api</artifactId>
+                       <version>1.0.1.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-envers</artifactId>
+                       <version>4.1.10.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hibernate</groupId>
+                       <artifactId>hibernate-entitymanager</artifactId>
+                       <version>4.1.10.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>dom4j</groupId>
+                       <artifactId>dom4j</artifactId>
+                       <version>1.6</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jadira.usertype</groupId>
+                       <artifactId>usertype.jodatime</artifactId>
+                       <version>2.0.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jadira.usertype</groupId>
+                       <artifactId>usertype.spi</artifactId>
+                       <version>2.0.1</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>4.11</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>log4j</artifactId>
+                       <version>1.2.17</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jdom</groupId>
+                       <artifactId>jdom</artifactId>
+                       <version>1.1.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.context</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.context.support</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.aspects</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.test</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.beans</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.transaction</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.web</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.core</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.aop</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.expression</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.orm</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.jdbc</artifactId>
+                       <version>3.2.2.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>spring-security-core</artifactId>
+                       <version>3.1.3.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>spring-security-config</artifactId>
+                       <version>3.1.3.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>spring-security-remoting</artifactId>
+                       <version>3.1.3.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jboss.logging</groupId>
+                       <artifactId>jboss-logging</artifactId>
+                       <version>3.1.3.GA</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.hamcrest</groupId>
+                       <artifactId>hamcrest-core</artifactId>
+                       <version>1.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.mchange</groupId>
+                       <artifactId>c3p0</artifactId>
+                       <version>0.9.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jboss.spec.javax.transaction</groupId>
+                       <artifactId>jboss-transaction-api_1.1_spec</artifactId>
+                       <version>1.0.0.Final</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.aspectj</groupId>
+                       <artifactId>aspectjrt</artifactId>
+                       <version>1.7.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-logging</groupId>
+                       <artifactId>commons-logging</artifactId>
+                       <version>1.1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-lang</groupId>
+                       <artifactId>commons-lang</artifactId>
+                       <version>2.6</version>
+               </dependency>
+               <dependency>
+                       <groupId>aopalliance</groupId>
+                       <artifactId>aopalliance</artifactId>
+                       <version>1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>joda-time</groupId>
+                       <artifactId>joda-time</artifactId>
+                       <version>2.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.ibm.lsid</groupId>
+                       <artifactId>lsid-client</artifactId>
+                       <version>1.1.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.ibm.lsid</groupId>
+                       <artifactId>lsid-server</artifactId>
+                       <version>1.1.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.lucene</groupId>
+                       <artifactId>lucene-core</artifactId>
+                       <version>3.6.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-api</artifactId>
+                       <version>1.7.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.javassist</groupId>
+                       <artifactId>javassist</artifactId>
+                       <version>3.17.1-GA</version>
+               </dependency>
+               <dependency>
+                       <groupId>au.com.bytecode</groupId>
+                       <artifactId>opencsv</artifactId>
+                       <version>2.4</version>
+               </dependency>
+
+
+               <!-- For Unit Tests Start -->
+               <dependency>
+                       <groupId>org.unitils</groupId>
+                       <artifactId>unitils-spring</artifactId>
+                       <version>3.4.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.unitils</groupId>
+                       <artifactId>unitils-database</artifactId>
+                       <version>3.4.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-dbcp</groupId>
+                       <artifactId>commons-dbcp</artifactId>
+                       <version>1.4</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-pool</groupId>
+                       <artifactId>commons-pool</artifactId>
+                       <version>1.5.4</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.unitils</groupId>
+                       <artifactId>unitils-dbmaintainer</artifactId>
+                       <version>3.4.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.h2database</groupId>
+                       <artifactId>h2</artifactId>
+                       <version>1.4.181</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.unitils</groupId>
+                       <artifactId>unitils-dbunit</artifactId>
+                       <version>3.4.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.dbunit</groupId>
+                       <artifactId>dbunit</artifactId>
+                       <version>2.4.9</version>
+               </dependency>
+               <!-- For Unit Tests End -->
+
+               <!-- For Hibernate Mapping Start -->
+               <dependency>
+                       <groupId>wsdl4j</groupId>
+                       <artifactId>wsdl4j</artifactId>
+                       <version>1.6.3</version>
+               </dependency>
+               <dependency>
+                       <groupId>javax.validation</groupId>
+                       <artifactId>validation-api</artifactId>
+                       <version>1.1.0.Final</version>
+               </dependency>
+               <!-- For Hibernate Mapping End -->
+       </dependencies>
+</project>
\ No newline at end of file
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteConfiguration.java
new file mode 100644 (file)
index 0000000..494194f
--- /dev/null
@@ -0,0 +1,134 @@
+/**\r
+* Copyright (C) 2014 EDIT\r
+* European Distributed Institute of Taxonomy\r
+* http://www.e-taxonomy.eu\r
+*\r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+\r
+package eu.etaxonomy.cdm.api.application;\r
+\r
+import javax.sql.DataSource;\r
+\r
+import org.apache.log4j.Logger;\r
+import org.hibernate.SessionFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.stereotype.Component;\r
+import org.springframework.transaction.PlatformTransactionManager;\r
+import org.springframework.transaction.TransactionStatus;\r
+\r
+import eu.etaxonomy.cdm.api.cache.ICachedCommonService;\r
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;\r
+import eu.etaxonomy.cdm.api.conversation.ConversationHolderMock;\r
+import eu.etaxonomy.cdm.api.service.ICommonService;\r
+import eu.etaxonomy.cdm.ext.geo.IEditGeoService;\r
+import eu.etaxonomy.taxeditor.remoting.session.CdmEntitySessionManager;\r
+\r
+\r
+/**\r
+ * CDM Application Configuration class which manages the configuration for remoting\r
+ * clients\r
+ *\r
+ */\r
+@Component\r
+public class CdmApplicationRemoteConfiguration extends CdmApplicationDefaultConfiguration {\r
+\r
+       @SuppressWarnings("unused")\r
+       private static final Logger logger = Logger.getLogger(CdmApplicationRemoteConfiguration.class);\r
+\r
+       @Autowired\r
+       IEditGeoService editGeoService;\r
+\r
+    @Autowired\r
+    private ICachedCommonService cachedCommonService;\r
+    \r
+       @Autowired\r
+       protected CdmEntitySessionManager cdmEntitySessionManager;\r
+\r
+       public CdmApplicationRemoteConfiguration() {\r
+       }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#getTransactionManager()\r
+     */\r
+    @Override\r
+    public PlatformTransactionManager getTransactionManager() throws UnsupportedOperationException {\r
+               throw new UnsupportedOperationException("getTransactionManager is not implemented for CdmApplicationRemoteConfiguration");\r
+       }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration#startTransaction()\r
+     */\r
+    @Override\r
+    public TransactionStatus startTransaction() throws UnsupportedOperationException {\r
+               throw new UnsupportedOperationException("startTransaction is not implemented for CdmApplicationRemoteConfiguration");\r
+       }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration#startTransaction()\r
+     */\r
+    @Override\r
+    public TransactionStatus startTransaction(Boolean readOnly) throws UnsupportedOperationException {\r
+               throw new UnsupportedOperationException("startTransaction is not implemented for CdmApplicationRemoteConfiguration");\r
+       }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#commitTransaction(org.springframework.transaction.TransactionStatus)\r
+     */\r
+    @Override\r
+    public void commitTransaction(TransactionStatus txStatus) throws UnsupportedOperationException {\r
+               throw new UnsupportedOperationException("commitTransaction is not implemented for CdmApplicationRemoteConfiguration");\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#NewConversation()\r
+        */\r
+       @Override\r
+       public ConversationHolder NewConversation() {\r
+               return new ConversationHolderMock();\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       public IEditGeoService getEditGeoService() {\r
+               return this.editGeoService;\r
+       }\r
+\r
+    /**\r
+     * @return\r
+     */\r
+    public ICachedCommonService getCachedCommonService(){\r
+        return this.cachedCommonService;\r
+    }\r
+    \r
+    \r
+    public CdmEntitySessionManager getCdmEntitySessionManager() {\r
+       return this.cdmEntitySessionManager;\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#setDataSource(javax.sql.DataSource)\r
+        */\r
+       @Override\r
+       public void setDataSource(DataSource dataSource) {\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#setTransactionManager(org.springframework.transaction.PlatformTransactionManager)\r
+        */\r
+       @Override\r
+       public void setTransactionManager(PlatformTransactionManager transactionManager) {\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.application.CdmApplicationDefaultConfiguration#setSessionFactory(org.hibernate.SessionFactory)\r
+        */\r
+       @Override\r
+    public void setSessionFactory(SessionFactory sessionFactory) {\r
+    }\r
+}\r
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java
new file mode 100644 (file)
index 0000000..9253104
--- /dev/null
@@ -0,0 +1,201 @@
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+
+package eu.etaxonomy.cdm.api.application;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.hibernate.collection.internal.AbstractPersistentCollection;
+import org.hibernate.proxy.AbstractLazyInitializer;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
+import eu.etaxonomy.cdm.common.monitor.NullProgressMonitor;
+import eu.etaxonomy.cdm.common.monitor.SubProgressMonitor;
+import eu.etaxonomy.cdm.remote.ICdmRemoteSource;
+import eu.etaxonomy.taxeditor.remoting.session.CdmEntitySessionManager;
+
+/**
+ * CDM Application Controller class for remoting clients
+ *
+ * FIXME:Remoting extending {@link CdmApplicationController} is a temporary workaround.
+ * The {@link CdmApplicationController} should be split into a CdmApplicationControllerBase
+ * class with {@link CdmApplicationController} and this class as subclasses
+ *
+ */
+public class CdmApplicationRemoteController  extends CdmApplicationController {
+
+    private static final Logger logger = Logger.getLogger(CdmApplicationRemoteController.class);
+
+       
+    public static final Resource DEFAULT_REMOTE_APPLICATION_CONTEXT_RESOURCE =
+               new ClassPathResource("/eu/etaxonomy/cdm/remotingApplicationContext.xml");
+    private final Resource applicationContextResource;
+    private final IProgressMonitor progressMonitor;
+
+    
+    /**
+     * Creates new instance of CdmApplicationRemoteController
+     *
+     * @param applicationContextResource
+     * @param remoteSource
+     * @param omitTermLoading
+     * @param progressMonitor
+     * @param listeners
+     * @return
+     */
+    public static CdmApplicationRemoteController NewInstance(Resource applicationContextResource,
+                       ICdmRemoteSource remoteSource,
+                       boolean omitTermLoading,
+                       IProgressMonitor progressMonitor,
+                       List<ApplicationListener> listeners) {
+       return new CdmApplicationRemoteController(applicationContextResource,
+                       remoteSource,
+                       omitTermLoading,
+                       progressMonitor,
+                               listeners);
+
+    }
+    /**
+     * Creates new instance of CdmApplicationRemoteController
+     *
+     * @param applicationContextResource
+     * @param remoteSource
+     * @param omitTermLoading
+     * @param progressMonitor
+     * @param listeners
+     * @return
+     */
+    public static CdmApplicationRemoteController NewInstance(ICdmRemoteSource remoteSource,
+                       boolean omitTermLoading,
+                       IProgressMonitor progressMonitor,
+                       List<ApplicationListener> listeners) {
+
+       return new CdmApplicationRemoteController(DEFAULT_REMOTE_APPLICATION_CONTEXT_RESOURCE,
+                       remoteSource,
+                       omitTermLoading,
+                       progressMonitor,
+                               listeners);
+
+    }
+
+       /**
+        * Constructs CdmApplicationRemoteController
+        *
+        * @param applicationContextResource
+        * @param remoteSource
+        * @param omitTermLoading
+        * @param progressMonitor
+        * @param listeners
+        */
+       private CdmApplicationRemoteController(Resource applicationContextResource,
+                               ICdmRemoteSource remoteSource,
+                               boolean omitTermLoading,
+                               IProgressMonitor progressMonitor,
+                               List<ApplicationListener> listeners){
+               logger.info("Start CdmApplicationRemoteController with remote source: " + remoteSource.getName());
+        this.applicationContextResource =
+                       applicationContextResource != null ? applicationContextResource : DEFAULT_REMOTE_APPLICATION_CONTEXT_RESOURCE;
+        this.progressMonitor = progressMonitor != null ? progressMonitor : new NullProgressMonitor();
+
+        setNewRemoteSource(remoteSource, omitTermLoading, listeners);
+
+       }
+
+
+
+
+    /**
+     * Creates and starts a new spring application context
+     *
+     * @param remoteSource object for connecting to an http-invoker server
+     * @param omitTermLoading
+     * @param listeners
+     * @return
+     */
+    protected boolean setNewRemoteSource(ICdmRemoteSource remoteSource,
+               boolean omitTermLoading,
+               List<ApplicationListener> listeners){
+
+        logger.info("Connecting to '" + remoteSource.getName() + "'");
+
+        MonitoredGenericApplicationContext applicationContext =  new MonitoredGenericApplicationContext();
+        int refreshTasks = 45;
+        int nTasks = 5 + refreshTasks;
+
+        progressMonitor.beginTask("Connecting to '" + remoteSource.getName() + "'", nTasks);
+
+        progressMonitor.subTask("Registering remote source.");
+        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
+        Properties properties = new Properties();
+        properties.setProperty("remoteServer", remoteSource.getServer());
+        properties.setProperty("remotePort", String.valueOf(remoteSource.getPort()));
+        properties.setProperty("remoteContext", remoteSource.getContextPath());
+        pspc.setProperties(properties);
+        applicationContext.addBeanFactoryPostProcessor(pspc);
+        applicationContext.getEnvironment().setActiveProfiles("remoting");
+        progressMonitor.worked(1);
+
+        XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(applicationContext);
+        //xmlReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
+        progressMonitor.subTask("Registering resources.");
+        xmlReader.loadBeanDefinitions(applicationContextResource);
+        progressMonitor.worked(1);
+
+        //omitTerms
+        if (omitTermLoading == true){
+            String initializerName = "persistentTermInitializer";
+            BeanDefinition beanDef = applicationContext.getBeanDefinition(initializerName);
+            MutablePropertyValues values = beanDef.getPropertyValues();
+            values.addPropertyValue("omit", omitTermLoading);
+        }
+
+        if (listeners != null){
+            for(ApplicationListener listener : listeners){
+                applicationContext.addApplicationListener(listener);
+            }
+        }
+
+
+        applicationContext.refresh(new SubProgressMonitor(progressMonitor, refreshTasks));
+        applicationContext.start();
+
+        progressMonitor.subTask("Cleaning up.");
+        setApplicationContext(applicationContext);
+        progressMonitor.worked(1);
+
+        progressMonitor.done();
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.cdm.api.application.CdmApplicationController#init()
+     */
+    @Override
+    protected void init(){
+        configuration = (ICdmApplicationConfiguration)applicationContext.getBean("cdmApplicationRemoteConfiguration");
+               AbstractLazyInitializer.setConfiguration((CdmApplicationRemoteConfiguration)configuration);
+               AbstractPersistentCollection.setConfiguration((CdmApplicationRemoteConfiguration)configuration);
+
+    }
+
+    public CdmEntitySessionManager getCdmEntitySessionManager() {
+       return ((CdmApplicationRemoteConfiguration)configuration).getCdmEntitySessionManager();
+    }
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CachedCommonServiceImpl.java
new file mode 100644 (file)
index 0000000..0a10de1
--- /dev/null
@@ -0,0 +1,192 @@
+// $Id$
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.api.cache;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.hibernate.collection.internal.PersistentList;
+import org.hibernate.collection.internal.PersistentMap;
+import org.hibernate.collection.internal.PersistentSet;
+import org.hibernate.collection.internal.PersistentSortedMap;
+import org.hibernate.collection.internal.PersistentSortedSet;
+import org.hibernate.collection.spi.PersistentCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.api.cache.CdmEntityCachingUtils.CollectionType;
+import eu.etaxonomy.cdm.api.service.ICommonService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
+import eu.etaxonomy.taxeditor.remoting.session.CdmEntitySessionManager;
+import eu.etaxonomy.taxeditor.remoting.CdmRemotingException;
+
+/**
+ * @author cmathew
+ * @date 14 Oct 2014
+ *
+ */
+@Component
+public class CachedCommonServiceImpl implements ICachedCommonService {
+
+
+    @Autowired
+    private ICommonService commonService;
+
+    private static boolean cacheEnabled = true;
+
+    @Autowired
+    private CdmEntitySessionManager cdmEntitySessionManager;
+
+    @Autowired
+    private CdmEntityCachingUtils cdmEntityCachingUtils;
+
+
+    public static boolean isCacheEnabled() {
+        return cacheEnabled;
+    }
+
+    public static void setCacheEnabled(boolean cacheEnabled) {
+        CachedCommonServiceImpl.cacheEnabled = cacheEnabled;
+    }
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#find(java.lang.Class, int)
+     */
+    @Override
+    public CdmBase find(Class<? extends CdmBase> clazz, int id) {
+        if(cacheEnabled) {
+            CdmBase cdmEntity = CdmBase.deproxy(commonService.find(clazz, id),clazz);
+            return cdmEntitySessionManager.getActiveCdmTransientEntityCacher().load(cdmEntity, true);
+        } else {
+            return CdmBase.deproxy(commonService.find(clazz, id),clazz);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#initializeCollection(org.hibernate.collection.spi.PersistentCollection)
+     */
+    @Override
+    public PersistentCollection initializeCollection(PersistentCollection col) {
+            PersistentCollection pc = commonService.initializeCollection(col);
+            return pc;
+    }
+
+    @Override
+    public void updatePersistentCollection(CollectionField colf) {
+       if(cacheEnabled) {
+               cdmEntitySessionManager.getActiveCdmTransientEntityCacher().load(colf.getCollection(), true);
+       }
+    }
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#isEmpty(org.hibernate.collection.spi.PersistentCollection)
+     */
+    @Override
+    public boolean isEmpty(PersistentCollection col) {
+            return commonService.isEmpty(col);
+
+    }
+
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#size(org.hibernate.collection.spi.PersistentCollection)
+     */
+    @Override
+    public int size(PersistentCollection col) {
+        return commonService.size(col);
+    }
+
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#get(org.hibernate.collection.spi.PersistentCollection, int)
+     */
+    @Override
+    public Object get(PersistentCollection col, int index) {
+        return commonService.get(col, index);
+    }
+
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#contains(org.hibernate.collection.spi.PersistentCollection, java.lang.Object)
+     */
+    @Override
+    public boolean contains(PersistentCollection col, Object element) {
+        return commonService.contains(col, element);
+    }
+
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#containsKey(org.hibernate.collection.spi.PersistentCollection, java.lang.Object)
+     */
+    @Override
+    public boolean containsKey(PersistentCollection col, Object key) {
+        return commonService.containsKey(col, key);
+    }
+
+
+    /* (non-Javadoc)
+     * @see eu.etaxonomy.taxeditor.remoting.service.ICachedCommonService#containsValue(org.hibernate.collection.spi.PersistentCollection, java.lang.Object)
+     */
+    @Override
+    public boolean containsValue(PersistentCollection col, Object element) {
+        return commonService.containsValue(col, element);
+    }
+
+    @SuppressWarnings("rawtypes")
+       @Override
+    public CollectionField getCollectionField(PersistentCollection pc) {
+        if(pc != null) {
+            if(pc instanceof PersistentSet) {
+                return new CollectionField(new HashSet((Set)pc), CollectionType.SET);
+            }
+            if(pc instanceof PersistentSortedSet) {
+                return new CollectionField(new TreeSet((Set)pc), CollectionType.SET);
+            }
+            if(pc instanceof PersistentList) {
+                return new CollectionField(new ArrayList((List)pc), CollectionType.LIST);
+            }
+            if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
+                return new CollectionField(new HashMap((Map)pc), CollectionType.MAP);
+            }
+            if(pc instanceof PersistentSortedMap) {
+                return new CollectionField(new TreeMap((Map)pc), CollectionType.MAP);
+            }
+            throw new CdmRemotingException("Cannot get Collection field for type " + pc.getClass().getName());
+        }
+        return null;
+    }
+
+    public class CollectionField {
+        private final Object col;
+        private final CollectionType type;
+        public CollectionField(Object col, CollectionType type) {
+            this.col = col;
+            this.type = type;
+        }
+
+        public Object getCollection() {
+            return this.col;
+        }
+
+        public CollectionType getType() {
+            return this.type;
+        }
+    }
+
+
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmClientCacheException.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmClientCacheException.java
new file mode 100644 (file)
index 0000000..3b7edba
--- /dev/null
@@ -0,0 +1,12 @@
+package eu.etaxonomy.cdm.api.cache;
+
+public class CdmClientCacheException extends RuntimeException {
+       
+       public CdmClientCacheException(String message) {
+               super(message);
+       }
+
+       public CdmClientCacheException(Exception e) {
+               super(e);
+       }
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheKey.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCacheKey.java
new file mode 100644 (file)
index 0000000..476522a
--- /dev/null
@@ -0,0 +1,56 @@
+package eu.etaxonomy.cdm.api.cache;
+
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+public class CdmEntityCacheKey {
+
+       private Class<? extends CdmBase> persistenceClass;
+       private int persistenceId;
+       
+       public CdmEntityCacheKey(CdmBase cdmBase) {
+               this.persistenceClass = cdmBase.getClass();
+               this.persistenceId = cdmBase.getId();
+       }
+       
+       public CdmEntityCacheKey(Class<? extends CdmBase> clazz, int id) {
+               this.persistenceClass = clazz;
+               this.persistenceId = id;
+       }
+       
+
+       
+       public Class<? extends CdmBase> getPersistenceClass() {
+               return persistenceClass;
+       }
+       
+       public int getPersistenceId() {
+               return persistenceId;
+       }
+       @Override
+       public boolean equals(Object obj) {
+               if(obj == null || !(obj instanceof CdmEntityCacheKey)) {
+                       return false;
+               }
+               
+               if(this == obj) {
+                       return true;
+               }
+               CdmEntityCacheKey that = (CdmEntityCacheKey) obj;
+               if(this.persistenceClass.equals(that.persistenceClass) && this.persistenceId == that.persistenceId) {
+                       return true;
+               }
+               
+               return false;
+       }
+       
+       @Override
+       public int hashCode() {
+               return (this.persistenceClass.getName() + String.valueOf(this.persistenceId)).hashCode();
+       }
+       
+       @Override
+       public String toString() {
+               return this.persistenceClass.getName() + String.valueOf(this.persistenceId);
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCachingUtils.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmEntityCachingUtils.java
new file mode 100644 (file)
index 0000000..1a3b99c
--- /dev/null
@@ -0,0 +1,86 @@
+// $Id$
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.api.cache;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sf.ehcache.Cache;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.taxeditor.remoting.session.CdmEntitySessionManager;
+
+/**
+ * @author cmathew
+ * @date 15 Oct 2014
+ *
+ */
+@Component
+public class CdmEntityCachingUtils {
+
+    @Autowired
+    private CdmEntitySessionManager cdmEntityCacheManager;
+    
+   
+
+    public static enum CollectionType {
+        SET,
+        LIST,
+        MAP;
+
+        @Override
+        public String toString() {
+            return this.name().toLowerCase();
+        }
+    }
+
+    public void cachify(Map<Object,Object> map) {
+        if(map == null || map.isEmpty()) {
+            return;
+        }
+
+        int originalMapSize = map.size();
+        Object[] result = new Object[ map.size() * 2 ];
+        Iterator<Map.Entry<Object,Object>> iter = map.entrySet().iterator();
+        int i=0;
+        while ( iter.hasNext() ) {
+            Map.Entry<Object,Object> e = (Map.Entry<Object,Object>) iter.next();
+            result[i++] = e.getKey();
+            result[i++] = e.getValue();
+        }
+
+        for(i=0; i<result.length;i++) {
+            if(result[i] instanceof CdmBase) {
+                CdmBase cdmBase = (CdmBase)result[i];
+                CdmBase cachedCdmBase = cdmEntityCacheManager.getActiveCdmTransientEntityCacher().load(cdmBase, true);
+                result[i] = cachedCdmBase;
+            }
+        }
+        map.clear();
+        for(i = 0; i < originalMapSize; i+=2 ) {
+            map.put(
+                    result[i],
+                    result[i+1]
+                );
+        }
+
+    }
+    
+    public void cachify(CdmBase cdmBase, boolean recursive) {
+       
+       
+    }
+
+
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelCacher.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelCacher.java
new file mode 100644 (file)
index 0000000..ae20c6a
--- /dev/null
@@ -0,0 +1,184 @@
+package eu.etaxonomy.cdm.api.cache;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+
+
+public class CdmModelCacher {
+
+
+       private static final Logger logger = Logger.getLogger(CdmModelCacher.class);
+
+       private List<CdmModelFieldPropertyFromClass> cmgmfcList = new ArrayList<CdmModelFieldPropertyFromClass>();
+
+       public void cacheGetters() {
+
+               Configuration configuration = new Configuration().configure("/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml");
+               configuration.buildMappings();
+               Iterator<PersistentClass> classMappingIterator =   configuration.getClassMappings();                      
+
+               Cache cache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
+               cache.removeAll();
+
+               while(classMappingIterator.hasNext()) {
+                       PersistentClass persistentClass = classMappingIterator.next();
+                       Class mappedClass = persistentClass.getMappedClass();
+                       String mappedClassName = mappedClass.getName();
+
+                       CdmModelFieldPropertyFromClass cmgmfc = new CdmModelFieldPropertyFromClass(mappedClassName);
+                       Iterator propertyIt = persistentClass.getPropertyIterator();       
+
+                       logger.info("Adding class : " + mappedClassName + " to cache");
+                                               
+                       while(propertyIt.hasNext())
+                       {
+                               Property property = (Property)propertyIt.next();
+                               Getter getter = property.getGetter(mappedClass);              
+                               if(getter != null && getter.getMember() != null) {         
+                                       Field field = (Field)getter.getMember();
+                                       String getMethod = getMethodNameFromFieldName(field.getName(), field.getType().getName());                                      
+                                       logger.info(" - getMethod : " + getMethod + " for type " + field.getType().getName());
+                                       cmgmfc.addGetMethods(getMethod);
+                               }
+                       }
+                       cache.put(new Element(mappedClassName, cmgmfc));
+
+               }
+               cache.flush();
+       }
+       
+       public void cacheGetterFields() {
+
+               Configuration configuration = new Configuration().configure("/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml");
+               configuration.buildMappings();
+               Iterator<PersistentClass> classMappingIterator =   configuration.getClassMappings();                      
+
+               Cache cache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
+               cache.removeAll();
+
+               while(classMappingIterator.hasNext()) {
+                       PersistentClass persistentClass = classMappingIterator.next();
+                       Class mappedClass = persistentClass.getMappedClass();
+                       String mappedClassName = mappedClass.getName();
+
+                       CdmModelFieldPropertyFromClass cmgmfc = new CdmModelFieldPropertyFromClass(mappedClassName);
+                       Iterator propertyIt = persistentClass.getPropertyIterator();       
+
+                       logger.info("Adding class : " + mappedClassName + " to cache");
+                                               
+                       while(propertyIt.hasNext())
+                       {
+                               Property property = (Property)propertyIt.next();
+                               Getter getter = property.getGetter(mappedClass);              
+                               if(getter != null && getter.getMember() != null) {         
+                                       Field field = (Field)getter.getMember();
+                                       //String getMethod = getMethodNameFromFieldName(field.getName(), field.getType().getName());                                    
+                                       logger.info(" - contains field '" + field.getName() + "' of type '" + field.getType().getName() + "'");
+                                       cmgmfc.addGetMethods(field.getName());
+                               }
+                       }
+                       cache.put(new Element(mappedClassName, cmgmfc));
+
+               }
+               cache.flush();
+       }
+       
+       public void checkGetterMethods() {
+
+               Configuration configuration = new Configuration().configure("/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml");
+               configuration.buildMappings();
+               Iterator<PersistentClass> classMappingIterator =   configuration.getClassMappings();                      
+
+               Cache cache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
+               cache.removeAll();
+
+               while(classMappingIterator.hasNext()) {
+                       PersistentClass persistentClass = classMappingIterator.next();
+                       Class mappedClass = persistentClass.getMappedClass();
+                       String mappedClassName = mappedClass.getName();
+                       
+                       Iterator propertyIt = persistentClass.getPropertyIterator();       
+                       
+                       Method[] methods = mappedClass.getMethods();
+
+                       while(propertyIt.hasNext())
+                       {
+                               Property property = (Property)propertyIt.next();
+                               Getter getter = property.getGetter(mappedClass);              
+                               if(getter != null && getter.getMember() != null) {         
+                                       Field field = (Field)getter.getMember();
+                                       String getMethod = getMethodNameFromFieldName(field.getName(), field.getType().getName());                                      
+                                       
+                                       boolean foundMethod = false;
+                                       for(Method method : methods) {
+                                               if(method.getName().equals(getMethod)) {
+                                                       foundMethod = true;
+                                                       break;
+                                               }
+                                       }
+                                       if(!foundMethod) {
+                                               logger.info("Inferred method " + getMethod + " does not exist in class " + mappedClassName);
+                                               //throw new CdmClientCacheException("Inferred method " + getMethod + " does not exist in class " + mappedClassName);
+                                       }
+                               }
+                       }
+                       
+
+               }
+               
+       }
+
+       public List<CdmModelFieldPropertyFromClass> getCdmModelGetMethodFromClassList() {
+               cmgmfcList.clear();
+               Configuration configuration = new Configuration().configure("/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml");
+               configuration.buildMappings();
+               Iterator<PersistentClass> classMappingIterator =   configuration.getClassMappings();                                                             
+
+               while(classMappingIterator.hasNext()) {
+                       PersistentClass persistentClass = classMappingIterator.next();
+                       Class mappedClass = persistentClass.getMappedClass();
+                       String mappedClassName = mappedClass.getName();
+
+                       CdmModelFieldPropertyFromClass cmgmfc = new CdmModelFieldPropertyFromClass(mappedClassName);
+                       Iterator propertyIt = persistentClass.getPropertyIterator();       
+
+                       while(propertyIt.hasNext())
+                       {
+                               Property property = (Property)propertyIt.next();
+                               Getter getter = property.getGetter(mappedClass);              
+                               if(getter != null && getter.getMember() != null) {      
+                                       Field field = (Field)getter.getMember();
+                                       String getMethod = getMethodNameFromFieldName(getter.getMember().getName(),field.getType().getName());                   
+                                       cmgmfc.addGetMethods(getMethod);
+                               }
+                       }
+                       cmgmfcList.add(cmgmfc);
+               }
+               return cmgmfcList;
+
+       }
+
+       public static String getMethodNameFromFieldName(String fieldName, String type) {
+               String prefix = type != null && type.toLowerCase().endsWith("boolean") ? "is" : "get";          
+               String getMethod =  prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+               return getMethod;
+       }
+       
+
+
+
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelFieldPropertyFromClass.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmModelFieldPropertyFromClass.java
new file mode 100644 (file)
index 0000000..37cb812
--- /dev/null
@@ -0,0 +1,51 @@
+package eu.etaxonomy.cdm.api.cache;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CdmModelFieldPropertyFromClass implements Serializable {
+
+       private static final long serialVersionUID = 5726395976531887526L;
+       private String className;
+       private String parentClassName;
+       
+       private List<String> fields = new ArrayList<String>();
+       
+       
+       public CdmModelFieldPropertyFromClass(String className) {
+               this.setClassName(className);
+       }
+       
+       public String getParentClassName() {
+               return parentClassName;
+       }
+
+       public void setParentClassName(String parentClassName) {
+               this.parentClassName = parentClassName;
+       }
+
+       public List<String> getFields() {
+               return fields;
+       }
+
+       public void setFields(List<String> fields) {
+               this.fields = fields;
+       }
+       
+       public void addGetMethods(String getMethod) {
+               this.fields.add(getMethod);
+       }
+
+       public String getClassName() {
+               return className;
+       }
+
+       public void setClassName(String className) {
+               this.className = className;
+       }
+       
+
+       
+       
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmRemoteCacheManager.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmRemoteCacheManager.java
new file mode 100644 (file)
index 0000000..330a64c
--- /dev/null
@@ -0,0 +1,75 @@
+package eu.etaxonomy.cdm.api.cache;
+
+import java.io.IOException;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.CacheManager;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.stereotype.Component;
+
+
+public class CdmRemoteCacheManager {   
+       
+       private CacheManager cdmlibModelCacheManager;
+       private CacheManager defaultCacheManager;
+       
+       private static CdmRemoteCacheManager cdmRemoteCacheManager = null;
+       
+    public static final Resource CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE =
+            new ClassPathResource("/cdmlib-ehcache.xml");
+    
+       
+    public enum CdmCacheManagerType {
+       CDMLIB_MODEL,
+       DEFAULT
+    }
+
+    public static CdmRemoteCacheManager getInstance(){
+       if(cdmRemoteCacheManager == null) {             
+               cdmRemoteCacheManager = new CdmRemoteCacheManager();            
+       }
+       return cdmRemoteCacheManager;
+    }
+    private CdmRemoteCacheManager() {
+       checkCacheProperties();
+       try {
+               String cacheFilePath = CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE.getFile().getAbsolutePath();
+                       cdmlibModelCacheManager = new CacheManager(cacheFilePath);
+                       
+               } catch (CacheException e) {
+                       throw new CdmClientCacheException(e);
+               } catch (IOException e) {
+                       throw new CdmClientCacheException(e);
+               }
+    }
+    
+       public Cache getCdmModelGetMethodsCache(){
+               return cdmlibModelCacheManager.getCache("cdmModelGetMethodsCache");
+       }
+       
+       public void shutdown(CdmCacheManagerType ccmt) {
+               CacheManager cm;
+               switch(ccmt) {          
+               case CDMLIB_MODEL:                      
+                       cdmlibModelCacheManager.shutdown();
+                       break;
+               case DEFAULT:
+                       cm = CacheManager.create();
+                       cm.shutdown();
+                       break;
+               default:
+                       //do nothing
+               }               
+       }
+       
+       public static void checkCacheProperties() {
+               String pathToCache = System.getProperty("ehcache.disk.store.dir");
+               if(pathToCache == null || pathToCache.isEmpty()) {
+                       throw new CdmClientCacheException("'ehcache.disk.store.dir' property is not set");
+               }
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java
new file mode 100644 (file)
index 0000000..c7d6bac
--- /dev/null
@@ -0,0 +1,35 @@
+package eu.etaxonomy.cdm.api.cache;
+
+import java.util.UUID;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.api.cache.CdmCacher;
+import eu.etaxonomy.cdm.api.service.ITermService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * Class which uses CDM services to cache cdm entities
+ *
+ * FIXME: Currently only handles terms entities. It would be
+ *        interesting to have a generic method which finds the
+ *        correct service to load / cache the entity.
+ *
+ * @author cmathew
+ *
+ * @param <T>
+ */
+@Component
+public class CdmServiceCacher extends CdmCacher {
+
+       @Autowired
+       ITermService termService;
+
+       @Override
+       protected CdmBase findByUuid(UUID uuid) {
+               CdmBase term = termService.findWithoutFlush(uuid);
+               return term;
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/CdmTransientEntityCacher.java
new file mode 100644 (file)
index 0000000..2387c23
--- /dev/null
@@ -0,0 +1,464 @@
+// $Id$
+/**
+ * Copyright (C) 2014 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.cdm.api.cache;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javassist.util.proxy.ProxyFactory;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
+import org.apache.log4j.Logger;
+import org.hibernate.collection.spi.PersistentCollection;
+import org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ReflectionUtils;
+
+import eu.etaxonomy.cdm.api.service.ICommonService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * 
+ * This cache guarantees that
+ *  - all objects put will be ancestors of CdmBase
+ *  - all CdmBase objects in the cache will be already de-proxied
+ *  - after any CdmBase object is put in the cache, 
+ *  all non-null / non-proxy CdmBase objects in the sub-graph 
+ *  will also be present in the cache.
+ *   
+ * @author cmathew
+ * @date 14 Oct 2014
+ *
+ */
+
+public class CdmTransientEntityCacher extends CdmServiceCacher {
+
+       private static final Logger logger = Logger.getLogger(CdmTransientEntityCacher.class);
+
+       @Autowired
+       private CdmEntityCachingUtils cdmEntityCachingUtils;
+
+    @Autowired
+    private ICommonService commonService;
+    
+       private String cacheId;
+
+       private Cache cache; 
+
+       private Cache cdmlibModelCache;
+
+       private static boolean isRecursiveEnabled = true;
+
+
+       public CdmTransientEntityCacher(String cacheId) {
+               this.cacheId = cacheId;
+
+               cache = new Cache(getEntityCacheConfiguration(cacheId));                
+               getDefaultCacheManager().addCache(cache);
+
+               cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
+
+       }
+
+       public CdmTransientEntityCacher(Object obj) {
+               this(obj.getClass().getName() +  String.valueOf(obj.hashCode()));
+       }
+
+       /**
+        * Returns the default cache configuration.
+        *
+        * @return
+        */
+       private CacheConfiguration getEntityCacheConfiguration(String cacheId) {
+               // For a better understanding on how to size caches, refer to
+               // http://ehcache.org/documentation/configuration/cache-size
+               return new CacheConfiguration(cacheId, 500)        
+               .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)
+               .eternal(false)
+               // default ttl and tti set to 2 hours
+               .timeToLiveSeconds(60*60*2)
+               .timeToIdleSeconds(60*60*2);
+
+       }
+
+
+       /**
+        * Returns the cache corresponding to the cache id
+        *
+        * @param cacheId
+        * @return
+        */
+       private Cache getCache() {
+               return getDefaultCacheManager().getCache(cacheId);
+       }
+
+       public <T extends Object> T load(T obj, boolean recursive) {
+               if(obj instanceof CdmBase) {
+                       return load(obj, recursive);
+               } else if (obj instanceof Map) {
+                       return load(obj, recursive);
+               }
+               
+               return obj;
+       }
+       
+       @SuppressWarnings("unchecked")
+       private <T extends Object> T loadRecursive(T obj, Set<CdmBase> alreadyVisitedEntities) {
+               if(obj instanceof CdmBase) {
+                       return loadRecursive(obj, alreadyVisitedEntities);
+               } else if (obj instanceof Map) {
+                       return (T) load((Map<T,T>)obj, alreadyVisitedEntities);
+               }
+               logger.info("No caching yet for type " + obj.getClass().getName());
+               
+               return obj;
+       }
+       
+       public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive){
+               if(isRecursiveEnabled && recursive) {
+                       logger.info("---- starting recursive load for map");
+                       Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
+                       Map<T,T> cachedMap = load(map, alreadyVisitedEntities);
+                       alreadyVisitedEntities.clear();
+                       logger.info("---- ending recursive load for cdm entity map \n");
+                       return cachedMap;
+               } else {
+                       return load(map, null);
+               }
+       }
+
+       private <T extends Object> Map<T,T> load(Map<T,T> map, Set<CdmBase> alreadyVisitedEntities){
+        if(map == null || map.isEmpty()) {
+            return map;
+        }
+
+        int originalMapSize = map.size();
+        Object[] result = new Object[ map.size() * 2 ];
+        Iterator<Map.Entry<T,T>> iter = map.entrySet().iterator();
+        int i=0;
+        while ( iter.hasNext() ) {
+            Map.Entry<T,T> e = (Map.Entry<T,T>) iter.next();
+            result[i++] = e.getKey();
+            result[i++] = e.getValue();
+        }
+
+        for(i=0; i<result.length;i++) {            
+               if(alreadyVisitedEntities == null) {
+                       result[i] = load(result[i], false);
+               } else {                              
+                       result[i] = loadRecursive(result[i], alreadyVisitedEntities);
+               }
+        }
+        map.clear();
+        for(i = 0; i < originalMapSize; i+=2 ) {
+            map.put(
+                    (T)result[i],
+                    (T)result[i+1]
+                );
+        }
+        return map;
+       }
+       /**
+        * Puts the (Key,Value) pair of ({@link java.util.UUID}, {@link eu.etaxonomy.cdm.model.common.CdmBase}),
+        * in the cache corresponding to the given cache id
+        *
+        * @param cacheId
+        * @param uuid
+        * @param cdmEntity
+        */
+       public CdmBase load(CdmBase cdmEntity, boolean recursive) {
+               
+               if(isRecursiveEnabled && recursive) {
+                       logger.info("---- starting recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
+                       Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
+                       CdmBase cb =  loadRecursive(cdmEntity, alreadyVisitedEntities);
+                       alreadyVisitedEntities.clear();
+                       logger.info("---- ending recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + "\n");
+                       return cb;
+               } else {
+                       return load(cdmEntity);
+               }
+               
+               // split into two methods 
+               // - load(CdmBase cdmBase)
+               // - recursiveLoad(CdmBase cdmbase, List<CdmBase> alreadyVisitedEntities) 
+               //   : the entity to be visted should added before the recursive call
+               //     and deleted after the call to end finally with a list
+               //     of size zero at the end
+               //   : entity to recurse should be the original entity and
+               //     not the cached one
+               
+       }
+
+       
+       private CdmBase load(CdmBase cdmEntity) {
+               logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
+
+               // start by looking up the cdm entity in the cache
+               CdmBase cachedCdmEntity = getFromCache(cdmEntity);
+               
+               if(cachedCdmEntity != null) {
+                       // if cdm entity was found in cache then return ...
+                       logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists");
+                       return cachedCdmEntity;
+               } else {                
+                       // ... else save the entity in the cache        
+                       getCache().put(new Element(generateKey(cdmEntity), cdmEntity));
+                       logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " put in cache");
+                       return cdmEntity;
+               }         
+       }
+       
+       private CdmBase loadRecursive(CdmBase cdmEntity, Set<CdmBase> alreadyVisitedEntities) {
+
+               CdmBase cachedCdmEntity = load(cdmEntity);
+               
+               // we want to recursive through the cdmEntity (and not the cachedCdmEntity)
+               // since there could be new initialized object in the cdmEntity sub-graph
+               
+               // start by getting the fields from the cdm entity
+               String className = cdmEntity.getClass().getName();
+               CdmModelFieldPropertyFromClass cmgmfc = getFromCdmlibModelCache(className);
+               if(cmgmfc != null) {
+                       alreadyVisitedEntities.add(cdmEntity);
+                       List<String> fields = cmgmfc.getFields();
+                       for(String field : fields) {
+                               // retrieve the actual object corresponding to the field.
+                               // this object will be either a CdmBase or a Collection / Map
+                               // with CdmBase as the generic type
+
+                               // In the case that the returned is either a Collection or a Map
+                               // the individual objects inside these also need to be loaded
+                               // by calling the corresponding cachify method in the
+                               // CdmEntityCachingUtils   
+                                                               
+                               CdmBase cdmEntityInSubGraph = getCdmBaseTypeFieldValue(cdmEntity, cachedCdmEntity, field);
+                               if(cdmEntityInSubGraph != null && !alreadyVisitedEntities.contains(cdmEntityInSubGraph)) {                                                                                              
+                                       logger.info("recursive loading object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId());
+                                       loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities);
+                               }                               
+                       }
+               }
+               return cachedCdmEntity;
+       }
+
+       
+       private CdmBase getCdmBaseTypeFieldValue(CdmBase cdmEntity, CdmBase cachedCdmEntity, String fieldName) {
+               
+               
+               if(cachedCdmEntity == null) {
+                       throw new CdmClientCacheException("When trying to set filed value, the cached cdm entity cannot be null");
+               }
+               
+               Class<?> clazz = cdmEntity.getClass();
+               try {
+                       // this call will search in the provided class as well as
+                       // the super classes until it finds the field
+                       Field field = ReflectionUtils.findField(clazz, fieldName);
+                       //                      logger.info("Retrieving field " + field
+                       //                                      + " from cdm entity of type " + c.getName() 
+                       //                                      + " with id " + cdmEntity.getId());
+
+
+                       if(field == null) {
+                               throw new CdmClientCacheException("Field '" + fieldName 
+                                               + "' not found when searching in class '" + clazz.getName() + "' and its supercalsses");
+                       }
+                       field.setAccessible(true);
+                       Object o = field.get(cdmEntity);
+                       //                      if(o == null) {
+                       //                              logger.info(" - resulting object is null");
+                       //                      } else if(ProxyFactory.isProxyClass(o.getClass())) {
+                       //                              logger.info(" - resulting object is a proxy object");
+                       //                      } else if(o instanceof PersistentCollection) {
+                       //                              logger.info(" - resulting object is a persistent collection object");
+                       //                      } else {                        
+                       //                              logger.info(" - resulting object is of type " + o.getClass().getName());
+                       //                      }
+                       CdmBase cdmEntityInSubGraph = null;
+                       if(o != null 
+                                       && !ProxyFactory.isProxyClass(o.getClass()) 
+                                       && !(o instanceof PersistentCollection)                                         
+                                       && CdmBase.class.isAssignableFrom(o.getClass())) {
+                               //                              logger.info("retrieving object of type " + o.getClass().getName() 
+                               //                                              + " with id " + ((CdmBase)o).getId());
+                               
+                               //FIXME:Remoting add case for collection / map
+                               //FIXME:Remoting if cached entity != original entity then
+                               //               replace original with cache using
+                               //               field.set and return original entity
+                               cdmEntityInSubGraph  = (CdmBase)o;
+                               
+                               CdmBase cachedCdmEntityInSubGraph = getFromCache(cdmEntityInSubGraph);
+
+                               if(cachedCdmEntityInSubGraph != null) {
+                                       if(cachedCdmEntityInSubGraph != cdmEntityInSubGraph) {                          
+                                               field.set(cachedCdmEntity, cachedCdmEntityInSubGraph);
+                                       }
+                               } else {
+                                       field.set(cachedCdmEntity, cdmEntityInSubGraph);
+                               }
+                       } 
+                       // we return the original cdm entity in the sub graph because we
+                       // want to continue to recurse on the input cdm entity graph
+                       // and not the one in the cache
+                       return cdmEntityInSubGraph;
+               } catch (SecurityException e) {
+                       throw new CdmClientCacheException(e);
+               } catch (IllegalArgumentException e) {
+                       throw new CdmClientCacheException(e);
+               } catch (IllegalAccessException e) {
+                       throw new CdmClientCacheException(e);
+               }        
+       }
+
+       public void put(CdmBase cdmEntity) {            
+               CdmEntityCacheKey id = new CdmEntityCacheKey(cdmEntity);
+               Element cachedCdmEntityElement = getCacheElement(id);
+
+               if(cachedCdmEntityElement == null) {
+                       cachedCdmEntityElement = getCacheElement(cdmEntity.getUuid());
+                       if(cachedCdmEntityElement != null) {
+                               logger.info("Cdm Entity with id : " + cdmEntity.getId() + " already exists in permanent cache. Ignoring put.");
+                               return;
+                       }
+               }
+               
+               getCache().put(new Element(id, cdmEntity));       
+       }
+
+
+       private Element getCacheElement(CdmEntityCacheKey key) {
+               return getCache().get(key);
+       }
+
+       public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) {
+               Element e = cdmlibModelCache.get(className);
+               if (e == null) {
+                       return null;
+               } else {
+                       return (CdmModelFieldPropertyFromClass) e.getObjectValue();
+               }
+       }
+
+       public CdmBase getFromCache(CdmEntityCacheKey id) {
+               Element e = getCacheElement(id);
+               if (e == null) {
+                       return null;
+               } else {
+                       return (CdmBase) e.getObjectValue();
+               }
+       }
+
+       public CdmBase getFromCache(Class<? extends CdmBase> clazz, int id) {
+               CdmEntityCacheKey cacheId = generateKey(clazz,id);
+               return getFromCache(cacheId);
+       }
+
+       public CdmBase getFromCache(CdmBase cdmBase) {
+               
+               CdmEntityCacheKey cacheId = generateKey(cdmBase);
+
+               CdmBase cachedCdmEntity = getFromCache(cacheId);
+
+               if(cachedCdmEntity == null) {
+                       // ... then try the permanent (uuid-based) cache
+                       cachedCdmEntity = getFromCache(cdmBase.getUuid());              
+               }
+
+               return cachedCdmEntity;
+       }
+       
+       public CdmBase getFromCache(CdmBase cdmBase, Class<? extends CdmBase> clazz) {
+               
+               cdmBase = CdmBase.deproxy(cdmBase, clazz);
+               
+               CdmEntityCacheKey cacheId = generateKey(cdmBase);
+
+               CdmBase cachedCdmEntity = getFromCache(cacheId);
+
+               if(cachedCdmEntity == null) {
+                       // ... then try the permanent (uuid-based) cache
+                       cachedCdmEntity = getFromCache(cdmBase.getUuid());              
+               }
+
+               return cachedCdmEntity;
+       }
+
+       public List<CdmBase> getAllEntities() {
+               List<CdmBase> entities = new ArrayList<CdmBase>();
+               Map<String, CdmBase> elementsMap = getCache().getAllWithLoader(getCache().getKeys(), null);
+               for (Map.Entry<String, CdmBase> entry : elementsMap.entrySet()) {
+                       entities.add(entry.getValue());
+               }
+               return entities;
+       }
+
+
+
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.model.ICdmCacher#exists(java.util.UUID)
+        */
+       @Override
+       public boolean exists(UUID uuid) {
+               return (getCacheElement(uuid) != null || super.getCacheElement(uuid) != null);
+       }
+
+       public boolean exists(CdmEntityCacheKey key) {
+               return (getCacheElement(key) != null);
+       }
+
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.model.ICdmCacher#existsAndIsNotNull(java.util.UUID)
+        */
+       @Override
+       public boolean existsAndIsNotNull(UUID uuid) {
+               return getFromCache(uuid) != null;
+       }
+
+       public boolean existsAndIsNotNull(CdmEntityCacheKey id) {
+               return getFromCache(id) != null;
+       }
+
+
+       public static CdmEntityCacheKey generateKey(Class<? extends CdmBase> clazz, int id) {
+               return new CdmEntityCacheKey(clazz, id);
+       }
+
+
+       public static CdmEntityCacheKey generateKey(CdmBase cdmBase) {
+               Class<? extends CdmBase> entityClass = cdmBase.getClass();
+               int id = cdmBase.getId();
+               return new CdmEntityCacheKey(entityClass, id);
+       }
+
+       public static boolean isRecursiveEnabled() {
+               return isRecursiveEnabled;
+       }
+
+       public static void  setRecursiveEnabled(boolean ire) {
+               isRecursiveEnabled = ire;
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/api/cache/ICachedCommonService.java
new file mode 100644 (file)
index 0000000..e3952fd
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$
+/**
+ * Copyright (C) 2014 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.cdm.api.cache;
+
+import org.hibernate.collection.spi.PersistentCollection;
+
+import eu.etaxonomy.cdm.api.cache.CachedCommonServiceImpl.CollectionField;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * @author cmathew
+ * @date 14 Oct 2014
+ *
+ */
+public interface ICachedCommonService {
+
+    public CdmBase find(Class<? extends CdmBase> clazz, int id);
+
+    public PersistentCollection initializeCollection(PersistentCollection col);
+
+       public void updatePersistentCollection(CollectionField colf);
+
+    public boolean isEmpty(PersistentCollection col);
+
+    public int size(PersistentCollection col);
+
+    public Object get(PersistentCollection col, int index);
+
+    public boolean contains(PersistentCollection col, Object element);
+
+    public boolean containsKey(PersistentCollection col, Object key);
+
+    public boolean containsValue(PersistentCollection col, Object element);
+
+    public CollectionField getCollectionField(PersistentCollection pc);
+
+
+
+}
\ No newline at end of file
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmPersistentRemoteSource.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmPersistentRemoteSource.java
new file mode 100644 (file)
index 0000000..854643d
--- /dev/null
@@ -0,0 +1,242 @@
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.cdm.remote;
+
+import static eu.etaxonomy.cdm.common.XmlHelp.getBeansRoot;
+import static eu.etaxonomy.cdm.common.XmlHelp.insertXmlBean;
+import static eu.etaxonomy.cdm.common.XmlHelp.insertXmlValueProperty;
+import static eu.etaxonomy.cdm.common.XmlHelp.saveToXml;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.jdom.Attribute;
+import org.jdom.Element;
+
+import eu.etaxonomy.cdm.common.CdmUtils;
+import eu.etaxonomy.cdm.common.XmlHelp;
+import eu.etaxonomy.cdm.config.CdmPersistentSourceUtils;
+import eu.etaxonomy.cdm.config.CdmPersistentXMLSource;
+import eu.etaxonomy.cdm.config.CdmPersistentXMLSource.CdmSourceProperties;
+import eu.etaxonomy.cdm.config.ICdmPersistentSource;
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
+
+/**
+ * Class representing a CDM remote source which can be persisted to a source config file
+ *
+ */
+public class CdmPersistentRemoteSource extends CdmRemoteSourceBase implements ICdmPersistentSource{
+       private static final Logger logger = Logger.getLogger(CdmPersistentRemoteSource.class);
+
+       public static final String REMOTESOURCE_BEAN_POSTFIX = "RemoteSource";
+       private String beanName;
+       private Properties cdmSourceProperties;
+       private List<Attribute> cdmSourceAttributes;
+
+       /**
+        * Creates a new instance of CdmPersistentRemoteSource
+        *
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        * @return
+        * @throws CdmRemoteSourceException
+        */
+       public static CdmPersistentRemoteSource NewInstance(String remoteSource) throws CdmRemoteSourceException {
+               if(exists(remoteSource)) {
+                       return new CdmPersistentRemoteSource(remoteSource);
+               } else {
+                       throw new CdmRemoteSourceException("Remote source '" + remoteSource + "' does not exist in sources setting file");
+               }
+
+       }
+
+       /**S
+        * Creates a new CdmPersistentRemoteSource
+        *
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        * @throws CdmRemoteSourceException
+        */
+       private CdmPersistentRemoteSource(String remoteSource) throws CdmRemoteSourceException {
+
+               CdmPersistentXMLSource cdmPersistentXMLSource = CdmPersistentXMLSource.NewInstance(remoteSource, REMOTESOURCE_BEAN_POSTFIX);
+               if(cdmPersistentXMLSource.getElement() != null) {
+                       beanName = cdmPersistentXMLSource.getBeanName();
+                       // properties from the persistent xml file
+                       cdmSourceProperties = cdmPersistentXMLSource.getCdmSourceProperties();
+                       cdmSourceAttributes = cdmPersistentXMLSource.getCdmSourceAttributes();
+                       checkProperties(cdmSourceProperties);
+               } else {
+                       throw new CdmRemoteSourceException("Remote source '" + remoteSource + "' does not exist in settings file");
+               }
+               initDatabaseConnection();
+       }
+
+       private static void checkProperties(Properties cdmSourceProperties) throws CdmRemoteSourceException {
+               if(!cdmSourceProperties.containsKey(CdmSourceProperties.SERVER.toString())) {
+                       throw new CdmRemoteSourceException("Could not initialise remote source. Required property '" + CdmSourceProperties.SERVER.toString() + "' is missing");
+               }
+               String port = (String)cdmSourceProperties.get(CdmSourceProperties.PORT.toString());
+               if(port == null || port.isEmpty()) {
+                       throw new CdmRemoteSourceException("Could not initialise remote source. Required property '" + CdmSourceProperties.SERVER.toString() + "' is missing");
+               }
+               if(!cdmSourceProperties.containsKey(CdmSourceProperties.CONTEXTPATH.toString())) {
+                       throw new CdmRemoteSourceException("Could not initialise remote source. Required property '" + CdmSourceProperties.SERVER.toString() + "' is missing");
+               }
+               // default NomenclaturalCode is always ICNAFP
+               if(!cdmSourceProperties.containsKey(CdmSourceProperties.NOMENCLATURAL_CODE.toString())) {
+                       cdmSourceProperties.put(CdmSourceProperties.NOMENCLATURAL_CODE.toString(), NomenclaturalCode.ICNAFP.name());
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.config.ICdmPersistentSource#getBeanName()
+        */
+       @Override
+       public String getBeanName() {
+               return beanName;
+       }
+
+       @Override
+       public String getServer() {
+               return cdmSourceProperties.getProperty(CdmSourceProperties.SERVER.toString());
+       }
+
+       @Override
+       public int getPort() {
+               String port = CdmUtils.Nz(cdmSourceProperties.getProperty(CdmSourceProperties.PORT.toString()));
+               if (port == null || "".equals(port)){
+                       return -1;
+               }else{
+                       //TODO exception if non integer
+                       return Integer.valueOf(port);
+               }
+       }
+
+       @Override
+       public String getContextPath() {
+               return cdmSourceProperties.getProperty(CdmSourceProperties.CONTEXTPATH.toString());
+       }
+
+       @Override
+       public NomenclaturalCode getNomenclaturalCode() {
+               return NomenclaturalCode.fromString(cdmSourceProperties.getProperty(CdmSourceProperties.NOMENCLATURAL_CODE.toString()));
+       }
+
+       public static CdmPersistentRemoteSource save(String strRemoteSourceName, ICdmRemoteSource remoteSource) throws CdmRemoteSourceException {
+               Properties cdmSourceProperties = new Properties();
+               cdmSourceProperties.put(CdmSourceProperties.SERVER.toString(), remoteSource.getServer());
+               cdmSourceProperties.put(CdmSourceProperties.PORT.toString(), String.valueOf(remoteSource.getPort()));
+               cdmSourceProperties.put(CdmSourceProperties.CONTEXTPATH.toString(), remoteSource.getContextPath());
+               cdmSourceProperties.put(CdmSourceProperties.NOMENCLATURAL_CODE.toString(), remoteSource.getNomenclaturalCode().name());
+               checkProperties(cdmSourceProperties);
+               return save(strRemoteSourceName, cdmSourceProperties);
+       }
+
+       private static CdmPersistentRemoteSource save(String strRemoteSourceName,Properties cdmSourceProperties) throws CdmRemoteSourceException {
+
+               //root
+               Element root = getBeansRoot(CdmPersistentSourceUtils.getCdmSourceInputStream());
+               if (root == null){
+                       return null;
+               }
+               //bean
+               Element bean = XmlHelp.getFirstAttributedChild(root, "bean", "id", CdmPersistentSourceUtils.getBeanName(strRemoteSourceName, REMOTESOURCE_BEAN_POSTFIX));
+               if (bean != null){
+                       bean.detach();  //delete old version if necessary
+               }
+               bean = insertXmlBean(root, CdmPersistentSourceUtils.getBeanName(strRemoteSourceName, REMOTESOURCE_BEAN_POSTFIX), CdmPersistentRemoteSource.class.getName());
+
+
+               Properties props = cdmSourceProperties;
+               Enumeration e = props.propertyNames();
+
+               while (e.hasMoreElements()) {
+                       String key = (String) e.nextElement();
+                       insertXmlValueProperty(bean, key, props.getProperty(key));
+               }
+
+               //save
+               saveToXml(root.getDocument(),
+                               CdmPersistentSourceUtils.getResourceDirectory(),
+                               CdmPersistentXMLSource.CDMSOURCE_FILE_NAME,
+                               XmlHelp.prettyFormat );
+
+               return NewInstance(strRemoteSourceName) ;
+
+       }
+
+       /**
+        * @param strDataSourceName
+        * @param dataSource
+        * @param code
+        * @return
+        *                      the updated dataSource, null if not succesful
+        */
+       public static CdmPersistentRemoteSource update(String strRemoteSourceName,
+                       ICdmRemoteSource remoteSource) throws CdmRemoteSourceException {
+               CdmPersistentSourceUtils.delete(CdmPersistentSourceUtils.getBeanName(strRemoteSourceName,REMOTESOURCE_BEAN_POSTFIX));
+               return save(strRemoteSourceName, remoteSource);
+       }
+
+       /**
+        * Tests existing of the datsource in the according config  file.
+        * @return true if a datasource with the given name exists in the according datasource config file.
+        */
+       public static boolean exists(String strRemoteSourceName){
+               Element bean = CdmPersistentSourceUtils.getCdmSourceBeanXml(strRemoteSourceName, REMOTESOURCE_BEAN_POSTFIX);
+               return (bean != null);
+       }
+
+       /**
+        * Returns a list of all datasources stored in the datasource config file
+        * @return all existing data sources
+        * @throws CdmRemoteSourceException
+        */
+       @SuppressWarnings("unchecked")
+       static public List<CdmPersistentRemoteSource> getAllRemoteSources() throws CdmRemoteSourceException{
+               List<CdmPersistentRemoteSource> remoteSources = new ArrayList<CdmPersistentRemoteSource>();
+
+               Element root = getBeansRoot(CdmPersistentSourceUtils.getCdmSourceInputStream());
+               if (root == null){
+                       return null;
+               }else{
+               List<Element> lsChildren  = root.getChildren("bean", root.getNamespace());
+
+               for (Element elBean : lsChildren){
+                       String strId = elBean.getAttributeValue("id");
+                       if (strId != null && strId.endsWith(REMOTESOURCE_BEAN_POSTFIX)){
+                               strId = strId.replace(REMOTESOURCE_BEAN_POSTFIX, "");
+                               remoteSources.add(new CdmPersistentRemoteSource(strId));
+                       }
+               }
+               }
+               return remoteSources;
+       }
+
+       @Override
+       public String toString(){
+               if (getName() != null){
+                       return getName();
+               }else{
+                       return null;
+               }
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSource.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSource.java
new file mode 100644 (file)
index 0000000..9dbb34b
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy 
+* http://www.e-taxonomy.eu
+* 
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.remote;
+
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
+
+/**
+ * Class representing a CDM remote source 
+ *
+ */
+public class CdmRemoteSource extends CdmRemoteSourceBase {
+       
+       /**
+        * Creates a new instance of CdmRemoteSource
+        * 
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        * @return
+        */
+       public static CdmRemoteSource NewInstance() {
+               return new CdmRemoteSource(DEFAULT_NAME, DEFAULT_SERVER, DEFAULT_PORT, DEFAULT_CONTEXT_PATH, DEFAULT_NOMENCLATURAL_CODE);
+       }
+       
+       /**
+        * Creates a new instance of CdmRemoteSource
+        * 
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        * @return
+        */
+       public static CdmRemoteSource NewInstance(String name, String server, int port, String contextPath, NomenclaturalCode nomenclaturalCode) {
+               return new CdmRemoteSource(name, server, port, contextPath, nomenclaturalCode);
+       }
+       
+       /**
+        * Creates a new CdmRemoteSource
+        * 
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        */
+       private CdmRemoteSource(String name, String server, int port, String contextPath, NomenclaturalCode nomenclaturalCode) { 
+               super(name, server, port, contextPath, nomenclaturalCode);
+               
+       }
+
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceBase.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceBase.java
new file mode 100644 (file)
index 0000000..9fbb8d4
--- /dev/null
@@ -0,0 +1,173 @@
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.remote;
+
+import java.util.Map;
+
+import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
+
+import eu.etaxonomy.cdm.api.service.IDatabaseService;
+import eu.etaxonomy.cdm.config.CdmSource;
+import eu.etaxonomy.cdm.config.CdmSourceException;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData.MetaDataPropertyName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
+
+/**
+ * Base class representing a CDM remote source.
+ * This class handles all the configuration relating to the remoting aspect of
+ * a CDM source.
+ *
+ */
+public class CdmRemoteSourceBase extends CdmSource implements ICdmRemoteSource {
+
+       protected static final String DEFAULT_NAME = "default";
+       protected static final String DEFAULT_SERVER = "127.0.0.1";
+       protected static final int DEFAULT_PORT = 8080;
+       protected static final String DEFAULT_CONTEXT_PATH = "";
+       protected static final NomenclaturalCode DEFAULT_NOMENCLATURAL_CODE = NomenclaturalCode.ICNAFP;
+       private String contextPath;
+       private String baseUrl;
+
+       private IDatabaseService databaseService;
+
+       /**
+        * Constructs a CdmRemoteSourceBase object with default values.
+        *
+        */
+       protected CdmRemoteSourceBase() {
+               setName(DEFAULT_NAME);
+               setServer(DEFAULT_SERVER);
+               setPort(DEFAULT_PORT);
+               setContextPath(DEFAULT_CONTEXT_PATH);
+               setNomenclaturalCode(DEFAULT_NOMENCLATURAL_CODE);
+       }
+
+       /**
+        * Constructs a CdmRemoteSourceBase
+        *
+        * @param name
+        * @param server
+        * @param port
+        * @param contextPath
+        * @param nomenclaturalCode
+        */
+       public CdmRemoteSourceBase(String name, String server, int port, String contextPath, NomenclaturalCode nomenclaturalCode) {
+               setName(name);
+               setServer(server);
+               setPort(port);
+               setContextPath(contextPath);
+               setNomenclaturalCode(nomenclaturalCode);
+               initDatabaseConnection();
+       }
+
+       protected void initDatabaseConnection() {
+               if(getContextPath() == null || getContextPath().equals("")) {
+                       setBaseUrl("http://" + getServer() + ":" + String.valueOf(getPort()));
+               } else {
+                       setBaseUrl("http://" + getServer()  + ":" + String.valueOf(getPort()) + "/" + getContextPath());
+               }
+               // the database service needs to be initialised (before the spring
+               // application context initialsation) since it is required to
+               // to make queries related to the source database
+           HttpInvokerProxyFactoryBean proxy = new HttpInvokerProxyFactoryBean();
+           proxy.setServiceInterface(IDatabaseService.class);
+           proxy.setServiceUrl(baseUrl + "/remoting/database.service");
+           proxy.afterPropertiesSet();
+           databaseService = (IDatabaseService) proxy.getObject();
+
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.remote.ICdmRemoteSource#getBaseUrl()
+        */
+       @Override
+       public String getBaseUrl() {
+               return baseUrl;
+       }
+
+       /**
+        * Sets the base url for the http-invoker services as listed in
+        * httpInvokerServicesClients.xml.
+        * e.g. for 'http://127.0.0.1:8080/col/remoting/common.service', the
+        * base url would be 'http://127.0.0.1:8080/col'
+        *
+        * @param baseUrl
+        */
+       public void setBaseUrl(String baseUrl) {
+               this.baseUrl = baseUrl;
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.remote.ICdmRemoteSource#getContextPath()
+        */
+       @Override
+       public String getContextPath() {
+               return contextPath;
+       }
+
+       /**
+        * Sets the context path.
+        * e.g. for 'http://127.0.0.1:8080/col/remoting/common.service', the
+        * context path would be 'col'
+        *
+        * @param contextPath
+        */
+       public void setContextPath(String contextPath) {
+               this.contextPath = contextPath;
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.config.CdmSource#getDbSchemaVersion()
+        */
+       @Override
+       public String getDbSchemaVersion() throws CdmSourceException {
+               return databaseService.getDbSchemaVersion();
+
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.config.CdmSource#isDbEmpty()
+        */
+       @Override
+       public boolean isDbEmpty() throws CdmSourceException {
+               return databaseService.isDbEmpty();
+
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.config.CdmSource#checkConnection()
+        */
+       @Override
+       public boolean checkConnection() throws CdmSourceException {
+               // assuming that database service works implies
+               // the connection is up
+               // if no exception is thrown then we assume that the
+               // connection is up
+               // FIXME:Remoting is this really correct?
+               databaseService.getDbSchemaVersion();
+
+               return true;
+       }
+
+       /* (non-Javadoc)
+        * @see eu.etaxonomy.cdm.config.CdmSource#getConnectionMessage()
+        */
+       @Override
+       public String getConnectionMessage() {
+               return "Conncting to Remote CDM Server " + getName();
+       }
+
+
+       @Override
+       public Map<MetaDataPropertyName, String> getMetaDataMap() throws CdmSourceException {
+               return databaseService.getCdmMetadataMap();
+       }
+
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceException.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/CdmRemoteSourceException.java
new file mode 100644 (file)
index 0000000..3c2d715
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * 
+ */
+package eu.etaxonomy.cdm.remote;
+
+/**
+ * 
+ *
+ */
+public class CdmRemoteSourceException extends Exception {
+       
+       public CdmRemoteSourceException(String message) {
+               super(message);
+       }
+
+       public CdmRemoteSourceException(Exception e) {
+               super(e);
+       }
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/ICdmRemoteSource.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/cdm/remote/ICdmRemoteSource.java
new file mode 100644 (file)
index 0000000..f278c74
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy 
+* http://www.e-taxonomy.eu
+* 
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.remote;
+
+import eu.etaxonomy.cdm.config.ICdmSource;
+
+/**
+ * Interface representing a CDM remote source
+ *
+ */
+public interface ICdmRemoteSource extends ICdmSource {
+       
+       /**
+        * Gets the context path.
+        * e.g. for 'http://127.0.0.1:8080/col/remoting/common.service', the 
+        * context path would be 'col'
+        */
+       public String getContextPath();
+       
+       /**
+        * Gets the base url for the http-invoker services as listed in 
+        * httpInvokerServicesClients.xml.
+        * e.g. for 'http://127.0.0.1:8080/col/remoting/common.service', the 
+        * base url would be 'http://127.0.0.1:8080/col'
+        */
+       public String getBaseUrl();     
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmRemotingException.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmRemotingException.java
new file mode 100644 (file)
index 0000000..68f5ca0
--- /dev/null
@@ -0,0 +1,14 @@
+package eu.etaxonomy.taxeditor.remoting;
+
+public class CdmRemotingException extends RuntimeException {
+       
+       /**
+        * 
+        */
+       private static final long serialVersionUID = -560332689478356360L;
+
+       public CdmRemotingException(String message) {
+               super(message);
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/RemotingTestPluginActivator.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/RemotingTestPluginActivator.java
new file mode 100644 (file)
index 0000000..65db6ba
--- /dev/null
@@ -0,0 +1,30 @@
+package eu.etaxonomy.taxeditor.remoting;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class RemotingTestPluginActivator implements BundleActivator {
+
+       private static BundleContext context;
+
+       static BundleContext getContext() {
+               return context;
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+        */
+       public void start(BundleContext bundleContext) throws Exception {
+               RemotingTestPluginActivator.context = bundleContext;
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+        */
+       public void stop(BundleContext bundleContext) throws Exception {
+               RemotingTestPluginActivator.context = null;
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmClientSessionException.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmClientSessionException.java
new file mode 100644 (file)
index 0000000..e48017d
--- /dev/null
@@ -0,0 +1,8 @@
+package eu.etaxonomy.taxeditor.remoting.session;
+
+public class CdmClientSessionException extends RuntimeException {
+
+       public CdmClientSessionException(String message) {
+               super(message);
+       }
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySession.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySession.java
new file mode 100644 (file)
index 0000000..e526024
--- /dev/null
@@ -0,0 +1,59 @@
+// $Id$
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.remoting.session;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.api.cache.CdmTransientEntityCacher;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+
+/**
+ * @author cmathew
+ * @date 20 Oct 2014
+ *
+ */
+
+public class CdmEntitySession {
+
+       
+       private CdmEntitySessionManager cdmEntitySessionManager;
+       
+       private ISessionEventListener sessionOwner;
+               
+       private CdmTransientEntityCacher cdmTransientEntityCacher;
+       
+       CdmEntitySession(ISessionEventListener sessionOwner, CdmEntitySessionManager cdmEntitySessionManager) {
+               this.sessionOwner = sessionOwner;
+               this.cdmTransientEntityCacher = new CdmTransientEntityCacher(sessionOwner);
+               cdmEntitySessionManager.addToOwnerSessionMap(sessionOwner, this);
+       }
+       
+       public CdmTransientEntityCacher getCdmTransientEntityCacher() {
+               return cdmTransientEntityCacher;
+       }
+       
+       public CdmBase cachify(CdmBase cdmBase) {
+               return cdmTransientEntityCacher.load(cdmBase,true);
+       }
+       
+       public void setEntitiesAsLatest() {
+               List<CdmBase> entities = cdmTransientEntityCacher.getAllEntities();
+               for(CdmBase entity : entities) {
+                       cdmEntitySessionManager.setEntityAsLatest(entity);
+               }
+       }
+               
+       
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySessionManager.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/CdmEntitySessionManager.java
new file mode 100644 (file)
index 0000000..817e430
--- /dev/null
@@ -0,0 +1,119 @@
+// $Id$
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.remoting.session;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.api.cache.CachedCommonServiceImpl;
+import eu.etaxonomy.cdm.api.cache.CdmClientCacheException;
+import eu.etaxonomy.cdm.api.cache.CdmClientCachingTest;
+import eu.etaxonomy.cdm.api.cache.CdmTransientEntityCacher;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * @author cmathew
+ * @date 16 Oct 2014
+ *
+ */
+@Component
+public class CdmEntitySessionManager {
+       private static final Logger logger = Logger.getLogger(CdmEntitySessionManager.class);
+
+    private Map<ISessionEventListener, CdmEntitySession> ownerSessionMap = 
+               new HashMap<ISessionEventListener, CdmEntitySession>();
+    
+//    private HashMap<String, HashSet<CdmClientBase<T>>> entitiesMap = 
+//             new HashMap<String, HashSet<CdmClientBase<T>>>();
+    
+    private CdmTransientEntityCacher latestEntityCacher =
+               new CdmTransientEntityCacher("latestEntityCacher");
+    
+    private CdmEntitySession activeSession;
+    
+    public CdmEntitySession getActiveSession() {
+               return activeSession;
+       }
+       
+       public CdmTransientEntityCacher getActiveCdmTransientEntityCacher() {
+        return activeSession.getCdmTransientEntityCacher();
+    }
+       
+       public CdmTransientEntityCacher getCdmTransientEntityCacher(ISessionEventListener sessionOwner) {
+               if(sessionOwner == null) {
+                       throw new CdmClientSessionException("Session owner object cannot be null");
+               }
+               CdmEntitySession session = ownerSessionMap.get(sessionOwner);
+               if(session == null) {
+                       logger.info("No session exists for session owner with class : " + sessionOwner.getClass().getName());
+                       return null;
+               }
+        return session.getCdmTransientEntityCacher();
+    }
+       
+       private CdmEntitySession newSession(ISessionEventListener sessionOwner, boolean setAsActive) {
+               CdmEntitySession session = ownerSessionMap.get(sessionOwner);
+               if(session == null) {           
+                       session = new CdmEntitySession(sessionOwner, this);
+                       addToOwnerSessionMap(sessionOwner, session);
+               }
+               
+               if(setAsActive) {
+                       activeSession = session;
+               }               
+               return session;
+       }
+       
+       public void bind(ISessionEventListener sessionOwner) {
+               CdmEntitySession session  = ownerSessionMap.get(sessionOwner);
+               if(session == null) {
+                       session = newSession(sessionOwner,true);
+               }
+               activeSession = session;
+       }
+       
+       @SuppressWarnings("unchecked")
+       public <T extends CdmBase> T add(ISessionEventListener sessionOwner, T cdmBase) {
+               CdmEntitySession session = newSession(sessionOwner,true);
+               return (T)session.getCdmTransientEntityCacher().load(cdmBase,true);
+       }
+       
+       void addToOwnerSessionMap(ISessionEventListener owner, CdmEntitySession session) {
+               ownerSessionMap.put(owner, session);
+       }
+       
+//     void addToLinkedEntities(T cdmBase) {
+//             if(cdmBase == null) {
+//                     return;
+//             }
+//             String id = CdmTransientEntityCacher.generateId(cdmBase);
+//             HashSet<CdmClientBase<T>> linkedEntities = entitiesMap.get(id);
+//             if(linkedEntities == null) {
+//                     linkedEntities = new HashSet<CdmClientBase<T>>();                       
+//             }
+//             linkedEntities.add(cdmBase);
+//     }
+
+       void setEntityAsLatest(CdmBase cdmBase) {               
+               latestEntityCacher.put(cdmBase);
+       }
+       
+       void promoteSessionEntitiesToLatest(ISessionEventListener owner) {
+               CdmEntitySession session = ownerSessionMap.get(owner);
+               if(session != null) {
+                       session.setEntitiesAsLatest();
+               }
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/ISessionEventListener.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/eu/etaxonomy/taxeditor/remoting/session/ISessionEventListener.java
new file mode 100644 (file)
index 0000000..fe008d0
--- /dev/null
@@ -0,0 +1,5 @@
+package eu.etaxonomy.taxeditor.remoting.session;
+
+public interface ISessionEventListener {
+
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
new file mode 100644 (file)
index 0000000..08c6dd5
--- /dev/null
@@ -0,0 +1,1329 @@
+
+
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+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.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.naming.NamingException;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
+import org.hibernate.Session;
+import org.hibernate.collection.spi.PersistentCollection;
+import org.hibernate.engine.internal.ForeignKeys;
+import org.hibernate.engine.spi.CollectionEntry;
+import org.hibernate.engine.spi.EntityEntry;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.engine.spi.Status;
+import org.hibernate.engine.spi.TypedValue;
+import org.hibernate.internal.SessionFactoryRegistry;
+import org.hibernate.internal.util.MarkerObject;
+import org.hibernate.internal.util.collections.EmptyIterator;
+import org.hibernate.internal.util.collections.IdentitySet;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+import org.jboss.logging.Logger;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration;
+import eu.etaxonomy.cdm.api.cache.CachedCommonServiceImpl.CollectionField;
+import eu.etaxonomy.cdm.api.cache.ICachedCommonService;
+
+/**
+ * Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection {
+       private static final Logger log = Logger.getLogger( AbstractPersistentCollection.class );
+
+       private static final long serialVersionUID = -7238232378593030571L;
+
+       private transient SessionImplementor session;
+       private boolean initialized;
+       private transient List<DelayedOperation> operationQueue;
+       private transient boolean directlyAccessible;
+       private transient boolean initializing;
+       private Object owner;
+       private int cachedSize = -1;
+
+       private String role;
+       private Serializable key;
+       // collections detect changes made via their public interface and mark
+       // themselves as dirty as a performance optimization
+       private boolean dirty;
+       private Serializable storedSnapshot;
+
+       private String sessionFactoryUuid;
+       private boolean specjLazyLoad = false;
+
+       @Override
+    public final String getRole() {
+               return role;
+       }
+
+       @Override
+    public final Serializable getKey() {
+               return key;
+       }
+
+       @Override
+    public final boolean isUnreferenced() {
+               return role == null;
+       }
+
+       @Override
+    public final boolean isDirty() {
+               return dirty;
+       }
+
+       @Override
+    public final void clearDirty() {
+               dirty = false;
+       }
+
+       @Override
+    public final void dirty() {
+               dirty = true;
+       }
+
+       @Override
+    public final Serializable getStoredSnapshot() {
+               return storedSnapshot;
+       }
+
+       //Careful: these methods do not initialize the collection.
+
+       /**
+        * Is the initialized collection empty?
+        */
+       @Override
+    public abstract boolean empty();
+
+       /**
+        * Called by any read-only method of the collection interface
+        */
+       protected final void read() {
+               initialize( false );
+       }
+
+       /**
+        * Called by the {@link Collection#size} method
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected boolean readSize() {
+               if ( !initialized ) {
+                       if ( cachedSize != -1 && !hasQueuedOperations() ) {
+                               return true;
+                       }
+                       else {
+                               // In remoting we are sure that session is null
+                               // both when using property paths and switching off conversations
+                               if(session == null && remoting) {
+                                       log.info("--> readSize, of " + getRole() + " with key " + getKey());
+                                       read();
+                               } else {
+                                       boolean isExtraLazy = withTemporarySessionIfNeeded(
+                                                       new LazyInitializationWork<Boolean>() {
+                                                               @Override
+                                                               public Boolean doWork() {
+                                                                       CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+
+                                                                       if ( entry != null ) {
+                                                                               CollectionPersister persister = entry.getLoadedPersister();
+                                                                               if ( persister.isExtraLazy() ) {
+                                                                                       if ( hasQueuedOperations() ) {
+                                                                                               session.flush();
+                                                                                       }
+                                                                                       cachedSize = persister.getSize( entry.getLoadedKey(), session );
+                                                                                       return true;
+                                                                               }
+                                                                               else {
+                                                                                       read();
+                                                                               }
+                                                                       }
+                                                                       else{
+                                                                               throwLazyInitializationExceptionIfNotConnected();
+                                                                       }
+                                                                       return false;
+                                                               }
+                                                       }
+                                                       );
+                                       if ( isExtraLazy ) {
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+
+       public static interface LazyInitializationWork<T> {
+               public T doWork();
+       }
+
+       private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) {
+               SessionImplementor originalSession = null;
+               boolean isTempSession = false;
+               boolean isJTA = false;
+
+               if ( session == null ) {
+                       if ( specjLazyLoad ) {
+                               session = openTemporarySessionForLoading();
+                               isTempSession = true;
+                       }
+                       else {
+                               throwLazyInitializationException( "could not initialize proxy - no Session" );
+                       }
+               }
+               else if ( !session.isOpen() ) {
+                       if ( specjLazyLoad ) {
+                               originalSession = session;
+                               session = openTemporarySessionForLoading();
+                               isTempSession = true;
+                       }
+                       else {
+                               throwLazyInitializationException( "could not initialize proxy - the owning Session was closed" );
+                       }
+               }
+               else if ( !session.isConnected() ) {
+                       if ( specjLazyLoad ) {
+                               originalSession = session;
+                               session = openTemporarySessionForLoading();
+                               isTempSession = true;
+                       }
+                       else {
+                               throwLazyInitializationException( "could not initialize proxy - the owning Session is disconnected" );
+                       }
+               }
+
+               if ( isTempSession ) {
+                       // TODO: On the next major release, add an
+                       // 'isJTA' or 'getTransactionFactory' method to Session.
+                       isJTA = session.getTransactionCoordinator()
+                                       .getTransactionContext().getTransactionEnvironment()
+                                       .getTransactionFactory()
+                                       .compatibleWithJtaSynchronization();
+
+                       if ( !isJTA ) {
+                               // Explicitly handle the transactions only if we're not in
+                               // a JTA environment.  A lazy loading temporary session can
+                               // be created even if a current session and transaction are
+                               // open (ex: session.clear() was used).  We must prevent
+                               // multiple transactions.
+                               ( ( Session) session ).beginTransaction();
+                       }
+
+                       session.getPersistenceContext().addUninitializedDetachedCollection(
+                                       session.getFactory().getCollectionPersister( getRole() ),
+                                       this
+                       );
+               }
+
+               try {
+                       return lazyInitializationWork.doWork();
+               }
+               finally {
+                       if ( isTempSession ) {
+                               // make sure the just opened temp session gets closed!
+                               try {
+                                       if ( !isJTA ) {
+                                               ( ( Session) session ).getTransaction().commit();
+                                       }
+                                       ( (Session) session ).close();
+                               }
+                               catch (Exception e) {
+                                       log.warn( "Unable to close temporary session used to load lazy collection associated to no session" );
+                               }
+                               session = originalSession;
+                       }
+               }
+       }
+
+       private SessionImplementor openTemporarySessionForLoading() {
+               if ( sessionFactoryUuid == null ) {
+                       throwLazyInitializationException( "SessionFactory UUID not known to create temporary Session for loading" );
+               }
+
+               SessionFactoryImplementor sf = (SessionFactoryImplementor)
+                               SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
+               return (SessionImplementor) sf.openSession();
+       }
+
+       protected Boolean readIndexExistence(final Object index) {
+               if ( !initialized ) {
+                       // In remoting we are sure that session is null
+                       // both when using property paths and switching off conversations
+                       if(session == null && remoting) {
+                               log.info("--> readIndexExistence, of " + getRole() + " with key " + getKey());
+                               read();
+                       } else {
+                               Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+                                               new LazyInitializationWork<Boolean>() {
+                                                       @Override
+                                                       public Boolean doWork() {
+                                                               CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+                                                               CollectionPersister persister = entry.getLoadedPersister();
+                                                               if ( persister.isExtraLazy() ) {
+                                                                       if ( hasQueuedOperations() ) {
+                                                                               session.flush();
+                                                                       }
+                                                                       return persister.indexExists( entry.getLoadedKey(), index, session );
+                                                               }
+                                                               else {
+                                                                       read();
+                                                               }
+                                                               return null;
+                                                       }
+                                               }
+                                               );
+                               if ( extraLazyExistenceCheck != null ) {
+                                       return extraLazyExistenceCheck;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       protected Boolean readElementExistence(final Object element) {
+               if ( !initialized ) {
+                       // In remoting we are sure that session is null
+                       // both when using property paths and switching off conversations
+                       if(session == null && remoting) {
+                               log.info("--> readElementExistence, of " + getRole() + " with key " + getKey());
+                               read();
+
+                       } else {
+                               Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+                                               new LazyInitializationWork<Boolean>() {
+                                                       @Override
+                                                       public Boolean doWork() {
+                                                               CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+                                                               CollectionPersister persister = entry.getLoadedPersister();
+                                                               if ( persister.isExtraLazy() ) {
+                                                                       if ( hasQueuedOperations() ) {
+                                                                               session.flush();
+                                                                       }
+                                                                       return persister.elementExists( entry.getLoadedKey(), element, session );
+                                                               }
+                                                               else {
+                                                                       read();
+                                                               }
+                                                               return null;
+                                                       }
+                                               }
+                                               );
+                               if ( extraLazyExistenceCheck != null ) {
+                                       return extraLazyExistenceCheck;
+                               }
+                       }
+               }
+               return null;
+       }
+
+       protected static final Object UNKNOWN = new MarkerObject( "UNKNOWN" );
+
+       protected Object readElementByIndex(final Object index) {
+               if ( !initialized ) {
+                       // In remoting we are sure that session is null
+                       // both when using property paths and switching off conversations
+                       if(session == null && remoting) {
+                               log.info("--> readElementByIndex, of " + getRole() + " with key " + getKey());
+                               read();
+
+                       } else {
+                               class ExtraLazyElementByIndexReader implements LazyInitializationWork {
+                                       private boolean isExtraLazy;
+                                       private Object element;
+
+                                       @Override
+                                       public Object doWork() {
+                                               CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+                                               CollectionPersister persister = entry.getLoadedPersister();
+                                               isExtraLazy = persister.isExtraLazy();
+                                               if ( isExtraLazy ) {
+                                                       if ( hasQueuedOperations() ) {
+                                                               session.flush();
+                                                       }
+                                                       element = persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
+                                               }
+                                               else {
+                                                       read();
+                                               }
+                                               return null;
+                                       }
+                               }
+
+                               ExtraLazyElementByIndexReader reader = new ExtraLazyElementByIndexReader();
+                               //noinspection unchecked
+                               withTemporarySessionIfNeeded( reader );
+                               if ( reader.isExtraLazy ) {
+                                       return reader.element;
+                               }
+                       }
+               }
+               return UNKNOWN;
+
+       }
+
+       protected int getCachedSize() {
+               return cachedSize;
+       }
+
+       private boolean isConnectedToSession() {
+               return session != null &&
+                               session.isOpen() &&
+                               session.getPersistenceContext().containsCollection( this );
+       }
+
+       /**
+        * Called by any writer method of the collection interface
+        */
+       protected final void write() {
+               initialize( true );
+               dirty();
+       }
+
+       /**
+        * Is this collection in a state that would allow us to
+        * "queue" operations?
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected boolean isOperationQueueEnabled() {
+               return !initialized &&
+                               isConnectedToSession() &&
+                               isInverseCollection();
+       }
+
+       /**
+        * Is this collection in a state that would allow us to
+        * "queue" puts? This is a special case, because of orphan
+        * delete.
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected boolean isPutQueueEnabled() {
+               return !initialized &&
+                               isConnectedToSession() &&
+                               isInverseOneToManyOrNoOrphanDelete();
+       }
+
+       /**
+        * Is this collection in a state that would allow us to
+        * "queue" clear? This is a special case, because of orphan
+        * delete.
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected boolean isClearQueueEnabled() {
+               return !initialized &&
+                               isConnectedToSession() &&
+                               isInverseCollectionNoOrphanDelete();
+       }
+
+       /**
+        * Is this the "inverse" end of a bidirectional association?
+        */
+       @SuppressWarnings({"JavaDoc"})
+       private boolean isInverseCollection() {
+               CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+               return ce != null && ce.getLoadedPersister().isInverse();
+       }
+
+       /**
+        * Is this the "inverse" end of a bidirectional association with
+        * no orphan delete enabled?
+        */
+       @SuppressWarnings({"JavaDoc"})
+       private boolean isInverseCollectionNoOrphanDelete() {
+               CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+               return ce != null &&
+                               ce.getLoadedPersister().isInverse() &&
+                               !ce.getLoadedPersister().hasOrphanDelete();
+       }
+
+       /**
+        * Is this the "inverse" end of a bidirectional one-to-many, or
+        * of a collection with no orphan delete?
+        */
+       @SuppressWarnings({"JavaDoc"})
+       private boolean isInverseOneToManyOrNoOrphanDelete() {
+               CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+               return ce != null && ce.getLoadedPersister().isInverse() && (
+                               ce.getLoadedPersister().isOneToMany() ||
+                                               !ce.getLoadedPersister().hasOrphanDelete()
+               );
+       }
+
+       /**
+        * Queue an addition
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected final void queueOperation(DelayedOperation operation) {
+               if ( operationQueue == null ) {
+                       operationQueue = new ArrayList<DelayedOperation>( 10 );
+               }
+               operationQueue.add( operation );
+               dirty = true; //needed so that we remove this collection from the second-level cache
+       }
+
+       /**
+        * After reading all existing elements from the database,
+        * add the queued elements to the underlying collection.
+        */
+       protected final void performQueuedOperations() {
+               for ( DelayedOperation operation : operationQueue ) {
+                       operation.operate();
+               }
+       }
+
+       /**
+        * After flushing, re-init snapshot state.
+        */
+       @Override
+    public void setSnapshot(Serializable key, String role, Serializable snapshot) {
+               this.key = key;
+               this.role = role;
+               this.storedSnapshot = snapshot;
+       }
+
+       /**
+        * After flushing, clear any "queued" additions, since the
+        * database state is now synchronized with the memory state.
+        */
+       @Override
+    public void postAction() {
+               operationQueue = null;
+               cachedSize = -1;
+               clearDirty();
+       }
+
+       /**
+        * Not called by Hibernate, but used by non-JDK serialization,
+        * eg. SOAP libraries.
+        */
+       public AbstractPersistentCollection() {
+       }
+
+       protected AbstractPersistentCollection(SessionImplementor session) {
+               this.session = session;
+       }
+
+       /**
+        * return the user-visible collection (or array) instance
+        */
+       @Override
+    public Object getValue() {
+               return this;
+       }
+
+       /**
+        * Called just before reading any rows from the JDBC result set
+        */
+       @Override
+    public void beginRead() {
+               // override on some subclasses
+               initializing = true;
+       }
+
+       /**
+        * Called after reading all rows from the JDBC result set
+        */
+       @Override
+    public boolean endRead() {
+               //override on some subclasses
+               return afterInitialize();
+       }
+
+       @Override
+    public boolean afterInitialize() {
+               setInitialized();
+               //do this bit after setting initialized to true or it will recurse
+               if ( operationQueue != null ) {
+                       performQueuedOperations();
+                       operationQueue = null;
+                       cachedSize = -1;
+                       return false;
+               }
+               else {
+                       return true;
+               }
+       }
+
+       /**
+        * Initialize the collection, if possible, wrapping any exceptions
+        * in a runtime exception
+        *
+        * @param writing currently obsolete
+        *
+        * @throws LazyInitializationException if we cannot initialize
+        */
+       protected final void initialize(final boolean writing) {
+               // In remoting we are sure that session is null
+               // both when using property paths and switching off conversations
+               if(session == null && remoting) {
+                       remoteInitialize();
+               }
+
+               if ( initialized ) {
+                       return;
+               }
+
+
+               withTemporarySessionIfNeeded(
+                               new LazyInitializationWork<Object>() {
+                                       @Override
+                                       public Object doWork() {
+                                               session.initializeCollection( AbstractPersistentCollection.this, writing );
+                                               return null;
+                                       }
+                               }
+               );
+       }
+
+       private void throwLazyInitializationExceptionIfNotConnected() {
+               if ( !isConnectedToSession() ) {
+                       throwLazyInitializationException( "no session or session was closed" );
+               }
+               if ( !session.isConnected() ) {
+                       throwLazyInitializationException( "session is disconnected" );
+               }
+       }
+
+       private void throwLazyInitializationException(String message) {
+               throw new LazyInitializationException(
+                               "failed to lazily initialize a collection" +
+                                               (role == null ? "" : " of role: " + role) +
+                                               ", " + message
+               );
+       }
+
+       protected final void setInitialized() {
+               this.initializing = false;
+               this.initialized = true;
+       }
+
+       protected final void setDirectlyAccessible(boolean directlyAccessible) {
+               this.directlyAccessible = directlyAccessible;
+       }
+
+       /**
+        * Could the application possibly have a direct reference to
+        * the underlying collection implementation?
+        */
+       @Override
+    public boolean isDirectlyAccessible() {
+               return directlyAccessible;
+       }
+
+       /**
+        * Disassociate this collection from the given session.
+        *
+        * @return true if this was currently associated with the given session
+        */
+       @Override
+    public final boolean unsetSession(SessionImplementor currentSession) {
+               prepareForPossibleSpecialSpecjInitialization();
+               if ( currentSession == this.session ) {
+                       this.session = null;
+                       return true;
+               }
+               else {
+                       return false;
+               }
+       }
+
+       protected void prepareForPossibleSpecialSpecjInitialization() {
+               if ( session != null ) {
+                       specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
+
+                       if ( specjLazyLoad && sessionFactoryUuid == null ) {
+                               try {
+                                       sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
+                               }
+                               catch (NamingException e) {
+                                       //not much we can do if this fails...
+                               }
+                       }
+               }
+       }
+
+
+       /**
+        * Associate the collection with the given session.
+        *
+        * @return false if the collection was already associated with the session
+        *
+        * @throws HibernateException if the collection was already associated
+        * with another open session
+        */
+       @Override
+    public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
+               if ( session == this.session ) {
+                       return false;
+               }
+               else {
+                       if ( isConnectedToSession() ) {
+                               CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+                               if ( ce == null ) {
+                                       throw new HibernateException(
+                                                       "Illegal attempt to associate a collection with two open sessions"
+                                       );
+                               }
+                               else {
+                                       throw new HibernateException(
+                                                       "Illegal attempt to associate a collection with two open sessions: " +
+                                                                       MessageHelper.collectionInfoString(
+                                                                                       ce.getLoadedPersister(), this,
+                                                                                       ce.getLoadedKey(), session
+                                                                       )
+                                       );
+                               }
+                       }
+                       else {
+                               this.session = session;
+                               return true;
+                       }
+               }
+       }
+
+       /**
+        * Do we need to completely recreate this collection when it changes?
+        */
+       @Override
+    public boolean needsRecreate(CollectionPersister persister) {
+               return false;
+       }
+
+       /**
+        * To be called internally by the session, forcing
+        * immediate initialization.
+        */
+       @Override
+    public final void forceInitialization() throws HibernateException {
+               if ( !initialized ) {
+                       if ( initializing ) {
+                               throw new AssertionFailure( "force initialize loading collection" );
+                       }
+                       if ( session == null ) {
+                               throw new HibernateException( "collection is not associated with any session" );
+                       }
+                       if ( !session.isConnected() ) {
+                               throw new HibernateException( "disconnected session" );
+                       }
+                       session.initializeCollection( this, false );
+               }
+       }
+
+
+       /**
+        * Get the current snapshot from the session
+        */
+       @SuppressWarnings({"JavaDoc"})
+       protected final Serializable getSnapshot() {
+               return session.getPersistenceContext().getSnapshot( this );
+       }
+
+       /**
+        * Is this instance initialized?
+        */
+       @Override
+    public final boolean wasInitialized() {
+               return initialized;
+       }
+
+       @Override
+    public boolean isRowUpdatePossible() {
+               return true;
+       }
+
+       /**
+        * Does this instance have any "queued" additions?
+        */
+       @Override
+    public final boolean hasQueuedOperations() {
+               return operationQueue != null;
+       }
+
+       /**
+        * Iterate the "queued" additions
+        */
+       @Override
+    public final Iterator queuedAdditionIterator() {
+               if ( hasQueuedOperations() ) {
+                       return new Iterator() {
+                               int i = 0;
+
+                               @Override
+                public Object next() {
+                                       return operationQueue.get( i++ ).getAddedInstance();
+                               }
+
+                               @Override
+                public boolean hasNext() {
+                                       return i < operationQueue.size();
+                               }
+
+                               @Override
+                public void remove() {
+                                       throw new UnsupportedOperationException();
+                               }
+                       };
+               }
+               else {
+                       return EmptyIterator.INSTANCE;
+               }
+       }
+
+       /**
+        * Iterate the "queued" additions
+        */
+       @Override
+    @SuppressWarnings({"unchecked"})
+       public final Collection getQueuedOrphans(String entityName) {
+               if ( hasQueuedOperations() ) {
+                       Collection additions = new ArrayList( operationQueue.size() );
+                       Collection removals = new ArrayList( operationQueue.size() );
+                       for ( DelayedOperation operation : operationQueue ) {
+                               additions.add( operation.getAddedInstance() );
+                               removals.add( operation.getOrphan() );
+                       }
+                       return getOrphans( removals, additions, entityName, session );
+               }
+               else {
+                       return Collections.EMPTY_LIST;
+               }
+       }
+
+       /**
+        * Called before inserting rows, to ensure that any surrogate keys
+        * are fully generated
+        */
+       @Override
+    public void preInsert(CollectionPersister persister) throws HibernateException {
+       }
+
+       /**
+        * Called after inserting a row, to fetch the natively generated id
+        */
+       @Override
+    public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {
+       }
+
+       /**
+        * get all "orphaned" elements
+        */
+       @Override
+    public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
+
+       /**
+        * Get the current session
+        */
+       @SuppressWarnings({"JavaDoc"})
+       public final SessionImplementor getSession() {
+               return session;
+       }
+
+       protected final class IteratorProxy implements Iterator {
+               protected final Iterator itr;
+
+               public IteratorProxy(Iterator itr) {
+                       this.itr = itr;
+               }
+
+               @Override
+        public boolean hasNext() {
+                       return itr.hasNext();
+               }
+
+               @Override
+        public Object next() {
+                       return itr.next();
+               }
+
+               @Override
+        public void remove() {
+                       write();
+                       itr.remove();
+               }
+
+       }
+
+       protected final class ListIteratorProxy implements ListIterator {
+               protected final ListIterator itr;
+
+               public ListIteratorProxy(ListIterator itr) {
+                       this.itr = itr;
+               }
+
+               @Override
+        @SuppressWarnings({"unchecked"})
+               public void add(Object o) {
+                       write();
+                       itr.add( o );
+               }
+
+               @Override
+        public boolean hasNext() {
+                       return itr.hasNext();
+               }
+
+               @Override
+        public boolean hasPrevious() {
+                       return itr.hasPrevious();
+               }
+
+               @Override
+        public Object next() {
+                       return itr.next();
+               }
+
+               @Override
+        public int nextIndex() {
+                       return itr.nextIndex();
+               }
+
+               @Override
+        public Object previous() {
+                       return itr.previous();
+               }
+
+               @Override
+        public int previousIndex() {
+                       return itr.previousIndex();
+               }
+
+               @Override
+        public void remove() {
+                       write();
+                       itr.remove();
+               }
+
+               @Override
+        @SuppressWarnings({"unchecked"})
+               public void set(Object o) {
+                       write();
+                       itr.set( o );
+               }
+
+       }
+
+       protected class SetProxy implements java.util.Set {
+               protected final Collection set;
+
+               public SetProxy(Collection set) {
+                       this.set = set;
+               }
+
+               @Override
+        @SuppressWarnings({"unchecked"})
+               public boolean add(Object o) {
+                       write();
+                       return set.add( o );
+               }
+
+               @Override
+        @SuppressWarnings({"unchecked"})
+               public boolean addAll(Collection c) {
+                       write();
+                       return set.addAll( c );
+               }
+
+               @Override
+        public void clear() {
+                       write();
+                       set.clear();
+               }
+
+               @Override
+        public boolean contains(Object o) {
+                       return set.contains( o );
+               }
+
+               @Override
+        public boolean containsAll(Collection c) {
+                       return set.containsAll( c );
+               }
+
+               @Override
+        public boolean isEmpty() {
+                       return set.isEmpty();
+               }
+
+               @Override
+        public Iterator iterator() {
+                       return new IteratorProxy( set.iterator() );
+               }
+
+               @Override
+        public boolean remove(Object o) {
+                       write();
+                       return set.remove( o );
+               }
+
+               @Override
+        public boolean removeAll(Collection c) {
+                       write();
+                       return set.removeAll( c );
+               }
+
+               @Override
+        public boolean retainAll(Collection c) {
+                       write();
+                       return set.retainAll( c );
+               }
+
+               @Override
+        public int size() {
+                       return set.size();
+               }
+
+               @Override
+        public Object[] toArray() {
+                       return set.toArray();
+               }
+
+               @Override
+        @SuppressWarnings({"unchecked"})
+               public Object[] toArray(Object[] array) {
+                       return set.toArray( array );
+               }
+
+       }
+
+       protected final class ListProxy implements java.util.List {
+               protected final List list;
+
+               public ListProxy(List list) {
+                       this.list = list;
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public void add(int index, Object value) {
+                       write();
+                       list.add( index, value );
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public boolean add(Object o) {
+                       write();
+                       return list.add( o );
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public boolean addAll(Collection c) {
+                       write();
+                       return list.addAll( c );
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public boolean addAll(int i, Collection c) {
+                       write();
+                       return list.addAll( i, c );
+               }
+
+               @Override
+               public void clear() {
+                       write();
+                       list.clear();
+               }
+
+               @Override
+               public boolean contains(Object o) {
+                       return list.contains( o );
+               }
+
+               @Override
+               public boolean containsAll(Collection c) {
+                       return list.containsAll( c );
+               }
+
+               @Override
+               public Object get(int i) {
+                       return list.get( i );
+               }
+
+               @Override
+               public int indexOf(Object o) {
+                       return list.indexOf( o );
+               }
+
+               @Override
+               public boolean isEmpty() {
+                       return list.isEmpty();
+               }
+
+               @Override
+               public Iterator iterator() {
+                       return new IteratorProxy( list.iterator() );
+               }
+
+               @Override
+               public int lastIndexOf(Object o) {
+                       return list.lastIndexOf( o );
+               }
+
+               @Override
+               public ListIterator listIterator() {
+                       return new ListIteratorProxy( list.listIterator() );
+               }
+
+               @Override
+               public ListIterator listIterator(int i) {
+                       return new ListIteratorProxy( list.listIterator( i ) );
+               }
+
+               @Override
+               public Object remove(int i) {
+                       write();
+                       return list.remove( i );
+               }
+
+               @Override
+               public boolean remove(Object o) {
+                       write();
+                       return list.remove( o );
+               }
+
+               @Override
+               public boolean removeAll(Collection c) {
+                       write();
+                       return list.removeAll( c );
+               }
+
+               @Override
+               public boolean retainAll(Collection c) {
+                       write();
+                       return list.retainAll( c );
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public Object set(int i, Object o) {
+                       write();
+                       return list.set( i, o );
+               }
+
+               @Override
+               public int size() {
+                       return list.size();
+               }
+
+               @Override
+               public List subList(int i, int j) {
+                       return list.subList( i, j );
+               }
+
+               @Override
+               public Object[] toArray() {
+                       return list.toArray();
+               }
+
+               @Override
+               @SuppressWarnings({"unchecked"})
+               public Object[] toArray(Object[] array) {
+                       return list.toArray( array );
+               }
+
+       }
+
+       /**
+        * Contract for operations which are part of a collection's operation queue.
+        */
+       protected interface DelayedOperation {
+               public void operate();
+
+               public Object getAddedInstance();
+
+               public Object getOrphan();
+       }
+
+       /**
+        * Given a collection of entity instances that used to
+        * belong to the collection, and a collection of instances
+        * that currently belong, return a collection of orphans
+        */
+       @SuppressWarnings({"JavaDoc", "unchecked"})
+       protected static Collection getOrphans(
+                       Collection oldElements,
+                       Collection currentElements,
+                       String entityName,
+                       SessionImplementor session) throws HibernateException {
+
+               // short-circuit(s)
+               if ( currentElements.size() == 0 ) {
+                       return oldElements; // no new elements, the old list contains only Orphans
+               }
+               if ( oldElements.size() == 0 ) {
+                       return oldElements; // no old elements, so no Orphans neither
+               }
+
+               final EntityPersister entityPersister = session.getFactory().getEntityPersister( entityName );
+               final Type idType = entityPersister.getIdentifierType();
+
+               // create the collection holding the Orphans
+               Collection res = new ArrayList();
+
+               // collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
+               java.util.Set currentIds = new HashSet();
+               java.util.Set currentSaving = new IdentitySet();
+               for ( Object current : currentElements ) {
+                       if ( current != null && ForeignKeys.isNotTransient( entityName, current, null, session ) ) {
+                               EntityEntry ee = session.getPersistenceContext().getEntry( current );
+                               if ( ee != null && ee.getStatus() == Status.SAVING ) {
+                                       currentSaving.add( current );
+                               }
+                               else {
+                                       Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+                                                       entityName,
+                                                       current,
+                                                       session
+                                       );
+                                       currentIds.add( new TypedValue( idType, currentId, entityPersister.getEntityMode() ) );
+                               }
+                       }
+               }
+
+               // iterate over the *old* list
+               for ( Object old : oldElements ) {
+                       if ( !currentSaving.contains( old ) ) {
+                               Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, old, session );
+                               if ( !currentIds.contains( new TypedValue( idType, oldId, entityPersister.getEntityMode() ) ) ) {
+                                       res.add( old );
+                               }
+                       }
+               }
+
+               return res;
+       }
+
+       public static void identityRemove(
+                       Collection list,
+                       Object object,
+                       String entityName,
+                       SessionImplementor session) throws HibernateException {
+
+               if ( object != null && ForeignKeys.isNotTransient( entityName, object, null, session ) ) {
+                       final EntityPersister entityPersister = session.getFactory().getEntityPersister( entityName );
+                       Type idType = entityPersister.getIdentifierType();
+
+                       Serializable idOfCurrent = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, object, session );
+                       Iterator itr = list.iterator();
+                       while ( itr.hasNext() ) {
+                               Serializable idOfOld = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, itr.next(), session );
+                               if ( idType.isEqual( idOfCurrent, idOfOld, session.getFactory() ) ) {
+                                       itr.remove();
+                                       break;
+                               }
+                       }
+
+               }
+       }
+
+       @Override
+    public Object getIdentifier(Object entry, int i) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+    public Object getOwner() {
+               return owner;
+       }
+
+       @Override
+    public void setOwner(Object owner) {
+               this.owner = owner;
+       }
+
+       /** ------ Below is section of code which makes remote service calls ----- */
+       // The affected methods are :
+       // initialize(final boolean writing)
+       // readSize()
+       // readIndexExistence(final Object index)
+       // readElementExistence(final Object element)
+       // readElementByIndex(final Object index)
+
+       private static CdmApplicationRemoteConfiguration configuration;
+       private static boolean remoting = false;
+
+       public static void setConfiguration(CdmApplicationRemoteConfiguration conf) {
+           remoting = true;
+               configuration = conf;
+       }
+
+
+       private void remoteInitialize() {
+
+               if (getOwner() != null && !initialized) {
+
+                       try {
+                               String role = getRole();
+                               String fieldName = role.substring(role.lastIndexOf(".") + 1);
+                               log.info("--> Remote Lazy Initializing Collection " + getRole() + " , key : " + getKey() + " , field : " + fieldName);
+                               Object owner = getOwner();
+
+                               if(configuration == null) {
+                                       throw new HibernateException("CdmApplicationRemoteConfiguration not initialized (null)");
+                               }
+                               ICachedCommonService cachedCommonService = configuration.getCachedCommonService();
+                               if(cachedCommonService == null) {
+                                       throw new HibernateException("commonService not initialized (null)");
+                               }
+
+                               PersistentCollection col = cachedCommonService.initializeCollection(this);
+                               afterInitialize();
+
+                               Class<?> clazz = getClass();
+                               if (clazz != null) {
+                                       CollectionField cf = cachedCommonService.getCollectionField(col);
+                                       cachedCommonService.updatePersistentCollection(cf);
+                                       Field field = clazz.getDeclaredField(cf.getType().toString());
+                                       field.setAccessible(true);
+                                       field.set(this, cf.getCollection());
+                               }
+                       } catch (Exception ex) {
+                               log.warn(ex.getMessage());
+                       }
+               }
+       }
+
+
+
+}
+
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java b/eu.etaxonomy.taxeditor.remoting/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
new file mode 100644 (file)
index 0000000..5c11354
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.proxy;
+
+import java.io.Serializable;
+
+import javax.naming.NamingException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
+import org.hibernate.Session;
+import org.hibernate.SessionException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.engine.spi.EntityKey;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.internal.SessionFactoryRegistry;
+import org.hibernate.persister.entity.EntityPersister;
+import org.jboss.logging.Logger;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration;
+import eu.etaxonomy.cdm.api.cache.ICachedCommonService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * Convenience base class for lazy initialization handlers.  Centralizes the basic plumbing of doing lazy
+ * initialization freeing subclasses to acts as essentially adapters to their intended entity mode and/or
+ * proxy generation strategy.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractLazyInitializer implements LazyInitializer {
+       private static final Logger log = Logger.getLogger( AbstractLazyInitializer.class );
+
+       private String entityName;
+       private Serializable id;
+       private Object target;
+       private boolean initialized;
+       private boolean readOnly;
+       private boolean unwrap;
+       private transient SessionImplementor session;
+       private Boolean readOnlyBeforeAttachedToSession;
+
+       private String sessionFactoryUuid;
+       private boolean specjLazyLoad = false;
+
+       /**
+        * For serialization from the non-pojo initializers (HHH-3309)
+        */
+       protected AbstractLazyInitializer() {
+       }
+
+       /**
+        * Main constructor.
+        *
+        * @param entityName The name of the entity being proxied.
+        * @param id The identifier of the entity being proxied.
+        * @param session The session owning the proxy.
+        */
+       protected AbstractLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
+               this.entityName = entityName;
+               this.id = id;
+               // initialize other fields depending on session state
+               if ( session == null ) {
+                       unsetSession();
+               }
+               else {
+                       setSession( session );
+               }
+       }
+
+       @Override
+       public final String getEntityName() {
+               return entityName;
+       }
+
+       @Override
+       public final Serializable getIdentifier() {
+               return id;
+       }
+
+       @Override
+       public final void setIdentifier(Serializable id) {
+               this.id = id;
+       }
+
+       @Override
+       public final boolean isUninitialized() {
+               return !initialized;
+       }
+
+       @Override
+       public final SessionImplementor getSession() {
+               return session;
+       }
+
+       @Override
+       public final void setSession(SessionImplementor s) throws HibernateException {
+               if ( s != session ) {
+                       // check for s == null first, since it is least expensive
+                       if ( s == null ) {
+                               unsetSession();
+                       }
+                       else if ( isConnectedToSession() ) {
+                               //TODO: perhaps this should be some other RuntimeException...
+                               throw new HibernateException( "illegally attempted to associate a proxy with two open Sessions" );
+                       }
+                       else {
+                               // s != null
+                               session = s;
+                               if ( readOnlyBeforeAttachedToSession == null ) {
+                                       // use the default read-only/modifiable setting
+                                       final EntityPersister persister = s.getFactory().getEntityPersister( entityName );
+                                       setReadOnly( s.getPersistenceContext().isDefaultReadOnly() || !persister.isMutable() );
+                               }
+                               else {
+                                       // use the read-only/modifiable setting indicated during deserialization
+                                       setReadOnly( readOnlyBeforeAttachedToSession.booleanValue() );
+                                       readOnlyBeforeAttachedToSession = null;
+                               }
+                       }
+               }
+       }
+
+       private static EntityKey generateEntityKeyOrNull(Serializable id, SessionImplementor s, String entityName) {
+               if ( id == null || s == null || entityName == null ) {
+                       return null;
+               }
+               return s.generateEntityKey( id, s.getFactory().getEntityPersister( entityName ) );
+       }
+
+       @Override
+       public final void unsetSession() {
+               prepareForPossibleSpecialSpecjInitialization();
+               session = null;
+               readOnly = false;
+               readOnlyBeforeAttachedToSession = null;
+       }
+
+       @Override
+       public final void initialize() throws HibernateException {
+               // In remoting we are sure that session is null
+               // both when using property paths and switching off conversations
+               if(session == null && remoting) {
+                       remoteInitialize();
+               }
+               if ( !initialized ) {
+                       if ( specjLazyLoad ) {
+                               specialSpecjInitialization();
+                       }
+                       else if ( session == null ) {
+                               throw new LazyInitializationException( "could not initialize proxy - no Session" );
+                       }
+                       else if ( !session.isOpen() ) {
+                               throw new LazyInitializationException( "could not initialize proxy - the owning Session was closed" );
+                       }
+                       else if ( !session.isConnected() ) {
+                               throw new LazyInitializationException( "could not initialize proxy - the owning Session is disconnected" );
+                       }
+                       else {
+                               target = session.immediateLoad( entityName, id );
+                               initialized = true;
+                               checkTargetState();
+                       }
+               }
+               else {
+                       checkTargetState();
+               }
+       }
+
+       protected void specialSpecjInitialization() {
+               if ( session == null ) {
+                       //we have a detached collection thats set to null, reattach
+                       if ( sessionFactoryUuid == null ) {
+                               throw new LazyInitializationException( "could not initialize proxy - no Session" );
+                       }
+                       try {
+                               SessionFactoryImplementor sf = (SessionFactoryImplementor)
+                                               SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
+                               SessionImplementor session = (SessionImplementor) sf.openSession();
+
+                               // TODO: On the next major release, add an
+                               // 'isJTA' or 'getTransactionFactory' method to Session.
+                               boolean isJTA = session.getTransactionCoordinator()
+                                               .getTransactionContext().getTransactionEnvironment()
+                                               .getTransactionFactory()
+                                               .compatibleWithJtaSynchronization();
+
+                               if ( !isJTA ) {
+                                       // Explicitly handle the transactions only if we're not in
+                                       // a JTA environment.  A lazy loading temporary session can
+                                       // be created even if a current session and transaction are
+                                       // open (ex: session.clear() was used).  We must prevent
+                                       // multiple transactions.
+                                       ( ( Session) session ).beginTransaction();
+                               }
+
+                               try {
+                                       target = session.immediateLoad( entityName, id );
+                               }
+                               finally {
+                                       // make sure the just opened temp session gets closed!
+                                       try {
+                                               if ( !isJTA ) {
+                                                       ( ( Session) session ).getTransaction().commit();
+                                               }
+                                               ( (Session) session ).close();
+                                       }
+                                       catch (Exception e) {
+                                               log.warn( "Unable to close temporary session used to load lazy proxy associated to no session" );
+                                       }
+                               }
+                               initialized = true;
+                               checkTargetState();
+                       }
+                       catch (Exception e) {
+                               e.printStackTrace();
+                               throw new LazyInitializationException( e.getMessage() );
+                       }
+               }
+               else if ( session.isOpen() && session.isConnected() ) {
+                       target = session.immediateLoad( entityName, id );
+                       initialized = true;
+                       checkTargetState();
+               }
+               else {
+                       throw new LazyInitializationException( "could not initialize proxy - Session was closed or disced" );
+               }
+       }
+
+       protected void prepareForPossibleSpecialSpecjInitialization() {
+               if ( session != null ) {
+                       specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
+
+                       if ( specjLazyLoad && sessionFactoryUuid == null ) {
+                               try {
+                                       sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
+                               }
+                               catch (NamingException e) {
+                                       //not much we can do if this fails...
+                               }
+                       }
+               }
+       }
+
+       private void checkTargetState() {
+               if ( !unwrap ) {
+                       if ( target == null ) {
+                               getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
+                       }
+               }
+       }
+
+       /**
+        * Getter for property 'connectedToSession'.
+        *
+        * @return Value for property 'connectedToSession'.
+        */
+       protected final boolean isConnectedToSession() {
+               return getProxyOrNull() != null;
+       }
+
+       private Object getProxyOrNull() {
+               final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
+               if ( entityKey != null && session != null && session.isOpen() ) {
+                       return session.getPersistenceContext().getProxy( entityKey );
+               }
+               return null;
+       }
+
+       @Override
+       public final Object getImplementation() {
+               initialize();
+               return target;
+       }
+
+       @Override
+       public final void setImplementation(Object target) {
+               this.target = target;
+               initialized = true;
+       }
+
+       @Override
+       public final Object getImplementation(SessionImplementor s) throws HibernateException {
+               final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), s, getEntityName() );
+               return (entityKey == null ? null : s.getPersistenceContext().getEntity( entityKey ));
+       }
+
+       /**
+        * Getter for property 'target'.
+        * <p/>
+        * Same as {@link #getImplementation()} except that this method will not force initialization.
+        *
+        * @return Value for property 'target'.
+        */
+       protected final Object getTarget() {
+               return target;
+       }
+
+       @Override
+       public final boolean isReadOnlySettingAvailable() {
+               return (session != null && !session.isClosed());
+       }
+
+       private void errorIfReadOnlySettingNotAvailable() {
+               if ( session == null ) {
+                       throw new TransientObjectException(
+                                       "Proxy is detached (i.e, session is null). The read-only/modifiable setting is only accessible when the proxy is associated with an open session."
+                       );
+               }
+               if ( session.isClosed() ) {
+                       throw new SessionException(
+                                       "Session is closed. The read-only/modifiable setting is only accessible when the proxy is associated with an open session."
+                       );
+               }
+       }
+
+       @Override
+       public final boolean isReadOnly() {
+               errorIfReadOnlySettingNotAvailable();
+               return readOnly;
+       }
+
+       @Override
+       public final void setReadOnly(boolean readOnly) {
+               errorIfReadOnlySettingNotAvailable();
+               // only update if readOnly is different from current setting
+               if ( this.readOnly != readOnly ) {
+                       final EntityPersister persister = session.getFactory().getEntityPersister( entityName );
+                       if ( !persister.isMutable() && !readOnly ) {
+                               throw new IllegalStateException( "cannot make proxies for immutable entities modifiable" );
+                       }
+                       this.readOnly = readOnly;
+                       if ( initialized ) {
+                               EntityKey key = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
+                               if ( key != null && session.getPersistenceContext().containsEntity( key ) ) {
+                                       session.getPersistenceContext().setReadOnly( target, readOnly );
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Get the read-only/modifiable setting that should be put in affect when it is
+        * attached to a session.
+        * <p/>
+        * This method should only be called during serialization when read-only/modifiable setting
+        * is not available (i.e., isReadOnlySettingAvailable() == false)
+        *
+        * @return null, if the default setting should be used;
+        *         true, for read-only;
+        *         false, for modifiable
+        *
+        * @throws IllegalStateException if isReadOnlySettingAvailable() == true
+        */
+       protected final Boolean isReadOnlyBeforeAttachedToSession() {
+               if ( isReadOnlySettingAvailable() ) {
+                       throw new IllegalStateException(
+                                       "Cannot call isReadOnlyBeforeAttachedToSession when isReadOnlySettingAvailable == true"
+                       );
+               }
+               return readOnlyBeforeAttachedToSession;
+       }
+
+       /**
+        * Set the read-only/modifiable setting that should be put in affect when it is
+        * attached to a session.
+        * <p/>
+        * This method should only be called during deserialization, before associating
+        * the proxy with a session.
+        *
+        * @param readOnlyBeforeAttachedToSession, the read-only/modifiable setting to use when
+        * associated with a session; null indicates that the default should be used.
+        *
+        * @throws IllegalStateException if isReadOnlySettingAvailable() == true
+        */
+       /* package-private */
+       final void setReadOnlyBeforeAttachedToSession(Boolean readOnlyBeforeAttachedToSession) {
+               if ( isReadOnlySettingAvailable() ) {
+                       throw new IllegalStateException(
+                                       "Cannot call setReadOnlyBeforeAttachedToSession when isReadOnlySettingAvailable == true"
+                       );
+               }
+               this.readOnlyBeforeAttachedToSession = readOnlyBeforeAttachedToSession;
+       }
+
+       @Override
+       public boolean isUnwrap() {
+               return unwrap;
+       }
+
+       @Override
+       public void setUnwrap(boolean unwrap) {
+               this.unwrap = unwrap;
+       }
+
+       /** Below is section of code which makes remote service calls */
+
+       private static CdmApplicationRemoteConfiguration configuration;
+       private static boolean remoting = false;
+
+       public static void setConfiguration(CdmApplicationRemoteConfiguration conf) {
+           remoting = true;
+           configuration = conf;
+       }
+
+
+       private void remoteInitialize() {
+
+               if(!initialized) {
+                       int classid = ((Integer)getIdentifier()).intValue();
+                       log.info("--> Remote Lazy Initializing Object " + getEntityName() + " with id " + classid);
+                       Class clazz;
+                       try {
+                               clazz = 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)");
+                       }
+                       ICachedCommonService cachedCommonService = configuration.getCachedCommonService();
+                       if(cachedCommonService == null) {
+                               throw new HibernateException("commonService not initialized (null)");
+                       }
+
+                       CdmBase cdmBase = cachedCommonService.find(clazz,classid);
+                       setImplementation(cdmBase);
+
+               }
+       }
+
+       public static boolean isInitialized(AbstractLazyInitializer obj) {
+               return obj.initialized;
+       }
+}
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/cdmlib-ehcache.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/cdmlib-ehcache.xml
new file mode 100644 (file)
index 0000000..7ab604c
--- /dev/null
@@ -0,0 +1,6 @@
+<ehcache name="cdmlibModelCacheManager">
+       <diskStore path="ehcache.disk.store.dir/cdmlib" />
+       <cache name="cdmModelGetMethodsCache" maxElementsInMemory="0" maxElementsOnDisk="0" eternal="true"
+               overflowToDisk="true" diskPersistent="true" memoryStoreEvictionPolicy="LRU">
+       </cache>
+</ehcache>
\ No newline at end of file
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore b/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/.svnignore
new file mode 100644 (file)
index 0000000..a09ae97
--- /dev/null
@@ -0,0 +1 @@
+cdmlib-remote-webapp.war
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar b/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar
new file mode 100644 (file)
index 0000000..91c88d6
Binary files /dev/null and b/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/jetty-runner-9.2.3.v20140905.jar differ
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar b/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar
new file mode 100644 (file)
index 0000000..ef2faaf
Binary files /dev/null and b/eu.etaxonomy.taxeditor.remoting/src/main/resources/etc/jetty/start-9.2.3.v20140905.jar differ
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/config.properties b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/config.properties
new file mode 100644 (file)
index 0000000..f706a6e
--- /dev/null
@@ -0,0 +1,2 @@
+serverName=localhost:8080
+contextPath=remoting
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/httpInvokerServiceClients.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/httpInvokerServiceClients.xml
new file mode 100644 (file)
index 0000000..e3c0f9f
--- /dev/null
@@ -0,0 +1,480 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+       xmlns:context="http://www.springframework.org/schema/context"\r
+       xmlns:tx="http://www.springframework.org/schema/tx"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd\r
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">\r
+\r
+       \r
+   <bean id="agentService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/agent.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IAgentService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="annotationService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/annotation.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IAnnotationService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="auditeventService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/auditevent.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IAuditEventService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="classificationService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/classification.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IClassificationService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="collectionService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/collection.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ICollectionService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="commonService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/common.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ICommonService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="descriptionService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/description.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IDescriptionService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="editGeoService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/editgeo.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.ext.geo.IEditGeoService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="featureNodeService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/featurenode.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IFeatureNodeService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="featureTreeService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/featuretree.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IFeatureTreeService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="groupService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/group.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IGroupService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="identificationKeyService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/identificationkey.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IIdentificationKeyService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="locationService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/location.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ILocationService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="markerService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/marker.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IMarkerService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="mediaService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/media.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IMediaService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="nameService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/name.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.INameService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="occurrenceService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/occurrence.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IOccurrenceService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="polytomousKeyNodeService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/polytomouskeynode.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IPolytomousKeyNodeService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="polytomousKeyService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/polytomouskey.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IPolytomousKeyService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="referenceService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/reference.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IReferenceService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+<!-- \r
+   <bean id="serviceService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/service.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IService</value>\r
+               </property>\r
+       </bean>\r
+ -->\r
\r
+   <bean id="taxonNodeService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/taxonnode.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ITaxonNodeService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="taxonService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/taxon.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ITaxonService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="termService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/term.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.ITermService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="userService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/user.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IUserService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="vocabularyService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/vocabulary.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IVocabularyService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+   <bean id="workingSetService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/workingset.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IWorkingSetService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="grantedAuthorityService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/grantedauthority.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IGrantedAuthorityService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="databaseService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/database.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.IDatabaseService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="lsidAuthorityService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/lsidauthoruty.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.lsid.LSIDAuthorityService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="lsidMetadataService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/lsidmetadata.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.lsid.LSIDMetadataService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+   <bean id="lsiDataService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/lsiddata.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.lsid.LSIDDataService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+       <bean id="providerManager"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/authenticationManager.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>org.springframework.security.authentication.AuthenticationManager</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="primerService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/primer.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.molecular.IPrimerService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="amplificationService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/amplification.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.molecular.IAmplificationService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+       \r
+       <bean id="sequenceService"\r
+               class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">\r
+               <property name="serviceUrl">\r
+                       <value>http://${remoteServer}:${remotePort}/${remoteContext}/remoting/sequence.service</value>\r
+               </property>\r
+               <property name="serviceInterface">\r
+                       <value>eu.etaxonomy.cdm.api.service.molecular.ISequenceService</value>\r
+               </property>\r
+               <property name="httpInvokerRequestExecutor">\r
+                       <bean class="org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor" />\r
+               </property>\r
+       </bean>\r
+\r
+\r
+\r
+</beans>\r
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/localApplicationContext.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/localApplicationContext.xml
new file mode 100644 (file)
index 0000000..11a206b
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+       
+       
+    <!-- Default application context and term initializer -->
+  <import resource="classpath:/eu/etaxonomy/cdm/defaultApplicationContext.xml"/>
+  <bean id="persistentTermInitializer" class="eu.etaxonomy.cdm.database.PersistentTermInitializer">
+    <property name="omit" value="false" />
+  </bean>
+    
+  <import resource="classpath:/eu/etaxonomy/cdm/remote.xml"/>
+  <import resource="classpath:eu/etaxonomy/cdm/remote/json/jsonConfigurations.xml"/>
+  
+  <context:component-scan base-package="eu/etaxonomy/cdm/ext"/>
+  
+  <context:component-scan base-package="eu/etaxonomy/cdm/remote">
+    <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.remote\.config\.DataSourceConfigurer" />
+    <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.remote\.config\.LoggingConfigurer" />
+    <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.remote\.view\.PatternViewResolver" />
+    <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.remote\.vaadin\..*" />
+    <context:exclude-filter type="regex" expression="eu\.etaxonomy\.cdm\.remote\.controller\..*Portal.*" /> 
+  </context:component-scan>
+  
+
+</beans>
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml
new file mode 100644 (file)
index 0000000..986bd16
--- /dev/null
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE hibernate-configuration PUBLIC\r
+ "-//Hibernate/Hibernate Configuration DTD 3.0//EN"\r
+ "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">\r
+\r
+<hibernate-configuration>\r
+    <session-factory>\r
+\r
+      <property name="connection.release_mode">after_transaction</property>\r
+         <property name="show_sql">true</property>\r
+               <property name="format_sql">true</property>\r
+               <property name="use_sql_comments">true</property>\r
+\r
+      <!-- Connection Pooling -->\r
+<!--       <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> -->\r
+      <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl</property>\r
+           <!--\r
+          Configuring the C3P0ConnectionProvider\r
+          ========================================\r
+          see http://www.mchange.com/projects/c3p0/index.html#hibernate-specific\r
+          and also org.springframework.orm.hibernate3.AbstractSessionFactoryBean.setDataSource(DataSource dataSource)\r
+\r
+          IMPORTANT:\r
+          Because of the constraint (1) the org.hibernate.connection.C3P0ConnectionProvider are not be used\r
+          for the Cdm Library because it requires the dataSource bean in some cases.\r
+\r
+          (1)\r
+          Do NOT specify the dataSource in the sessionFactory for example in the\r
+          org.springframework.orm.hibernate3.LocalSessionFactoryBean\r
+          !!!==> If *dataSource* is set, this will override corresponding settings in Hibernate properties.!!!\r
+                         If this is set, the Hibernate settings should not define a connection provider to\r
+                     avoid meaningless double configuration.\r
+          (2)\r
+          Hibernate uses the hibernate.c3p0.max_size property to determine if c3p0\r
+          is beeing used.  Therefore the max_size property MUST be set. - maybe not need in hibernate 3.4 +\r
+\r
+          (3) If you are using Hibernate's C3P0ConnectionProvider you must set the following properties\r
+          in your hibernate configuration, using hibernate-specific configuration keys.\r
+          All other properties must be defined as usual in a c3p0.properties file.\r
+          This is confusing, and will hopefully be simplified some time in the future, but for now...\r
+\r
+            hibernate.c3p0.acquire_increment\r
+                       hibernate.c3p0.idle_test_period\r
+                       hibernate.c3p0.timeout\r
+                       hibernate.c3p0.max_size\r
+                       hibernate.c3p0.max_statements\r
+                       hibernate.c3p0.min_size\r
+                       hibernate.c3p0.validate\r
+      -->\r
+      <mapping package="eu.etaxonomy.cdm.model.common"/>\r
+      <!-- Annotation Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.Address"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.AgentBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.Contact"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.Institution"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.InstitutionalMembership"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.Person"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.Team"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.agent.TeamOrPersonBase"/>\r
+      <!-- Common Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Annotation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.AnnotationType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Credit"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.DefinedTerm"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.DefinedTermBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Extension"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.ExtensionType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.IdentifiableSource"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Identifier"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Group"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Language"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.LanguageString"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.LSID"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.LSIDAuthority"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Marker"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.MarkerType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.OrderedTermBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.OrderedTermVocabulary"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.OriginalSourceBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.RelationshipTermBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.Representation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.TermVocabulary"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.common.User"/>\r
+      <!-- Description Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.description.AbsenceTerm"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.CategoricalData"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.CommonTaxonName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.DescriptionBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.DescriptionElementBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.DescriptionElementSource"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.Distribution"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.Feature"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.FeatureNode"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.FeatureTree"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.KeyStatement"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.MediaKey"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.IndividualsAssociation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.MeasurementUnit"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.MultiAccessKey"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.PolytomousKey"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.PolytomousKeyNode"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.PresenceTerm"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.QuantitativeData"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.SpecimenDescription"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.State"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.StateData"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.StatisticalMeasure"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.TaxonDescription"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.TaxonInteraction"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.TaxonNameDescription"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.TextData"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.TextFormat"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.description.WorkingSet"/>\r
+      <!-- Location Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.location.NamedArea"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.location.NamedAreaLevel"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.location.NamedAreaType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.location.ReferenceSystem"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.location.Point"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.location.Country"/>\r
+      <!-- Media Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.media.AudioFile"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.ImageFile"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.Media"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.MediaRepresentationPart"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.MovieFile"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.Rights"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.media.RightsType"/>\r
+      <!-- Meta Data Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.metadata.CdmMetaData"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.metadata.CdmPreference"/>\r
+      <!-- Molecular Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.PhylogeneticTree"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.DnaQuality"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.DnaSample"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.Amplification"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.Primer"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.Sequence"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.SequenceString"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.SingleRead"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.molecular.Cloning"/>\r
+      <!-- Name Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.name.BacterialName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.BotanicalName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.CultivarPlantName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.HomotypicalGroup"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.HybridRelationship"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.HybridRelationshipType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NameRelationship"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NameRelationshipType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NameTypeDesignation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NomenclaturalCode"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NomenclaturalStatus"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NomenclaturalStatusType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.NonViralName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.Rank"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.TaxonNameBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.TypeDesignationBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.ViralName"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.name.ZoologicalName"/>\r
+      <!-- Occurrence Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.Collection"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.DerivationEvent"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.DerivationEventType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.DerivedUnit"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.MaterialOrMethodEvent"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.MediaSpecimen"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.DeterminationEvent"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.FieldUnit"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.GatheringEvent"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.PreservationMethod"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase"/>\r
+      <!-- Reference Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.reference.Reference"/>\r
+\r
+      <!-- Taxon Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.Synonym"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.SynonymRelationship"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.Taxon"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.TaxonBase"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.TaxonNode"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.Classification"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.TaxonRelationship"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType"/>\r
+      \r
+      <!-- Validation Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.validation.EntityValidationResult"/>\r
+      <mapping class="eu.etaxonomy.cdm.model.validation.EntityConstraintViolation"/>\r
+      \r
+      <!-- View Package -->\r
+      <mapping class="eu.etaxonomy.cdm.model.view.AuditEvent"/>\r
+      \r
+      <!-- for filling caches -->\r
+      <!-- since hibernate 4 listeners are not handled via hibernate.cfg.xml anymore -->\r
+      <!--  http://stackoverflow.com/questions/8616146/eventlisteners-using-hibernate-4-0-with-spring-3-1-0-release\r
+            https://community.jboss.org/wiki/HibernateCoreMigrationGuide40 -->\r
+\r
+    </session-factory>\r
+</hibernate-configuration>
\ No newline at end of file
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remotingApplicationContext.xml
new file mode 100644 (file)
index 0000000..60b8cd2
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \r
+       xmlns:context="http://www.springframework.org/schema/context"\r
+       xmlns:tx="http://www.springframework.org/schema/tx"\r
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+    http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd">\r
+\r
+\r
+       <!-- <bean id="remoteTermInitializer" class="eu.etaxonomy.cdm.remote.service.RemoteTermInitializer"/> -->\r
+\r
+       <context:annotation-config />\r
+\r
+       <import resource="classpath:/eu/etaxonomy/cdm/httpInvokerServiceClients.xml" />\r
+\r
+       <bean id="cdmApplicationRemoteConfiguration"\r
+               class="eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration" />\r
+\r
+       <import resource="classpath:/eu/etaxonomy/cdm/remoting_services_security.xml" />\r
+\r
+       <context:component-scan base-package="eu.etaxonomy.cdm.api.cache">\r
+               <!-- FIXME:Remoting Temp workaround to make remoting work -->\r
+               <context:exclude-filter type="regex"\r
+                       expression="eu\.etaxonomy\.cdm\.api\.cache\.CdmDaoCacher" />\r
+       </context:component-scan>\r
+\r
+       <context:component-scan base-package="eu/etaxonomy/taxeditor/remoting/session" />\r
+\r
+       \r
+       <!-- EditGeoService was moved to ext. Therefore it will not be found by \r
+               the default component scan. We added it here because the Editor needs it. \r
+               However, this is only a temporary solution. In the future we want to pass \r
+               in an application context with the editor. -->\r
+\r
+\r
+       <!-- <bean id="conversationHolder" class="eu.etaxonomy.cdm.api.conversation.ConversationHolder" \r
+               scope="prototype"/> -->\r
+\r
+       <!-- TODO move to io -->\r
+       <!-- <context:component-scan base-package="eu/etaxonomy/cdm/io"> <context:exclude-filter \r
+               type="regex" expression="eu\.etaxonomy\.cdm\.io\.berlinModel.*" /> </context:component-scan> -->\r
+       <!-- enable the configuration of transactional behavior based on annotations -->\r
+       <!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->\r
+\r
+</beans>\r
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_persistence_security.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_persistence_security.xml
new file mode 100644 (file)
index 0000000..46916f5
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"\r
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"\r
+  xsi:schemaLocation="http://www.springframework.org/schema/beans\r
+    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\r
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\r
+    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd\r
+    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd\r
+    ">\r
+\r
+\r
+    <!--\r
+      ============================== SECURITY ==============================\r
+    -->\r
+    <bean id="accessDecisionManager" class="eu.etaxonomy.cdm.persistence.hibernate.permission.UnanimousBasedUnrevokable">\r
+        <property name="decisionVoters">\r
+            <list>\r
+                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.GrantAlwaysVoter" />\r
+                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonNodeVoter" />\r
+                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonBaseVoter" />\r
+                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionBaseVoter" />\r
+                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionElementVoter" />\r
+            </list>\r
+        </property>\r
+    </bean>\r
+\r
+    <!--\r
+        CdmPermissionEvaluator.hasPermissions() evaluates the CdmPermissions like TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}\r
+    -->\r
+    <bean id="cdmPermissionEvaluator" class="eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator">\r
+        <property name="accessDecisionManager" ref="accessDecisionManager" />\r
+    </bean>\r
+\r
+    <!-- The CdmSecurityHibernateInterceptor checks onSave() and on flushDirty() if the currently authenticated principal or token  has\r
+    sufficient permissions on the entity to be persisted -->\r
+    <bean id="securityHibernateInterceptor" class="eu.etaxonomy.cdm.persistence.hibernate.CdmSecurityHibernateInterceptor">\r
+        <property name="permissionEvaluator" ref="cdmPermissionEvaluator" />\r
+    </bean>\r
+\r
+</beans>\r
diff --git a/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_services_security.xml b/eu.etaxonomy.taxeditor.remoting/src/main/resources/eu/etaxonomy/cdm/remoting_services_security.xml
new file mode 100644 (file)
index 0000000..4b5a565
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns="http://www.springframework.org/schema/beans"\r
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xmlns:context="http://www.springframework.org/schema/context"\r
+  xmlns:security="http://www.springframework.org/schema/security"\r
+  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\r
+    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd\r
+    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\r
+    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"\r
+    >\r
+\r
+    <import resource="classpath:/eu/etaxonomy/cdm/remoting_persistence_security.xml"/>\r
+    <!--\r
+        ======================================================================\r
+          security specific configuration\r
+        ======================================================================\r
+     -->\r
+    <security:global-method-security pre-post-annotations="enabled" run-as-manager-ref="runAsManager" >\r
+        <security:expression-handler ref="expressionHandler" />\r
+    </security:global-method-security>\r
+\r
+    <!--\r
+        To use "hasPermission()" in the Spring EL method annotations like @PreAuthorize we explicitly configure the permissionEvaluator\r
+        the cdmPermissionEvaluator is already defined in the persistence security context\r
+    -->\r
+    <bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">\r
+        <property name="permissionEvaluator" ref="cdmPermissionEvaluator" />\r
+    </bean>\r
+\r
+    <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">\r
+        <property name="providers">\r
+            <list>\r
+                <ref local="daoAuthenticationProvider"/>\r
+            </list>\r
+        </property>\r
+    </bean>\r
+\r
+    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">\r
+        <property name="userDetailsService" ref="userService"/>\r
+        <property name="saltSource" ref="saltSource"/>\r
+        <property name="passwordEncoder" ref="passwordEncoder"/>\r
+    </bean>\r
+\r
+    <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>\r
+\r
+    <bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">\r
+        <property name="userPropertyToUse" value="getUsername"/>\r
+    </bean>\r
+\r
+    <!--\r
+        Run-As Authentication Replacement for system operations\r
+        as e.g. performed by the eu.etaxonomy.cdm.api.application.FirstDataInserter\r
+\r
+        the key must match FirstDataInserter.RUN_AS_KEY\r
+     -->\r
+    <bean id="runAsManager"\r
+        class="org.springframework.security.access.intercept.RunAsManagerImpl">\r
+      <property name="key" value="TtlCx3pgKC4l"/>\r
+    </bean>\r
+\r
+\r
+</beans>\r
diff --git a/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.java b/eu.etaxonomy.taxeditor.remoting/src/test/java/eu/etaxonomy/cdm/api/cache/CdmClientCachingTest.java
new file mode 100644 (file)
index 0000000..4d2abf5
--- /dev/null
@@ -0,0 +1,359 @@
+// $Id$
+/**
+* Copyright (C) 2014 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.api.cache;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.hibernate.collection.spi.PersistentCollection;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.unitils.dbunit.annotation.DataSet;
+
+import eu.etaxonomy.cdm.api.service.ICommonService;
+import eu.etaxonomy.cdm.api.service.IPolytomousKeyService;
+import eu.etaxonomy.cdm.api.service.ITaxonService;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.Language;
+import eu.etaxonomy.cdm.model.common.LanguageString;
+import eu.etaxonomy.cdm.model.description.KeyStatement;
+import eu.etaxonomy.cdm.model.description.PolytomousKey;
+import eu.etaxonomy.cdm.model.description.PolytomousKeyNode;
+import eu.etaxonomy.taxeditor.httpinvoker.BaseRemotingTest;
+import eu.etaxonomy.taxeditor.httpinvoker.CDMServer;
+import eu.etaxonomy.taxeditor.remoting.session.CdmEntitySessionManager;
+import eu.etaxonomy.taxeditor.remoting.session.ISessionEventListener;
+import eu.etaxonomy.taxeditor.remoting.session.MockSessionOwner;
+
+/**
+ * @author cmathew
+ * @date 7 Oct 2014
+ *
+ */
+@DataSet
+public class CdmClientCachingTest extends BaseRemotingTest {
+
+    private static final Logger logger = Logger.getLogger(CdmClientCachingTest.class);
+
+    UUID polytomousKeyUuid = UUID.fromString("0d53ba20-7de4-4baa-bd8a-401048447d66");
+    UUID taxon1Uuid = UUID.fromString("2b336df7-29e8-4f79-985f-66502739d22f");
+
+
+    IPolytomousKeyService polytomousKeyService = getRemoteApplicationController().getPolytomousKeyService();
+    ICommonService commonService = getRemoteApplicationController().getCommonService();
+    ITaxonService taxonService = getRemoteApplicationController().getTaxonService();
+
+    CdmEntitySessionManager cdmEntitySessionManager = getRemoteApplicationController().getCdmEntitySessionManager();
+    
+       CdmTransientEntityCacher cacher;
+       
+    Language english = Language.getLanguageFromUuid(Language.uuidEnglish);
+       
+    private static final List<String> PKEY_DEPTH1_INIT_STRATEGY = Arrays.asList(new String[] {
+                       });
+    
+    private static final List<String> PKEY_DEPTH2_INIT_STRATEGY = Arrays.asList(new String[] {
+               "root"});
+    
+    private static final List<String> PKEY_DEPTH3_INIT_STRATEGY = Arrays.asList(new String[] {                 
+               "root.statement"});
+    
+    private ISessionEventListener sessionOwner;
+    
+    @BeforeClass
+    public static void initializePolytomousKeyTest() {
+        logger.setLevel(Level.INFO);
+        CDMServer.getInstance().setKeepServerRunning(true);    
+
+               CdmModelCacher cmdmc = new CdmModelCacher();
+               cmdmc.cacheGetterFields();
+               
+        //initializeController("default", "127.0.0.1", 8080, "", NomenclaturalCode.ICNAFP);
+    }
+
+    @Before
+    public void initializeSession() {
+       sessionOwner = new MockSessionOwner();    
+       cdmEntitySessionManager.bind(sessionOwner);
+       cacher = cdmEntitySessionManager.getCdmTransientEntityCacher(sessionOwner);
+    }
+
+    @Test
+    public void whenRecursiveCachingIsDisabledObjectsInSubGraphAreNotLoadedInSessionCache() {
+       CdmTransientEntityCacher.setRecursiveEnabled(false);
+       ISessionEventListener sessionOwner = new MockSessionOwner();
+       cdmEntitySessionManager.bind(sessionOwner);
+        PolytomousKey pkey = CdmBase.deproxy(polytomousKeyService.find(polytomousKeyUuid),PolytomousKey.class);
+        cdmEntity