This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5659-lazy-params-request-scoping
in repository https://gitbox.apache.org/repos/asf/struts.git

commit c35483c65eab332e0635f508399804732bf36d98
Author: Lukasz Lenart <[email protected]>
AuthorDate: Mon Jul 27 10:18:42 2026 +0200

    WW-5659 feat(core): add InterceptorParams contract and DisableParams holder
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 .../apache/struts2/interceptor/DisableParams.java  | 51 ++++++++++++++++++
 .../struts2/interceptor/InterceptorParams.java     | 43 ++++++++++++++++
 .../struts2/interceptor/DisableParamsTest.java     | 60 ++++++++++++++++++++++
 3 files changed, 154 insertions(+)

diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/DisableParams.java 
b/core/src/main/java/org/apache/struts2/interceptor/DisableParams.java
new file mode 100644
index 000000000..aa3446787
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/DisableParams.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor;
+
+/**
+ * Opt-in support for the {@code disabled} interceptor parameter.
+ * <p>
+ * Interceptors implementing {@link WithLazyParams} must have their params 
holder extend this
+ * class to support {@code <param name="disabled">...</param>}; there is 
deliberately no
+ * fallback to the interceptor instance, which would reintroduce shared 
mutable state.
+ *
+ * @since 7.3.0
+ */
+public class DisableParams implements InterceptorParams {
+
+    private boolean disabled;
+
+    public DisableParams() {
+    }
+
+    protected DisableParams(DisableParams other) {
+        this.disabled = other.disabled;
+    }
+
+    /**
+     * @param disable if {@code true}, execution of the interceptor is skipped 
for this invocation
+     */
+    public void setDisabled(String disable) {
+        this.disabled = Boolean.parseBoolean(disable);
+    }
+
+    public boolean isDisabled() {
+        return disabled;
+    }
+}
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/InterceptorParams.java 
b/core/src/main/java/org/apache/struts2/interceptor/InterceptorParams.java
new file mode 100644
index 000000000..68cf3e2ba
--- /dev/null
+++ b/core/src/main/java/org/apache/struts2/interceptor/InterceptorParams.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor;
+
+/**
+ * Contract for an object holding the parameters of a single interceptor.
+ * <p>
+ * Implementations are per-invocation value objects: the framework resolves 
configured
+ * parameters into a fresh instance for each action invocation, so nothing is 
written back
+ * onto the interceptor, which stays immutable after {@link 
Interceptor#init()}.
+ *
+ * @since 7.3.0
+ */
+public interface InterceptorParams {
+
+    /**
+     * Called when a {@code ${...}} parameter could not be resolved for the 
current invocation.
+     * The framework skips the write, leaving the seeded configuration value 
in place, and
+     * notifies the holder so it can decide how to degrade.
+     * <p>
+     * The default implementation does nothing.
+     *
+     * @param paramName name of the parameter that could not be resolved
+     */
+    default void unresolved(String paramName) {
+    }
+}
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/DisableParamsTest.java 
b/core/src/test/java/org/apache/struts2/interceptor/DisableParamsTest.java
new file mode 100644
index 000000000..3a41b0b84
--- /dev/null
+++ b/core/src/test/java/org/apache/struts2/interceptor/DisableParamsTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.interceptor;
+
+import junit.framework.TestCase;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DisableParamsTest extends TestCase {
+
+    public void testDisabledDefaultsToFalse() {
+        assertThat(new DisableParams().isDisabled()).isFalse();
+    }
+
+    public void testSetDisabledParsesStringValue() {
+        DisableParams params = new DisableParams();
+        params.setDisabled("true");
+        assertThat(params.isDisabled()).isTrue();
+
+        params.setDisabled("false");
+        assertThat(params.isDisabled()).isFalse();
+    }
+
+    public void testSetDisabledTreatsNonBooleanTextAsFalse() {
+        DisableParams params = new DisableParams();
+        params.setDisabled("yes");
+        assertThat(params.isDisabled()).isFalse();
+    }
+
+    public void testCopyConstructorCarriesDisabledFlag() {
+        DisableParams original = new DisableParams();
+        original.setDisabled("true");
+
+        DisableParams copy = new DisableParams(original);
+
+        assertThat(copy.isDisabled()).isTrue();
+    }
+
+    public void testUnresolvedDefaultsToNoOp() {
+        DisableParams params = new DisableParams();
+        params.unresolved("someParam");   // must not throw
+        assertThat(params.isDisabled()).isFalse();
+    }
+}

Reply via email to