From f8b8a41bce5319ff664fc5eb9959277c13070dc7 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Fri, 21 Aug 2015 17:33:43 +1200 Subject: [PATCH] #394 - ENH: Add plugin API SpiServer, SpiBeanType ... migrate plugins towards using this API, migrate away from direct use of BeanDescriptor etc. --- .../java/com/avaje/ebean/EbeanServer.java | 6 ++ .../com/avaje/ebean/plugin/SpiBeanType.java | 59 +++++++++++++++++++ .../com/avaje/ebean/plugin/SpiServer.java | 33 +++++++++++ .../server/core/DefaultServer.java | 31 +++++++++- .../server/deploy/BeanDescriptor.java | 18 +++++- .../server/deploy/BeanDescriptorManager.java | 8 +++ .../com/avaje/ebean/plugin/SpiServerTest.java | 42 +++++++++++++ .../ebeaninternal/api/TDSpiEbeanServer.java | 6 ++ 8 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/avaje/ebean/plugin/SpiBeanType.java create mode 100644 src/main/java/com/avaje/ebean/plugin/SpiServer.java create mode 100644 src/test/java/com/avaje/ebean/plugin/SpiServerTest.java diff --git a/src/main/java/com/avaje/ebean/EbeanServer.java b/src/main/java/com/avaje/ebean/EbeanServer.java index 5c74bcb1f..ab4df20f9 100644 --- a/src/main/java/com/avaje/ebean/EbeanServer.java +++ b/src/main/java/com/avaje/ebean/EbeanServer.java @@ -12,6 +12,7 @@ import com.avaje.ebean.annotation.CacheStrategy; import com.avaje.ebean.cache.ServerCacheManager; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.meta.MetaInfoManager; +import com.avaje.ebean.plugin.SpiServer; import com.avaje.ebean.text.csv.CsvReader; import com.avaje.ebean.text.json.JsonContext; import org.jetbrains.annotations.Nullable; @@ -128,6 +129,11 @@ public interface EbeanServer { */ MetaInfoManager getMetaInfoManager(); + /** + * Return the extended API intended for use by plugins. + */ + SpiServer getPluginApi(); + /** * Return the BeanState for a given entity bean. *

diff --git a/src/main/java/com/avaje/ebean/plugin/SpiBeanType.java b/src/main/java/com/avaje/ebean/plugin/SpiBeanType.java new file mode 100644 index 000000000..11f68f06d --- /dev/null +++ b/src/main/java/com/avaje/ebean/plugin/SpiBeanType.java @@ -0,0 +1,59 @@ +package com.avaje.ebean.plugin; + +import com.avaje.ebean.config.dbplatform.IdType; +import com.avaje.ebean.event.BeanFindController; +import com.avaje.ebean.event.BeanPersistController; +import com.avaje.ebean.event.BeanPersistListener; +import com.avaje.ebean.event.BeanQueryAdapter; + +/** + * Information and methods on BeanDescriptors made available to plugins. + */ +public interface SpiBeanType { + + /** + * Return the class type this BeanDescriptor describes. + */ + Class getBeanType(); + + /** + * Return the base table this bean type maps to. + */ + String getBaseTable(); + + /** + * Return the id value for the given bean. + */ + Object getBeanId(T bean); + + /** + * Return the bean persist controller. + */ + BeanPersistController getPersistController(); + + /** + * Return the bean persist listener. + */ + BeanPersistListener getPersistListener(); + + /** + * Return the beanFinder. Usually null unless overriding the finder. + */ + BeanFindController getFindController(); + + /** + * Return the BeanQueryAdapter or null if none is defined. + */ + BeanQueryAdapter getQueryAdapter(); + + /** + * Return the identity generation type. + */ + IdType getIdType(); + + /** + * Return the sequence name associated to this entity bean type (if there is one). + */ + String getSequenceName(); + +} diff --git a/src/main/java/com/avaje/ebean/plugin/SpiServer.java b/src/main/java/com/avaje/ebean/plugin/SpiServer.java new file mode 100644 index 000000000..0171ef13f --- /dev/null +++ b/src/main/java/com/avaje/ebean/plugin/SpiServer.java @@ -0,0 +1,33 @@ +package com.avaje.ebean.plugin; + +import com.avaje.ebean.EbeanServer; +import com.avaje.ebean.config.dbplatform.DatabasePlatform; + +import java.util.List; + +/** + * Extensions to EbeanServer API made available to plugins. + */ +public interface SpiServer extends EbeanServer { + + /** + * Return the DatabasePlatform for this server. + */ + DatabasePlatform getDatabasePlatform(); + + /** + * Return all the bean types registered on this server instance. + */ + List> getBeanTypes(); + + /** + * Return the bean type for a given entity bean class. + */ + SpiBeanType getBeanType(Class beanClass); + + /** + * Return the bean types mapped to the given base table. + */ + List> getBeanTypes(String baseTableName); + +} diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java index fa74466d3..fd0c3e4e6 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java @@ -15,6 +15,8 @@ import com.avaje.ebean.config.dbplatform.DatabasePlatform; import com.avaje.ebean.event.BeanPersistController; import com.avaje.ebean.event.BeanQueryAdapter; import com.avaje.ebean.meta.MetaInfoManager; +import com.avaje.ebean.plugin.SpiBeanType; +import com.avaje.ebean.plugin.SpiServer; import com.avaje.ebean.text.csv.CsvReader; import com.avaje.ebean.text.json.JsonContext; import com.avaje.ebeaninternal.api.LoadBeanRequest; @@ -86,7 +88,7 @@ import java.util.concurrent.FutureTask; /** * The default server side implementation of EbeanServer. */ -public final class DefaultServer implements SpiEbeanServer { +public final class DefaultServer implements SpiServer, SpiEbeanServer { private static final Logger logger = LoggerFactory.getLogger(DefaultServer.class); @@ -310,6 +312,11 @@ public final class DefaultServer implements SpiEbeanServer { return metaInfoManager; } + @Override + public SpiServer getPluginApi() { + return this; + } + public BackgroundExecutor getBackgroundExecutor() { return backgroundExecutor; } @@ -1937,6 +1944,28 @@ public final class DefaultServer implements SpiEbeanServer { return beanDescriptorManager.getBeanDescriptors(tableName); } + /** + * Return all the SPI BeanTypes. + */ + public List> getBeanTypes() { + return getBeanDescriptors(); + } + + /** + * Return the SPI bean types mapped to the given table. + */ + public List> getBeanTypes(String tableName) { + return beanDescriptorManager.getBeanTypes(tableName); + } + + /** + * Return the SPI bean types for the given bean class. + */ + @Override + public SpiBeanType getBeanType(Class beanType) { + return getBeanDescriptor(beanType); + } + /** * Return the BeanDescriptor using its unique id. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index 8d9b8a8d4..17661dc76 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -21,6 +21,7 @@ import com.avaje.ebean.event.changelog.ChangeLogFilter; import com.avaje.ebean.event.changelog.ChangeType; import com.avaje.ebean.meta.MetaBeanInfo; import com.avaje.ebean.meta.MetaQueryPlanStatistic; +import com.avaje.ebean.plugin.SpiBeanType; import com.avaje.ebeaninternal.api.HashQueryPlan; import com.avaje.ebeaninternal.api.SpiEbeanServer; import com.avaje.ebeaninternal.api.SpiQuery; @@ -73,7 +74,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * Describes Beans including their deployment information. */ -public class BeanDescriptor implements MetaBeanInfo { +public class BeanDescriptor implements MetaBeanInfo, SpiBeanType { private static final Logger logger = LoggerFactory.getLogger(BeanDescriptor.class); @@ -1353,6 +1354,11 @@ public class BeanDescriptor implements MetaBeanInfo { return (idProperty == null) ? null : idProperty.getValue(bean); } + @Override + public Object getBeanId(T bean) { + return getId((EntityBean)bean); + } + /** * Return the default order by that may need to be added if a many property is * included in the query. @@ -1630,12 +1636,20 @@ public class BeanDescriptor implements MetaBeanInfo { } /** - * Return the beanFinder. Usually null unless overriding the finder. + * Return the beanFinder (Migrate over to getFindController). */ public BeanFindController getBeanFinder() { return beanFinder; } + /** + * Return the find controller (SPI interface). + */ + @Override + public BeanFindController getFindController() { + return beanFinder; + } + /** * Return the BeanQueryAdapter or null if none is defined. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java index 6f6410218..076a39fd6 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java @@ -20,6 +20,7 @@ import com.avaje.ebean.event.changelog.ChangeLogFilter; import com.avaje.ebean.event.changelog.ChangeLogListener; import com.avaje.ebean.event.changelog.ChangeLogPrepare; import com.avaje.ebean.event.changelog.ChangeLogRegister; +import com.avaje.ebean.plugin.SpiBeanType; import com.avaje.ebeaninternal.api.SpiEbeanServer; import com.avaje.ebeaninternal.api.TransactionEventTable; import com.avaje.ebeaninternal.server.core.BootupClasses; @@ -346,6 +347,13 @@ public class BeanDescriptorManager implements BeanDescriptorMap { return tableToDescMap.get(tableName.toLowerCase()); } + /** + * Return the BeanDescriptors mapped to the table. + */ + public List> getBeanTypes(String tableName) { + return tableToDescMap.get(tableName.toLowerCase()); + } + /** * Build a map of table names to BeanDescriptors. *

diff --git a/src/test/java/com/avaje/ebean/plugin/SpiServerTest.java b/src/test/java/com/avaje/ebean/plugin/SpiServerTest.java new file mode 100644 index 000000000..1f752217c --- /dev/null +++ b/src/test/java/com/avaje/ebean/plugin/SpiServerTest.java @@ -0,0 +1,42 @@ +package com.avaje.ebean.plugin; + +import com.avaje.ebean.Ebean; +import com.avaje.ebean.EbeanServer; +import com.avaje.tests.model.basic.Customer; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.*; + + +public class SpiServerTest { + + @Test + public void test() { + + EbeanServer defaultServer = Ebean.getDefaultServer(); + SpiServer pluginApi = defaultServer.getPluginApi(); + + SpiBeanType beanType = pluginApi.getBeanType(Customer.class); + assertEquals("o_customer", beanType.getBaseTable()); + assertNotNull(pluginApi.getDatabasePlatform()); + assertNull(beanType.getFindController()); + assertNotNull(beanType.getPersistController()); + assertNull(beanType.getPersistListener()); + assertNull(beanType.getQueryAdapter()); + + Customer customer = new Customer(); + customer.setId(42); + + assertEquals(42, beanType.getBeanId(customer)); + + List> beanTypes = pluginApi.getBeanTypes("o_customer"); + assertEquals(1, beanTypes.size()); + assertSame(beanType, beanTypes.get(0)); + + List> allTypes = pluginApi.getBeanTypes(); + assertTrue(!allTypes.isEmpty()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/avaje/ebeaninternal/api/TDSpiEbeanServer.java b/src/test/java/com/avaje/ebeaninternal/api/TDSpiEbeanServer.java index d400732fc..8f3be7f19 100644 --- a/src/test/java/com/avaje/ebeaninternal/api/TDSpiEbeanServer.java +++ b/src/test/java/com/avaje/ebeaninternal/api/TDSpiEbeanServer.java @@ -9,6 +9,7 @@ import com.avaje.ebean.cache.ServerCacheManager; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.config.dbplatform.DatabasePlatform; import com.avaje.ebean.meta.MetaInfoManager; +import com.avaje.ebean.plugin.SpiServer; import com.avaje.ebean.text.csv.CsvReader; import com.avaje.ebean.text.json.JsonContext; import com.avaje.ebeaninternal.server.autofetch.AutoFetchManager; @@ -42,6 +43,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer { } + @Override + public SpiServer getPluginApi() { + return null; + } + @Override public boolean isCollectQueryOrigins() { return false;