This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 39858ad15b Clean up SonarQube/SonarLint findings in commons,
console-ui FreeMarker, and datatables modules
39858ad15b is described below
commit 39858ad15b636868fa55dc078b6fbb2aba58b20f
Author: James Bognar <[email protected]>
AuthorDate: Mon Aug 17 08:15:20 2026 -0400
Clean up SonarQube/SonarLint findings in commons, console-ui FreeMarker,
and datatables modules
Real fixes: restricted-identifier renames, method references, entrySet
iteration instead of keySet+get, corrected assert argument order,
parameterized/deduplicated tests, removal of unthrown declared throws,
single-throw lambda refactors for assertThrows, reduced regex backtracking,
toList() over collect(Collectors.toList()), deduplicated literal constants,
and null-to-empty-collection returns.
Suppress-with-rationale (intentional design, not bugs): process-lifetime
ThreadLocals, API-hiding factory methods, GC/timing test helpers, and
reflection-target fixtures.
Also corrects a suppression on ObjectUtils_Coverage_Test (java:S1481 ->
java:S1854) so it actually matches the dead-store finding on the
checkcast-triggering local variable.
---
.../apache/juneau/commons/logging/LogContext.java | 7 ++-
.../apache/juneau/commons/logging/LogRecord.java | 12 ++--
.../juneau/commons/logging/LogRecordContext.java | 18 +++---
.../juneau/commons/logging/MessageGenerator.java | 6 +-
.../apache/juneau/commons/logging/RichLogger.java | 13 ++--
.../org/apache/juneau/commons/utils/Uuid7.java | 3 +
.../commons/LogRecordContextCrossPackage_Test.java | 12 ++--
.../juneau/commons/bean/BeanMap_Coverage_Test.java | 19 +++---
.../bean/BeanMeta_Discovery_Coverage_Test.java | 26 +++++---
.../bean/BeanMeta_FindMethods_Coverage_Test.java | 43 ++++++-------
...BeanPropertyMeta_Marshalling_Coverage_Test.java | 73 +++++++++-------------
.../BeanPropertyMeta_Validate_Coverage_Test.java | 8 ++-
.../inject/BeanInstantiator_Coverage_Test.java | 12 ++--
.../commons/inject/BeanInstantiator_Test.java | 6 ++
.../juneau/commons/io/PathReaderBuilder_Test.java | 3 +-
.../commons/logging/LogRecordContext_Test.java | 28 ++++-----
.../juneau/commons/logging/LogRecord_Test.java | 6 +-
.../juneau/commons/logging/RichLogger_Test.java | 23 ++++---
.../commons/reflect/ClassInfo_Coverage_Test.java | 14 ++++-
.../reflect/ReflectionMap_Coverage_Test.java | 4 +-
.../commons/secret/EnvVarSecretStore_Test.java | 6 +-
.../commons/secret/InMemorySecretStore_Test.java | 3 +-
.../utils/CollectionUtils_Coverage_Test.java | 10 +--
.../commons/utils/ObjectUtils_Coverage_Test.java | 4 +-
.../ConsoleDataTablesFreemarkerMixin.java | 3 +
.../console/datatables/DataTableMethodModel.java | 2 +-
.../ConsoleDataTablesFreemarkerMixin_Test.java | 9 ++-
.../freemarker/console/ConsoleFreemarkerMixin.java | 3 +
.../console/ConsoleFreemarkerMixin_Test.java | 6 +-
.../console/ModuleGraph_ImportScan_Test.java | 2 +-
.../rest/server/datatables/DataTablesMixin.java | 3 +
.../server/datatables/DataTablesQueryProtocol.java | 29 +++++----
.../rest/server/datatables/DataTablesResults.java | 2 +-
.../rest/server/datatables/DataTablesTable.java | 2 +-
.../datatables/DataTablesClientHelpers_Test.java | 8 +--
.../DataTablesTable_HtmlRenderHonoring_Test.java | 12 ++--
36 files changed, 254 insertions(+), 186 deletions(-)
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogContext.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogContext.java
index c28533ba2b..7a52b64544 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogContext.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogContext.java
@@ -73,6 +73,9 @@ public final class LogContext {
/** The single shared instance. There is exactly one thread-local map;
sharing the instance is harmless. */
static final LogContext INSTANCE = new LogContext();
+ @SuppressWarnings({
+ "java:S5164" // Scope#close() restores/empties the per-thread
map on every key; the cached empty map is harmless to retain for the thread's
lifetime.
+ })
private static final ThreadLocal<Map<String,Object>> CONTEXT =
ThreadLocal.withInitial(LinkedHashMap::new);
private LogContext() {}
@@ -209,8 +212,8 @@ public final class LogContext {
return;
closed = true;
var map = CONTEXT.get();
- for (var key : priors.keySet())
- restore(map, key, hadPrior.get(key),
priors.get(key));
+ for (var e : priors.entrySet())
+ restore(map, e.getKey(),
hadPrior.get(e.getKey()), e.getValue());
}
}
}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecord.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecord.java
index 2424e0c0dd..b17bcbcdfc 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecord.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecord.java
@@ -228,15 +228,15 @@ public class LogRecord extends
java.util.logging.LogRecord {
/**
* Formats a JUL log record with the same placeholders as {@link
#formatted(String)}.
*
- * @param record The record to format.
+ * @param rec The record to format.
* @param format The format string.
* @return The formatted string.
*/
@SuppressWarnings({
"deprecation" // Date constructor is deprecated but needed for
compatibility
})
- public static String formatted(java.util.logging.LogRecord record,
String format) {
- var date = new Date(record.getMillis());
+ public static String formatted(java.util.logging.LogRecord rec, String
format) {
+ var date = new Date(rec.getMillis());
Function<String,Object> resolver = key -> switch (key) {
case KEY_date -> "%1$s";
@@ -245,11 +245,11 @@ public class LogRecord extends
java.util.logging.LogRecord {
case KEY_msg -> "%4$s";
case KEY_thrown -> "%5$s";
case KEY_timestamp -> new
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(date);
- case KEY_thread, KEY_threadid ->
s(record.getThreadID());
- case KEY_exception -> o(record.getThrown()).map(x ->
x.getMessage()).orElse("");
+ case KEY_thread, KEY_threadid -> s(rec.getThreadID());
+ case KEY_exception -> o(rec.getThrown()).map(x ->
x.getMessage()).orElse("");
default -> "";
};
- return safeOptCatch(() -> f(formatNamed(format, resolver),
date, record.getLoggerName(), record.getLevel(), record.getMessage(),
record.getThrown()), x -> x.getLocalizedMessage()).orElse(null);
+ return safeOptCatch(() -> f(formatNamed(format, resolver),
date, rec.getLoggerName(), rec.getLevel(), rec.getMessage(), rec.getThrown()),
x -> x.getLocalizedMessage()).orElse(null);
}
}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecordContext.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecordContext.java
index 40b097bc4e..88c314eb86 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecordContext.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/LogRecordContext.java
@@ -59,12 +59,12 @@ public final class LogRecordContext {
/**
* Returns the context snapshot attached to the specified record.
*
- * @param record The record. Must not be <jk>null</jk>.
+ * @param rec The record. Must not be <jk>null</jk>.
* @return The attached snapshot, or the shared empty {@link Map#of()}
singleton if none is attached. Never
* <jk>null</jk>.
*/
- public static Map<String,Object> of(java.util.logging.LogRecord record)
{
- var m = TABLE.get(record);
+ public static Map<String,Object> of(java.util.logging.LogRecord rec) {
+ var m = TABLE.get(rec);
return m == null ? Map.of() : m;
}
@@ -77,10 +77,10 @@ public final class LogRecordContext {
* the live context is empty this returns immediately, before touching
the synchronized side table, so callers who
* never use {@link LogContext} pay only a thread-local read and an
{@code isEmpty()} check — never a lock.
*
- * @param record The record to attach to. Must not be <jk>null</jk>.
+ * @param rec The record to attach to. Must not be <jk>null</jk>.
*/
- public static void attachIfAbsent(java.util.logging.LogRecord record) {
- attachIfAbsent(record, LogContext.INSTANCE.snapshot());
+ public static void attachIfAbsent(java.util.logging.LogRecord rec) {
+ attachIfAbsent(rec, LogContext.INSTANCE.snapshot());
}
/**
@@ -92,14 +92,14 @@ public final class LogRecordContext {
* — symmetric with the one-arg overload — so a later
one-arg call from an empty emitting thread cannot
* clobber a previously pre-seeded snapshot.
*
- * @param record The record to attach to. Must not be <jk>null</jk>.
+ * @param rec The record to attach to. Must not be <jk>null</jk>.
* @param ctx The context snapshot to attach. Must not be
<jk>null</jk>.
*/
- public static void attachIfAbsent(java.util.logging.LogRecord record,
Map<String,Object> ctx) {
+ public static void attachIfAbsent(java.util.logging.LogRecord rec,
Map<String,Object> ctx) {
if (ctx.isEmpty())
return;
PUT_COUNT.incrementAndGet();
- TABLE.putIfAbsent(record, ctx);
+ TABLE.putIfAbsent(rec, ctx);
}
/**
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/MessageGenerator.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/MessageGenerator.java
index 7003e50414..5f4757803a 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/MessageGenerator.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/MessageGenerator.java
@@ -16,6 +16,8 @@
*/
package org.apache.juneau.commons.logging;
+import org.apache.juneau.commons.utils.StringUtils;
+
/**
* Strategy interface for rendering log message patterns.
*/
@@ -25,12 +27,12 @@ public interface MessageGenerator {
/**
* Printf-style message generator backed by {@link #format(String,
Object...)}.
*/
- MessageGenerator PRINTF = (pattern, args) ->
org.apache.juneau.commons.utils.StringUtils.format(pattern, args);
+ MessageGenerator PRINTF = StringUtils::format;
/**
* MessageFormat-style message generator backed by {@link
org.apache.juneau.commons.utils.StringUtils#mformat(String, Object...)}.
*/
- MessageGenerator MESSAGE_FORMAT = (pattern, args) ->
org.apache.juneau.commons.utils.StringUtils.mformat(pattern, args);
+ MessageGenerator MESSAGE_FORMAT = StringUtils::mformat;
/**
* Renders a message pattern with arguments.
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/RichLogger.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/RichLogger.java
index fd60c6a7f4..ac7b257bf1 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/RichLogger.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/logging/RichLogger.java
@@ -154,6 +154,9 @@ public class RichLogger extends java.util.logging.Logger {
* @param name The logger name. Must not be <jk>null</jk>.
* @return A logger instance (cached and reused for the same name).
*/
+ @SuppressWarnings({
+ "java:S9149" // Intentional factory override of the hidden
static Logger.getLogger(String); public API callers depend on this
name/signature.
+ })
public static RichLogger getLogger(String name) {
drainCollectedLoggers();
while (true) {
@@ -338,19 +341,19 @@ public class RichLogger extends java.util.logging.Logger {
}
@Override
- public void log(java.util.logging.LogRecord record) {
- LogRecordContext.attachIfAbsent(record);
- canonical.listeners.forEach(x -> x.onLogRecord(record));
+ public void log(java.util.logging.LogRecord rec) {
+ LogRecordContext.attachIfAbsent(rec);
+ canonical.listeners.forEach(x -> x.onLogRecord(rec));
if (canonical.useParentListeners) {
var ancestors = new ArrayList<RichLogger>();
forEachLiveAncestor(canonical.getName(),
ancestors::add);
for (var ancestor : ancestors) {
- ancestor.listeners.forEach(x ->
x.onLogRecord(record));
+ ancestor.listeners.forEach(x ->
x.onLogRecord(rec));
if (!ancestor.useParentListeners)
break;
}
}
- delegate.log(record);
+ delegate.log(rec);
}
private static boolean hasAnyListenerInChain(RichLogger logger) {
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Uuid7.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Uuid7.java
index ec10736227..323859b557 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Uuid7.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/Uuid7.java
@@ -38,6 +38,9 @@ import java.util.*;
*/
public final class Uuid7 {
+ @SuppressWarnings({
+ "java:S5164" // Process-lifetime cached SecureRandom per thread
is intentional; there is no scope boundary at which remove() would apply.
+ })
private static final ThreadLocal<SecureRandom> RANDOM =
ThreadLocal.withInitial(SecureRandom::new);
private static final long VERSION_7 = 0x7000L; // version nibble
in the low 16 bits of the MSB long
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/LogRecordContextCrossPackage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/LogRecordContextCrossPackage_Test.java
index 54a162d5c2..5815791d4c 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/LogRecordContextCrossPackage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/LogRecordContextCrossPackage_Test.java
@@ -32,14 +32,14 @@ import org.junit.jupiter.api.*;
class LogRecordContextCrossPackage_Test extends TestBase {
@Test void a01_publicApiCallableCrossPackage() {
- var record = new java.util.logging.LogRecord(Level.INFO, "msg");
+ var rec = new java.util.logging.LogRecord(Level.INFO, "msg");
try (var s = RichLogger.context().with("requestId", "xyz")) {
- LogRecordContext.attachIfAbsent(record);
+ LogRecordContext.attachIfAbsent(rec);
}
- assertEquals("xyz",
LogRecordContext.of(record).get("requestId"));
+ assertEquals("xyz", LogRecordContext.of(rec).get("requestId"));
- var record2 = new java.util.logging.LogRecord(Level.INFO,
"msg");
- LogRecordContext.attachIfAbsent(record2, Map.of("requestId",
"pre"));
- assertEquals("pre",
LogRecordContext.of(record2).get("requestId"));
+ var rec2 = new java.util.logging.LogRecord(Level.INFO, "msg");
+ LogRecordContext.attachIfAbsent(rec2, Map.of("requestId",
"pre"));
+ assertEquals("pre", LogRecordContext.of(rec2).get("requestId"));
}
}
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMap_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMap_Coverage_Test.java
index a864d00d46..f7bd56ee17 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMap_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMap_Coverage_Test.java
@@ -109,9 +109,9 @@ class BeanMap_Coverage_Test extends TestBase {
@NullSource
@ValueSource(strings = {"nonExistent", "*"})
void b02_containsKey_absentKeys_returnFalse(String key) {
- // null -> emptyIfNull(null) yields "" which is not in the
property map;
- // "nonExistent" -> not a declared property;
- // "*" -> excluded from containsKey (JUNEAU-248).
+ // a null key is normalized to an empty string, which is not in
the property map;
+ // "nonExistent" is simply not a declared property; and
+ // "*" is deliberately excluded from containsKey (JUNEAU-248).
var bm = BeanMap.of(new A_Pojo());
assertFalse(bm.containsKey(key));
}
@@ -246,9 +246,10 @@ class BeanMap_Coverage_Test extends TestBase {
@Test
void e0a2_entrySet_dynaBean_keysAreRealPerEntryKeys() {
- // Regression test: BeanMapEntry.getKey() must return the real
per-entry key (pName) for
- // dyna-property entries, not the dyna-property meta name
("*"). keySet() already got this right;
- // entrySet() previously collapsed every dyna entry's key to
"*".
+ // Regression test: a bean map entry's key must be the real
per-entry key (pName) for
+ // dyna-property entries, not the dyna-property meta name of a
single asterisk. The key set view
+ // already handled this correctly, but the entry set view
previously collapsed every dyna entry's
+ // key to that same asterisk.
var c = new C_DynaPojo();
c.name = "n1";
c.extras.put("x1", "v1");
@@ -273,9 +274,9 @@ class BeanMap_Coverage_Test extends TestBase {
// Exercises the "p = getPropertyMeta("*")" branch in put()
(BeanMap.java:710-712).
var c = new C_DynaPojo();
var bm = BeanMap.of(c);
- // "unknownProp" is not a declared field. If WithDynaField
recognizes the dyna property, this should
- // route to the dyna setter. If not, it throws
BeanRuntimeException. Either outcome is acceptable;
- // assert that no other exception type escapes the put() dyna
branch.
+ // The key here is not a declared field. If the dyna-aware bean
recognizes it as a dyna
+ // property, this routes to the dyna setter with no exception.
If not, a bean runtime exception
+ // is the acceptable outcome; we're only asserting that no
other exception type escapes this branch.
assertDoesNotThrow(() -> {
try {
bm.put("unknownDynaKey", "value");
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_Discovery_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_Discovery_Coverage_Test.java
index dec690cd63..2a255bea95 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_Discovery_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_Discovery_Coverage_Test.java
@@ -164,8 +164,11 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
}
@Test
+ @SuppressWarnings({
+ "java:S2133" // An actual anonymous class (not Runnable.class)
is required so cm.isAnonymousClass() is exercised.
+ })
void a08_create_anonymousClass_returnsReason() {
- var anon = new Runnable() { @Override public void run() {} };
+ var anon = new Runnable() { @Override public void run() { /*
Never invoked; only the anonymous class identity is under test. */ } };
var r = BeanMeta.create(new FakeBeanInfo<>(anon.getClass()),
null);
assertNull(r.beanMeta());
assertEquals("Class is not public", r.notABeanReason());
@@ -177,9 +180,12 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
// PUBLIC visibility already makes "! isVisible" true for the anonymous
class, so isAnonymousClass() is
// never reached at all) - this is the only way to exercise that
disjunct's "true" outcome.
@Test
+ @SuppressWarnings({
+ "java:S2133" // An actual anonymous class (not Runnable.class)
is required so cm.isAnonymousClass() is exercised.
+ })
void
a08b_create_anonymousClass_permissiveVisibility_stillReturnsReason() {
var cfg =
BeanConfigContext.create().beanClassVisibility(org.apache.juneau.commons.reflect.Visibility.PRIVATE).build();
- var anon = new Runnable() { @Override public void run() {} };
+ var anon = new Runnable() { @Override public void run() { /*
Never invoked; only the anonymous class identity is under test. */ } };
var r = BeanMeta.create(new FakeBeanInfo<>(anon.getClass(),
cfg), null);
assertNull(r.beanMeta());
assertEquals("Class is not public", r.notABeanReason());
@@ -354,8 +360,8 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
void
d01b_marshallingContextNonNull_postProcessorThrows_wrappedAsBeanRuntimeException()
{
// validateAndRegisterProperty()'s try block covers both
p.validate() AND the post-processor hook
// (~line 722) - a RuntimeException thrown by the latter must
be caught and re-wrapped by the same
- // generic "catch (Exception e) { throw brex(...); }" clause as
a validate()-thrown exception would be.
- // BeanMeta.create()'s own outer "catch (RuntimeException e)"
then catches THAT BeanRuntimeException
+ // generic catch-all clause (which throws via brex) that a
validate()-thrown exception would hit.
+ // BeanMeta.create()'s own outer catch for RuntimeException
then catches that BeanRuntimeException
// and surfaces it as notABeanReason rather than propagating it
to the caller.
var postProcessor = (BeanPropertyPostProcessor) (mc, builder)
-> { throw new RuntimeException("boom-postprocess"); };
var cfg =
BeanConfigContext.create().beanPropertyPostProcessor(postProcessor).build();
@@ -604,6 +610,10 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
public record ExtraCtorArgWithSetterOnlyPropertyRecord(String a) {
@BeanCtor(properties = "a,extra")
public ExtraCtorArgWithSetterOnlyPropertyRecord(String a,
String extra) { this(a); }
+
+ @SuppressWarnings({
+ "java:S1172" // Deliberately setter-only: no backing
field/getter; the unused param is the point of this fixture.
+ })
public void setBar(String v) { /* no-op - setter-only extra
property: no field, no getter */ }
}
@@ -688,7 +698,7 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
//====================================================================================================
// useJavaBeanIntrospector: BeanFilter#getInterfaceClass() override,
and a bad stop class surfacing as
- // the constructor's generic "catch (Exception)" fallback
(Introspector.getBeanInfo declares a checked
+ // the constructor's generic catch-all fallback
(Introspector.getBeanInfo declares a checked
// IntrospectionException, which isn't a BeanRuntimeException and so
isn't rethrown as-is).
//====================================================================================================
@@ -714,7 +724,7 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
void
g08_useJavaBeanIntrospector_stopClassNotSuperclass_capturedAsGenericException()
{
// String isn't a superclass of IntrospectableBean, so
Introspector.getBeanInfo(IntrospectableBean.class,
// String.class) throws a checked IntrospectionException -
caught by the constructor's trailing
- // "catch (Exception e)" (the BeanRuntimeException-specific
catch above it only rethrows, it doesn't
+ // catch-all clause (the BeanRuntimeException-specific catch
above it only rethrows, it doesn't
// apply here), landing in notABeanReason rather than
propagating.
var filter = new FakeBeanFilter().stopClass(info(String.class));
var cfg =
BeanConfigContext.create().useJavaBeanIntrospector(true).beanMetaInitializer(BeanTestFakes.initializerWithFilter(filter)).build();
@@ -848,8 +858,8 @@ class BeanMeta_Discovery_Coverage_Test extends TestBase {
@Test
void
e08_newBean_factoryThrowsExecutableExceptionDirectly_rethrownUnwrapped() {
// Distinct from e05 above (which throws a plain
RuntimeException, wrapped by the generic
- // "catch (Exception e)" clause): here the factory throws an
ExecutableException directly, which
- // newBean()'s dedicated "catch (ExecutableException e) { throw
e; }" clause must rethrow as-is
+ // catch-all clause): here the factory throws an
ExecutableException directly, which
+ // newBean()'s dedicated ExecutableException-rethrow clause
must rethrow as-is
// rather than double-wrapping it inside another
ExecutableException.
var bm = BeanMeta.of(ExecutableExceptionFactoryBean.class);
var ex = assertThrows(ExecutableException.class, () ->
bm.newBean(null));
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_FindMethods_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_FindMethods_Coverage_Test.java
index 04237c8c11..a0272e771f 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_FindMethods_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanMeta_FindMethods_Coverage_Test.java
@@ -48,13 +48,13 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase {
public String fooBar() { return "x"; }
}
- // SUSPECTED BUG (not fixed here): a normal, unannotated `getFoo()`
(non-void)
+ // SUSPECTED BUG (not fixed here): a normal, unannotated getter
(non-void)
// resolves to property "foo" (lowercased by the PropertyNamer at line
~1436) - but this bare-@BeanProp
- // void-returning `getFoo()` resolves to "Foo" (capital F,
unlowercased). Root cause: the bpName-fallback
- // branch (~1391-1396) sets `bpName = n` using the *pre-namer* stripped
name ("Foo"), and that raw value
- // then overrides the already-namered `n` again at line ~1442-1443 (`if
(nn(bpName) && !bpName.isEmpty())
- // n = bpName;`), undoing the lowercasing that just happened one line
earlier for every other bpName-driven
- // getter shape. Pinning current (buggy) behavior here rather than
silently fixing it.
+ // void-returning getter resolves to "Foo" (capital F, unlowercased).
Root cause: the bpName-fallback
+ // branch (~1391-1396) assigns the name using the pre-namer stripped
name ("Foo"), and that raw value
+ // then overrides the already-namered name again a few lines later,
undoing the lowercasing that just
+ // happened one line earlier for every other bpName-driven getter
shape. Pinning current (buggy)
+ // behavior here rather than silently fixing it.
@Test
void
a01_bareBeanProp_voidGetPrefixed_stripsGetPrefix_butSkipsNamerLowercasing() {
var bm = BeanMeta.of(BareBeanPropZeroParamBean.class);
@@ -174,7 +174,7 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase {
//====================================================================================================
// 2-param: "*" dyna shape that does NOT match the setter pattern (name
doesn't start with "set") ->
- // falls through to the `else { methodType = GETTER; }` branch for
2-param methods.
+ // falls through to the trailing GETTER-fallback branch for 2-param
methods.
//====================================================================================================
public static class DynaTwoParamNonSetterShapeBean {
@@ -187,9 +187,10 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase {
@Test
void c01_dynaTwoParam_nonSetterShape_fallsThroughToGetterBranch() {
- // oddTwoArgMethod's 2-param condition (bpName=="*" &&
param0==String && name.startsWith("set") && ...)
- // is false purely because the method name doesn't start with
"set" - exercising the `else` GETTER
- // fallback at the end of the params.size()==2 block. The
resulting BeanMeta still just reflects
+ // oddTwoArgMethod's 2-param dyna-setter condition (a
conjunction of the "*" bpName, a String first
+ // param, and a "set"-prefixed name) is false purely because
the method name doesn't start with "set" -
+ // exercising the trailing GETTER fallback at the end of the
two-param handling block. The resulting
+ // BeanMeta still just reflects
// whichever dyna getter method was processed last; this test
only proves construction doesn't throw
// and the dyna property remains discoverable.
var bm = BeanMeta.of(DynaTwoParamNonSetterShapeBean.class);
@@ -291,9 +292,9 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase {
//====================================================================================================
// 1-param setter: explicit (non-empty) @BeanProp name on a method that
doesn't match "set"/"with" at
- // all - exercises the `else { n = bpName; }` branch
(bpName.isEmpty()==false) of the setter-side
- // bare/explicit-@BeanProp fallback, as opposed to d01/d02 above (which
both use a BARE @BeanProp, so
- // bpName is empty rather than a real name).
+ // all - exercises the non-empty-bpName-wins branch of the setter-side
bare/explicit-@BeanProp
+ // fallback, as opposed to d01/d02 above (which both use a BARE
@BeanProp, so bpName is empty rather
+ // than a real name).
//====================================================================================================
public static class ExplicitNamedOneParamSetterBean {
@@ -368,10 +369,10 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase
{
//====================================================================================================
// 2-param: "*" dyna shape, String key, "set"-prefixed, but return type
is NEITHER void NOR assignable to
- // the declaring class (an unrelated return type) - both disjuncts of
`rt.isAssignableFrom(ci) ||
- // rt.is(Void.TYPE)` must be explicitly evaluated to false here (as
opposed to c02, where the second
- // disjunct short-circuits true via void, and c04, where the first
disjunct short-circuits true via a
- // fluent return type), so the whole condition is false and this falls
through to the `else` GETTER
+ // the declaring class (an unrelated return type) - both disjuncts of
the "return type assignable to the
+ // declaring class, or void" condition must be explicitly evaluated to
false here (as opposed to c02, where
+ // the second disjunct short-circuits true via void, and c04, where the
first disjunct short-circuits true
+ // via a fluent return type), so the whole condition is false and this
falls through to the trailing GETTER
// branch despite matching every other conjunct.
//====================================================================================================
@@ -388,10 +389,10 @@ class BeanMeta_FindMethods_Coverage_Test extends TestBase
{
}
//====================================================================================================
- // 2-param: bpName present but NOT "*" - the outer `"*".equals(bpName)`
conjunct is false (as opposed to
- // c01 above, where bpName IS "*" but a later conjunct in the same
condition is what's false), so this
- // exercises a distinct branch outcome for that same guard even though
both fall through to the same
- // `else { methodType = GETTER; }`.
+ // 2-param: bpName present but NOT "*" - the outer "bpName is the dyna
marker" conjunct is false (as
+ // opposed to c01 above, where bpName IS "*" but a later conjunct in
the same condition is what's false),
+ // so this exercises a distinct branch outcome for that same guard even
though both fall through to the
+ // same trailing GETTER fallback.
//====================================================================================================
public static class ExplicitNamedTwoParamMethodBean {
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Marshalling_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Marshalling_Coverage_Test.java
index b0a7d01240..0b5c26e35d 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Marshalling_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Marshalling_Coverage_Test.java
@@ -20,11 +20,14 @@ import static
org.apache.juneau.commons.reflect.ReflectionUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
+import java.util.stream.*;
import org.apache.juneau.commons.*;
import org.apache.juneau.commons.bean.BeanTestFakes.*;
import org.apache.juneau.commons.reflect.*;
import org.junit.jupiter.api.*;
+import org.junit.jupiter.params.*;
+import org.junit.jupiter.params.provider.*;
/**
* Coverage tests for the marshalling-only-path branches of {@link
BeanPropertyMeta#add}, {@link BeanPropertyMeta#set}
@@ -528,7 +531,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
}
@Test
- void d07_set_sortedMap_abstractType_noExistingNoAccessor_throws()
throws Exception {
+ void d07_set_sortedMap_abstractType_noExistingNoAccessor_throws() {
var beanMeta = marshallingBeanMeta(SortedMapFieldBean.class);
var pm = BeanPropertyMeta.builder(beanMeta, "props")
.canRead().canWrite()
@@ -626,7 +629,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
}
@Test
- void e07_set_collection_abstractType_noExistingNoAccessor_throws()
throws Exception {
+ void e07_set_collection_abstractType_noExistingNoAccessor_throws() {
var beanMeta = marshallingBeanMeta(SetFieldBean.class);
var pm = BeanPropertyMeta.builder(beanMeta, "items")
.canRead().canWrite()
@@ -828,7 +831,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
}
@Test
- void h03_dynaSet_noAccessorAtAll_throwsWithMarshallingClassName()
throws Exception {
+ void h03_dynaSet_noAccessorAtAll_throwsWithMarshallingClassName() {
var bean = new NoAccessorBean();
var beanMeta = marshallingBeanMeta(NoAccessorBean.class);
var builder = BeanPropertyMeta.builder(beanMeta,
"*").canRead().canWrite();
@@ -845,21 +848,21 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
//====================================================================================================
@Test
- void i01_add_collection_noAccessor_propagatesBeanRuntimeException()
throws Exception {
+ void i01_add_collection_noAccessor_propagatesBeanRuntimeException() {
var bean = new NoAccessorCollectionBean();
var beanMeta =
marshallingBeanMeta(NoAccessorCollectionBean.class);
var pm = BeanPropertyMeta.builder(beanMeta,
"items").canRead().canWrite()
.rawMetaType(new
FakeBeanInfo<>(ArrayList.class).elementType(new FakeBeanInfo<>(Object.class)))
.build();
var bMap = mapOf(bean);
- // invokeGetter() throws (no getter, no field) inside the try
block; add()'s
- // `catch (BeanRuntimeException e) { throw e; }` must rethrow
it unwrapped rather than
- // re-wrapping it via the generic `catch (Exception e1)` clause.
+ // The getter invocation throws (no getter, no field) inside
the try block, so add()'s dedicated
+ // BeanRuntimeException-rethrow clause must rethrow it
unwrapped rather than re-wrapping it
+ // via the generic catch-all clause.
assertThrowsWithMessage(BeanRuntimeException.class, "Getter or
public field not defined", () -> pm.add(bMap, null, "x"));
}
@Test
- void i02_addKeyValue_map_noAccessor_propagatesBeanRuntimeException()
throws Exception {
+ void i02_addKeyValue_map_noAccessor_propagatesBeanRuntimeException() {
var bean = new NoAccessorCollectionBean();
var beanMeta =
marshallingBeanMeta(NoAccessorCollectionBean.class);
var pm = BeanPropertyMeta.builder(beanMeta,
"props").canRead().canWrite()
@@ -908,22 +911,10 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
// set() — no setter/no field, non-collection/non-map property,
ignore-* config combos
//====================================================================================================
- @Test
- void
k01_set_noSetterNoField_ignoreUnknownNullBeanProperties_nullValue_returnsNullWithoutThrowing()
throws Exception {
- var cfg =
BeanConfigContext.create().ignoreMissingSetters(false).ignoreUnknownNullBeanProperties(true).build();
- var beanMeta = marshallingBeanMeta(GetterBean.class, cfg);
- var pm = BeanPropertyMeta.builder(beanMeta, "x")
- .setGetter(info(GetterBean.class.getMethod("getX")))
- .canRead().canWrite()
- .rawMetaType(new FakeBeanInfo<>(String.class))
- .build();
- var bMap = mapOf(new GetterBean());
- assertNull(pm.set(bMap, null, null));
- }
-
- @Test
- void
k02_set_noSetterNoField_ignoreMissingSetters_nonNullValue_returnsNullWithoutThrowing()
throws Exception {
- var cfg =
BeanConfigContext.create().ignoreMissingSetters(true).ignoreUnknownNullBeanProperties(false).build();
+ @ParameterizedTest
+ @MethodSource("noSetterNoFieldConfigsProvider")
+ void k01_set_noSetterNoField_variousIgnoreConfigs(boolean
ignoreMissingSetters, boolean ignoreUnknownNullBeanProperties, Object value,
boolean shouldThrow) throws Exception {
+ var cfg =
BeanConfigContext.create().ignoreMissingSetters(ignoreMissingSetters).ignoreUnknownNullBeanProperties(ignoreUnknownNullBeanProperties).build();
var beanMeta = marshallingBeanMeta(GetterBean.class, cfg);
var pm = BeanPropertyMeta.builder(beanMeta, "x")
.setGetter(info(GetterBean.class.getMethod("getX")))
@@ -931,20 +922,19 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
.rawMetaType(new FakeBeanInfo<>(String.class))
.build();
var bMap = mapOf(new GetterBean());
- assertNull(pm.set(bMap, null, "ignored"));
+ if (shouldThrow)
+ assertThrowsWithMessage(BeanRuntimeException.class,
"Setter or public field not defined", () -> pm.set(bMap, null, value));
+ else
+ assertNull(pm.set(bMap, null, value));
}
- @Test
- void k03_set_noSetterNoField_strictConfig_nonNullValue_throws() throws
Exception {
- var cfg =
BeanConfigContext.create().ignoreMissingSetters(false).ignoreUnknownNullBeanProperties(false).build();
- var beanMeta = marshallingBeanMeta(GetterBean.class, cfg);
- var pm = BeanPropertyMeta.builder(beanMeta, "x")
- .setGetter(info(GetterBean.class.getMethod("getX")))
- .canRead().canWrite()
- .rawMetaType(new FakeBeanInfo<>(String.class))
- .build();
- var bMap = mapOf(new GetterBean());
- assertThrowsWithMessage(BeanRuntimeException.class, "Setter or
public field not defined", () -> pm.set(bMap, null, "v"));
+ static Stream<Arguments> noSetterNoFieldConfigsProvider() {
+ return Stream.of(
+ // ignoreMissingSetters,
ignoreUnknownNullBeanProperties, value, shouldThrow
+ Arguments.of(false, true, null, false),
+ Arguments.of(true, false, "ignored", false),
+ Arguments.of(false, false, "v", true)
+ );
}
//====================================================================================================
@@ -993,7 +983,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
}
//====================================================================================================
- // add(BeanMap, String, String, Object) — generic Exception catch (not
a BeanRuntimeException)
+ // add(BeanMap, String, String, Object) — generic catch-all wraps a
non-BeanRuntimeException failure
//====================================================================================================
@Test
@@ -1004,9 +994,8 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
.build();
var bMap = mapOf(bean);
// FakeBeanInfo.newInstance() throws ExecutableException (not a
BeanRuntimeException) when the target
- // type has no no-arg constructor - add()'s `catch (Exception
e) { throw brex(e); }` clause (distinct
- // from the `catch (BeanRuntimeException e) { throw e; }`
clause exercised elsewhere) must still surface
- // it as a BeanRuntimeException.
+ // type has no no-arg constructor - add()'s generic catch-all
clause (distinct from the dedicated
+ // BeanRuntimeException-rethrow clause exercised elsewhere)
must still surface it as a BeanRuntimeException.
assertThrows(BeanRuntimeException.class, () -> pm.add(bMap,
null, "name", "x"));
}
@@ -1129,7 +1118,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
//====================================================================================================
@Test
- void h04_dynaGet_noAccessorAtAll_throwsWithMarshallingClassName()
throws Exception {
+ void h04_dynaGet_noAccessorAtAll_throwsWithMarshallingClassName() {
var bean = new NoAccessorBean();
var beanMeta = marshallingBeanMeta(NoAccessorBean.class);
var builder = BeanPropertyMeta.builder(beanMeta,
"*").canRead().canWrite();
@@ -1156,7 +1145,7 @@ class BeanPropertyMeta_Marshalling_Coverage_Test extends
TestBase {
// writeTransform.apply() runs directly inside set()'s own try
block (unlike the setPropertyValue()
// calls, whose exceptions are all caught and re-wrapped
internally by setPropertyValue()'s own
// try/catch before ever reaching this frame) - it's the only
realistic way to have a raw
- // BasicRuntimeException reach set()'s own `catch
(BasicRuntimeException e2) { throw brex(e2); }` clause,
+ // BasicRuntimeException reach set()'s own dedicated
BasicRuntimeException-rethrow-as-brex clause,
// which must translate it to a BeanRuntimeException
(BeanRuntimeException itself does NOT extend
// BasicRuntimeException, per the comment on that catch clause,
so it would otherwise propagate unchanged).
assertThrows(BeanRuntimeException.class, () -> pm.set(bMap,
null, "x"));
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Validate_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Validate_Coverage_Test.java
index e00cb163ab..725c3f2186 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Validate_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/bean/BeanPropertyMeta_Validate_Coverage_Test.java
@@ -55,7 +55,13 @@ class BeanPropertyMeta_Validate_Coverage_Test extends
TestBase {
public String getStr() { return null; }
public Integer getInt() { return null; }
public Map<String,Object> getMap() { return null; }
+ @SuppressWarnings({
+ "java:S1172" // Reflection target only: the "key"
param's presence/type is what's under test, not its usage.
+ })
public Map<String,Object> getMapByKey(String key) { return
null; }
+ @SuppressWarnings({
+ "java:S1172" // Reflection target only: the "x" param's
presence/type is what's under test, not its usage.
+ })
public String getBadDynaGetter(int x) { return null; }
public String getBadDynaGetterNoArgs() { return null; }
}
@@ -573,7 +579,7 @@ class BeanPropertyMeta_Validate_Coverage_Test extends
TestBase {
}
@Test
- void e02_getDynaMap_noGetterOrFieldOrExtraKeys_throws() throws
Exception {
+ void e02_getDynaMap_noGetterOrFieldOrExtraKeys_throws() {
// isDyna can only be set true through validate() (private
field), and validate() rejects a dyna property
// that ends up with no getter/field/extraKeys before returning
true - so the "no accessor" throw in
// getDynaMap() can only be observed by relaxing isDyna to
package-private for direct test construction.
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Coverage_Test.java
index 381400fc67..5eb948b8dc 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Coverage_Test.java
@@ -210,8 +210,8 @@ class BeanInstantiator_Coverage_Test extends TestBase {
assertEquals(B01_GrandParent.class.getName(),
subTypes.get(2).getName());
}
- public interface B02_IFace { /* empty */ }
- public static class B02_Impl implements B02_IFace { /* empty */ }
+ public interface B02Iface { /* empty */ }
+ public static class B02_Impl implements B02Iface { /* empty */ }
/**
* LATENT-BUG PIN: {@code findBeanSubTypes()}'s final defensive check
is commented
@@ -224,7 +224,7 @@ class BeanInstantiator_Coverage_Test extends TestBase {
*/
@Test
void
b02_findBeanSubTypesThrowsWhenBeanTypeIsInterfaceNotInSuperclassChain() {
- var creator = bc(B02_IFace.class).type(B02_Impl.class);
+ var creator = bc(B02Iface.class).type(B02_Impl.class);
var ex = assertThrows(IllegalArgumentException.class,
creator::getBeanSubTypes);
assertContains("was not found in the parent hierarchy",
ex.getMessage());
}
@@ -509,7 +509,7 @@ class BeanInstantiator_Coverage_Test extends TestBase {
assertFalse(bean.wired);
}
- public interface E05_MultiSupplier<X, Y> extends Supplier<X> {
+ public interface E05MultiSupplier<X, Y> extends Supplier<X> {
// Second type parameter is used here (rather than left
decorative) solely so the setter's parameter
// type carries two actual generic type arguments, per the
scenario under test.
Y other();
@@ -521,8 +521,8 @@ class BeanInstantiator_Coverage_Test extends TestBase {
public final boolean wired;
E05_Bean(Builder b) { this.wired = b.multi != null; }
public static class Builder {
- E05_MultiSupplier<E05_ServiceX, E05_ServiceY> multi;
- public void setMulti(E05_MultiSupplier<E05_ServiceX,
E05_ServiceY> v) { this.multi = v; }
+ E05MultiSupplier<E05_ServiceX, E05_ServiceY> multi;
+ public void setMulti(E05MultiSupplier<E05_ServiceX,
E05_ServiceY> v) { this.multi = v; }
public E05_Bean build() { return new E05_Bean(this); }
}
}
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
index 6ad9fd402c..9407626dbc 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
@@ -260,6 +260,9 @@ class BeanInstantiator_Test extends TestBase {
}
}
+ @SuppressWarnings({
+ "java:S9149" // Intentionally hides the parent's
create(): this is the exact covariant-return static-factory convention
BeanInstantiator's builder detection is being tested against.
+ })
public static BuilderForChild create() {
return new BuilderForChild();
}
@@ -2046,6 +2049,9 @@ class BeanInstantiator_Test extends TestBase {
}
// Static method to return the builder (needed for
builder detection on child class)
+ @SuppressWarnings({
+ "java:S9149" // Intentionally hides the
parent's create(): this is the exact covariant-return static-factory convention
BeanInstantiator's builder detection is being tested against.
+ })
public static D28_BuilderForParentMethod create() {
return new D28_BuilderForParentMethod();
}
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/io/PathReaderBuilder_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/io/PathReaderBuilder_Test.java
index 52af297e63..9f15393783 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/io/PathReaderBuilder_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/io/PathReaderBuilder_Test.java
@@ -122,6 +122,7 @@ class PathReaderBuilder_Test extends TestBase {
}
@Test void a09_allowNoFileBoolean_false() {
- assertThrows(IllegalStateException.class, () ->
PathReaderBuilder.create().allowNoFile(false).build());
+ var builder = PathReaderBuilder.create().allowNoFile(false);
+ assertThrows(IllegalStateException.class, builder::build);
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecordContext_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecordContext_Test.java
index f2fc3c310b..74e898d429 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecordContext_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecordContext_Test.java
@@ -37,12 +37,12 @@ class LogRecordContext_Test extends TestBase {
//====================================================================================================
@Test void a01_emptyContextNoTableEntry() {
- var record = new java.util.logging.LogRecord(Level.INFO, "msg");
+ var rec = new java.util.logging.LogRecord(Level.INFO, "msg");
var putBefore = LogRecordContext.putCount();
- LogRecordContext.attachIfAbsent(record);
+ LogRecordContext.attachIfAbsent(rec);
// No live context → must return before touching the
synchronized table.
assertEquals(putBefore, LogRecordContext.putCount());
- assertSame(Map.of(), LogRecordContext.of(record));
+ assertSame(Map.of(), LogRecordContext.of(rec));
}
//====================================================================================================
@@ -51,13 +51,13 @@ class LogRecordContext_Test extends TestBase {
@Test void a02_nonEmptyContextAttachesSnapshot() {
var c = RichLogger.context();
- var record = new java.util.logging.LogRecord(Level.INFO, "msg");
+ var rec = new java.util.logging.LogRecord(Level.INFO, "msg");
try (var s = c.with("k", "v")) {
- LogRecordContext.attachIfAbsent(record);
- assertEquals("v", LogRecordContext.of(record).get("k"));
+ LogRecordContext.attachIfAbsent(rec);
+ assertEquals("v", LogRecordContext.of(rec).get("k"));
}
// After the scope closes, the already-attached snapshot is
unchanged (point-in-time fact).
- assertEquals("v", LogRecordContext.of(record).get("k"));
+ assertEquals("v", LogRecordContext.of(rec).get("k"));
}
//====================================================================================================
@@ -65,19 +65,19 @@ class LogRecordContext_Test extends TestBase {
//====================================================================================================
@Test void a03_preseedWinsOverLaterEmptyAttach() {
- var record = new java.util.logging.LogRecord(Level.INFO, "msg");
- LogRecordContext.attachIfAbsent(record, Map.of("requestId",
"abc"));
+ var rec = new java.util.logging.LogRecord(Level.INFO, "msg");
+ LogRecordContext.attachIfAbsent(rec, Map.of("requestId",
"abc"));
// Live context is empty here — the one-arg call must not
clobber the pre-seed.
- LogRecordContext.attachIfAbsent(record);
- assertEquals("abc",
LogRecordContext.of(record).get("requestId"));
+ LogRecordContext.attachIfAbsent(rec);
+ assertEquals("abc", LogRecordContext.of(rec).get("requestId"));
}
@Test void a04_twoArgEmptyMapSkipsTable() {
- var record = new java.util.logging.LogRecord(Level.INFO, "msg");
+ var rec = new java.util.logging.LogRecord(Level.INFO, "msg");
var putBefore = LogRecordContext.putCount();
- LogRecordContext.attachIfAbsent(record, Map.of());
+ LogRecordContext.attachIfAbsent(rec, Map.of());
assertEquals(putBefore, LogRecordContext.putCount());
- assertSame(Map.of(), LogRecordContext.of(record));
+ assertSame(Map.of(), LogRecordContext.of(rec));
}
//====================================================================================================
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecord_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecord_Test.java
index 1caf63b2eb..0178728134 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecord_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/LogRecord_Test.java
@@ -104,7 +104,7 @@ class LogRecord_Test extends TestBase {
}
@Test void c01_getMessage_defaultGenerator_usesPrintf() {
- var rec = new LogRecord("test.logger", Level.INFO, "%s + %s =
%s", new Object[]{1, 2, 3}, null);
+ var rec = new LogRecord("test.logger", Level.INFO, "%s + %s =
%s", new Object[]{1, 2, 3}, null, MessageGenerator.PRINTF);
assertEquals("1 + 2 = 3", rec.getMessage());
}
@@ -306,10 +306,10 @@ class LogRecord_Test extends TestBase {
assertEquals("test.logger:INFO:plain-jul", formatted);
}
- private static LogRecord roundTrip(LogRecord record) throws Exception {
+ private static LogRecord roundTrip(LogRecord rec) throws Exception {
byte[] data;
try (var baos = new ByteArrayOutputStream(); var oos = new
ObjectOutputStream(baos)) {
- oos.writeObject(record);
+ oos.writeObject(rec);
oos.flush();
data = baos.toByteArray();
}
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/RichLogger_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/RichLogger_Test.java
index ab0d6eff14..f01c9e035e 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/RichLogger_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/logging/RichLogger_Test.java
@@ -724,7 +724,11 @@ class RichLogger_Test extends TestBase {
}
}
- @Test void j03_unreferencedCanonical_eventuallyCollectable() throws
Exception {
+ @Test
+ @SuppressWarnings({
+ "java:S1854" // Load-bearing: nulling the local drops its
stack-frame liveness before the GC-poll below; removing it made this test
flaky/failing (confirmed empirically).
+ })
+ void j03_unreferencedCanonical_eventuallyCollectable() throws Exception
{
var name = "j03.collectable." + System.nanoTime();
var logger = RichLogger.getLogger(name);
var ref = new WeakReference<>(logger);
@@ -739,11 +743,11 @@ class RichLogger_Test extends TestBase {
var published = new AtomicInteger();
var h = new Handler() {
@Override
- public void publish(java.util.logging.LogRecord record)
{
+ public void publish(java.util.logging.LogRecord rec2) {
published.incrementAndGet();
}
- @Override public void flush() {}
- @Override public void close() {}
+ @Override public void flush() { /* Not needed: this
fixture only counts publish() calls. */ }
+ @Override public void close() { /* Not needed: this
fixture only counts publish() calls. */ }
};
delegate.addHandler(h);
try (var capture = logger.captureEvents()) {
@@ -881,12 +885,12 @@ class RichLogger_Test extends TestBase {
var published = new AtomicInteger();
var h = new Handler() {
@Override
- public void publish(java.util.logging.LogRecord record)
{
- if (name.equals(record.getLoggerName()))
+ public void publish(java.util.logging.LogRecord rec2) {
+ if (name.equals(rec2.getLoggerName()))
published.incrementAndGet();
}
- @Override public void flush() {}
- @Override public void close() {}
+ @Override public void flush() { /* Not needed: this
fixture only counts publish() calls. */ }
+ @Override public void close() { /* Not needed: this
fixture only counts publish() calls. */ }
};
// Before delegate.log(record) interception existed, wrapper
publication ended on the
// unregistered wrapper and never reached root handlers.
@@ -905,6 +909,9 @@ class RichLogger_Test extends TestBase {
}
}
+ @SuppressWarnings({
+ "java:S2925" // Polling for an async GC event has no
latch/await equivalent; the sleep is load-bearing for the poll interval.
+ })
private static boolean awaitCollected(WeakReference<?> ref) throws
Exception {
for (int i = 0; i < 20; i++) {
System.gc();
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ClassInfo_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ClassInfo_Coverage_Test.java
index 94885c3d01..71ab85f152 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ClassInfo_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ClassInfo_Coverage_Test.java
@@ -123,7 +123,7 @@ class ClassInfo_Coverage_Test extends TestBase {
@Test
void d02_equals_notAClassInfo_returnsFalse() {
- assertNotEquals(ClassInfo.of(String.class), "not a ClassInfo");
+ assertNotEquals("not a ClassInfo", ClassInfo.of(String.class));
}
//-----------------------------------------------------------------------------------------------------------------
@@ -141,6 +141,9 @@ class ClassInfo_Coverage_Test extends TestBase {
void e02_isElementFlag_notAnonymous_bothOutcomes() {
assertTrue(ClassInfo.of(String.class).is(NOT_ANONYMOUS));
// Lambdas aren't anonymous classes per
Class.isAnonymousClass() - need a real anonymous class expression.
+ @SuppressWarnings({
+ "java:S2133" // An actual anonymous class (not
Greeter.class) is required so isAnonymousClass() is exercised.
+ })
var anon = new Greeter() {
@Override
public String greet() { return null; }
@@ -164,6 +167,9 @@ class ClassInfo_Coverage_Test extends TestBase {
@Test
void f03_isChildOfType_nonClassType_false() {
+ @SuppressWarnings({
+ "java:S2133" // An anonymous subclass (not
ArrayList.class) is required to obtain a genuine ParameterizedType via
getGenericSuperclass().
+ })
var pt = new ArrayList<String>()
{}.getClass().getGenericSuperclass();
assertFalse(ClassInfo.of(ArrayList.class).isChildOf(pt));
}
@@ -235,6 +241,9 @@ class ClassInfo_Coverage_Test extends TestBase {
@Test
void i04_isParentOfType_nonClassType_false() {
+ @SuppressWarnings({
+ "java:S2133" // An anonymous subclass (not
ArrayList.class) is required to obtain a genuine ParameterizedType via
getGenericSuperclass().
+ })
var pt = new ArrayList<String>()
{}.getClass().getGenericSuperclass();
assertFalse(ClassInfo.of(List.class).isParentOf(pt));
}
@@ -361,6 +370,9 @@ class ClassInfo_Coverage_Test extends TestBase {
@Test
void l07_isAssignableFromType_nonClassType_false() {
+ @SuppressWarnings({
+ "java:S2133" // An anonymous subclass (not
ArrayList.class) is required to obtain a genuine ParameterizedType via
getGenericSuperclass().
+ })
var pt = new ArrayList<String>()
{}.getClass().getGenericSuperclass();
assertFalse(ClassInfo.of(List.class).isAssignableFrom(pt));
}
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ReflectionMap_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ReflectionMap_Coverage_Test.java
index b1d3b915f8..ea464224e9 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ReflectionMap_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/reflect/ReflectionMap_Coverage_Test.java
@@ -72,7 +72,7 @@ class ReflectionMap_Coverage_Test extends TestBase {
@Test
void a06_constructorEntryEquals_notAConstructorEntry_false() {
var a = new ReflectionMap.ConstructorEntry<>("Foo",
"com.foo.Foo", new String[] {"String"}, 1);
- assertNotEquals(a, "not a ConstructorEntry");
+ assertNotEquals("not a ConstructorEntry", a);
}
@Test
@@ -131,7 +131,7 @@ class ReflectionMap_Coverage_Test extends TestBase {
@Test
void b07_methodEntryEquals_notAMethodEntry_false() {
var a = new ReflectionMap.MethodEntry<>("Foo", "com.foo.Foo",
"myMethod", new String[] {"String"}, 1);
- assertNotEquals(a, "not a MethodEntry");
+ assertNotEquals("not a MethodEntry", a);
}
@Test
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/EnvVarSecretStore_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/EnvVarSecretStore_Test.java
index ff6ac7068a..de2baa37cf 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/EnvVarSecretStore_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/EnvVarSecretStore_Test.java
@@ -57,11 +57,13 @@ class EnvVarSecretStore_Test extends TestBase {
}
@Test void a05_storeIsUnsupported() {
- assertThrows(UnsupportedOperationException.class, () -> new
EnvVarSecretStore().store("k", "v".toCharArray()));
+ var store = new EnvVarSecretStore();
+ assertThrows(UnsupportedOperationException.class, () ->
store.store("k", "v".toCharArray()));
}
@Test void a06_deleteIsUnsupported() {
- assertThrows(UnsupportedOperationException.class, () -> new
EnvVarSecretStore().delete("k"));
+ var store = new EnvVarSecretStore();
+ assertThrows(UnsupportedOperationException.class, () ->
store.delete("k"));
}
@Test void a07_nullKeyRejected() {
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/InMemorySecretStore_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/InMemorySecretStore_Test.java
index 5a1f86ddab..a27561c6fc 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/InMemorySecretStore_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/secret/InMemorySecretStore_Test.java
@@ -91,7 +91,8 @@ class InMemorySecretStore_Test extends TestBase {
@Test void a10_nullArgumentsRejected() {
var store = new InMemorySecretStore();
- assertThrows(IllegalArgumentException.class, () ->
store.store(null, "v".toCharArray()));
+ var chars = "v".toCharArray();
+ assertThrows(IllegalArgumentException.class, () ->
store.store(null, chars));
assertThrows(IllegalArgumentException.class, () ->
store.store("k", null));
assertThrows(IllegalArgumentException.class, () ->
store.find(null));
assertThrows(IllegalArgumentException.class, () ->
store.exists(null));
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/CollectionUtils_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/CollectionUtils_Coverage_Test.java
index c8432efcab..01c81226cf 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/CollectionUtils_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/CollectionUtils_Coverage_Test.java
@@ -91,11 +91,11 @@ class CollectionUtils_Coverage_Test extends TestBase {
@Test
void b04_removeNegations_nullAndBorderlineTokens_areTreatedAsLiterals()
{
- // Exercises every branch of the "token != null &&
token.length() > 1 && token.charAt(0) == '-'"
- // check in both loops:
- // null -> short-circuits on the null check
- // "-" -> length 1, fails the "length() > 1" check
- // "ab" -> length > 1 but doesn't start with '-'
+ // Exercises every branch of the not-null / length-over-one /
leading-dash negation-token check
+ // in both loops, using these deliberately borderline inputs:
+ // null -> short-circuits on the not-null check
+ // "-" -> length one, fails the length-over-one check
+ // "ab" -> length over one but doesn't start with a dash
// "-a" -> the one genuine negation token, present to force
the second loop to run
var input = new ArrayList<String>();
input.add(null);
diff --git
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ObjectUtils_Coverage_Test.java
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ObjectUtils_Coverage_Test.java
index 37638f450f..17e24c8509 100644
---
a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ObjectUtils_Coverage_Test.java
+++
b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ObjectUtils_Coverage_Test.java
@@ -178,8 +178,10 @@ class ObjectUtils_Coverage_Test extends TestBase {
// own abs(). Pinning the CURRENT (buggy) behavior here rather
than fixing it.
var value = BigDecimal.valueOf(-5);
assertThrows(ClassCastException.class, () -> {
+ @SuppressWarnings({
+ "java:S1854" // Dead store: the checkcast to
BigDecimal, inserted at this assignment, is what's under test.
+ })
BigDecimal result = abs(value);
- assertNotNull(result); // unreachable; keeps the
assignment from being flagged as dead
});
}
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin.java
index 4123990e98..9d0c254ec2 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin.java
@@ -78,6 +78,9 @@ public class ConsoleDataTablesFreemarkerMixin extends
ConsoleFreemarkerMixin {
*
* @return A new builder.
*/
+ @SuppressWarnings({
+ "java:S9149" // Intentional per-subclass builder-factory
override matching FreemarkerMixin.create()'s own convention; each mixin
subclass returns its own nested Builder type.
+ })
public static Builder create() {
return new Builder();
}
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/DataTableMethodModel.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/DataTableMethodModel.java
index 3a1c76471d..26b10133c8 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/DataTableMethodModel.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/DataTableMethodModel.java
@@ -32,7 +32,7 @@ import freemarker.template.utility.*;
*
* <p>
* Reuses the exact serialize-then-mark-trusted adapter {@code
console-ui-freemarker}'s {@code TagMethodModel} built
- * for {@code <@tag>} (TODO-361 Phase 5) — not reinvented here: (1) call
{@link DataTablesTable#of(String,
+ * for {@code <@tag>} (ticket 361 Phase 5) — not reinvented here: (1)
call {@link DataTablesTable#of(String,
* Collection, Class)} (which additively honors each row property's {@code
@Html(render=...)} as of Phase 6), (2) add
* {@code class="jc-table"} alongside the {@link DataTablesTable#MARKER_ATTR}
marker the shipped
* {@code juneau-datatables.js} glue already looks for, (3) serialize the
returned {@link Table} via its own
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin_Test.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin_Test.java
index 03be210445..d9aa5c6ce0 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin_Test.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker-datatables/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/datatables/ConsoleDataTablesFreemarkerMixin_Test.java
@@ -19,6 +19,7 @@ package
org.apache.juneau.rest.server.view.freemarker.console.datatables;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
+import java.util.regex.*;
import org.apache.juneau.*;
import org.apache.juneau.commons.inject.*;
@@ -33,7 +34,7 @@ import
org.apache.juneau.rest.server.view.freemarker.console.*;
import org.junit.jupiter.api.*;
/**
- * TODO-361 Phase 7 gate: the {@code <@datatable>} macro (this module's only
deliverable) — a golden-HTML
+ * Ticket 361 Phase 7 gate: the {@code <@datatable>} macro (this module's only
deliverable) — a golden-HTML
* integration proof that a row bean's {@code
@Html(render=TagHtmlRender.class)} enum property (Phase 4) renders as
* pill markup (Phase 6's now-render-aware {@code DataTablesTable}) nested
inside a {@code jc-table} through the
* same trusted-HTML adapter Phase 5 built for {@code <@tag>}.
@@ -99,9 +100,11 @@ class ConsoleDataTablesFreemarkerMixin_Test extends
TestBase {
@Test void
a02_consoleDataTablesFreemarkerMixin_rendersPillMarkupInsideJcTable() throws
Exception {
var c = MockRestClient.buildLax(DataTablesHost.class);
var body =
c.get("/releases").run().assertStatus(200).getContent().asString();
-
assertTrue(body.matches("(?s).*<table(?=[^>]*class=['\"]jc-table['\"])(?=[^>]*data-juneau-datatable)[^>]*>.*"),
+ // find() on an anchor-free pattern (no wrapping .*) avoids the
super-linear backtracking risk of
+ // String.matches() with unbounded quantifiers at both ends.
+
assertTrue(Pattern.compile("<table(?=[^>]*class=['\"]jc-table['\"])(?=[^>]*data-juneau-datatable)[^>]*>").matcher(body).find(),
() -> "expected <table class='jc-table'
...data-juneau-datatable...> (attribute order not asserted), body:\n" + body);
-
assertTrue(body.matches("(?s).*<td[^>]*>\\s*<span[^>]*class=['\"]tag status
released['\"][^>]*>.*</td>.*"),
+
assertTrue(Pattern.compile("<td[^>]*>\\s*<span[^>]*class=['\"]tag status
released['\"][^>]*>.*?</td>", Pattern.DOTALL).matcher(body).find(),
() -> "expected <span class='tag status released'>
nested inside a <td>, body:\n" + body);
assertTrue(body.contains("widget"), () -> "expected the plain
property's raw value too, body:\n" + body);
assertFalse(body.contains("<span"), () -> "macro output was
HTML-escaped (double-escaped), body:\n" + body);
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin.java
index 0e714a888e..dfac7307ac 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/main/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin.java
@@ -98,6 +98,9 @@ public class ConsoleFreemarkerMixin extends FreemarkerMixin {
*
* @return A new builder.
*/
+ @SuppressWarnings({
+ "java:S9149" // Intentional per-subclass builder-factory
override matching FreemarkerMixin.create()'s own convention; each mixin
subclass returns its own nested Builder type.
+ })
public static Builder create() {
return new Builder();
}
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin_Test.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin_Test.java
index 6de82a4bb8..119dfdafba 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin_Test.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ConsoleFreemarkerMixin_Test.java
@@ -18,6 +18,8 @@ package org.apache.juneau.rest.server.view.freemarker.console;
import static org.junit.jupiter.api.Assertions.*;
+import java.util.regex.*;
+
import org.apache.juneau.*;
import org.apache.juneau.commons.inject.*;
import org.apache.juneau.rest.mock.classic.*;
@@ -167,7 +169,9 @@ class ConsoleFreemarkerMixin_Test extends TestBase {
var c = MockRestClient.buildLax(ConsoleHost.class);
var body =
c.get("/mypage").run().assertStatus(200).getContent().asString();
assertFalse(body.contains("<span"), () -> "macro output was
HTML-escaped (double-escaped), body:\n" + body);
- assertTrue(body.matches("(?s).*<span[^>]*class=['\"]tag status
released['\"][^>]*>.*"),
+ // find() on an anchor-free pattern (no wrapping .*) avoids the
super-linear backtracking risk of
+ // String.matches() with unbounded quantifiers at both ends.
+ assertTrue(Pattern.compile("<span[^>]*class=['\"]tag status
released['\"][^>]*>").matcher(body).find(),
() -> "expected literal <span class='tag status
released'> markup, body:\n" + body);
}
diff --git
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ModuleGraph_ImportScan_Test.java
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ModuleGraph_ImportScan_Test.java
index 6ea9e41a21..71acf7c325 100644
---
a/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ModuleGraph_ImportScan_Test.java
+++
b/juneau-rest/juneau-rest-server-console-ui-freemarker/src/test/java/org/apache/juneau/rest/server/view/freemarker/console/ModuleGraph_ImportScan_Test.java
@@ -41,7 +41,7 @@ class ModuleGraph_ImportScan_Test extends TestBase {
.filter(p -> p.toString().endsWith(".java"))
.filter(ModuleGraph_ImportScan_Test::importsDatatables)
.map(Path::toString)
- .collect(Collectors.toList());
+ .toList();
assertTrue(offenders.isEmpty(), () -> "Found forbidden
org.apache.juneau.rest.server.datatables.* import(s) in: " + offenders);
}
}
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesMixin.java
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesMixin.java
index 6b891ace01..0639dc30d4 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesMixin.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesMixin.java
@@ -110,6 +110,9 @@ public class DataTablesMixin {
static final String GLUE_CACHE_CONTROL = "max-age=86400, public";
/** The shipped glue script bytes, read once from the classpath on
first request. */
+ @SuppressWarnings({
+ "java:S3077" // Double-checked-locking safe publication of one
whole immutable array reference, not per-element mutation; AtomicReferenceArray
solves a different problem.
+ })
private static volatile byte[] glueScript;
/** A known-good CDN URL for jQuery (the caller-supplied DataTables
dependency). Documentation aid. */
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesQueryProtocol.java
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesQueryProtocol.java
index b423f80633..627d790536 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesQueryProtocol.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesQueryProtocol.java
@@ -107,6 +107,9 @@ import org.apache.juneau.rest.server.converter.*;
*/
public class DataTablesQueryProtocol implements QueryProtocol {
+ private static final String PARAM_COLUMNS_PREFIX = "columns[";
+ private static final String PARAM_ORDER_PREFIX = "order[";
+
private final Class<?> rowType;
/**
@@ -144,14 +147,14 @@ public class DataTablesQueryProtocol implements
QueryProtocol {
// Column descriptors
(columns[i][data|name|searchable|orderable|search[value]|search[regex]]),
capped.
var cols = new ArrayList<Column>();
- for (var i = 0; i < settings.maxColumns() &&
p.contains("columns[" + i + "][data]"); i++) {
- var data = p.get("columns[" + i +
"][data]").asString().orElse("");
- var name = p.get("columns[" + i +
"][name]").asString().orElse("");
+ for (var i = 0; i < settings.maxColumns() &&
p.contains(PARAM_COLUMNS_PREFIX + i + "][data]"); i++) {
+ var data = p.get(PARAM_COLUMNS_PREFIX + i +
"][data]").asString().orElse("");
+ var name = p.get(PARAM_COLUMNS_PREFIX + i +
"][name]").asString().orElse("");
var key = resolveKey(data, name, positionalKeys);
- var searchable = p.get("columns[" + i +
"][searchable]").asString().map(Boolean::parseBoolean).orElse(Boolean.TRUE);
- var orderable = p.get("columns[" + i +
"][orderable]").asString().map(Boolean::parseBoolean).orElse(Boolean.TRUE);
- var colSearch = p.get("columns[" + i +
"][search][value]").asString().orElse("");
- var colRegex = p.get("columns[" + i +
"][search][regex]").asString().map(Boolean::parseBoolean).orElse(Boolean.FALSE);
+ var searchable = p.get(PARAM_COLUMNS_PREFIX + i +
"][searchable]").asString().map(Boolean::parseBoolean).orElse(Boolean.TRUE);
+ var orderable = p.get(PARAM_COLUMNS_PREFIX + i +
"][orderable]").asString().map(Boolean::parseBoolean).orElse(Boolean.TRUE);
+ var colSearch = p.get(PARAM_COLUMNS_PREFIX + i +
"][search][value]").asString().orElse("");
+ var colRegex = p.get(PARAM_COLUMNS_PREFIX + i +
"][search][regex]").asString().map(Boolean::parseBoolean).orElse(Boolean.FALSE);
cols.add(new Column(key, searchable, orderable,
colSearch, colRegex));
}
@@ -175,9 +178,9 @@ public class DataTablesQueryProtocol implements
QueryProtocol {
// Ordering (capped; an order referencing a non-orderable or
empty-key column is skipped).
var sort = new ArrayList<String>();
- for (var j = 0; j < settings.maxOrderColumns() &&
p.contains("order[" + j + "][column]"); j++) {
- var ci = p.get("order[" + j +
"][column]").asInteger().orElse(-1);
- var dir = p.get("order[" + j +
"][dir]").asString().orElse("asc");
+ for (var j = 0; j < settings.maxOrderColumns() &&
p.contains(PARAM_ORDER_PREFIX + j + "][column]"); j++) {
+ var ci = p.get(PARAM_ORDER_PREFIX + j +
"][column]").asInteger().orElse(-1);
+ var dir = p.get(PARAM_ORDER_PREFIX + j +
"][dir]").asString().orElse("asc");
if (ci >= 0 && ci < cols.size()) {
var c = cols.get(ci);
if (c.orderable && ! c.key.isEmpty())
@@ -216,10 +219,10 @@ public class DataTablesQueryProtocol implements
QueryProtocol {
return
req.getContext().getBeanStore().getBean(QueryableSettings.class).orElse(QueryableSettings.DEFAULT);
}
- /** The readable bean-property names of {@link #rowType} (in bean
order), or <jk>null</jk> if no row type was supplied. */
+ /** The readable bean-property names of {@link #rowType} (in bean
order), or empty if no row type was supplied. */
private List<String> positionalKeys() {
if (rowType == null)
- return null;
+ return List.of();
var out = new ArrayList<String>();
for (var col : DataTablesColumns.of(rowType))
out.add((String) col.get("data"));
@@ -238,7 +241,7 @@ public class DataTablesQueryProtocol implements
QueryProtocol {
return data;
if (! name.isEmpty())
return name;
- if (! data.isEmpty() && positionalKeys != null) {
+ if (! data.isEmpty()) {
// data is all-digits here (non-numeric data returned
above), so the parsed index is always >= 0.
var index = Integer.parseInt(data);
if (index < positionalKeys.size())
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesResults.java
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesResults.java
index 40c0d9c03f..acc53733be 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesResults.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesResults.java
@@ -55,7 +55,7 @@ public class DataTablesResults<T> {
/**
* Constructor.
*/
- public DataTablesResults() {}
+ public DataTablesResults() { /* All fields are populated via the fluent
setters below. */ }
/**
* Static creator.
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesTable.java
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesTable.java
index f2ddff9e6c..67cbbd10e6 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesTable.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/main/java/org/apache/juneau/rest/server/datatables/DataTablesTable.java
@@ -83,7 +83,7 @@ public class DataTablesTable {
* Builds a DataTables-ready table using the specified marshalling
context, deriving the columns from the specified
* row bean type via {@link DataTablesColumns#of(MarshallingContext,
Class)}, additively honoring each bean
* property's {@link Html @Html(render)} the same way the ordinary
{@code HtmlSerializer}/{@code HtmlDocSerializer}
- * path already does (TODO-361 Phase 6).
+ * path already does (ticket 361 Phase 6).
*
* <p>
* Using one context for both column derivation and cell reads keeps
the {@code data} keys and the row values
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesClientHelpers_Test.java
b/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesClientHelpers_Test.java
index c0c1785caf..3aa7a51379 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesClientHelpers_Test.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesClientHelpers_Test.java
@@ -119,7 +119,7 @@ class DataTablesClientHelpers_Test extends TestBase {
// DataTablesTable
//------------------------------------------------------------------------------------------------------------------
- @Test void b01_beanRowsRender() throws Exception {
+ @Test void b01_beanRowsRender() {
var html =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of("releases", List.of(new
Row()), Row.class));
assertTrue(html.contains("id='releases'") ||
html.contains("id=\"releases\""), html);
assertTrue(html.contains(DataTablesTable.MARKER_ATTR), html);
@@ -127,7 +127,7 @@ class DataTablesClientHelpers_Test extends TestBase {
assertTrue(html.contains("Alice"), html);
// tbody cell (bean read)
}
- @Test void b02_mapRowsWithExplicitColumnsAndNullCell() throws Exception
{
+ @Test void b02_mapRowsWithExplicitColumnsAndNullCell() {
var columns = List.of(
col("name", "Name"),
col("age", "Age")
@@ -142,13 +142,13 @@ class DataTablesClientHelpers_Test extends TestBase {
assertTrue(html.contains(">40<") || html.contains("40"), html);
}
- @Test void b03_emptyRows() throws Exception {
+ @Test void b03_emptyRows() {
var html =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of("empty", List.of(),
Row.class));
assertTrue(html.contains("id='empty'") ||
html.contains("id=\"empty\""), html);
}
// MarshallingContext overloads (of(ctx,id,rows,rowType) and
of(ctx,id,rows,columns)) render the same content.
- @Test void b04_marshallingContextOverloads() throws Exception {
+ @Test void b04_marshallingContextOverloads() {
var fromType =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of(MarshallingContext.DEFAULT,
"releases", List.of(new Row()), Row.class));
assertTrue(fromType.contains("Alice") &&
fromType.contains("Ship Code"), fromType);
diff --git
a/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesTable_HtmlRenderHonoring_Test.java
b/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesTable_HtmlRenderHonoring_Test.java
index f4daef4f5b..6d69121176 100644
---
a/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesTable_HtmlRenderHonoring_Test.java
+++
b/juneau-rest/juneau-rest-server-datatables/src/test/java/org/apache/juneau/rest/server/datatables/DataTablesTable_HtmlRenderHonoring_Test.java
@@ -27,7 +27,7 @@ import org.apache.juneau.marshall.serializer.*;
import org.junit.jupiter.api.*;
/**
- * TODO-361 Phase 6: {@code DataTablesTable.of(ctx, id, rows, rowType)}
additively honors a property's
+ * Ticket 361 Phase 6: {@code DataTablesTable.of(ctx, id, rows, rowType)}
additively honors a property's
* {@code @Html(render=...)} the same way the ordinary {@code
HtmlSerializer}/{@code HtmlDocSerializer} path already
* does — closing r3 should-fixes S4 (Map-row branch preserved) and S5
({@code DataTablesTable} does not
* actually resolve {@code BeanMeta} today; it delegates to the raw-value
{@code DataTablesColumns}-overload path).
@@ -63,7 +63,7 @@ class DataTablesTable_HtmlRenderHonoring_Test extends
TestBase {
// it delegates to the raw-value columns-overload path
(DataTablesTable.java:94-96 as of pre-Phase-6 source).
//------------------------------------------------------------------------------------------------------------------
- @Test void a01_htmlRenderHonored_annotatedPropertyIsTransformed()
throws Exception {
+ @Test void a01_htmlRenderHonored_annotatedPropertyIsTransformed() {
var html =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of(MarshallingContext.DEFAULT,
"t", List.of(new Row()), Row.class));
assertTrue(html.contains("RELEASED"), () -> "expected the
LocalFixtureRender-transformed (uppercased) value in the <td>, got:\n" + html);
}
@@ -72,7 +72,7 @@ class DataTablesTable_HtmlRenderHonoring_Test extends
TestBase {
// Back-compat: an un-annotated property on the SAME row bean still
emits the raw value, unchanged.
//------------------------------------------------------------------------------------------------------------------
- @Test void a02_unannotatedPropertyOnSameRow_stillRaw() throws Exception
{
+ @Test void a02_unannotatedPropertyOnSameRow_stillRaw() {
var html =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of(MarshallingContext.DEFAULT,
"t", List.of(new Row()), Row.class));
assertTrue(html.contains("widget"), () -> "expected the plain
property's raw (lowercase, unmodified) value, got:\n" + html);
assertFalse(html.contains("WIDGET"), () -> "un-annotated
property must NOT be transformed, got:\n" + html);
@@ -95,7 +95,7 @@ class DataTablesTable_HtmlRenderHonoring_Test extends
TestBase {
// String.valueOf(value) would happily print "NULL" for -- assert the
SHORT-CIRCUIT, not just "no exception").
//------------------------------------------------------------------------------------------------------------------
- @Test void a04_nullValueOnAnnotatedProperty_noNpe_rendersEmpty() throws
Exception {
+ @Test void a04_nullValueOnAnnotatedProperty_noNpe_rendersEmpty() {
var html =
HtmlSerializer.DEFAULT.toString(DataTablesTable.of(MarshallingContext.DEFAULT,
"t", List.of(new NullRow()), NullRow.class));
assertFalse(html.contains("NULL"), () -> "getContent(...) must
not be invoked on a null value, got:\n" + html);
}
@@ -106,7 +106,7 @@ class DataTablesTable_HtmlRenderHonoring_Test extends
TestBase {
// both before and after this change (a Map row has no BeanPropertyMeta
/ @Html(render)).
//------------------------------------------------------------------------------------------------------------------
- @Test void a05_mapRowWithBeanRowType_stillRawNoRenderAttempted() throws
Exception {
+ @Test void a05_mapRowWithBeanRowType_stillRawNoRenderAttempted() {
var row = new LinkedHashMap<String,Object>();
row.put("status", "released");
row.put("name", "widget");
@@ -121,7 +121,7 @@ class DataTablesTable_HtmlRenderHonoring_Test extends
TestBase {
// DataTablesTable.of(..., rowType) -- named explicitly so it shows up
in the diff/PR description.
//------------------------------------------------------------------------------------------------------------------
- @Test void
a06_behaviorChangeNotPurelyAdditive_existingHtmlRenderNowAppliesInDataTablesTableToo()
throws Exception {
+ @Test void
a06_behaviorChangeNotPurelyAdditive_existingHtmlRenderNowAppliesInDataTablesTableToo()
{
// The serializer path (unrelated to DataTablesTable) already
honors @Html(render) -- this is pre-existing.
var plainSerializerHtml = HtmlSerializer.DEFAULT.toString(new
Row());
assertTrue(plainSerializerHtml.contains("RELEASED"), () ->
"sanity: plain HtmlSerializer already honors @Html(render), got:\n" +
plainSerializerHtml);