[jOOQ/jOOQ#7585] Move java.desktop related logic of DefaultRecordMapper
into a new jooq-beans-extensions module
This commit is contained in:
parent
6626120db8
commit
a5be8cd89d
3
jOOQ-beans-extensions/.gitignore
vendored
Normal file
3
jOOQ-beans-extensions/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
/.idea
|
||||
/*.iml
|
||||
19
jOOQ-beans-extensions/LICENSE.txt
Normal file
19
jOOQ-beans-extensions/LICENSE.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Other licenses:
|
||||
-----------------------------------------------------------------------------
|
||||
Commercial licenses for this work are available. These replace the above
|
||||
ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
database integrations.
|
||||
|
||||
For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
10
jOOQ-beans-extensions/NOTICE.txt
Normal file
10
jOOQ-beans-extensions/NOTICE.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Third party NOTICE.txt contents
|
||||
===============================
|
||||
|
||||
Contents of https://github.com/apache/commons-lang/blob/master/NOTICE.txt
|
||||
-------------------------------------------------------------------------
|
||||
Apache Commons Lang
|
||||
Copyright 2001-2019 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
67
jOOQ-beans-extensions/pom.xml
Normal file
67
jOOQ-beans-extensions/pom.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-parent</artifactId>
|
||||
<version>3.20.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>jooq-beans-extensions</artifactId>
|
||||
<name>jOOQ Beans Extensions Beans</name>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>https://www.jooq.org/inc/LICENSE.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</licenses>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Automatic-Module-Name>org.jooq.beans.extensions</Automatic-Module-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
15
jOOQ-beans-extensions/src/main/java/module-info.java
Normal file
15
jOOQ-beans-extensions/src/main/java/module-info.java
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* The jOOQ beans extensions module.
|
||||
*/
|
||||
module org.jooq.beans.extensions {
|
||||
|
||||
// Other jOOQ modules
|
||||
requires transitive org.jooq;
|
||||
|
||||
// Nullability annotations for better Kotlin interop
|
||||
requires static org.jetbrains.annotations;
|
||||
|
||||
// The DefaultRecordMapper makes use of JavaBeans utilities, including:
|
||||
// - Support for ConstructorProperties
|
||||
requires transitive java.desktop;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package org.jooq.beans.extensions;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.jooq.ConstructorPropertiesProvider;
|
||||
|
||||
/**
|
||||
* The default {@link ConstructorPropertiesProvider} implementation that looks
|
||||
* up constructor properties from {@link ConstructorProperties}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultConstructorPropertiesProvider implements ConstructorPropertiesProvider {
|
||||
|
||||
@Override
|
||||
public String[] properties(Constructor<?> constructor) {
|
||||
ConstructorProperties cp = constructor.getAnnotation(ConstructorProperties.class);
|
||||
|
||||
return cp != null ? cp.value() : null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Other licenses:
|
||||
-----------------------------------------------------------------------------
|
||||
Commercial licenses for this work are available. These replace the above
|
||||
ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
database integrations.
|
||||
|
||||
For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
@ -0,0 +1,2 @@
|
||||
Thanks for downloading jOOQ.
|
||||
Please visit http://www.jooq.org for more information.
|
||||
@ -14,10 +14,6 @@ module org.jooq {
|
||||
// - InformationSchema (org.jooq.util.xml.jaxb)
|
||||
requires static jakarta.xml.bind;
|
||||
|
||||
// The DefaultRecordMapper makes use of JavaBeans utilities, including:
|
||||
// - Support for ConstructorProperties
|
||||
requires static java.desktop;
|
||||
|
||||
// Various utilities can make use of JPA annotations, when present, including:
|
||||
// - The DefaultRecordMapper
|
||||
// - The JPADatabase in the code generator
|
||||
|
||||
@ -414,6 +414,12 @@ public interface Configuration extends Serializable {
|
||||
@NotNull
|
||||
CharsetProvider charsetProvider();
|
||||
|
||||
/**
|
||||
* Get this configuration's underlying constructor properties provider.
|
||||
*/
|
||||
@NotNull
|
||||
ConstructorPropertiesProvider constructorPropertiesProvider();
|
||||
|
||||
/**
|
||||
* Get this configuration's underlying record mapper provider.
|
||||
*/
|
||||
@ -760,6 +766,19 @@ public interface Configuration extends Serializable {
|
||||
@NotNull
|
||||
Configuration set(TransactionProvider newTransactionProvider);
|
||||
|
||||
/**
|
||||
* Change this configuration to hold a new constructor properties provider.
|
||||
* <p>
|
||||
* This method is not thread-safe and should not be used in globally
|
||||
* available <code>Configuration</code> objects.
|
||||
*
|
||||
* @param newConstructorPropertiesProvider The new constructor properties
|
||||
* provider to be contained in the changed configuration.
|
||||
* @return The changed configuration.
|
||||
*/
|
||||
@NotNull
|
||||
Configuration set(ConstructorPropertiesProvider newConstructorPropertiesProvider);
|
||||
|
||||
/**
|
||||
* Change this configuration to hold a new record mapper.
|
||||
* <p>
|
||||
@ -1500,6 +1519,17 @@ public interface Configuration extends Serializable {
|
||||
@NotNull
|
||||
Configuration derive(TransactionProvider newTransactionProvider);
|
||||
|
||||
/**
|
||||
* Create a derived configuration from this one, with a new constructor
|
||||
* properties provider.
|
||||
*
|
||||
* @param newConstructorPropertiesProvider The new constructor properties
|
||||
* provider to be contained in the derived configuration.
|
||||
* @return The derived configuration.
|
||||
*/
|
||||
@NotNull
|
||||
Configuration derive(ConstructorPropertiesProvider newConstructorPropertiesProvider);
|
||||
|
||||
/**
|
||||
* Create a derived configuration from this one, with a new record mapper.
|
||||
* <p>
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.jooq.impl.DefaultRecordMapper;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An SPI that can be used to provider <code>java.beans</code> style constructor
|
||||
* properties to the {@link DefaultRecordMapper}.
|
||||
* <p>
|
||||
* Starting with jOOQ 3.20 and <a href=
|
||||
* "https://github.com/jOOQ/jOOQ/issues/7585">https://github.com/jOOQ/jOOQ/issues/7585</a>,
|
||||
* the {@link java.beans.ConstructorProperties} annotation support has been
|
||||
* moved out of the core library to the
|
||||
* <code>jOOQ-mapper-extensions-beans</code> module, to allow for:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>Removal of the dependency on the <code>java.beans</code> JDK module from
|
||||
* the core library</li>
|
||||
* <li>Maintenance of backwards compatibility for those users using the
|
||||
* annotation</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Implementations can be provided to
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConstructorPropertiesProvider {
|
||||
|
||||
/**
|
||||
* Provide the constructor properties on the argument constructor, like
|
||||
* {@link java.beans.ConstructorProperties#value()}.
|
||||
* <p>
|
||||
*
|
||||
* @return The constructor properties, if applicable, or <code>null</code>
|
||||
* if the argument {@link Constructor} does not expose any
|
||||
* constructor properties.
|
||||
*/
|
||||
@Nullable
|
||||
public String @Nullable [] properties(Constructor<?> constructor);
|
||||
}
|
||||
@ -5578,7 +5578,7 @@ public class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether constructor parameter names obtained from the {@link java.beans.ConstructorProperties} annotation should be considered by the DefaultRecordMapper.
|
||||
* Whether constructor parameter names obtained from the {@link org.jooq.ConstructorPropertiesProvider} SPI (default implementation in the <code>jOOQ-beans-extensions</code> module) should be considered by the DefaultRecordMapper.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
@ -5590,7 +5590,7 @@ public class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether constructor parameter names obtained from the {@link java.beans.ConstructorProperties} annotation should be considered by the DefaultRecordMapper.
|
||||
* Whether constructor parameter names obtained from the {@link org.jooq.ConstructorPropertiesProvider} SPI (default implementation in the <code>jOOQ-beans-extensions</code> module) should be considered by the DefaultRecordMapper.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
@ -8981,7 +8981,7 @@ public class Settings
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether constructor parameter names obtained from the {@link java.beans.ConstructorProperties} annotation should be considered by the DefaultRecordMapper.
|
||||
* Whether constructor parameter names obtained from the {@link org.jooq.ConstructorPropertiesProvider} SPI (default implementation in the <code>jOOQ-beans-extensions</code> module) should be considered by the DefaultRecordMapper.
|
||||
*
|
||||
*/
|
||||
public Settings withMapConstructorPropertiesParameterNames(Boolean value) {
|
||||
|
||||
@ -68,7 +68,8 @@ import org.jooq.tools.JooqLogger;
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public abstract class AbstractConfiguration implements Configuration {
|
||||
private static final JooqLogger log = JooqLogger.getLogger(AbstractConfiguration.class);
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(AbstractConfiguration.class);
|
||||
|
||||
@Override
|
||||
public final Configuration set(RecordListener... newRecordListeners) {
|
||||
|
||||
@ -37,8 +37,6 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.beans.Introspector.decapitalize;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
@ -58,6 +56,7 @@ import javax.xml.namespace.QName;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterContext;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* A binding that binds JAXB-annotated {@link Object} types to {@link SQLXML}
|
||||
@ -120,7 +119,7 @@ public class AbstractXMLasObjectBinding<T> extends AbstractXMLBinding<T> {
|
||||
|
||||
Object o = u;
|
||||
if (root == null)
|
||||
o = new JAXBElement<>(new QName(decapitalize(toType().getSimpleName())), toType(), u);
|
||||
o = new JAXBElement<>(new QName(toLCNoAcronyms(toType().getSimpleName())), toType(), u);
|
||||
|
||||
Marshaller m = ctx.createMarshaller();
|
||||
m.setProperty(Marshaller.JAXB_FRAGMENT, true);
|
||||
@ -132,6 +131,17 @@ public class AbstractXMLasObjectBinding<T> extends AbstractXMLBinding<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String toLCNoAcronyms(String s) {
|
||||
if (StringUtils.isEmpty(s))
|
||||
return s;
|
||||
|
||||
// [#7585] See also java.beans.Introspector::decapitalize
|
||||
else if (s.length() > 1 && Character.isUpperCase(s.charAt(0)) && Character.isUpperCase(s.charAt(1)))
|
||||
return s;
|
||||
else
|
||||
return StringUtils.toLC(s);
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
oos.defaultWriteObject();
|
||||
}
|
||||
|
||||
@ -60,6 +60,7 @@ import org.jooq.CharsetProvider;
|
||||
import org.jooq.CommitProvider;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ConnectionProvider;
|
||||
import org.jooq.ConstructorPropertiesProvider;
|
||||
import org.jooq.ConverterProvider;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DiagnosticsListener;
|
||||
@ -126,6 +127,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
private transient ExecutorProvider executorProvider;
|
||||
private transient CacheProvider cacheProvider;
|
||||
private transient TransactionProvider transactionProvider;
|
||||
private transient ConstructorPropertiesProvider constructorPropertiesProvider;
|
||||
private transient RecordMapperProvider recordMapperProvider;
|
||||
private transient RecordUnmapperProvider recordUnmapperProvider;
|
||||
private transient RecordListenerProvider[] recordListenerProviders;
|
||||
@ -205,6 +207,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
|
||||
|
||||
|
||||
@ -237,6 +240,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
configuration.executorProvider,
|
||||
configuration.cacheProvider,
|
||||
configuration.transactionProvider,
|
||||
configuration.constructorPropertiesProvider,
|
||||
configuration.recordMapperProvider,
|
||||
configuration.recordUnmapperProvider,
|
||||
configuration.recordListenerProviders,
|
||||
@ -280,6 +284,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
ExecutorProvider executorProvider,
|
||||
CacheProvider cacheProvider,
|
||||
TransactionProvider transactionProvider,
|
||||
ConstructorPropertiesProvider constructorPropertiesProvider,
|
||||
RecordMapperProvider recordMapperProvider,
|
||||
RecordUnmapperProvider recordUnmapperProvider,
|
||||
RecordListenerProvider[] recordListenerProviders,
|
||||
@ -312,6 +317,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
set(executorProvider);
|
||||
set(cacheProvider);
|
||||
set(transactionProvider);
|
||||
set(constructorPropertiesProvider);
|
||||
set(recordMapperProvider);
|
||||
set(recordUnmapperProvider);
|
||||
set(recordListenerProviders);
|
||||
@ -379,6 +385,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -416,6 +423,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -453,6 +461,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -490,6 +499,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -532,6 +542,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
newExecutorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -569,6 +580,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
newCacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -606,6 +618,45 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
newTransactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
executeListenerProviders,
|
||||
migrationListenerProviders,
|
||||
visitListenerProviders,
|
||||
transactionListenerProviders,
|
||||
diagnosticsListenerProviders,
|
||||
unwrapperProvider,
|
||||
charsetProvider,
|
||||
converterProvider,
|
||||
formattingProvider,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
clock,
|
||||
dialect,
|
||||
settings,
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Configuration derive(ConstructorPropertiesProvider newConstructorPropertiesProvider) {
|
||||
return new DefaultConfiguration(
|
||||
connectionProvider,
|
||||
interpreterConnectionProvider,
|
||||
systemConnectionProvider,
|
||||
connectionFactory,
|
||||
metaProvider,
|
||||
commitProvider,
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
newConstructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -648,6 +699,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
newRecordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -690,6 +742,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
newRecordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -727,6 +780,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
newRecordListenerProviders,
|
||||
@ -764,6 +818,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -801,6 +856,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -838,6 +894,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -875,6 +932,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -912,6 +970,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -954,6 +1013,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -991,6 +1051,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1028,6 +1089,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1065,6 +1127,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1233,6 +1296,10 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1250,6 +1317,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1287,6 +1355,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1324,6 +1393,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
executorProvider,
|
||||
cacheProvider,
|
||||
transactionProvider,
|
||||
constructorPropertiesProvider,
|
||||
recordMapperProvider,
|
||||
recordUnmapperProvider,
|
||||
recordListenerProviders,
|
||||
@ -1436,6 +1506,12 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Configuration set(ConstructorPropertiesProvider newConstructorPropertiesProvider) {
|
||||
this.constructorPropertiesProvider = newConstructorPropertiesProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Configuration set(RecordMapper<?, ?> newRecordMapper) {
|
||||
return set(new RecordMapperWrapper(newRecordMapper));
|
||||
@ -1696,6 +1772,13 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
set(newTransactionProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #set(ConstructorPropertiesProvider)
|
||||
*/
|
||||
public final void setConstructorPropertiesProvider(ConstructorPropertiesProvider newConstructorPropertiesProvider) {
|
||||
set(newConstructorPropertiesProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #set(RecordMapper)
|
||||
*/
|
||||
@ -1954,6 +2037,13 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
return transactionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ConstructorPropertiesProvider constructorPropertiesProvider() {
|
||||
return constructorPropertiesProvider != null
|
||||
? constructorPropertiesProvider
|
||||
: new LegacyConstructorPropertiesProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordMapperProvider recordMapperProvider() {
|
||||
|
||||
@ -2133,6 +2223,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
oos.writeObject(serializableOrNull(metaProvider));
|
||||
oos.writeObject(serializableOrNull(commitProvider));
|
||||
oos.writeObject(serializableOrNull(transactionProvider));
|
||||
oos.writeObject(serializableOrNull(constructorPropertiesProvider));
|
||||
oos.writeObject(serializableOrNull(recordMapperProvider));
|
||||
oos.writeObject(serializableOrNull(recordUnmapperProvider));
|
||||
oos.writeObject(cloneSerializables(executeListenerProviders));
|
||||
@ -2189,6 +2280,7 @@ public class DefaultConfiguration extends AbstractConfiguration {
|
||||
metaProvider = (MetaProvider) ois.readObject();
|
||||
commitProvider = (CommitProvider) ois.readObject();
|
||||
transactionProvider = (TransactionProvider) ois.readObject();
|
||||
constructorPropertiesProvider = (ConstructorPropertiesProvider) ois.readObject();
|
||||
recordMapperProvider = (RecordMapperProvider) ois.readObject();
|
||||
recordUnmapperProvider = (RecordUnmapperProvider) ois.readObject();
|
||||
executeListenerProviders = (ExecuteListenerProvider[]) ois.readObject();
|
||||
|
||||
@ -52,19 +52,14 @@ import static org.jooq.impl.Tools.getMatchingMembers;
|
||||
import static org.jooq.impl.Tools.getMatchingSetters;
|
||||
import static org.jooq.impl.Tools.getPropertyName;
|
||||
import static org.jooq.impl.Tools.hasColumnAnnotations;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
import static org.jooq.impl.Tools.newRecord;
|
||||
import static org.jooq.impl.Tools.recordType;
|
||||
import static org.jooq.impl.Tools.row0;
|
||||
import static org.jooq.tools.reflect.Reflect.accessible;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -73,7 +68,6 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@ -84,23 +78,21 @@ import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
|
||||
import org.jooq.Attachable;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ConstructorPropertiesProvider;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterProvider;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.RecordMapper;
|
||||
import org.jooq.RecordMapperProvider;
|
||||
import org.jooq.RecordType;
|
||||
@ -115,6 +107,8 @@ import org.jooq.tools.StringUtils;
|
||||
import org.jooq.tools.reflect.Reflect;
|
||||
import org.jooq.tools.reflect.ReflectException;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
|
||||
/**
|
||||
* This is the default implementation for <code>RecordMapper</code> types, which
|
||||
* applies to {@link Record#into(Class)}, {@link Result#into(Class)}, and
|
||||
@ -224,8 +218,11 @@ import org.jooq.tools.reflect.ReflectException;
|
||||
* used</h5>
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>The standard JavaBeans {@link ConstructorProperties} annotation is used
|
||||
* to match constructor arguments against POJO members or getters.</li>
|
||||
* <li>The standard JavaBeans {@link java.beans.ConstructorProperties}
|
||||
* annotation is used to match constructor arguments against POJO members or
|
||||
* getters, if the default {@link ConstructorPropertiesProvider} can look up the
|
||||
* implementation from the <code>jOOQ-mapper-extensions-beans</code> module, or
|
||||
* if you provide your own.</li>
|
||||
* <li>If the property names provided to the constructor match the record's
|
||||
* columns via the aforementioned naming conventions, that information is used.
|
||||
* </li>
|
||||
@ -440,11 +437,13 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
// [#1837] [#10349] [#11123] If any java.beans.ConstructorProperties annotations are
|
||||
// present use those rather than matching constructors by the number of arguments
|
||||
if (debugCPSettings = !FALSE.equals(configuration.settings().isMapConstructorPropertiesParameterNames())) {
|
||||
ConstructorPropertiesProvider cpp = configuration.constructorPropertiesProvider();
|
||||
|
||||
for (Constructor<E> constructor : constructors) {
|
||||
ConstructorProperties properties = constructor.getAnnotation(ConstructorProperties.class);
|
||||
String[] properties = cpp.properties(constructor);
|
||||
|
||||
if (properties != null) {
|
||||
delegate = new ImmutablePOJOMapper(constructor, constructor.getParameterTypes(), Arrays.asList(properties.value()), true);
|
||||
delegate = new ImmutablePOJOMapper(constructor, constructor.getParameterTypes(), Arrays.asList(properties), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -635,7 +634,7 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
return debug == null ? "check skipped" : debug.toString();
|
||||
}
|
||||
|
||||
private List<String> collectParameterNames(Parameter[] parameters) {
|
||||
private static final List<String> collectParameterNames(Parameter[] parameters) {
|
||||
return Arrays.stream(parameters).map(Parameter::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -1211,7 +1210,7 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
}
|
||||
}
|
||||
|
||||
private static <E> E attach(E attachable, Record record) {
|
||||
private static final <E> E attach(E attachable, Record record) {
|
||||
// [#2869] Attach the mapped outcome if it is Attachable and if the context's
|
||||
// Settings.attachRecords flag is set
|
||||
if (attachable instanceof Attachable a)
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jooq.ConstructorPropertiesProvider;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
|
||||
/**
|
||||
* Class maintaining backwards compatible behaviour, without formal declaration
|
||||
* of <code>java.beans</code> dependency in module info.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
final class LegacyConstructorPropertiesProvider implements ConstructorPropertiesProvider {
|
||||
|
||||
static final JooqLogger log = JooqLogger.getLogger(LegacyConstructorPropertiesProvider.class, 1);
|
||||
static final ConstructorPropertiesProvider DELEGATE;
|
||||
static final Class<Annotation> P;
|
||||
static final Method V;
|
||||
|
||||
static {
|
||||
Class<Annotation> p;
|
||||
Method v;
|
||||
|
||||
try {
|
||||
|
||||
// [#14180] Break the maven-bundle-plugin class analyser, to prevent
|
||||
// adding a package import to MANIFEST.MF for this lookup
|
||||
p = (Class<Annotation>) Class.forName(new String("java.beans.") + new String("ConstructorProperties"));
|
||||
v = p.getMethod("value");
|
||||
}
|
||||
catch (Exception e) {
|
||||
p = null;
|
||||
v = null;
|
||||
}
|
||||
|
||||
P = p;
|
||||
V = v;
|
||||
|
||||
DELEGATE = c -> {
|
||||
if (V != null) {
|
||||
Annotation a = c.getAnnotation(P);
|
||||
|
||||
try {
|
||||
if (a != null) {
|
||||
log.warn("ConstructorProperties", """
|
||||
No explicit ConstructorPropertiesProvider configuration present.
|
||||
|
||||
ConstructorProperties annotation is present on POJO {pojo}
|
||||
without any explicit ConstructorPropertiesProvider configuration.
|
||||
|
||||
Starting from jOOQ 3.20, the Configuration.constructorPropertiesProvider() SPI is required for the
|
||||
DefaultRecordMapper to map a Record to a POJO that is annotated with ConstructorProperties. For
|
||||
backwards compatibility, This LegacyConstructorPropertiesProvider keeps the historic behaviour in
|
||||
place using reflection. This implementation is due for removal in a future version of jOOQ.
|
||||
|
||||
If you wish to continue working with the java.beans.ConstructorProperties annotation, use the
|
||||
jOOQ-beans-extensions module and its DefaultConstructorPropertiesProvider implementation
|
||||
""".replace("{pojo}", c.getDeclaringClass().getName())
|
||||
);
|
||||
|
||||
return (String[]) V.invoke(a);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] properties(Constructor<?> constructor) {
|
||||
return DELEGATE.properties(constructor);
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,7 @@ import org.jooq.CharsetProvider;
|
||||
import org.jooq.CommitProvider;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ConnectionProvider;
|
||||
import org.jooq.ConstructorPropertiesProvider;
|
||||
import org.jooq.ConverterProvider;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DiagnosticsListenerProvider;
|
||||
@ -169,6 +170,11 @@ public class MockConfiguration extends AbstractConfiguration {
|
||||
return delegate.transactionProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorPropertiesProvider constructorPropertiesProvider() {
|
||||
return delegate.constructorPropertiesProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecordMapperProvider recordMapperProvider() {
|
||||
return delegate.recordMapperProvider();
|
||||
@ -340,6 +346,12 @@ public class MockConfiguration extends AbstractConfiguration {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration set(ConstructorPropertiesProvider newConstructorPropertiesProvider) {
|
||||
delegate.set(newConstructorPropertiesProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration set(RecordMapper<?, ?> newRecordMapper) {
|
||||
delegate.set(newRecordMapper);
|
||||
@ -531,6 +543,11 @@ public class MockConfiguration extends AbstractConfiguration {
|
||||
return new MockConfiguration(delegate.derive(newTransactionProvider), provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration derive(ConstructorPropertiesProvider newConstructorPropertiesProvider) {
|
||||
return new MockConfiguration(delegate.derive(newConstructorPropertiesProvider), provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration derive(RecordMapper<?, ?> newRecordMapper) {
|
||||
return new MockConfiguration(delegate.derive(newRecordMapper), provider);
|
||||
|
||||
@ -1409,7 +1409,7 @@ IDENTITY values, and if {@link #returnAllOnUpdatableRecord} is active, also othe
|
||||
</element>
|
||||
|
||||
<element name="mapConstructorPropertiesParameterNames" type="boolean" minOccurs="0" maxOccurs="1" default="true">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether constructor parameter names obtained from the {@link java.beans.ConstructorProperties} annotation should be considered by the DefaultRecordMapper.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether constructor parameter names obtained from the {@link org.jooq.ConstructorPropertiesProvider} SPI (default implementation in the <code>jOOQ-beans-extensions</code> module) should be considered by the DefaultRecordMapper.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="mapConstructorParameterNames" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
|
||||
6
pom.xml
6
pom.xml
@ -114,6 +114,11 @@
|
||||
<artifactId>jooq-checker</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-beans-extensions</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jooq</groupId>
|
||||
<artifactId>jooq-postgres-extensions</artifactId>
|
||||
@ -841,6 +846,7 @@
|
||||
<module>jOOQ-checker</module>
|
||||
<module>jOOQ-jackson-extensions</module>
|
||||
<module>jOOQ-postgres-extensions</module>
|
||||
<module>jOOQ-beans-extensions</module>
|
||||
|
||||
<module>jOOQ-meta</module>
|
||||
<module>jOOQ-meta-extensions</module>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user