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 3ebddbf460 Marshall module improvements
3ebddbf460 is described below
commit 3ebddbf46036456347fec1d15661b54ebd38e560
Author: James Bognar <[email protected]>
AuthorDate: Thu Dec 11 15:12:21 2025 -0500
Marshall module improvements
---
TODO.md | 50 +------
.../juneau/commons/utils/AssertionUtils.java | 2 -
.../juneau/commons/utils/ThrowableUtils.java | 1 +
.../src/main/java/org/apache/juneau/BeanMeta.java | 7 +-
.../java/org/apache/juneau/BeanPropertyMeta.java | 160 +++++++++++++++------
.../main/java/org/apache/juneau/BeanSession.java | 5 +
.../apache/juneau/internal/DelegateBeanMap.java | 2 +-
7 files changed, 129 insertions(+), 98 deletions(-)
diff --git a/TODO.md b/TODO.md
index a928b0298f..18c6c1eea3 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,48 +1,4 @@
-# TODO List
+# TODO
-**Last generated TODO number: TODO-94**
-
-This file tracks pending tasks for the Apache Juneau project. For completed
items, see [TODO-completed.md](TODO-completed.md).
-
-## Issues to Fix
-
-- [ ] TODO-3 Figure out why CallLogger and ThrownStore objects are not
automatically injected into REST classes in spring boot.
-
-## Code Quality Improvements
-
-- [ ] TODO-5 Fields should be alphabetized.
-- [ ] TODO-6 Investigate if there are any other W3 or RFC specifications that
would make good candidates for new bean modules.
-- [ ] TODO-12 Tests for Spring Boot testing.
-- [ ] TODO-14 The name parameter on annotations like Query when used on method
parameters should be optional if parameter names are persisted in the bytecode.
-- [x] TODO-15 It appears StringUtils is going to become a commonly-used
external class. Let's see if we can enhance it with commonly used string
utility methods.
-- [ ] TODO-27 Determine if there are any other good candidates for
Stringifiers and Listifiers.
-- [ ] TODO-29 Finish setting up SonarQube analysis in git workflow.
-- [ ] TODO-54 Search for places in code where Calendar should be replaced with
ZonedDateTime.
-- [ ] TODO-90 Investigate replacing `StringUtils.parseIsoCalendar()` with
java.time APIs and removing the helper if possible.
-- [ ] TODO-92 Investigate if `ClassInfo.asSubclass(Class<U>)` can return a
`ClassInfoTyped<U>` object instead of `ClassInfo` for better type safety.
-- [ ] TODO-93 Investigate if `ReflectionUtils.info(Class<?>)` should return a
`ClassInfoTyped` object instead of `ClassInfo` for better type safety.
-
-## Framework Improvements
-
-- [x] TODO-19 ClassInfo improvements to getMethod (e.g. getMethodExact vs
getMethod).
-- [ ] TODO-21 Thrown NotFound causes - javax.servlet.ServletException: Invalid
method response: 200
-- [x] TODO-89 Add ClassInfoTyped
-- [ ] TODO-91 Security: LogsResource returns HTTP 500 instead of 404 for
malformed query parameters (CWE-74). When accessing log file URLs with encoded
special characters in query parameters (e.g., `?method=VIEW%5C%5C%5C%22`), the
system returns HTTP 500 "Invalid method response: 200" instead of HTTP 404. The
error suggests it's incorrectly trying to find a Java method matching a
malformed path. Should return 404 for invalid/malformed requests.
-- [ ] TODO-94 Add a "cloaked" mode to IRS to always return 404s in place of
40x/50x responses.
-
-## HTTP Response/Exception Improvements
-
-- [ ] TODO-22 HttpResponse should use list of Headers and have a
headers(Header...) method.
-- [ ] TODO-23 HttpResponse should allow you to set code.
-- [ ] TODO-24 HttpException subclasses can set status, but does it use code?
-- [ ] TODO-25 HttpException should use list of Headers and have a
headers(Header...) method.
-
-- [ ] TODO-26 @ResponseBody and @ResponseHeaders shouldn't be required on
HttpResponse objects.
-
-## Notes
-
-This TODO list tracks specific issues that need to be addressed in the Juneau
project.
-
-## Website/Docs
-
-- [ ] TODO-29 Add searching to website using Algolia DocSearch.
+- Find all places where we have system properties defined for juneau and
convert them to use the new Settings class.
+- Document "juneau.enableVerboseExceptions" setting.
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/AssertionUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/AssertionUtils.java
index 3e48330236..30f2cf3612 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/AssertionUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/AssertionUtils.java
@@ -19,8 +19,6 @@ package org.apache.juneau.commons.utils;
import static org.apache.juneau.commons.utils.ThrowableUtils.*;
import static org.apache.juneau.commons.utils.Utils.*;
-import java.util.concurrent.atomic.*;
-
/**
* Utility methods for argument validation and assertion.
*
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
index 7621517243..cec04b04de 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ThrowableUtils.java
@@ -31,6 +31,7 @@ import org.apache.juneau.commons.settings.*;
public class ThrowableUtils {
static AtomicBoolean VERBOSE = new
AtomicBoolean(Settings.get().getBoolean("juneau.enableVerboseExceptions").orElse(false));
+// static AtomicBoolean VERBOSE = new AtomicBoolean(true);
/**
* Interface used with {@link
Utils#safeSupplier(SupplierWithThrowable)}.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index eba30e0626..5be5b93fa3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -495,7 +495,7 @@ public class BeanMeta<T> {
var p = i.next();
try {
if (p.field == null)
-
p.setInnerField(findInnerBeanField(p.name));
+
findInnerBeanField(p.name).ifPresent(x -> p.setInnerField(x));
if (p.validate(beanContext,
beanRegistry.get(), typeVarImpls, readOnlyProps, writeOnlyProps)) {
@@ -1349,7 +1349,7 @@ public class BeanMeta<T> {
* @return The {@link FieldInfo} for the field if found, or
<jk>null</jk> if no matching field exists
* in the class hierarchy.
*/
- private FieldInfo findInnerBeanField(String name) {
+ private Optional<FieldInfo> findInnerBeanField(String name) {
var noIgnoreTransients = !
beanContext.isIgnoreTransientFields();
var ap = beanContext.getAnnotationProvider();
@@ -1362,8 +1362,7 @@ public class BeanMeta<T> {
&& ! ap.has(BeanIgnore.class, x)
&& x.hasName(name)
).stream())
- .findFirst()
- .orElse(null);
+ .findFirst();
// @formatter:on
}
}
\ No newline at end of file
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index 2929add051..12a2ffd3e9 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -18,6 +18,7 @@ package org.apache.juneau;
import static org.apache.juneau.commons.reflect.AnnotationTraversal.*;
import static org.apache.juneau.commons.reflect.ReflectionUtils.*;
+import static org.apache.juneau.commons.utils.AssertionUtils.*;
import static org.apache.juneau.commons.utils.ClassUtils.*;
import static org.apache.juneau.commons.utils.CollectionUtils.*;
import static org.apache.juneau.commons.utils.StringUtils.*;
@@ -88,6 +89,7 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
* @return This object.
*/
public Builder beanRegistry(BeanRegistry value) {
+ assertArgNotNull("value", value);
this.beanRegistry = value;
return this;
}
@@ -106,6 +108,7 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
* @return This object.
*/
public Builder delegateFor(BeanPropertyMeta value) {
+ assertArgNotNull("value", value);
this.delegateFor = value;
return this;
}
@@ -128,6 +131,7 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
* @return This object.
*/
public Builder rawMetaType(ClassMeta<?> value) {
+ assertArgNotNull("value", value);
this.rawTypeMeta = value;
this.typeMeta = rawTypeMeta;
return this;
@@ -156,60 +160,128 @@ public class BeanPropertyMeta implements
Comparable<BeanPropertyMeta> {
}
if (ci.isChildOf(Surrogate.class))
throw unsupportedOp("TODO - Surrogate swaps not
yet supported on bean properties.");
- throw rex("Invalid class used in @Swap annotation.
Must be a subclass of ObjectSwap or Surrogate. {0}", cn(c));
- }
+ throw rex("Invalid class used in @Swap annotation. Must be a
subclass of ObjectSwap or Surrogate. {0}", cn(c));
+ }
- Builder canRead() {
- this.canRead = true;
- return this;
- }
+ /**
+ * Marks this property as readable.
+ *
+ * @return This object.
+ */
+ public Builder canRead() {
+ this.canRead = true;
+ return this;
+ }
- Builder canWrite() {
- this.canWrite = true;
- return this;
- }
+ /**
+ * Marks this property as writable.
+ *
+ * @return This object.
+ */
+ public Builder canWrite() {
+ this.canWrite = true;
+ return this;
+ }
- BeanPropertyMeta.Builder setAsConstructorArg() {
- this.isConstructorArg = true;
- return this;
- }
+ /**
+ * Marks this property as a constructor argument.
+ *
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setAsConstructorArg() {
+ this.isConstructorArg = true;
+ return this;
+ }
- BeanPropertyMeta.Builder setExtraKeys(Method extraKeys) {
- setAccessible(extraKeys);
- this.extraKeys = extraKeys;
- return this;
- }
+ /**
+ * Sets the extra keys method for this bean property.
+ *
+ * @param value The method that returns extra keys for this property.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setExtraKeys(Method value) {
+ assertArgNotNull("value", value);
+ setAccessible(value);
+ this.extraKeys = value;
+ return this;
+ }
- BeanPropertyMeta.Builder setField(Field field) {
- setAccessible(field);
- this.field = field;
- this.innerField = field;
- return this;
- }
+ /**
+ * Sets the field for this bean property.
+ *
+ * @param value The field for this bean property.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setField(Field value) {
+ assertArgNotNull("value", value);
+ setAccessible(value);
+ this.field = value;
+ this.innerField = value;
+ return this;
+ }
- BeanPropertyMeta.Builder setGetter(Method getter) {
- setAccessible(getter);
- this.getter = getter;
- return this;
- }
+ /**
+ * Sets the getter method for this bean property.
+ *
+ * @param value The getter method for this bean property.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setGetter(Method value) {
+ assertArgNotNull("value", value);
+ setAccessible(value);
+ this.getter = value;
+ return this;
+ }
- BeanPropertyMeta.Builder setInnerField(FieldInfo innerField) {
- this.innerField = innerField == null ? null :
innerField.inner();
- return this;
- }
+ /**
+ * Sets the inner field for this bean property from a {@link FieldInfo}.
+ *
+ * @param value The field info containing the inner field.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setInnerField(FieldInfo value) {
+ assertArgNotNull("value", value);
+ this.innerField = value == null ? null : value.inner();
+ return this;
+ }
- BeanPropertyMeta.Builder setInnerField(Field innerField) {
- this.innerField = innerField;
- return this;
- }
+ /**
+ * Sets the inner field for this bean property.
+ *
+ * @param value The inner field for this bean property.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setInnerField(Field value) {
+ assertArgNotNull("value", value);
+ this.innerField = value;
+ return this;
+ }
- BeanPropertyMeta.Builder setSetter(Method setter) {
- setAccessible(setter);
- this.setter = setter;
- return this;
- }
+ /**
+ * Sets the setter method for this bean property.
+ *
+ * @param value The setter method for this bean property.
+ * @return This object.
+ */
+ public BeanPropertyMeta.Builder setSetter(Method value) {
+ assertArgNotNull("value", value);
+ setAccessible(value);
+ this.setter = value;
+ return this;
+ }
- boolean validate(BeanContext bc, BeanRegistry
parentBeanRegistry, Map<Class<?>,Class<?>[]> typeVarImpls, Set<String> bpro,
Set<String> bpwo) throws Exception {
+ /**
+ * Validates this bean property configuration.
+ *
+ * @param bc The bean context.
+ * @param parentBeanRegistry The parent bean registry.
+ * @param typeVarImpls Type variable implementations.
+ * @param bpro Bean properties read-only set.
+ * @param bpwo Bean properties write-only set.
+ * @return <jk>true</jk> if this property is valid, <jk>false</jk>
otherwise.
+ * @throws Exception If validation fails.
+ */
+ public boolean validate(BeanContext bc, BeanRegistry
parentBeanRegistry, Map<Class<?>,Class<?>[]> typeVarImpls, Set<String> bpro,
Set<String> bpwo) throws Exception {
var bdClasses = list();
var ap = bc.getAnnotationProvider();
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index de7c08f462..c6ee73707c 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -300,6 +300,11 @@ public class BeanSession extends ContextSession {
return ctx._class();
}
+ /**
+ * Returns the annotation provider for this session.
+ *
+ * @return The annotation provider for this session.
+ */
public AnnotationProvider getAnnotationProvider() {
return ctx.getAnnotationProvider();
}
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
index b5dacaab5b..426c3b8d54 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
@@ -132,7 +132,7 @@ public class DelegateBeanMap<T> extends BeanMap<T> {
if (overrideValues.containsKey(k))
p = BeanPropertyMeta.builder(this.meta,
k).overrideValue(overrideValues.get(k)).delegateFor(p).build();
if (p == null)
- p = BeanPropertyMeta.builder(this.meta,
k).overrideValue(null).delegateFor(p).build();
+ p = BeanPropertyMeta.builder(this.meta,
k).overrideValue(null).build();
l.add(p);
});
return l;