From f57db28f1c101cc37e56267fe7793e3755c7249e Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Sat, 10 Oct 2020 17:12:13 +1300 Subject: [PATCH] #2075 - Refactor external mapping api and use ServiceLoader --- .../server/core/InternalConfigXmlMap.java | 70 +++++++++++ .../server/core/InternalConfigXmlRead.java | 109 ------------------ .../server/core/InternalConfiguration.java | 31 ++++- .../server/deploy/BeanDescriptorManager.java | 40 +++---- .../ebeaninternal/xmapping/api/XmapDto.java | 23 ++++ .../ebeaninternal/xmapping/api/XmapEbean.java | 19 +++ .../xmapping/api/XmapEntity.java | 27 +++++ .../xmapping/api/XmapNamedQuery.java | 20 ++++ .../xmapping/api/XmapRawSql.java | 42 +++++++ .../xmapping/api/XmapService.java | 15 +++ .../xmlmapping/InternalConfigXmlRead.java | 66 +++++++++++ .../xmlmapping/JaxbXmapService.java | 14 +++ .../ebeaninternal/xmlmapping/ToXmapEbean.java | 85 ++++++++++++++ .../io.ebeaninternal.xmapping.api.XmapService | 1 + 14 files changed, 426 insertions(+), 136 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlRead.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapDto.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEbean.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEntity.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapNamedQuery.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapRawSql.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapService.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmlmapping/InternalConfigXmlRead.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmlmapping/JaxbXmapService.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/xmlmapping/ToXmapEbean.java create mode 100644 ebean-core/src/main/resources/META-INF/services/io.ebeaninternal.xmapping.api.XmapService diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java new file mode 100644 index 000000000..ccfa08de3 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java @@ -0,0 +1,70 @@ +package io.ebeaninternal.server.core; + +import io.ebeaninternal.server.dto.DtoNamedQueries; +import io.ebeaninternal.xmapping.api.XmapDto; +import io.ebeaninternal.xmapping.api.XmapEbean; +import io.ebeaninternal.xmapping.api.XmapRawSql; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Reads the Xml deployment information. + */ +class InternalConfigXmlMap { + + private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlMap.class); + + private final List xmlEbeanList; + private final ClassLoader classLoader; + private final Map, DtoNamedQueries> dtoNamedQueries = new HashMap<>(); + + InternalConfigXmlMap(List xmlEbeanList, ClassLoader classLoader) { + this.xmlEbeanList = xmlEbeanList; + this.classLoader = classLoader; + initDtoMapping(); + } + + void initDtoMapping() { + if (xmlEbeanList != null) { + for (XmapEbean mapping : xmlEbeanList) { + List dtoList = mapping.getDto(); + for (XmapDto dto : dtoList) { + readDtoMapping(dto); + } + } + } + } + + /** + * Return the XML deployment information for entity beans. + */ + List xmlDeployment() { + return xmlEbeanList; + } + + /** + * Return the named queries for Dto beans. + */ + Map, DtoNamedQueries> readDtoMapping() { + return dtoNamedQueries; + } + + private void readDtoMapping(XmapDto dto) { + Class dtoClass; + try { + dtoClass = Class.forName(dto.getClazz(), false, classLoader); + } catch (Exception e) { + log.error("Could not load dto bean class " + dto.getClazz() + " for ebean xml entry"); + return; + } + DtoNamedQueries namedQueries = dtoNamedQueries.computeIfAbsent(dtoClass, aClass -> new DtoNamedQueries()); + for (XmapRawSql sql : dto.getRawSql()) { + namedQueries.addRawSql(sql.getName(), sql.getQuery()); + } + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlRead.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlRead.java deleted file mode 100644 index 3865baafa..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlRead.java +++ /dev/null @@ -1,109 +0,0 @@ -package io.ebeaninternal.server.core; - -import io.avaje.classpath.scanner.ClassPathScanner; -import io.avaje.classpath.scanner.Resource; -import io.ebean.config.DatabaseConfig; -import io.ebeaninternal.server.dto.DtoNamedQueries; -import io.ebeaninternal.xmlmapping.XmlMappingReader; -import io.ebeaninternal.xmlmapping.model.XmDto; -import io.ebeaninternal.xmlmapping.model.XmEbean; -import io.ebeaninternal.xmlmapping.model.XmRawSql; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Reads the Xml deployment information. - */ -class InternalConfigXmlRead { - - private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlRead.class); - - private final DatabaseConfig config; - - private final ClassLoader classLoader; - - private final Map, DtoNamedQueries> dtoNamedQueries = new HashMap<>(); - - private List xmlEbeanList; - - InternalConfigXmlRead(DatabaseConfig config) { - this.config = config; - this.classLoader = config.getClassLoadConfig().getClassLoader(); - if (config.getClassLoadConfig().isJavaxJAXBPresent()) { - init(); - } - } - - private void init() { - this.xmlEbeanList = XmlMappingReader.readByResourceName(classLoader, "ebean.xml"); - xmlEbeanList.addAll(XmlMappingReader.readByResourceList(xmlMappingResources())); - } - - private List xmlMappingResources() { - List scanners = ClassPathScanners.find(config); - List mappingLocations = config.getMappingLocations(); - List resourceList = new ArrayList<>(); - long st = System.currentTimeMillis(); - if (mappingLocations != null && !mappingLocations.isEmpty()) { - for (ClassPathScanner finder : scanners) { - for (String mappingLocation : mappingLocations) { - resourceList.addAll(finder.scanForResources(mappingLocation, resourceName -> resourceName.endsWith(".xml"))); - } - } - } - long searchTime = System.currentTimeMillis() - st; - log.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime); - return resourceList; - } - - /** - * Return the XML deployment information for entity beans. - */ - List xmlDeployment() { - return xmlEbeanList; - } - - /** - * Return the named queries for Dto beans. - */ - Map, DtoNamedQueries> readDtoMapping() { - if (xmlEbeanList != null) { - for (XmEbean mapping : xmlEbeanList) { - List dtoList = mapping.getDto(); - for (XmDto dto : dtoList) { - readDtoMapping(dto); - } - } - } - - return dtoNamedQueries; - } - - private void readDtoMapping(XmDto dto) { - - String dtoClassName = dto.getClazz(); - Class dtoClass; - try { - dtoClass = Class.forName(dtoClassName, false, classLoader); - } catch (Exception e) { - log.error("Could not load dto bean class " + dtoClassName + " for ebean xml entry"); - return; - } - - DtoNamedQueries namedQueries = dtoNamedQueries.computeIfAbsent(dtoClass, aClass -> new DtoNamedQueries()); - - for (XmRawSql sql : dto.getRawSql()) { - namedQueries.addRawSql(sql.getName(), sql.getQuery().getValue()); - } - - if (!dto.getNamedQuery().isEmpty()) { - log.error("Only raw-sql named queries supported for DTO beans - bean:" + dtoClass); - } - } - -} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java index 42f8a5f11..1bd7eec7b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java @@ -22,6 +22,7 @@ import io.ebean.event.readaudit.ReadAuditLogger; import io.ebean.event.readaudit.ReadAuditPrepare; import io.ebean.plugin.Plugin; import io.ebean.plugin.SpiServer; +import io.ebeaninternal.api.DbOffline; import io.ebeaninternal.api.ExtraMetrics; import io.ebeaninternal.api.QueryPlanManager; import io.ebeaninternal.api.SpiBackgroundExecutor; @@ -33,7 +34,6 @@ import io.ebeaninternal.api.SpiLogManager; import io.ebeaninternal.api.SpiLogger; import io.ebeaninternal.api.SpiLoggerFactory; import io.ebeaninternal.api.SpiProfileHandler; -import io.ebeaninternal.api.DbOffline; import io.ebeaninternal.server.autotune.AutoTuneService; import io.ebeaninternal.server.autotune.AutoTuneServiceProvider; import io.ebeaninternal.server.autotune.NoAutoTuneService; @@ -93,6 +93,8 @@ import io.ebeaninternal.server.transaction.TransactionManagerOptions; import io.ebeaninternal.server.transaction.TransactionScopeManager; import io.ebeaninternal.server.type.DefaultTypeManager; import io.ebeaninternal.server.type.TypeManager; +import io.ebeaninternal.xmapping.api.XmapEbean; +import io.ebeaninternal.xmapping.api.XmapService; import io.ebeanservice.docstore.api.DocStoreFactory; import io.ebeanservice.docstore.api.DocStoreIntegration; import io.ebeanservice.docstore.api.DocStoreUpdateProcessor; @@ -101,6 +103,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -195,10 +198,11 @@ public class InternalConfiguration { this.deployUtil = new DeployUtil(typeManager, config); this.serverCachePlugin = initServerCachePlugin(); this.cacheManager = initCacheManager(); - InternalConfigXmlRead xmlRead = new InternalConfigXmlRead(config); - this.dtoBeanManager = new DtoBeanManager(typeManager, xmlRead.readDtoMapping()); + + final InternalConfigXmlMap xmlMap = initExternalMapping(); + this.dtoBeanManager = new DtoBeanManager(typeManager, xmlMap.readDtoMapping()); this.beanDescriptorManager = new BeanDescriptorManager(this); - Map asOfTableMapping = beanDescriptorManager.deploy(xmlRead.xmlDeployment()); + Map asOfTableMapping = beanDescriptorManager.deploy(xmlMap.xmlDeployment()); Map draftTableMap = beanDescriptorManager.getDraftTableMap(); beanDescriptorManager.scheduleBackgroundTrim(); this.dataTimeZone = initDataTimeZone(); @@ -206,14 +210,29 @@ public class InternalConfiguration { this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping, draftTableMap); } - private SpiLogManager initLogManager() { + private InternalConfigXmlMap initExternalMapping() { + final List xmEbeans = readExternalMapping(); + return new InternalConfigXmlMap(xmEbeans, config.getClassLoadConfig().getClassLoader()); + } + private List readExternalMapping() { + //TODO: Remove the isJavaxJAXBPresent() check once this is external module + if (!config.getClassLoadConfig().isJavaxJAXBPresent()) { + return Collections.emptyList(); + } + final XmapService xmapService = config.service(XmapService.class); + if (xmapService == null) { + return Collections.emptyList(); + } + return xmapService.read(config.getClassLoadConfig().getClassLoader(), config.getMappingLocations()); + } + + private SpiLogManager initLogManager() { // allow plugin - i.e. capture executed SQL for testing/asserts SpiLoggerFactory loggerFactory = config.service(SpiLoggerFactory.class); if (loggerFactory == null) { loggerFactory = new DLoggerFactory(); } - SpiLogger sql = loggerFactory.create("io.ebean.SQL"); SpiLogger sum = loggerFactory.create("io.ebean.SUM"); SpiLogger txn = loggerFactory.create("io.ebean.TXN"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java index 279175d59..7102a4bc0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java @@ -59,12 +59,10 @@ import io.ebeaninternal.server.properties.EnhanceBeanPropertyAccess; import io.ebeaninternal.server.type.ScalarType; import io.ebeaninternal.server.type.ScalarTypeInteger; import io.ebeaninternal.server.type.TypeManager; -import io.ebeaninternal.xmlmapping.model.XmAliasMapping; -import io.ebeaninternal.xmlmapping.model.XmColumnMapping; -import io.ebeaninternal.xmlmapping.model.XmEbean; -import io.ebeaninternal.xmlmapping.model.XmEntity; -import io.ebeaninternal.xmlmapping.model.XmNamedQuery; -import io.ebeaninternal.xmlmapping.model.XmRawSql; +import io.ebeaninternal.xmapping.api.XmapEbean; +import io.ebeaninternal.xmapping.api.XmapEntity; +import io.ebeaninternal.xmapping.api.XmapNamedQuery; +import io.ebeaninternal.xmapping.api.XmapRawSql; import io.ebeanservice.docstore.api.DocStoreBeanAdapter; import io.ebeanservice.docstore.api.DocStoreFactory; import org.slf4j.Logger; @@ -350,7 +348,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap { /** * Deploy returning the asOfTableMap (which is required by the SQL builders). */ - public Map deploy(List mappings) { + public Map deploy(List mappings) { try { createListeners(); readEntityDeploymentInitial(); @@ -386,19 +384,19 @@ public class BeanDescriptorManager implements BeanDescriptorMap { } } - private void readXmlMapping(List mappings) { + private void readXmlMapping(List mappings) { if (mappings != null) { ClassLoader classLoader = config.getClassLoadConfig().getClassLoader(); - for (XmEbean mapping : mappings) { - List entityDeploy = mapping.getEntity(); - for (XmEntity deploy : entityDeploy) { + for (XmapEbean mapping : mappings) { + List entityDeploy = mapping.getEntity(); + for (XmapEntity deploy : entityDeploy) { readEntityMapping(classLoader, deploy); } } } } - private void readEntityMapping(ClassLoader classLoader, XmEntity entityDeploy) { + private void readEntityMapping(ClassLoader classLoader, XmapEntity entityDeploy) { String entityClassName = entityDeploy.getClazz(); Class entityClass; @@ -414,25 +412,25 @@ public class BeanDescriptorManager implements BeanDescriptorMap { logger.error("No entity bean for ebean.xml entry " + entityClassName); } else { - for (XmRawSql sql : entityDeploy.getRawSql()) { + for (XmapRawSql sql : entityDeploy.getRawSql()) { RawSqlBuilder builder; try { - builder = RawSqlBuilder.parse(sql.getQuery().getValue()); + builder = RawSqlBuilder.parse(sql.getQuery()); } catch (RuntimeException e) { - builder = RawSqlBuilder.unparsed(sql.getQuery().getValue()); + builder = RawSqlBuilder.unparsed(sql.getQuery()); } - for (XmColumnMapping columnMapping : sql.getColumnMapping()) { - builder.columnMapping(columnMapping.getColumn(), columnMapping.getProperty()); + for (Map.Entry columnMapping : sql.getColumnMapping().entrySet()) { + builder.columnMapping(columnMapping.getKey(), columnMapping.getValue()); } - for (XmAliasMapping aliasMapping : sql.getAliasMapping()) { - builder.tableAliasMapping(aliasMapping.getAlias(), aliasMapping.getProperty()); + for (Map.Entry aliasMapping : sql.getAliasMapping().entrySet()) { + builder.tableAliasMapping(aliasMapping.getKey(), aliasMapping.getValue()); } info.addRawSql(sql.getName(), builder.create()); } - for (XmNamedQuery namedQuery : entityDeploy.getNamedQuery()) { - info.addNamedQuery(namedQuery.getName(), namedQuery.getQuery().getValue()); + for (XmapNamedQuery namedQuery : entityDeploy.getNamedQuery()) { + info.addNamedQuery(namedQuery.getName(), namedQuery.getQuery()); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapDto.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapDto.java new file mode 100644 index 000000000..3d6c25ab5 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapDto.java @@ -0,0 +1,23 @@ +package io.ebeaninternal.xmapping.api; + +import java.util.ArrayList; +import java.util.List; + +public class XmapDto { + + protected final String clazz; + protected final List rawSql = new ArrayList<>(); + + public XmapDto(String clazz) { + this.clazz = clazz; + } + + public String getClazz() { + return clazz; + } + + public List getRawSql() { + return rawSql; + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEbean.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEbean.java new file mode 100644 index 000000000..439dc9779 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEbean.java @@ -0,0 +1,19 @@ +package io.ebeaninternal.xmapping.api; + +import java.util.ArrayList; +import java.util.List; + +public class XmapEbean { + + protected final List entity = new ArrayList<>(); + protected final List dto = new ArrayList<>(); + + public List getEntity() { + return entity; + } + + public List getDto() { + return dto; + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEntity.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEntity.java new file mode 100644 index 000000000..f87b25d8a --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapEntity.java @@ -0,0 +1,27 @@ +package io.ebeaninternal.xmapping.api; + +import java.util.ArrayList; +import java.util.List; + +public class XmapEntity { + + protected final String clazz; + protected final List namedQuery = new ArrayList<>(); + protected final List rawSql = new ArrayList<>(); + + public XmapEntity(String clazz) { + this.clazz = clazz; + } + + public String getClazz() { + return clazz; + } + + public List getNamedQuery() { + return namedQuery; + } + + public List getRawSql() { + return rawSql; + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapNamedQuery.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapNamedQuery.java new file mode 100644 index 000000000..c5737a8d6 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapNamedQuery.java @@ -0,0 +1,20 @@ +package io.ebeaninternal.xmapping.api; + +public class XmapNamedQuery { + + protected final String name; + protected final String query; + + public XmapNamedQuery(String name, String query) { + this.name = name; + this.query = query; + } + + public String getName() { + return name; + } + + public String getQuery() { + return query; + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapRawSql.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapRawSql.java new file mode 100644 index 000000000..0f83398f3 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapRawSql.java @@ -0,0 +1,42 @@ +package io.ebeaninternal.xmapping.api; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class XmapRawSql { + + protected final String name; + protected final String query; + protected final Map columnMapping = new LinkedHashMap<>(); + protected final Map aliasMapping = new LinkedHashMap<>(); + + public XmapRawSql(String name, String query) { + this.name = name; + this.query = query; + } + + public void addColumnMapping(String column, String property) { + columnMapping.put(column, property); + } + + public void addAliasMapping(String alias, String property) { + aliasMapping.put(alias, property); + } + + public String getName() { + return name; + } + + public String getQuery() { + return query; + } + + public Map getColumnMapping() { + return columnMapping; + } + + public Map getAliasMapping() { + return aliasMapping; + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapService.java b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapService.java new file mode 100644 index 000000000..ccdea0876 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmapping/api/XmapService.java @@ -0,0 +1,15 @@ +package io.ebeaninternal.xmapping.api; + +import java.util.List; + +/** + * Read and return external mapping for named queries etc. + */ +public interface XmapService { + + /** + * Read and return external named queries etc. + */ + List read(ClassLoader classLoader, List mappingLocations); + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/InternalConfigXmlRead.java b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/InternalConfigXmlRead.java new file mode 100644 index 000000000..7880b10ae --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/InternalConfigXmlRead.java @@ -0,0 +1,66 @@ +package io.ebeaninternal.xmlmapping; + +import io.avaje.classpath.scanner.ClassPathScanner; +import io.avaje.classpath.scanner.ClassPathScannerFactory; +import io.avaje.classpath.scanner.Resource; +import io.ebeaninternal.xmapping.api.XmapEbean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; + +/** + * Reads the Xml deployment information. + */ +class InternalConfigXmlRead { + + private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlRead.class); + + private final ToXmapEbean to = new ToXmapEbean(); + private final ClassLoader classLoader; + private final List mappingLocations; + + InternalConfigXmlRead(ClassLoader classLoader, List mappingLocations) { + this.classLoader = classLoader; + this.mappingLocations = mappingLocations; +// if (config.getClassLoadConfig().isJavaxJAXBPresent()) { +// init(); +// } + } + + List read() { + List list = new ArrayList<>(); + list.addAll(to.toBeans(XmlMappingReader.readByResourceName(classLoader, "ebean.xml"))); + list.addAll(to.toBeans(XmlMappingReader.readByResourceList(xmlMappingResources()))); + return list; + } + + private List xmlMappingResources() { + List scanners = scanners(); + List resourceList = new ArrayList<>(); + long st = System.currentTimeMillis(); + if (mappingLocations != null && !mappingLocations.isEmpty()) { + for (ClassPathScanner finder : scanners) { + for (String mappingLocation : mappingLocations) { + resourceList.addAll(finder.scanForResources(mappingLocation, resourceName -> resourceName.endsWith(".xml"))); + } + } + } + long searchTime = System.currentTimeMillis() - st; + log.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime); + return resourceList; + } + + /** + * Return the list of ClassPathScanner services using DatabaseConfig service loader. + */ + private List scanners() { + List scanners = new ArrayList<>(); + for (ClassPathScannerFactory factory : ServiceLoader.load(ClassPathScannerFactory.class, classLoader)) { + scanners.add(factory.createScanner(classLoader)); + } + return scanners; + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/JaxbXmapService.java b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/JaxbXmapService.java new file mode 100644 index 000000000..f5581bfa7 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/JaxbXmapService.java @@ -0,0 +1,14 @@ +package io.ebeaninternal.xmlmapping; + +import io.ebeaninternal.xmapping.api.XmapEbean; +import io.ebeaninternal.xmapping.api.XmapService; + +import java.util.List; + +public class JaxbXmapService implements XmapService { + + @Override + public List read(ClassLoader classLoader, List mappingLocations) { + return new InternalConfigXmlRead(classLoader, mappingLocations).read(); + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/ToXmapEbean.java b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/ToXmapEbean.java new file mode 100644 index 000000000..f822111b2 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/xmlmapping/ToXmapEbean.java @@ -0,0 +1,85 @@ +package io.ebeaninternal.xmlmapping; + +import io.ebeaninternal.xmapping.api.XmapDto; +import io.ebeaninternal.xmapping.api.XmapEbean; +import io.ebeaninternal.xmapping.api.XmapEntity; +import io.ebeaninternal.xmapping.api.XmapNamedQuery; +import io.ebeaninternal.xmapping.api.XmapRawSql; +import io.ebeaninternal.xmlmapping.model.XmAliasMapping; +import io.ebeaninternal.xmlmapping.model.XmColumnMapping; +import io.ebeaninternal.xmlmapping.model.XmDto; +import io.ebeaninternal.xmlmapping.model.XmEbean; +import io.ebeaninternal.xmlmapping.model.XmEntity; +import io.ebeaninternal.xmlmapping.model.XmNamedQuery; +import io.ebeaninternal.xmlmapping.model.XmRawSql; + +import java.util.List; + +import static java.util.stream.Collectors.toList; + +public class ToXmapEbean { + + public List toBeans(List xmBeans) { + return xmBeans.stream() + .map(this::toBean) + .collect(toList()); + } + + private XmapEbean toBean(XmEbean bean) { + XmapEbean xmap = new XmapEbean(); + xmap.getDto().addAll(toDto(bean.getDto())); + xmap.getEntity().addAll(toEntity(bean.getEntity())); + return xmap; + } + + private List toEntity(List xmEntity) { + return xmEntity.stream() + .map(this::toEntity) + .collect(toList()); + } + + private XmapEntity toEntity(XmEntity xmEntity) { + XmapEntity entity = new XmapEntity(xmEntity.getClazz()); + for (XmNamedQuery named : xmEntity.getNamedQuery()) { + entity.getNamedQuery().add(toNamed(named)); + } + for (XmRawSql xmRawSql : xmEntity.getRawSql()) { + entity.getRawSql().add(toRaw(xmRawSql)); + } + return entity; + } + + private XmapNamedQuery toNamed(XmNamedQuery named) { + return new XmapNamedQuery(named.getName(), named.getQuery().getValue()); + } + + private List toDto(List dto) { + return dto.stream() + .map(this::toDto) + .collect(toList()); + } + + private XmapDto toDto(XmDto xmapDto) { + XmapDto dto = new XmapDto(xmapDto.getClazz()); + dto.getRawSql().addAll(toRaw(xmapDto.getRawSql())); + return dto; + } + + private List toRaw(List rawSql) { + return rawSql.stream() + .map(this::toRaw) + .collect(toList()); + } + + private XmapRawSql toRaw(XmRawSql xmRawSql) { + XmapRawSql rawSql = new XmapRawSql(xmRawSql.getName(), xmRawSql.getQuery().getValue()); + for (XmColumnMapping xmCol : xmRawSql.getColumnMapping()) { + rawSql.addColumnMapping(xmCol.getColumn(), xmCol.getProperty()); + } + for (XmAliasMapping xmAlias : xmRawSql.getAliasMapping()) { + rawSql.addAliasMapping(xmAlias.getAlias(), xmAlias.getProperty()); + } + return rawSql; + } + +} diff --git a/ebean-core/src/main/resources/META-INF/services/io.ebeaninternal.xmapping.api.XmapService b/ebean-core/src/main/resources/META-INF/services/io.ebeaninternal.xmapping.api.XmapService new file mode 100644 index 000000000..e65ada2df --- /dev/null +++ b/ebean-core/src/main/resources/META-INF/services/io.ebeaninternal.xmapping.api.XmapService @@ -0,0 +1 @@ +io.ebeaninternal.xmlmapping.JaxbXmapService