diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index c9aba4c42f..044df3c7aa 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -516,25 +516,12 @@ public class JavaGenerator extends AbstractGenerator { } private boolean generateCatalogIfEmpty(CatalogDefinition catalog) { - if (generateEmptyCatalogs()) - return true; - - List schemas = catalog.getSchemata(); - if (schemas.isEmpty()) - return false; - - for (SchemaDefinition schema : schemas) - if (generateSchemaIfEmpty(schema)) - return true; - - return false; + return generateEmptyCatalogs() || catalog.getSchemata().stream().anyMatch(this::generateSchemaIfEmpty); } private final boolean generateSchemaIfEmpty(SchemaDefinition schema) { - if (generateEmptySchemas()) - return true; - - return !database.getArrays(schema).isEmpty() + return generateEmptySchemas() + || !database.getArrays(schema).isEmpty() || !database.getDomains(schema).isEmpty() || !database.getEmbeddables(schema).isEmpty() || !database.getEnums(schema).isEmpty() diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java index d829398374..e78540dd6f 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java @@ -74,6 +74,7 @@ import java.util.Properties; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -1873,11 +1874,7 @@ public abstract class AbstractDatabase implements Database { } private boolean matches(DataTypeDefinition type, Pattern pattern) { - for (String matchName : type.getMatchNames()) - if (pattern.matcher(matchName).matches()) - return true; - - return false; + return type.getMatchNames().stream().map(pattern::matcher).anyMatch(Matcher::matches); } @Override diff --git a/jOOQ/src/main/java/org/jooq/CacheProvider.java b/jOOQ/src/main/java/org/jooq/CacheProvider.java index e3854af76a..48d778fe19 100644 --- a/jOOQ/src/main/java/org/jooq/CacheProvider.java +++ b/jOOQ/src/main/java/org/jooq/CacheProvider.java @@ -41,8 +41,6 @@ import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentMap; -import org.jooq.impl.CacheType; - import org.jetbrains.annotations.Nullable; /** diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index e4a7a6673d..5fb4e339ba 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -104,7 +104,6 @@ import org.jooq.exception.InvalidResultException; import org.jooq.exception.MappingException; import org.jooq.exception.NoDataFoundException; import org.jooq.exception.TooManyRowsException; -import org.jooq.impl.CacheType; import org.jooq.impl.DSL; import org.jooq.impl.ParserException; import org.jooq.impl.ThreadLocalTransactionProvider; diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java index a7f917379c..6e3790ae79 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRecord.java @@ -101,7 +101,6 @@ import org.jooq.XMLFormat; import org.jooq.exception.IOException; import org.jooq.exception.InvalidResultException; import org.jooq.exception.MappingException; -import org.jooq.impl.Tools.ThreadGuard; import org.jooq.tools.Convert; import org.jooq.tools.JooqLogger; import org.jooq.tools.StringUtils; diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java index b4bbdea64c..797cde7a98 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java @@ -625,7 +625,7 @@ final class CreateTableImpl extends AbstractDDLQuery implements } private final boolean isPrimaryKey(int i) { - return anyMatch(primaryKeyColumns(), f -> f.equals(columnFields.get(i))); + return anyMatch(primaryKeyColumns(), columnFields.get(i)::equals); } private final boolean matchingPrimaryKey(Constraint constraint, Field identity) { diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java index 32d29c52e2..fcba9fbb66 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java @@ -38,6 +38,7 @@ package org.jooq.impl; import org.jooq.CacheContext; +import org.jooq.impl.CacheType; import org.jooq.Configuration; /** diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java b/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java index ea4fa9b943..bb7c253187 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java @@ -54,6 +54,7 @@ import java.util.concurrent.Executor; import javax.sql.DataSource; import org.jooq.CacheProvider; +import org.jooq.impl.CacheType; import org.jooq.CharsetProvider; import org.jooq.CommitProvider; import org.jooq.Configuration; diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapperProvider.java b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapperProvider.java index f9ebdb47b2..bf665949d4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapperProvider.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapperProvider.java @@ -47,7 +47,6 @@ import org.jooq.Record; import org.jooq.RecordMapper; import org.jooq.RecordMapperProvider; import org.jooq.RecordType; -import org.jooq.impl.Tools.Cache; /** * A default {@link RecordMapperProvider} implementation, providing a diff --git a/jOOQ/src/main/java/org/jooq/impl/F.java b/jOOQ/src/main/java/org/jooq/impl/F.java index e3592bf355..71e84f1f40 100644 --- a/jOOQ/src/main/java/org/jooq/impl/F.java +++ b/jOOQ/src/main/java/org/jooq/impl/F.java @@ -87,6 +87,14 @@ interface ThrowingPredicate { boolean test(T t) throws E; } +/** + * A checked exception throwing {@link Predicate}. + */ +@FunctionalInterface +interface ThrowingIntPredicate { + boolean test(T t, int i) throws E; +} + /** * A checked exception throwing {@link IntFunction}. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java index ab1c54b001..10aa4d336d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java @@ -46,6 +46,7 @@ import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.impl.DSL.name; import static org.jooq.impl.Keywords.K_DEFAULT_VALUES; import static org.jooq.impl.Keywords.K_VALUES; +import static org.jooq.impl.Tools.anyMatch; import static org.jooq.impl.Tools.collect; import static org.jooq.impl.Tools.flatten; import static org.jooq.impl.Tools.flattenCollection; @@ -425,11 +426,7 @@ final class FieldMapsForInsert extends AbstractQueryPart { @Override public boolean containsValue(Object value) { - for (List> list : values.values()) - if (list.get(index).equals(value)) - return true; - - return false; + return anyMatch(values.values(), list -> list.get(index).equals(value)); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/IdentityImpl.java b/jOOQ/src/main/java/org/jooq/impl/IdentityImpl.java index fb026b3dec..c286c65fc7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/IdentityImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/IdentityImpl.java @@ -78,13 +78,11 @@ final class IdentityImpl implements Identity { @Override public boolean equals(Object obj) { - if (this == obj) { + if (this == obj) return true; - } - if (obj instanceof Identity) { + if (obj instanceof Identity) return toString().equals(obj.toString()); - } return false; } diff --git a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java index 1b0921c0a5..20e1228e3b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java +++ b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java @@ -53,7 +53,6 @@ import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.anyMatch; import static org.jooq.impl.Tools.dataTypes; import static org.jooq.impl.Tools.findAny; -import static org.jooq.impl.Tools.intersect; import static org.jooq.impl.Tools.map; import static org.jooq.impl.Tools.normaliseNameCase; import static org.jooq.impl.Tools.reverseIterable; @@ -414,7 +413,7 @@ final class Interpreter { for (boolean check : cascade == CASCADE ? new boolean [] { false } : new boolean [] { true, false }) { if (table.primaryKey != null) { - if (intersect(table.primaryKey.fields, fields)) { + if (anyMatch(table.primaryKey.fields, t1 -> fields.contains(t1))) { cascade(table.primaryKey, fields, check ? RESTRICT : CASCADE); if (!check) @@ -447,7 +446,7 @@ final class Interpreter { while (it2.hasNext()) { MutableKey key = it2.next(); - if (fields == null || intersect(key.fields, fields)) { + if (fields == null || anyMatch(key.fields, t1 -> fields.contains(t1))) { if (key instanceof MutableUniqueKey) cascade((MutableUniqueKey) key, fields, check ? RESTRICT : CASCADE); @@ -1856,12 +1855,8 @@ final class Interpreter { final boolean fieldsEquals(Field[] f) { if (fields.size() != f.length) return false; - - for (int i = 0; i < fields.size(); i++) - if (!fields.get(i).nameEquals((UnqualifiedName) f[i].getUnqualifiedName())) - return false; - - return true; + else + return !anyMatch(fields, (x, i) -> !x.nameEquals((UnqualifiedName) f[i].getUnqualifiedName())); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index e2de055451..9c0693c9ba 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -12446,7 +12446,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { @Override public final boolean parseFunctionNameIf(String... names) { - return anyMatch(names, this::parseFunctionNameIf); + return anyMatch(names, n -> parseFunctionNameIf(n)); } private final boolean parseOperator(String operator) { @@ -12526,7 +12526,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { @Override public final boolean parseKeywordIf(String... keywords) { - return anyMatch(keywords, this::parseKeywordIf); + return anyMatch(keywords, k -> parseKeywordIf(k)); } @Override @@ -12547,7 +12547,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { } private final Keyword parseAndGetKeywordIf(String... keywords) { - return findAny(keywords, this::parseKeywordIf, k -> keyword(k.toLowerCase())); + return findAny(keywords, k -> parseKeywordIf(k), k -> keyword(k.toLowerCase())); } private final Keyword parseAndGetKeywordIf(String keyword) { @@ -12585,7 +12585,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { @Override public final boolean peekKeyword(String... keywords) { - return anyMatch(keywords, this::peekKeyword); + return anyMatch(keywords, k -> peekKeyword(k)); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java b/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java index e9a79330e4..769b930c49 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParsingConnection.java @@ -52,6 +52,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.jooq.impl.CacheType; import org.jooq.Configuration; import org.jooq.DSLContext; import org.jooq.Param; @@ -59,7 +60,6 @@ import org.jooq.SQLDialect; import org.jooq.exception.DataAccessException; import org.jooq.exception.DetachedException; import org.jooq.impl.DefaultRenderContext.Rendered; -import org.jooq.impl.Tools.Cache; import org.jooq.tools.JooqLogger; import org.jooq.tools.jdbc.DefaultConnection; diff --git a/jOOQ/src/main/java/org/jooq/impl/QualifiedName.java b/jOOQ/src/main/java/org/jooq/impl/QualifiedName.java index 5ca256ed07..f95399298a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QualifiedName.java +++ b/jOOQ/src/main/java/org/jooq/impl/QualifiedName.java @@ -103,8 +103,8 @@ final class QualifiedName extends AbstractName { String[] result; int nulls = 0; - for (int i = 0; i < qualifiedName.length; i++) - if (StringUtils.isEmpty(qualifiedName[i])) + for (String name : qualifiedName) + if (StringUtils.isEmpty(name)) nulls++; if (nulls > 0) { @@ -127,8 +127,8 @@ final class QualifiedName extends AbstractName { Name[] result; int nulls = 0; - for (int i = 0; i < names.length; i++) - if (names[i] == null || names[i].equals(NO_NAME)) + for (Name name : names) + if (name == null || name.equals(NO_NAME)) nulls++; if (nulls > 0) { @@ -154,8 +154,8 @@ final class QualifiedName extends AbstractName { if (ctx.qualify()) { String separator = ""; - for (int i = 0; i < qualifiedName.length; i++) { - ctx.sql(separator).visit(qualifiedName[i]); + for (UnqualifiedName name : qualifiedName) { + ctx.sql(separator).visit(name); separator = "."; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/R2DBC.java b/jOOQ/src/main/java/org/jooq/impl/R2DBC.java index dfad8dc889..0416cb839d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/R2DBC.java +++ b/jOOQ/src/main/java/org/jooq/impl/R2DBC.java @@ -94,8 +94,7 @@ import org.jooq.conf.SettingsTools; import org.jooq.exception.DataAccessException; import org.jooq.exception.DataTypeException; import org.jooq.impl.DefaultRenderContext.Rendered; -import org.jooq.impl.Tools.ThreadGuard; -import org.jooq.impl.Tools.ThreadGuard.Guard; +import org.jooq.impl.ThreadGuard.Guard; import org.jooq.tools.Convert; import org.jooq.tools.JooqLogger; import org.jooq.tools.jdbc.DefaultPreparedStatement; diff --git a/jOOQ/src/main/java/org/jooq/impl/SortFieldList.java b/jOOQ/src/main/java/org/jooq/impl/SortFieldList.java index 28b5f3417c..edab4303ee 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SortFieldList.java +++ b/jOOQ/src/main/java/org/jooq/impl/SortFieldList.java @@ -88,6 +88,6 @@ final class SortFieldList extends QueryPartList> { } final List> fields() { - return map(this, f -> ((SortFieldImpl) f).getField()); + return Tools.map(this, f -> ((SortFieldImpl) f).getField()); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index c802e57022..6386211c96 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -43,6 +43,13 @@ import static java.lang.Character.isJavaIdentifierPart; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_GETTER; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_MEMBERS; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_SETTERS; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_GETTER; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_MEMBERS; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_SETTERS; +import static org.jooq.impl.CacheType.REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS; // ... // ... // ... @@ -77,13 +84,6 @@ import static org.jooq.conf.SettingsTools.getBackslashEscaping; import static org.jooq.conf.SettingsTools.updatablePrimaryKeys; import static org.jooq.conf.ThrowExceptions.THROW_FIRST; import static org.jooq.conf.ThrowExceptions.THROW_NONE; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_GETTER; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_MEMBERS; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_ANNOTATED_SETTERS; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_GETTER; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_MEMBERS; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_GET_MATCHING_SETTERS; -import static org.jooq.impl.CacheType.REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS; import static org.jooq.impl.DDLStatementType.ALTER_SCHEMA; import static org.jooq.impl.DDLStatementType.ALTER_TABLE; import static org.jooq.impl.DDLStatementType.ALTER_VIEW; @@ -170,7 +170,6 @@ import static org.jooq.impl.SQLDataType.XML; import static org.jooq.impl.Tools.DataKey.DATA_BLOCK_NESTING; import static org.jooq.tools.StringUtils.defaultIfNull; -import java.io.Serializable; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -212,12 +211,10 @@ import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool.ManagedBlocker; import java.util.function.BiFunction; import java.util.function.Consumer; -import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.function.Supplier; @@ -323,32 +320,32 @@ final class Tools { // Empty arrays for use with Collection.toArray() // ------------------------------------------------------------------------ - static final byte[] EMPTY_BYTE = {}; - static final Catalog[] EMPTY_CATALOG = {}; - static final Check[] EMPTY_CHECK = {}; - static final Clause[] EMPTY_CLAUSE = {}; - static final Collection[] EMPTY_COLLECTION = {}; - static final CommonTableExpression[] EMPTY_COMMON_TABLE_EXPRESSION = {}; - static final ExecuteListener[] EMPTY_EXECUTE_LISTENER = {}; - static final Field[] EMPTY_FIELD = {}; - static final int[] EMPTY_INT = {}; - static final JSONEntry[] EMPTY_JSONENTRY = {}; - static final Name[] EMPTY_NAME = {}; - static final Object[] EMPTY_OBJECT = {}; - static final Param[] EMPTY_PARAM = {}; - static final OrderField[] EMPTY_ORDERFIELD = {}; - static final Query[] EMPTY_QUERY = {}; - static final QueryPart[] EMPTY_QUERYPART = {}; - static final Record[] EMPTY_RECORD = {}; - static final Row[] EMPTY_ROW = {}; - static final Schema[] EMTPY_SCHEMA = {}; - static final SortField[] EMPTY_SORTFIELD = {}; - static final Source[] EMPTY_SOURCE = {}; - static final String[] EMPTY_STRING = {}; - static final Table[] EMPTY_TABLE = {}; - static final TableField[] EMPTY_TABLE_FIELD = {}; - static final TableRecord[] EMPTY_TABLE_RECORD = {}; - static final UpdatableRecord[] EMPTY_UPDATABLE_RECORD = {}; + static final byte[] EMPTY_BYTE = {}; + static final Catalog[] EMPTY_CATALOG = {}; + static final Check[] EMPTY_CHECK = {}; + static final Clause[] EMPTY_CLAUSE = {}; + static final Collection[] EMPTY_COLLECTION = {}; + static final CommonTableExpression[] EMPTY_COMMON_TABLE_EXPRESSION = {}; + static final ExecuteListener[] EMPTY_EXECUTE_LISTENER = {}; + static final Field[] EMPTY_FIELD = {}; + static final int[] EMPTY_INT = {}; + static final JSONEntry[] EMPTY_JSONENTRY = {}; + static final Name[] EMPTY_NAME = {}; + static final Object[] EMPTY_OBJECT = {}; + static final Param[] EMPTY_PARAM = {}; + static final OrderField[] EMPTY_ORDERFIELD = {}; + static final Query[] EMPTY_QUERY = {}; + static final QueryPart[] EMPTY_QUERYPART = {}; + static final Record[] EMPTY_RECORD = {}; + static final Row[] EMPTY_ROW = {}; + static final Schema[] EMTPY_SCHEMA = {}; + static final SortField[] EMPTY_SORTFIELD = {}; + static final Source[] EMPTY_SOURCE = {}; + static final String[] EMPTY_STRING = {}; + static final Table[] EMPTY_TABLE = {}; + static final TableField[] EMPTY_TABLE_FIELD = {}; + static final TableRecord[] EMPTY_TABLE_RECORD = {}; + static final UpdatableRecord[] EMPTY_UPDATABLE_RECORD = {}; // ------------------------------------------------------------------------ // Some constants for use with Context.data() @@ -1779,18 +1776,34 @@ final class Tools { return findAny(array, test, t -> TRUE) != null; } + static final boolean anyMatch(T[] array, ThrowingIntPredicate test) throws E { + return findAny(array, test, t -> TRUE) != null; + } + static final boolean anyMatch(Iterable it, ThrowingPredicate test) throws E { return findAny(it, test, t -> TRUE) != null; } + static final boolean anyMatch(Iterable it, ThrowingIntPredicate test) throws E { + return findAny(it, test, t -> TRUE) != null; + } + static final T findAny(T[] array, ThrowingPredicate test) throws E { return findAny(array, test, t -> t); } + static final T findAny(T[] array, ThrowingIntPredicate test) throws E { + return findAny(array, test, t -> t); + } + static final T findAny(Iterable it, ThrowingPredicate test) throws E { return findAny(it, test, t -> t); } + static final T findAny(Iterable it, ThrowingIntPredicate test) throws E { + return findAny(it, test, t -> t); + } + static final U findAny(T[] array, ThrowingPredicate test, ThrowingFunction function) throws E { if (array != null) for (T t : array) @@ -1800,6 +1813,18 @@ final class Tools { return null; } + static final U findAny(T[] array, ThrowingIntPredicate test, ThrowingFunction function) throws E { + if (array != null) { + int i = 0; + + for (T t : array) + if (test.test(t, i++)) + return function.apply(t); + } + + return null; + } + static final U findAny(Iterable it, ThrowingPredicate test, ThrowingFunction function) throws E { if (it != null) for (T t : it) @@ -1809,6 +1834,18 @@ final class Tools { return null; } + static final U findAny(Iterable it, ThrowingIntPredicate test, ThrowingFunction function) throws E { + if (it != null) { + int i = 0; + + for (T t : it) + if (test.test(t, i++)) + return function.apply(t); + } + + return null; + } + /** * Like Stream.of(array).map(mapper).toArray(constructor) but * without the entire stream pipeline. @@ -3272,195 +3309,6 @@ final class Tools { return (value == null) ? field.isNull() : field.eq(value); } - // ------------------------------------------------------------------------ - // XXX: [#2965] Reflection cache - // ------------------------------------------------------------------------ - - /** - * This API acts as a "guard" to prevent the same code from being executed - * recursively within the same thread. - */ - static class ThreadGuard { - - static class Guard { - ThreadLocal tl = new ThreadLocal<>(); - } - - static final Guard RECORD_TOSTRING = new Guard(); - - /** - * A guarded operation. - */ - static interface GuardedOperation { - - /** - * This callback is executed only once on the current stack. - */ - V unguarded(); - - /** - * This callback is executed if {@link #unguarded()} has already been executed on the current stack. - */ - V guarded(); - } - - /** - * Run an operation using a guard. - */ - static final void run(Guard guard, Runnable unguardedOperation, Runnable guardedOperation) { - run(guard, () -> { unguardedOperation.run(); return null; }, () -> { guardedOperation.run(); return null; }); - } - - /** - * Run an operation using a guard. - */ - static final V run(Guard guard, Supplier unguardedOperation, Supplier guardedOperation) { - boolean unguarded = (guard.tl.get() == null); - if (unguarded) - guard.tl.set(Guard.class); - - try { - if (unguarded) - return unguardedOperation.get(); - else - return guardedOperation.get(); - } - finally { - if (unguarded) - guard.tl.remove(); - } - } - } - - /** - * [#2965] This is a {@link Configuration}-based cache that can cache reflection information and other things - */ - static class Cache { - - /** - * Run a cached operation in the context of a {@link Configuration}. - * - * @param configuration The configuration that may cache the outcome of - * the cached operation. - * @param operation The expensive operation. - * @param type The cache type to be used. - * @param key The cache keys. - * @return The cached value or the outcome of the cached operation. - */ - @SuppressWarnings("unchecked") - static final V run(Configuration configuration, Supplier operation, CacheType type, Supplier key) { - - // If no configuration is provided take the default configuration that loads the default Settings - if (configuration == null) - configuration = new DefaultConfiguration(); - - // Shortcut caching when the relevant Settings flag isn't set. - if (!type.category.predicate.test(configuration.settings())) - return operation.get(); - - Object cacheOrNull = configuration.data(type); - if (cacheOrNull == null) { - synchronized (type) { - cacheOrNull = configuration.data(type); - - if (cacheOrNull == null) - configuration.data(type, cacheOrNull = defaultIfNull( - configuration.cacheProvider().provide(new DefaultCacheContext(configuration, type)), - NULL - )); - } - } - - if (cacheOrNull == NULL) - return operation.get(); - - // The cache is guaranteed to be thread safe by the CacheProvider - // contract. However since we cannot use ConcurrentHashMap.computeIfAbsent() - // recursively, we have to revert to double checked locking nonetheless. - Map cache = (Map) cacheOrNull; - Object k = key.get(); - Object v = cache.get(k); - if (v == null) { - synchronized (cache) { - v = cache.get(k); - - if (v == null) - cache.put(k, (v = operation.get()) == null ? NULL : v); - } - } - - return (V) (v == NULL ? null : v); - } - - /** - * A null placeholder to be put in {@link ConcurrentHashMap}. - */ - private static final Object NULL = new Object(); - - /** - * Create a single-value or multi-value key for caching. - */ - static final Object key(Object key1, Object key2) { - return new Key2(key1, key2); - } - - /** - * A 2-value key for caching. - */ - private static class Key2 implements Serializable { - - /** - * Generated UID. - */ - private static final long serialVersionUID = 5822370287443922993L; - private final Object key1; - private final Object key2; - - Key2(Object key1, Object key2) { - this.key1 = key1; - this.key2 = key2; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((key1 == null) ? 0 : key1.hashCode()); - result = prime * result + ((key2 == null) ? 0 : key2.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Key2 other = (Key2) obj; - if (key1 == null) { - if (other.key1 != null) - return false; - } - else if (!key1.equals(other.key1)) - return false; - if (key2 == null) { - if (other.key2 != null) - return false; - } - else if (!key2.equals(other.key2)) - return false; - return true; - } - - @Override - public String toString() { - return "[" + key1 + ", " + key2 + "]"; - } - } - } - // ------------------------------------------------------------------------ // XXX: Reflection utilities used for POJO mapping // ------------------------------------------------------------------------ @@ -3590,19 +3438,12 @@ final class Tools { if (type.getAnnotation(javax.persistence.Table.class) != null) return true; - for (java.lang.reflect.Field member : getInstanceMembers(type)) { - if (member.getAnnotation(Column.class) != null) - return true; - - if (member.getAnnotation(Id.class) != null) - return true; - } - - for (Method method : getInstanceMethods(type)) - if (method.getAnnotation(Column.class) != null) - return true; - - return false; + if (anyMatch(getInstanceMembers(type), m -> + m.getAnnotation(Column.class) != null + || m.getAnnotation(Id.class) != null)) + return true; + else + return anyMatch(getInstanceMethods(type), m -> m.getAnnotation(Column.class) != null); }, REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS, () -> type); } @@ -5241,6 +5082,7 @@ final class Tools { }; } + @SuppressWarnings("unchecked") static final E[] enums(Class type) { // Java implementation @@ -5291,14 +5133,11 @@ final class Tools { return false; Set names = new HashSet<>(); - for (Field field : fields) - if (!names.add(field.getName())) - return true; - - return false; + return anyMatch(fields, f -> !names.add(f.getName())); } static final QueryPartList qualify(final Table table, Iterable fields) { + @SuppressWarnings("serial") QueryPartList result = new QueryPartList() { @Override public final boolean rendersContent(Context ctx) { @@ -5582,19 +5421,11 @@ final class Tools { } static final boolean hasEmbeddedFields(Field[] fields) { - for (Field f : fields) - if (f.getDataType().isEmbeddable()) - return true; - - return false; + return anyMatch(fields, f -> f.getDataType().isEmbeddable()); } static final boolean hasEmbeddedFields(Iterable> fields) { - for (Field f : fields) - if (f.getDataType().isEmbeddable()) - return true; - - return false; + return anyMatch(fields, f -> f.getDataType().isEmbeddable()); } static final List collect(Iterable iterable) { @@ -5824,17 +5655,6 @@ final class Tools { return sb.toString(); } - /** - * Whether the intersection of two collection is non-empty. - */ - static final boolean intersect(Collection c1, Collection c2) { - for (T t1 : c1) - if (c2.contains(t1)) - return true; - - return false; - } - /** * Normalise a name case depending on the dialect and the setting for * {@link ParseNameCase}. diff --git a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java index a511548f09..66793ced16 100644 --- a/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/VersionImpl.java @@ -43,6 +43,7 @@ import static java.util.Collections.unmodifiableList; import static org.jooq.impl.DSL.createSchema; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.schema; +import static org.jooq.impl.Tools.anyMatch; import static org.jooq.impl.Tools.map; import java.util.AbstractList; @@ -206,13 +207,7 @@ final class VersionImpl extends AbstractNode implements Version { } private final boolean forceApply() { - for (Parent parent : parents) - if (parent.queries != null) - return true; - else if (parent.version.forceApply()) - return true; - - return false; + return anyMatch(parents, p -> p.queries != null || p.version.forceApply()); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/XMLHandler.java b/jOOQ/src/main/java/org/jooq/impl/XMLHandler.java index 7e76c283f7..6bb6350568 100644 --- a/jOOQ/src/main/java/org/jooq/impl/XMLHandler.java +++ b/jOOQ/src/main/java/org/jooq/impl/XMLHandler.java @@ -42,6 +42,7 @@ import static org.jooq.impl.DSL.name; import static org.jooq.impl.DefaultDataType.getDataType; import static org.jooq.impl.SQLDataType.VARCHAR; import static org.jooq.impl.Tools.EMPTY_FIELD; +import static org.jooq.impl.Tools.anyMatch; import static org.jooq.tools.StringUtils.defaultIfBlank; import java.util.ArrayList; @@ -154,12 +155,8 @@ final class XMLHandler extends DefaultHandler { private static boolean onlyValueFields(List> fields) { if (fields.size() <= 1) return false; - - for (Field field : fields) - if (!"value".equals(field.getName())) - return false; - - return true; + else + return !anyMatch(fields, f -> !"value".equals(f.getName())); } @Override